add/update/delete slice tags should be fine
authorThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Mon, 22 Nov 2010 22:17:57 +0000 (23:17 +0100)
committerThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Mon, 22 Nov 2010 22:17:57 +0000 (23:17 +0100)
12 files changed:
PLC/AuthorizeHelpers.py
PLC/Methods/AddPersonTag.py
PLC/Methods/AddSiteTag.py
PLC/Methods/AddSliceTag.py
PLC/Methods/DeletePersonTag.py
PLC/Methods/DeleteSiteTag.py
PLC/Methods/DeleteSliceTag.py
PLC/Methods/UpdatePersonTag.py
PLC/Methods/UpdateSiteTag.py
PLC/Methods/UpdateSliceTag.py
PLC/PersonTags.py
PLC/SiteTags.py

index 8c09cc3..7cbc5ab 100644 (file)
@@ -9,54 +9,78 @@ from PLC.Nodes import Nodes,Node
 class AuthorizeHelpers:
 
     @staticmethod
-    def interface_belongs_to_person (api,interface, person):
-        try:
-            node=Nodes(api,[interface['node_id']])[0]
-            return AuthorizeHelpers.node_belong_to_person (api, node, person)
-        except:
-            return False
-
-    @staticmethod
-    def node_belongs_to_person (api, node, person):
-        try:
-            site=Sites(api,[node['site_id']])[0]
-            return AuthorizeHelpers.person_belongs_to_site (api, person, site)
-        except:
-            return False
-
-    @staticmethod
-    def person_belongs_to_site (api, person, site):
-        return site['site_id'] in person['site_ids']
+    def person_tag_type_common_roles (api, person, tag_type):
+        return list (set(person['roles']).intersection(set(tag_type['roles'])))
 
     @staticmethod
     def caller_may_access_tag_type (api, caller, tag_type):
         if isinstance(caller,Person):
-            return len(set(caller['roles']).intersection(set(tag_type['roles'])))!=0
+            return len(AuthorizeHelpers.person_tag_type_common_roles(api,caller,tag_type))!=0
         elif isinstance(caller,Node):
             return 'node' in tag_type['roles']
         else:
             raise PLCInvalidArgument, "caller_may_access_tag_type - unexpected arg"
 
     @staticmethod
-    def person_access_person (api, caller_person, subject_person):
+    def person_may_access_person (api, caller_person, subject_person):
         # keep it simple for now - could be a bit more advanced for PIs maybe
         try:    return caller_person['person_id'] == subject_person['person_id']
         except: return False
 
+    @staticmethod
+    def person_in_site (api, person, site):
+        return site['site_id'] in person['site_ids']
+
     @staticmethod
     def person_in_slice (api, caller_person, slice):
         return caller_person['person_id'] in slice['person_ids']
 
     @staticmethod
-    def node_in_slice (api, caller_node, slice):
-        return caller_node['node_id'] in slice['node_ids']
+    def slice_in_site (api, slice, slice):
+        return caller_person['person_id'] in slice['person_ids']
 
     @staticmethod
-    def node_id_or_hostname_in_slice (api, node_id_or_hostname, slice):
+    def node_id_in_slice (api, node_id_or_hostname, slice):
         if isinstance (node_id_or_hostname,int):
             return node_id_or_hostname in slice['node_ids']
         else:
-            try:   return Nodes(api,node_id_or_hostname_in_slice)[0]['node_id'] in slice['node_ids']
+            try:   return Nodes(api,node_id_or_hostname)[0]['node_id'] in slice['node_ids']
+            except:return False
+
+    @staticmethod
+    def node_id_in_site (api, node_id_or_hostname, site):
+        if isinstance (node_id_or_hostname,int):
+            return node_id_or_hostname in site['node_ids']
+        else:
+            try:   return Nodes(api,node_id_or_hostname)[0]['node_id'] in site['node_ids']
             except:return False
 
 
