enforce rights subsets in credentials
[sfa.git] / util / rights.py
1 # rights.py
2 #
3 # support for privileges according to GENI specification
4
5 # privilege_table:
6 #
7 # a list of priviliges and what operations are allowed per privilege
8
9 privilege_table = {"authority": ["*"],
10                    "refresh": ["remove", "update"],
11                    "resolve": ["resolve", "list", "getcredential"],
12                    "sa": ["*"],
13                    "embed": ["getticket", "createslice", "deleteslice", "updateslice"],
14                    "bind": ["getticket", "loanresources"],
15                    "control": ["updateslice", "stopslice", "startslice", "deleteslice", "resetslice"],
16                    "info": ["listslices", "listcomponentresources", "getsliceresources"],
17                    "ma": ["*"]}
18
19 # a "Right" is a single privilege.
20
21 class Right:
22    def __init__(self, kind):
23       self.kind = kind
24
25    def can_perform(self, op_name):
26       allowed_ops = privilege_table.get(self.kind.lower(), None)
27       if not allowed_ops:
28          return False
29
30       # if "*" is specified, then all ops are permitted
31       if "*" in allowed_ops:
32          return True
33
34       return (op_name.lower() in allowed_ops)
35
36    def is_superset(self, child):
37       my_allowed_ops = privilege_table.get(self.kind.lower(), None)
38       child_allowed_ops = privilege_table.get(child.kind.lower(), None)
39
40       if "*" in my_allowed_ops:
41           return True
42
43       for right in child_allowed_ops:
44           if not right in my_allowed_ops:
45               return False
46
47       return True
48
49 # a "RightList" is a list of privileges
50
51 class RightList:
52     def __init__(self, string=None):
53         self.rights = []
54         if string:
55             self.load_from_string(string)
56
57     def add(self, right):
58         if isinstance(right, str):
59             right = Right(kind = right)
60         self.rights.append(right)
61
62     def load_from_string(self, string):
63         self.rights = []
64
65         # none == no rights, so leave the list empty
66         if not string:
67             return
68
69         parts = string.split(",")
70         for part in parts:
71             self.rights.append(Right(part))
72
73     def save_to_string(self):
74         right_names = []
75         for right in self.rights:
76             right_names.append(right.kind)
77
78         return ",".join(right_names)
79
80     def can_perform(self, op_name):
81         for right in self.rights:
82             if right.can_perform(op_name):
83                 return True
84         return False
85
86     def is_superset(self, child):
87         for child_right in child.rights:
88             allowed = False
89             for my_right in self.rights:
90                 if my_right.is_superset(child_right):
91                     allowed = True
92             if not allowed:
93                 return False
94         return True
95