removed another bunch of references to geni
[sfa.git] / sfa / trust / rights.py
1 ##
2 # This Module implements rights and lists of rights for the SFA. Rights
3 # are implemented by two classes:
4 #
5 # Right - represents a single right
6 #
7 # RightList - represents a list of rights
8 #
9 # A right may allow several different operations. For example, the "info" right
10 # allows "listslices", "listcomponentresources", etc.
11 ##
12
13 ##
14 # privilege_table is a list of priviliges and what operations are allowed
15 # per privilege.
16
17 privilege_table = {"authority": ["register", "remove", "update", "resolve", "list", "getcredential", "*"],
18                    "refresh": ["remove", "update"],
19                    "resolve": ["resolve", "list", "getcredential"],
20                    "sa": ["getticket", "redeemslice", "redeemticket", "createslice", "deleteslice", "updateslice", 
21                           "getsliceresources", "getticket", "loanresources", "stopslice", "startslice", 
22                           "deleteslice", "resetslice", "listslices", "listnodes", "getpolicy"],
23                    "embed": ["getticket", "redeemslice", "redeemticket", "createslice", "deleteslice", "updateslice", "getsliceresources"],
24                    "bind": ["getticket", "loanresources", "redeemticket"],
25                    "control": ["updateslice", "createslice", "stopslice", "startslice", "deleteslice", "resetslice", "getsliceresources", "getgids"],
26                    "info": ["listslices", "listnodes", "getpolicy"],
27                    "ma": ["setbootstate", "getbootstate", "reboot", "getgids", "gettrustedcerts"],
28                    "operator": ["gettrustedcerts", "getgids"]}
29
30
31 ##
32 # Determine tje rights that an object should have. The rights are entirely
33 # dependent on the type of the object. For example, users automatically
34 # get "refresh", "resolve", and "info".
35 #
36 # @param type the type of the object (user | sa | ma | slice | node)
37 # @param name human readable name of the object (not used at this time)
38 #
39 # @return RightList object containing rights
40
41 def determine_rights(type, name):
42     rl = RightList()
43
44     # rights seem to be somewhat redundant with the type of the credential.
45     # For example, a "sa" credential implies the authority right, because
46     # a sa credential cannot be issued to a user who is not an owner of
47     # the authority
48     if type == "user":
49         rl.add("refresh")
50         rl.add("resolve")
51         rl.add("info")
52     elif type == "sa":
53         rl.add("authority,sa")
54     elif type == "ma":
55         rl.add("authority,ma")
56     elif type == "authority":
57         rl.add("authority,sa,ma")
58     elif type == "slice":
59         rl.add("refresh")
60         rl.add("embed")
61         rl.add("bind")
62         rl.add("control")
63         rl.add("info")
64     elif type == "component":
65         rl.add("operator")
66     return rl
67
68
69 ##
70 # The Right class represents a single privilege.
71
72
73
74 class Right:
75    ##
76    # Create a new right.
77    #
78    # @param kind is a string naming the right. For example "control"
79
80    def __init__(self, kind):
81       self.kind = kind
82
83    ##
84    # Test to see if this right object is allowed to perform an operation.
85    # Returns True if the operation is allowed, False otherwise.
86    #
87    # @param op_name is a string naming the operation. For example "listslices".
88
89    def can_perform(self, op_name):
90       allowed_ops = privilege_table.get(self.kind.lower(), None)
91       if not allowed_ops:
92          return False
93
94       # if "*" is specified, then all ops are permitted
95       if "*" in allowed_ops:
96          return True
97
98       return (op_name.lower() in allowed_ops)
99
100    ##
101    # Test to see if this right is a superset of a child right. A right is a
102    # superset if every operating that is allowed by the child is also allowed
103    # by this object.
104    #
105    # @param child is a Right object describing the child right
106
107    def is_superset(self, child):
108       my_allowed_ops = privilege_table.get(self.kind.lower(), None)
109       child_allowed_ops = privilege_table.get(child.kind.lower(), None)
110
111       if "*" in my_allowed_ops:
112           return True
113
114       for right in child_allowed_ops:
115           if not right in my_allowed_ops:
116               return False
117
118       return True
119
120 ##
121 # A RightList object represents a list of privileges.
122
123 class RightList:
124     ##
125     # Create a new rightlist object, containing no rights.
126     #
127     # @param string if string!=None, load the rightlist from the string
128
129     def __init__(self, string=None):
130         self.rights = []
131         if string:
132             self.load_from_string(string)
133
134     def is_empty(self):
135         return self.rights == []
136
137     ##
138     # Add a right to this list
139     #
140     # @param right is either a Right object or a string describing the right
141
142     def add(self, right):
143         if isinstance(right, str):
144             right = Right(kind = right)
145         self.rights.append(right)
146
147     ##
148     # Load the rightlist object from a string
149
150     def load_from_string(self, string):
151         self.rights = []
152
153         # none == no rights, so leave the list empty
154         if not string:
155             return
156
157         parts = string.split(",")
158         for part in parts:
159             self.rights.append(Right(part))
160
161     ##
162     # Save the rightlist object to a string. It is saved in the format of a
163     # comma-separated list.
164
165     def save_to_string(self):
166         right_names = []
167         for right in self.rights:
168             right_names.append(right.kind)
169
170         return ",".join(right_names)
171
172     ##
173     # Check to see if some right in this list allows an operation. This is
174     # done by evaluating the can_perform function of each operation in the
175     # list.
176     #
177     # @param op_name is an operation to check, for example "listslices"
178
179     def can_perform(self, op_name):
180         for right in self.rights:
181             if right.can_perform(op_name):
182                 return True
183         return False
184
185     ##
186     # Check to see if all of the rights in this rightlist are a superset
187     # of all the rights in a child rightlist. A rightlist is a superset
188     # if there is no operation in the child rightlist that cannot be
189     # performed in the parent rightlist.
190     #
191     # @param child is a rightlist object describing the child
192
193     def is_superset(self, child):
194         for child_right in child.rights:
195             allowed = False
196             for my_right in self.rights:
197                 if my_right.is_superset(child_right):
198                     allowed = True
199             if not allowed:
200                 return False
201         return True
202
203
204     ##
205     # Determine tje rights that an object should have. The rights are entirely
206     # dependent on the type of the object. For example, users automatically
207     # get "refresh", "resolve", and "info".
208     #
209     # @param type the type of the object (user | sa | ma | slice | node)
210     # @param name human readable name of the object (not used at this time)
211     #
212     # @return RightList object containing rights
213
214     def determine_rights(self, type, name):
215         rl = RightList()
216
217         # rights seem to be somewhat redundant with the type of the credential.
218         # For example, a "sa" credential implies the authority right, because
219         # a sa credential cannot be issued to a user who is not an owner of
220         # the authority
221
222         if type == "user":
223             rl.add("refresh")
224             rl.add("resolve")
225             rl.add("info")
226         elif type == "sa":
227             rl.add("authority,sa")
228         elif type == "ma":
229             rl.add("authority,ma")
230         elif type == "authority":
231             rl.add("authority,sa,ma")
232         elif type == "slice":
233             rl.add("refresh")
234             rl.add("embed")
235             rl.add("bind")
236             rl.add("control")
237             rl.add("info")
238         elif type == "component":
239             rl.add("operator")
240
241         return rl