+    @staticmethod
+    def node_match_id (api, node, node_id_or_hostname):
+        if isinstance (node_id_or_hostname,int):
+            return node['node_id']==node_id_or_hostname
+        else:
+            return node['hostname']==node_id_or_hostname
+
+    @staticmethod
+    def interface_belongs_to_person (api,interface, person):
+        try:
+            node=Nodes(api,[interface['node_id']])[0]
+            return AuthorizeHelpers.node_belongs_to_person (api, node, person)
+        except:
+            return False
+
+    @staticmethod
+    def node_belongs_to_person (api, node, person):
+        try:
+            site=Sites(api,[node['site_id']])[0]
+            return AuthorizeHelpers.person_in_site (api, person, site)
+        except:
+            return False
+
+    # does the slice belong to the site that the (pi) user is in ?
+    @staticmethod
+    def slice_belongs_to_pi (api, slice, pi):
+        return slice['site_id'] in pi['site_ids']
+
index 6bba377..edd3970 100644 (file)
@@ -59,7 +59,7 @@ class AddPersonTag(Method):
         if 'admin' in self.caller['roles']:
             pass
         # user can change tags on self
-        elif AuthorizeHelpers.person_access_person (self.api, self.caller, person):
+        elif AuthorizeHelpers.person_may_access_person (self.api, self.caller, person):
             pass
         else:
             raise PLCPermissionDenied, "%s: you can only change your own tags"%self.name
index 3c59f0b..2069698 100644 (file)
@@ -64,7 +64,7 @@ class AddSiteTag(Method):
             pass
         elif not AuthorizeHelpers.caller_may_access_tag_type (self.api, self.caller, tag_type):
             raise PLCPermissionDenied, "%s, forbidden tag %s"%(self.name,tag_type['tagname'])
-        elif AuthorizeHelpers.person_belongs_to_site (self.api, self.caller, site):
+        elif AuthorizeHelpers.person_in_site (self.api, self.caller, site):
             pass
         else:
             raise PLCPermissionDenied, "%s: you must be part of the subject site"%self.name
index 4638116..0d7fe68 100644 (file)
@@ -26,9 +26,8 @@ class AddSliceTag(Method):
     Non-admins need to have at least one of the roles 
     attached to the tagtype. In addition:
     (*) Users may only set tags of slices or slivers of which they are members. 
-    (*) PIs may only set tags of slices or slivers at their sites, or of which they
-    are members. 
-    (*) techs may only set tags of slivers at their sites.
+    (*) PIs may only set tags of slices in their site
+    (*) techs cannot use this method
 
     Returns the new slice_tag_id (> 0) if successful, faults
     otherwise.
@@ -65,34 +64,43 @@ class AddSliceTag(Method):
         tag_type = tag_types[0]
 
         # check authorizations
-        if 'admin' not in self.caller['roles']:
-            # this knows how to deal with self.caller being a node
-            if not AuthorizeHelpers.caller_may_access_tag_type (self.api, self.caller, tag_type):
-                raise PLCPermissionDenied, "%s, forbidden tag %s"%(self.name,tag_type['tagname'])
-            # node callers: check the node is in the slice
-            if isinstance(self.caller, Node): 
-                granted=AuthorizeHelpers.node_in_slice (self.api, self.caller, slice)
-            else:
-                if nodegroup_id_or_name:
-                    raise PLCPermissionDenied, "%s, cannot set slice tag on nodegroup"%self.name
-                # try all roles to find a match
+        granted=False
+        if 'admin' in self.caller['roles']:
+            granted=True
+        # does caller have right role(s) ? this knows how to deal with self.caller being a node
+        elif not AuthorizeHelpers.caller_may_access_tag_type (self.api, self.caller, tag_type):
+            granted=False
+        # node callers: check the node is in the slice
+        elif isinstance(self.caller, Node): 
+            # nodes can only set their own sliver tags
+            if node_id_or_hostname is None: 
                 granted=False
