X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Ftrust%2Frights.py;h=eb0bb74720b4b48bbc0c95d21f43c4a92857e634;hb=862dfa7f7b8cce8c17e80c42aedd8d500ea86cb6;hp=2e2660f4504a5226dc097d068bb2eed77f0250bd;hpb=1d15635c313f9fe13a977a347382ab716fd4e52b;p=sfa.git diff --git a/sfa/trust/rights.py b/sfa/trust/rights.py index 2e2660f4..eb0bb747 100644 --- a/sfa/trust/rights.py +++ b/sfa/trust/rights.py @@ -1,44 +1,53 @@ ## -# This Module implements rights and lists of rights for the Geni wrapper. Rights +# This Module implements rights and lists of rights for the SFA. Rights # are implemented by two classes: # # Right - represents a single right # -# RightList - represents a list of rights +# Rights - represents a list of rights # # A right may allow several different operations. For example, the "info" right # allows "listslices", "listcomponentresources", etc. ## + + ## # privilege_table is a list of priviliges and what operations are allowed # per privilege. +# Note that "*" is a privilege granted by ProtoGENI slice authorities, and we +# give it access to the GENI AM calls -privilege_table = {"authority": ["register", "remove", "update", "resolve", "list", "getcredential"], +privilege_table = {"authority": ["register", "remove", "update", "resolve", "list", "getcredential", "*"], "refresh": ["remove", "update"], "resolve": ["resolve", "list", "getcredential"], - "sa": ["getticket", "redeemslice", "createslice", "deleteslice", "updateslice", - "getsliceresources", "getticket", "loanresources", "stopslice", "startslice", - "deleteslice", "resetslice", "listslices", "listnodes", "getpolicy"], - "embed": ["getticket", "redeemslice", "createslice", "deleteslice", "updateslice", "getsliceresources"], - "bind": ["getticket", "loanresources"], - "control": ["updateslice", "createslice", "stopslice", "startslice", "deleteslice", "resetslice", "getsliceresources"], + "sa": ["getticket", "redeemslice", "redeemticket", "createslice", "createsliver", "deleteslice", "deletesliver", "updateslice", + "getsliceresources", "getticket", "loanresources", "stopslice", "startslice", "renewsliver", + "deleteslice", "deletesliver", "resetslice", "listslices", "listnodes", "getpolicy", "sliverstatus"], + "embed": ["getticket", "redeemslice", "redeemticket", "createslice", "createsliver", "renewsliver", "deleteslice", + "deletesliver", "updateslice", "sliverstatus", "getsliceresources", "shutdown"], + "bind": ["getticket", "loanresources", "redeemticket"], + "control": ["updateslice", "createslice", "createsliver", "renewsliver", "sliverstatus", "stopslice", "startslice", + "deleteslice", "deletesliver", "resetslice", "getsliceresources", "getgids"], "info": ["listslices", "listnodes", "getpolicy"], - "ma": ["setbootstate", "getbootstate", "reboot"]} + "ma": ["setbootstate", "getbootstate", "reboot", "getgids", "gettrustedcerts"], + "operator": ["gettrustedcerts", "getgids"], + "*": ["createsliver", "deletesliver", "sliverstatus", "renewsliver", "shutdown"]} + ## -# Determine tje rights that an object should have. The rights are entirely +# Determine the rights that an object should have. The rights are entirely # dependent on the type of the object. For example, users automatically # get "refresh", "resolve", and "info". # # @param type the type of the object (user | sa | ma | slice | node) # @param name human readable name of the object (not used at this time) # -# @return RightList object containing rights +# @return Rights object containing rights def determine_rights(type, name): - rl = RightList() + rl = Rights() # rights seem to be somewhat redundant with the type of the credential. # For example, a "sa" credential implies the authority right, because @@ -48,18 +57,23 @@ def determine_rights(type, name): rl.add("refresh") rl.add("resolve") rl.add("info") - elif type == "sa": - rl.add("authority,sa") - elif type == "ma": - rl.add("authority,ma") + elif type in ["sa", "authority+sa"]: + rl.add("authority") + rl.add("sa") + elif type in ["ma", "authority+ma", "cm", "authority+cm", "sm", "authority+sm"]: + rl.add("authority") + rl.add("ma") elif type == "authority": - rl.add("authority,sa,ma") + rl.add("authority") + rl.add("sa") + rl.add("ma") elif type == "slice": rl.add("refresh") rl.add("embed") rl.add("bind") rl.add("control") rl.add("info") +# wouldn't that be authority+cm instead ? elif type == "component": rl.add("operator") return rl @@ -71,55 +85,59 @@ def determine_rights(type, name): class Right: - ## - # Create a new right. - # - # @param kind is a string naming the right. For example "control" + ## + # Create a new right. + # + # @param kind is a string naming the right. For example "control" + + def __init__(self, kind, delegate=False): + self.kind = kind + self.delegate = delegate - def __init__(self, kind): - self.kind = kind + ## + # Test to see if this right object is allowed to perform an operation. + # Returns True if the operation is allowed, False otherwise. + # + # @param op_name is a string naming the operation. For example "listslices". - ## - # Test to see if this right object is allowed to perform an operation. - # Returns True if the operation is allowed, False otherwise. - # - # @param op_name is a string naming the operation. For example "listslices". + def can_perform(self, op_name): + allowed_ops = privilege_table.get(self.kind.lower(), None) + if not allowed_ops: + return False - def can_perform(self, op_name): - allowed_ops = privilege_table.get(self.kind.lower(), None) - if not allowed_ops: - return False + # if "*" is specified, then all ops are permitted + if "*" in allowed_ops: + return True - # if "*" is specified, then all ops are permitted - if "*" in allowed_ops: - return True + return (op_name.lower() in allowed_ops) - return (op_name.lower() in allowed_ops) + ## + # Test to see if this right is a superset of a child right. A right is a + # superset if every operating that is allowed by the child is also allowed + # by this object. + # + # @param child is a Right object describing the child right - ## - # Test to see if this right is a superset of a child right. A right is a - # superset if every operating that is allowed by the child is also allowed - # by this object. - # - # @param child is a Right object describing the child right + def is_superset(self, child): + my_allowed_ops = privilege_table.get(self.kind.lower(), None) + child_allowed_ops = privilege_table.get(child.kind.lower(), None) - def is_superset(self, child): - my_allowed_ops = privilege_table.get(self.kind.lower(), None) - child_allowed_ops = privilege_table.get(child.kind.lower(), None) + if not self.delegate: + return False - if "*" in my_allowed_ops: - return True + if "*" in my_allowed_ops: + return True - for right in child_allowed_ops: - if not right in my_allowed_ops: - return False + for right in child_allowed_ops: + if not right in my_allowed_ops: + return False - return True + return True ## -# A RightList object represents a list of privileges. +# A Rights object represents a list of privileges. -class RightList: +class Rights: ## # Create a new rightlist object, containing no rights. # @@ -138,9 +156,9 @@ class RightList: # # @param right is either a Right object or a string describing the right - def add(self, right): + def add(self, right, delegate=False): if isinstance(right, str): - right = Right(kind = right) + right = Right(right, delegate) self.rights.append(right) ## @@ -155,7 +173,14 @@ class RightList: parts = string.split(",") for part in parts: - self.rights.append(Right(part)) + if ':' in part: + spl = part.split(':') + kind = spl[0].strip() + delegate = bool(int(spl[1])) + else: + kind = part.strip() + delegate = 0 + self.rights.append(Right(kind, bool(delegate))) ## # Save the rightlist object to a string. It is saved in the format of a @@ -164,7 +189,7 @@ class RightList: def save_to_string(self): right_names = [] for right in self.rights: - right_names.append(right.kind) + right_names.append('%s:%d' % (right.kind.strip(), right.delegate)) return ",".join(right_names) @@ -176,6 +201,7 @@ class RightList: # @param op_name is an operation to check, for example "listslices" def can_perform(self, op_name): + for right in self.rights: if right.can_perform(op_name): return True @@ -195,46 +221,29 @@ class RightList: for my_right in self.rights: if my_right.is_superset(child_right): allowed = True + break if not allowed: return False return True ## - # Determine tje rights that an object should have. The rights are entirely - # dependent on the type of the object. For example, users automatically - # get "refresh", "resolve", and "info". - # - # @param type the type of the object (user | sa | ma | slice | node) - # @param name human readable name of the object (not used at this time) + # set the delegate bit to 'delegate' on + # all privileges # - # @return RightList object containing rights - - def determine_rights(self, type, name): - rl = RightList() - - # rights seem to be somewhat redundant with the type of the credential. - # For example, a "sa" credential implies the authority right, because - # a sa credential cannot be issued to a user who is not an owner of - # the authority - - if type == "user": - rl.add("refresh") - rl.add("resolve") - rl.add("info") - elif type == "sa": - rl.add("authority,sa") - elif type == "ma": - rl.add("authority,ma") - elif type == "authority": - rl.add("authority,sa,ma") - elif type == "slice": - rl.add("refresh") - rl.add("embed") - rl.add("bind") - rl.add("control") - rl.add("info") - elif type == "component": - rl.add("operator") - - return rl + # @param delegate boolean (True or False) + + def delegate_all_privileges(self, delegate): + for right in self.rights: + right.delegate = delegate + + ## + # true if all privileges have delegate bit set true + # false otherwise + + def get_all_delegate(self): + for right in self.rights: + if not right.delegate: + return False + return True +