2 # This Module implements rights and lists of rights for the SFA. Rights
3 # are implemented by two classes:
5 # Right - represents a single right
7 # Rights - represents a list of rights
9 # A right may allow several different operations. For example, the "info" right
10 # allows "listslices", "listcomponentresources", etc.
16 # privilege_table is a list of priviliges and what operations are allowed
18 # Note that "*" is a privilege granted by ProtoGENI slice authorities, and we
19 # give it access to the GENI AM calls
21 privilege_table = {"authority": ["register", "remove", "update", "resolve", "list", "getcredential", "*"],
22 "refresh": ["remove", "update"],
23 "resolve": ["resolve", "list", "getcredential"],
24 "sa": ["getticket", "redeemslice", "redeemticket", "createslice", "createsliver", "deleteslice", "deletesliver", "updateslice",
25 "getsliceresources", "getticket", "loanresources", "stopslice", "startslice", "renewsliver",
26 "deleteslice", "deletesliver", "resetslice", "listslices", "listnodes", "getpolicy", "sliverstatus"],
27 "embed": ["getticket", "redeemslice", "redeemticket", "createslice", "createsliver", "renewsliver", "deleteslice",
28 "deletesliver", "updateslice", "sliverstatus", "getsliceresources", "shutdown"],
29 "bind": ["getticket", "loanresources", "redeemticket"],
30 "control": ["updateslice", "createslice", "createsliver", "renewsliver", "sliverstatus", "stopslice", "startslice",
31 "deleteslice", "deletesliver", "resetslice", "getsliceresources", "getgids"],
32 "info": ["listslices", "listnodes", "getpolicy"],
33 "ma": ["setbootstate", "getbootstate", "reboot", "getgids", "gettrustedcerts"],
34 "operator": ["gettrustedcerts", "getgids"],
35 "*": ["createsliver", "deletesliver", "sliverstatus", "renewsliver", "shutdown"]}
40 # Determine the rights that an object should have. The rights are entirely
41 # dependent on the type of the object. For example, users automatically
42 # get "refresh", "resolve", and "info".
44 # @param type the type of the object (user | sa | ma | slice | node)
45 # @param name human readable name of the object (not used at this time)
47 # @return Rights object containing rights
49 def determine_rights(type, name):
52 # rights seem to be somewhat redundant with the type of the credential.
53 # For example, a "sa" credential implies the authority right, because
54 # a sa credential cannot be issued to a user who is not an owner of
66 elif type == "authority":
76 elif type == "component":
82 # The Right class represents a single privilege.
90 # @param kind is a string naming the right. For example "control"
92 def __init__(self, kind, delegate=False):
94 self.delegate = delegate
97 # Test to see if this right object is allowed to perform an operation.
98 # Returns True if the operation is allowed, False otherwise.
100 # @param op_name is a string naming the operation. For example "listslices".
102 def can_perform(self, op_name):
103 allowed_ops = privilege_table.get(self.kind.lower(), None)
107 # if "*" is specified, then all ops are permitted
108 if "*" in allowed_ops:
111 return (op_name.lower() in allowed_ops)
114 # Test to see if this right is a superset of a child right. A right is a
115 # superset if every operating that is allowed by the child is also allowed
118 # @param child is a Right object describing the child right
120 def is_superset(self, child):
121 my_allowed_ops = privilege_table.get(self.kind.lower(), None)
122 child_allowed_ops = privilege_table.get(child.kind.lower(), None)
124 if not self.delegate:
127 if "*" in my_allowed_ops:
130 for right in child_allowed_ops:
131 if not right in my_allowed_ops:
137 # A Rights object represents a list of privileges.
141 # Create a new rightlist object, containing no rights.
143 # @param string if string!=None, load the rightlist from the string
145 def __init__(self, string=None):
148 self.load_from_string(string)
151 return self.rights == []
154 # Add a right to this list
156 # @param right is either a Right object or a string describing the right
158 def add(self, right, delegate=False):
159 if isinstance(right, str):
160 right = Right(right, delegate)
161 self.rights.append(right)
164 # Load the rightlist object from a string
166 def load_from_string(self, string):
169 # none == no rights, so leave the list empty
173 parts = string.split(",")
176 spl = part.split(':')
177 kind = spl[0].strip()
178 delegate = bool(int(spl[1]))
182 self.rights.append(Right(kind, bool(delegate)))
185 # Save the rightlist object to a string. It is saved in the format of a
186 # comma-separated list.
188 def save_to_string(self):
190 for right in self.rights:
191 right_names.append('%s:%d' % (right.kind.strip(), right.delegate))
193 return ",".join(right_names)
196 # Check to see if some right in this list allows an operation. This is
197 # done by evaluating the can_perform function of each operation in the
200 # @param op_name is an operation to check, for example "listslices"
202 def can_perform(self, op_name):
203 for right in self.rights:
204 if right.can_perform(op_name):
209 # Check to see if all of the rights in this rightlist are a superset
210 # of all the rights in a child rightlist. A rightlist is a superset
211 # if there is no operation in the child rightlist that cannot be
212 # performed in the parent rightlist.
214 # @param child is a rightlist object describing the child
216 def is_superset(self, child):
217 for child_right in child.rights:
219 for my_right in self.rights:
220 if my_right.is_superset(child_right):
228 # set the delegate bit to 'delegate' on
231 # @param delegate boolean (True or False)
233 def delegate_all_privileges(self, delegate):
234 for right in self.rights:
235 right.delegate = delegate
238 # true if all privileges have delegate bit set true
241 def get_all_delegate(self):
242 for right in self.rights:
243 if not right.delegate:
250 # Determine the rights that an object should have. The rights are entirely
251 # dependent on the type of the object. For example, users automatically
252 # get "refresh", "resolve", and "info".
254 # @param type the type of the object (user | sa | ma | slice | node)
255 # @param name human readable name of the object (not used at this time)
257 # @return Rights object containing rights
259 def determine_rights(self, type, name):
262 # rights seem to be somewhat redundant with the type of the credential.
263 # For example, a "sa" credential implies the authority right, because
264 # a sa credential cannot be issued to a user who is not an owner of
277 elif type == "authority":
281 elif type == "slice":
287 elif type == "component":