-                for role in self.caller['roles']:
-                    if role=='pi':
-                        if AuthorizeHelpers.person_in_slice(self.api, self.caller, slice): 
-                            granted=True ; break
-                        if node_id_or_hostname is not None and \
-                                AuthorizeHelpers.node_id_or_hostname_in_slice(self.api, node_id_or_hostname_in_slice, slice):
-                            granted=True ; break
-                    elif role=='user':
-                        if AuthorizeHelpers.person_in_slice(self.api, self.caller, slice):
-                            granted=True ; break
-                    elif role=='tech':
-                        if node_id_or_hostname is not None and \
-                                AuthorizeHelpers.node_id_or_hostname_in_slice(self.api, node_id_or_hostname_in_slice, slice):
-                            granted=True ; break
-            if not granted:
-                raise PLCPermissionDenied, "%s, forbidden tag %s"%(self.name,tag_type['tagname'])
+            elif not AuthorizeHelpers.node_match_id (self.api, self.caller, node_id_or_hostname):
+                granted=False
+            elif not AuthorizeHelpers.node_in_slice (self.api, self.caller, slice):
+                granted=False
+        # caller is a non-admin person
+        else:
+            # only admins can handle slice tags on a nodegroup
+            if nodegroup_id_or_name:
+                raise PLCPermissionDenied, "%s, cannot set slice tag %s on nodegroup - restricted to admins"%\
+                    (self.name,tag_type['tagname'])
+            # if a node is specified it is expected to be in the slice
+            if node_id_or_hostname:
+                if not AuthorizeHelpers.node_id_in_slice (self.api, node_id_or_hostname, slice):
+                    raise PLCPermissionDenied, "%s, node must be in slice when setting sliver tag"
+            # try all roles to find a match - tech are ignored b/c not in AddSliceTag.roles anyways
+            for role in AuthorizeHelpers.person_tag_type_common_roles(self.api,self.caller,tag_type):
+                # regular users need to be in the slice
+                if role=='user':
+                    if AuthorizeHelpers.person_in_slice(self.api, self.caller, slice):
+                        granted=True ; break
+                # for convenience, pi's can tweak all the slices in their site
+                elif role=='pi':
+                    if AuthorizeHelpers.slice_belongs_to_pi (self.api, slice, self.caller):
+                        granted=True ; break
+        if not granted:
+            raise PLCPermissionDenied, "%s, forbidden tag %s"%(self.name,tag_type['tagname'])
 
         # if initscript is specified, validate value
         if tag_type['tagname'] in ['initscript']:
index 19ab5fe..ee4f6b3 100644 (file)
@@ -41,7 +41,7 @@ class DeletePersonTag(Method):
         if 'admin' in self.caller['roles']:
             pass
         # user can change tags on self
-        elif AuthorizeHelpers.person_access_person (self.api, self.caller, person):
+        elif AuthorizeHelpers.person_may_access_person (self.api, self.caller, person):
             pass
         else:
             raise PLCPermissionDenied, "%s: you can only change your own tags"%self.name
index 3aa8d83..6c31c1d 100644 (file)
@@ -48,7 +48,7 @@ class DeleteSiteTag(Method):
             pass
         elif not AuthorizeHelpers.caller_may_access_tag_type (self.api, self.caller, tag_type):
             raise PLCPermissionDenied, "%s, forbidden tag %s"%(self.name,tag_type['tagname'])
-        elif AuthorizeHelpers.person_belongs_to_site (self.api, self.caller, site):
+        elif AuthorizeHelpers.person_in_site (self.api, self.caller, site):
             pass
         else:
             raise PLCPermissionDenied, "%s: you must be part of the subject site"%self.name
index e63393e..d433e02 100644 (file)
@@ -47,17 +47,46 @@ class DeleteSliceTag(Method):
 
         assert slice_tag['slice_tag_id'] in slice['slice_tag_ids']
 
