sa/ma credentials include the rights authority+sa or authority+ma, authorities includ...
[sfa.git] / geni / util / rights.py
1 ##
2 # This Module implements rights and lists of rights for the Geni wrapper. 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", "createslice", "deleteslice", "updateslice", "getsliceresources", "getticket", "loanresources", "stopslice", "startslice", "deleteslice", "resetslice", "listslices", "listnodes", "getpolicy"],
21                    "embed": ["getticket", "redeemslice", "createslice", "deleteslice", "updateslice", "getsliceresources"],
22                    "bind": ["getticket", "loanresources"],
23                    "control": ["updateslice", "createslice", "stopslice", "startslice", "deleteslice", "resetslice", "getsliceresources"],
24                    "info": ["listslices", "listnodes", "getpolicy"],
25                    "ma": ["setbootstate", "getbootstate", "reboot"]}
26
27 ##
28 # The Right class represents a single privilege.
29
30 class Right:
31    ##
32    # Create a new right.
33    #
34    # @param kind is a string naming the right. For example "control"
35
36    def __init__(self, kind):
37       self.kind = kind
38
39    ##
40    # Test to see if this right object is allowed to perform an operation.
41    # Returns True if the operation is allowed, False otherwise.
42    #
43    # @param op_name is a string naming the operation. For example "listslices".
44
45    def can_perform(self, op_name):
46       allowed_ops = privilege_table.get(self.kind.lower(), None)
47       if not allowed_ops:
48          return False
49
50       # if "*" is specified, then all ops are permitted
51       if "*" in allowed_ops:
52          return True
53
54       return (op_name.lower() in allowed_ops)
55
56    ##
57    # Test to see if this right is a superset of a child right. A right is a
58    # superset if every operating that is allowed by the child is also allowed
59    # by this object.
60    #
61    # @param child is a Right object describing the child right
62
63    def is_superset(self, child):
64       my_allowed_ops = privilege_table.get(self.kind.lower(), None)
65       child_allowed_ops = privilege_table.get(child.kind.lower(), None)
66
67       if "*" in my_allowed_ops:
68           return True
69
70       for right in child_allowed_ops:
71           if not right in my_allowed_ops:
72               return False
73
74       return True
75
76 ##
77 # A RightList object represents a list of privileges.
78
79 class RightList:
80     ##
81     # Create a new rightlist object, containing no rights.
82     #
83     # @param string if string!=None, load the rightlist from the string
84
85     def __init__(self, string=None):
86         self.rights = []
87         if string:
88             self.load_from_string(string)
89
90     ##
91     # Add a right to this list
92     #
93     # @param right is either a Right object or a string describing the right
94
95     def add(self, right):
96         if isinstance(right, str):
97             right = Right(kind = right)
98         self.rights.append(right)
99
100     ##
101     # Load the rightlist object from a string
102
103     def load_from_string(self, string):
104         self.rights = []
105
106         # none == no rights, so leave the list empty
107         if not string:
108             return
109
110         parts = string.split(",")
111         for part in parts:
112             self.rights.append(Right(part))
113
114     ##
115     # Save the rightlist object to a string. It is saved in the format of a
116     # comma-separated list.
117
118     def save_to_string(self):
119         right_names = []
120         for right in self.rights:
121             right_names.append(right.kind)
122
123         return ",".join(right_names)
124
125     ##
126     # Check to see if some right in this list allows an operation. This is
127     # done by evaluating the can_perform function of each operation in the
128     # list.
129     #
130     # @param op_name is an operation to check, for example "listslices"
131
132     def can_perform(self, op_name):
133         for right in self.rights:
134             if right.can_perform(op_name):
135                 return True
136         return False
137
138     ##
139     # Check to see if all of the rights in this rightlist are a superset
140     # of all the rights in a child rightlist. A rightlist is a superset
141     # if there is no operation in the child rightlist that cannot be
142     # performed in the parent rightlist.
143     #
144     # @param child is a rightlist object describing the child
145
146     def is_superset(self, child):
147         for child_right in child.rights:
148             allowed = False
149             for my_right in self.rights:
150                 if my_right.is_superset(child_right):
151                     allowed = True
152             if not allowed:
153                 return False
154         return True
155