-        if 'admin' not in self.caller['roles']:
-            if self.caller['person_id'] in slice['person_ids']:
-                pass
-            elif 'pi' not in self.caller['roles']:
-                raise PLCPermissionDenied, "Not a member of the specified slice"
-            elif slice['site_id'] not in self.caller['site_ids']:
-                raise PLCPermissionDenied, "Specified slice not associated with any of your sites"
-
-            if slice_tag['min_role_id'] is not None and \
-               min(self.caller['role_ids']) > slice_tag['min_role_id']:
-                raise PLCPermissioinDenied, "Not allowed to delete the specified attribute"
+        # check authorizations
+        node_id_or_hostname=slice_tag['node_id']
+        nodegroup_id_or_name=slice_tag['nodegroup_id']
+        granted=False
+        if 'admin' in self.caller['roles']:
+            granted=True
+        # does caller have right role(s) ? this knows how to deal with self.caller being a node
+        elif not AuthorizeHelpers.caller_may_access_tag_type (self.api, self.caller, tag_type):
+            granted=False
+        # node callers: check the node is in the slice
+        elif isinstance(self.caller, Node): 
+            # nodes can only set their own sliver tags
+            if node_id_or_hostname is None: 
+                granted=False
+            elif not AuthorizeHelpers.node_match_id (self.api, self.caller, node_id_or_hostname):
+                granted=False
+            elif not AuthorizeHelpers.node_in_slice (self.api, self.caller, slice):
+                granted=False
+        # caller is a non-admin person
+        else:
+            # only admins can handle slice tags on a nodegroup
+            if nodegroup_id_or_name:
+                raise PLCPermissionDenied, "%s, cannot set slice tag %s on nodegroup - restricted to admins"%\
+                    (self.name,tag_type['tagname'])
+            # if a node is specified it is expected to be in the slice
+            if node_id_or_hostname:
+                if not AuthorizeHelpers.node_id_in_slice (self.api, node_id_or_hostname, slice):
+                    raise PLCPermissionDenied, "%s, node must be in slice when setting sliver tag"
+            # try all roles to find a match - tech are ignored b/c not in AddSliceTag.roles anyways
+            for role in AuthorizeHelpers.person_tag_type_common_roles(self.api,self.caller,tag_type):
+                # regular users need to be in the slice
+                if role=='user':
+                    if AuthorizeHelpers.person_in_slice(self.api, self.caller, slice):
+                        granted=True ; break
+                # for convenience, pi's can tweak all the slices in their site
+                elif role=='pi':
+                    if AuthorizeHelpers.slice_belongs_to_pi (self.api, slice, self.caller):
+                        granted=True ; break
+        if not granted:
+            raise PLCPermissionDenied, "%s, forbidden tag %s"%(self.name,tag_type['tagname'])
 
         slice_tag.delete()
         self.event_objects = {'SliceTag': [slice_tag['slice_tag_id']]}
index 97862ef..2a88179 100644 (file)
@@ -42,7 +42,7 @@ class UpdatePersonTag(Method):
         if 'admin' in self.caller['roles']:
             pass
         # user can change tags on self
-        elif AuthorizeHelpers.person_access_person (self.api, self.caller, person):
+        elif AuthorizeHelpers.person_may_access_person (self.api, self.caller, person):
             pass
         else:
             raise PLCPermissionDenied, "%s: you can only change your own tags"%self.name
index fadd953..733cb12 100644 (file)
@@ -49,7 +49,7 @@ class UpdateSiteTag(Method):
             pass
         elif not AuthorizeHelpers.caller_may_access_tag_type (self.api, self.caller, tag_type):
             raise PLCPermissionDenied, "%s, forbidden tag %s"%(self.name,tag_type['tagname'])
-        elif AuthorizeHelpers.person_belongs_to_site (self.api, self.caller, site):
+        elif AuthorizeHelpers.person_in_site (self.api, self.caller, site):
             pass
         else:
             raise PLCPermissionDenied, "%s: you must be part of the subject site"%self.name
index e8b8b33..5e1123a 100644 (file)
@@ -49,23 +49,46 @@ class UpdateSliceTag(Method):
 
         assert slice_tag['slice_tag_id'] in slice['slice_tag_ids']
 
-        if not isinstance(self.caller, Node):
-            if 'admin' not in self.caller['roles']:
-                if self.caller['person_id'] in slice['person_ids']:
-                    pass
-                elif 'pi' not in self.caller['roles']:
-                    raise PLCPermissionDenied, "Not a member of the specified slice"
-                elif slice['site_id'] not in self.caller['site_ids']:
-                    raise PLCPermissionDenied, "Specified slice not associated with any of your sites"
-
-                if slice_tag['min_role_id'] is not None and \
-                       min(self.caller['role_ids']) > slice_tag['min_role_id']:
-                    raise PLCPermissionDenied, "Not allowed to update the specified attribute"
+        # check authorizations
+        node_id_or_hostname=slice_tag['node_id']
+        nodegroup_id_or_name=slice_tag['nodegroup_id']
+        granted=False
+        if 'admin' in self.caller['roles']:
+            granted=True
+        # does caller have right role(s) ? this knows how to deal with self.caller being a node
+        elif not AuthorizeHelpers.caller_may_access_tag_type (self.api, self.caller, tag_type):
+            granted=False
+        # node callers: check the node is in the slice
+        elif isinstance(self.caller, Node): 
+            # nodes can only set their own sliver tags
+            if node_id_or_hostname is None: 
+                granted=False
+            elif not AuthorizeHelpers.node_match_id (self.api, self.caller, node_id_or_hostname):
+                granted=False
+            elif not AuthorizeHelpers.node_in_slice (self.api, self.caller, slice):
+                granted=False
+        # caller is a non-admin person
         else:
-            ### make node's min_role_id == PI min_role_id
-            node_role_id = 20
-            if slice_tag['min_role_id'] is not None and node_role_id > slice_tag['min_role_id']:
-                raise PLCPermissionDenied, "Not allowed to update the specified slice attribute"
+            # only admins can handle slice tags on a nodegroup
+            if nodegroup_id_or_name:
+                raise PLCPermissionDenied, "%s, cannot set slice tag %s on nodegroup - restricted to admins"%\
+                    (self.name,tag_type['tagname'])
+            # if a node is specified it is expected to be in the slice
+            if node_id_or_hostname:
+                if not AuthorizeHelpers.node_id_in_slice (self.api, node_id_or_hostname, slice):
+                    raise PLCPermissionDenied, "%s, node must be in slice when setting sliver tag"
+            # try all roles to find a match - tech are ignored b/c not in AddSliceTag.roles anyways
+            for role in AuthorizeHelpers.person_tag_type_common_roles(self.api,self.caller,tag_type):
+                # regular users need to be in the slice
+                if role=='user':
+                    if AuthorizeHelpers.person_in_slice(self.api, self.caller, slice):
+                        granted=True ; break
+                # for convenience, pi's can tweak all the slices in their site
+                elif role=='pi':
+                    if AuthorizeHelpers.slice_belongs_to_pi (self.api, slice, self.caller):
+                        granted=True ; break
+        if not granted:
+            raise PLCPermissionDenied, "%s, forbidden tag %s"%(self.name,tag_type['tagname'])
 
         if slice_tag['tagname'] in ['initscript']:
             initscripts = InitScripts(self.api, {'enabled': True, 'name': value})
index 30869af..9327abf 100644 (file)
@@ -1,5 +1,3 @@
-# $Id$
-# $URL$
 #
 # Thierry Parmentelat - INRIA
 #
index 45cbfd9..d04b947 100644 (file)
@@ -1,5 +1,3 @@
-# $Id$
-# $URL$
 #
 # Thierry Parmentelat - INRIA
 #