From f28a75a2cb621b02f78983d9b32b99b7b030b9de Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Thu, 25 Nov 2010 18:41:04 +0100 Subject: [PATCH] all tag types use permission helpers in AuthorizeHelpers accessors properly checked as well --- PLC/Accessors/Factory.py | 2 - PLC/AuthorizeHelpers.py | 88 ++++++++++++++++++++++++++++++- PLC/Methods/AddInterfaceTag.py | 10 +--- PLC/Methods/AddPersonTag.py | 10 +--- PLC/Methods/AddSiteTag.py | 11 +--- PLC/Methods/AddSliceTag.py | 40 +------------- PLC/Methods/DeleteInterfaceTag.py | 9 +--- PLC/Methods/DeletePersonTag.py | 10 +--- PLC/Methods/DeleteSiteTag.py | 11 +--- PLC/Methods/DeleteSliceTag.py | 40 +------------- PLC/Methods/UpdateInterfaceTag.py | 10 +--- PLC/Methods/UpdatePersonTag.py | 10 +--- PLC/Methods/UpdateSiteTag.py | 11 +--- PLC/Methods/UpdateSliceTag.py | 38 +------------ 14 files changed, 99 insertions(+), 201 deletions(-) diff --git a/PLC/Accessors/Factory.py b/PLC/Accessors/Factory.py index 2629587..a207513 100644 --- a/PLC/Accessors/Factory.py +++ b/PLC/Accessors/Factory.py @@ -21,8 +21,6 @@ from PLC.SiteTags import SiteTags, SiteTag from PLC.Persons import Persons, Person from PLC.PersonTags import PersonTags, PersonTag -from PLC.AuthorizeHelpers import AuthorizeHelpers - # known classes : { class -> details } taggable_classes = { Node : {'table_class' : Nodes, 'joins_class' : NodeTags, 'join_class' : NodeTag, diff --git a/PLC/AuthorizeHelpers.py b/PLC/AuthorizeHelpers.py index 5651c10..f2bb2ad 100644 --- a/PLC/AuthorizeHelpers.py +++ b/PLC/AuthorizeHelpers.py @@ -86,8 +86,10 @@ class AuthorizeHelpers: return slice['site_id'] in pi['site_ids'] -# authorization method - check if a given caller can set tag on this object -# called in {Add,Update,Delete}NodeTags methods and in the accessors factory +# authorization methods - check if a given caller can set tag on this object +# called in {Add,Update,Delete}Tags methods, and in the accessors created in factory +# attach these as .caller_may_write_tag so accessors can find it + def caller_may_write_node_tag (node, api, caller, tag_type): if 'admin' in caller['roles']: pass @@ -101,3 +103,85 @@ def caller_may_write_node_tag (node, api, caller, tag_type): setattr(Node,'caller_may_write_tag',caller_may_write_node_tag) + +def caller_may_write_interface_tag (interface, api, caller, tag_type): + if 'admin' in caller['roles']: + pass + elif not AuthorizeHelpers.caller_may_access_tag_type (api, caller, tag_type): + raise PLCPermissionDenied, "Role mismatch for writing tag %s"%(tag_type['tagname']) + elif AuthorizeHelpers.interface_belongs_to_person (api, interface, caller): + pass + else: + raise PLCPermissionDenied, "Writing interface tag: must belong in the same site as %s"%\ + (interface['ip']) + +setattr(Interface,'caller_may_write_tag',caller_may_write_interface_tag) + + +def caller_may_write_site_tag (site, api, caller, tag_type): + if 'admin' in caller['roles']: + pass + elif not AuthorizeHelpers.caller_may_access_tag_type (api, caller, tag_type): + raise PLCPermissionDenied, "Role mismatch for writing tag %s"%(tag_type['tagname']) + elif AuthorizeHelpers.person_in_site (api, caller, site): + pass + else: + raise PLCPermissionDenied, "Writing site tag: must be part of site"%site['login_base'] + +setattr(Site,'caller_may_write_tag',caller_may_write_site_tag) + + +def caller_may_write_person_tag (person, api, caller, tag_type): + if 'admin' in caller['roles']: + pass + # user can change tags on self + elif AuthorizeHelpers.person_may_access_person (api, caller, person): + pass + else: + raise PLCPermissionDenied, "Writing person tag: you can only change your own tags" + +setattr(Person,'caller_may_write_tag',caller_may_write_person_tag) + + +def caller_may_write_slice_tag (slice, api, caller, tag_type, node_id_or_hostname=None, nodegroup_id_or_name=None): + granted=False + if 'admin' in caller['roles']: + granted=True + # does caller have right role(s) ? this knows how to deal with caller being a node + elif not AuthorizeHelpers.caller_may_access_tag_type (api, caller, tag_type): + granted=False + # node callers: check the node is in the slice + elif isinstance(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 (api, caller, node_id_or_hostname): + granted=False + elif not AuthorizeHelpers.node_in_slice (api, 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, "Cannot set slice tag %s on nodegroup - restricted to admins"%\ + (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 (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(api,caller,tag_type): + # regular users need to be in the slice + if role=='user': + if AuthorizeHelpers.person_in_slice(api, 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 (api, slice, caller): + granted=True ; break + if not granted: + raise PLCPermissionDenied, "Cannot write slice tag %s"%(tag_type['tagname']) + +setattr(Slice,'caller_may_write_tag',caller_may_write_slice_tag) + + diff --git a/PLC/Methods/AddInterfaceTag.py b/PLC/Methods/AddInterfaceTag.py index 8d09fd0..56d232b 100644 --- a/PLC/Methods/AddInterfaceTag.py +++ b/PLC/Methods/AddInterfaceTag.py @@ -59,15 +59,7 @@ class AddInterfaceTag(Method): tag_type['tag_type_id']) # check authorizations - if 'admin' in self.caller['roles']: - 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.interface_belongs_to_person (self.api, interface, self.caller): - pass - else: - raise PLCPermissionDenied, "%s: you must belong in the same site as subject interface"%self.name - + interface.caller_may_write_tag(self.api,self.caller,tag_type) interface_tag = InterfaceTag(self.api) interface_tag['interface_id'] = interface['interface_id'] diff --git a/PLC/Methods/AddPersonTag.py b/PLC/Methods/AddPersonTag.py index edd3970..819d4e4 100644 --- a/PLC/Methods/AddPersonTag.py +++ b/PLC/Methods/AddPersonTag.py @@ -10,7 +10,6 @@ from PLC.Persons import Person, Persons from PLC.TagTypes import TagType, TagTypes from PLC.PersonTags import PersonTag, PersonTags -from PLC.AuthorizeHelpers import AuthorizeHelpers class AddPersonTag(Method): """ @@ -56,14 +55,7 @@ class AddPersonTag(Method): (person['person_id'],person['email'], tag_type['tag_type_id']) # check authorizations - if 'admin' in self.caller['roles']: - pass - # user can change tags on self - 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 - + person.caller_may_write_tag (self.api,self.caller,tag_type) person_tag = PersonTag(self.api) person_tag['person_id'] = person['person_id'] diff --git a/PLC/Methods/AddSiteTag.py b/PLC/Methods/AddSiteTag.py index 2069698..8d6489a 100644 --- a/PLC/Methods/AddSiteTag.py +++ b/PLC/Methods/AddSiteTag.py @@ -11,8 +11,6 @@ from PLC.Nodes import Nodes from PLC.TagTypes import TagType, TagTypes from PLC.SiteTags import SiteTag, SiteTags -from PLC.AuthorizeHelpers import AuthorizeHelpers - class AddSiteTag(Method): """ Sets the specified setting for the specified site @@ -60,14 +58,7 @@ class AddSiteTag(Method): tag_type['tag_type_id']) # check authorizations - if 'admin' in self.caller['roles']: - 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_in_site (self.api, self.caller, site): - pass - else: - raise PLCPermissionDenied, "%s: you must be part of the subject site"%self.name + site.caller_may_write_tag(self.api,self.caller,tag_type) site_tag = SiteTag(self.api) site_tag['site_id'] = site['site_id'] diff --git a/PLC/Methods/AddSliceTag.py b/PLC/Methods/AddSliceTag.py index 0d7fe68..3deebe1 100644 --- a/PLC/Methods/AddSliceTag.py +++ b/PLC/Methods/AddSliceTag.py @@ -13,8 +13,6 @@ from PLC.SliceTags import SliceTag, SliceTags from PLC.NodeGroups import NodeGroup, NodeGroups from PLC.InitScripts import InitScript, InitScripts -from PLC.AuthorizeHelpers import AuthorizeHelpers - class AddSliceTag(Method): """ Sets the specified tag of the slice to the specified value. @@ -64,43 +62,7 @@ class AddSliceTag(Method): tag_type = tag_types[0] # check authorizations - 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.caller_may_write_tag (self.api,self.caller,tag_type,node_id_or_hostname,nodegroup_id_or_name) # if initscript is specified, validate value if tag_type['tagname'] in ['initscript']: diff --git a/PLC/Methods/DeleteInterfaceTag.py b/PLC/Methods/DeleteInterfaceTag.py index b1672a7..9d333a4 100644 --- a/PLC/Methods/DeleteInterfaceTag.py +++ b/PLC/Methods/DeleteInterfaceTag.py @@ -47,14 +47,7 @@ class DeleteInterfaceTag(Method): interface=interfaces[0] # check authorizations - if 'admin' in self.caller['roles']: - 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.interface_belongs_to_person (self.api, interface, self.caller): - pass - else: - raise PLCPermissionDenied, "%s: you must belong in the same site as subject interface"%self.name + interface.caller_may_write_tag(self.api,self.caller,tag_type) interface_tag.delete() self.object_ids = [interface_tag['interface_tag_id']] diff --git a/PLC/Methods/DeletePersonTag.py b/PLC/Methods/DeletePersonTag.py index 5597785..6767aff 100644 --- a/PLC/Methods/DeletePersonTag.py +++ b/PLC/Methods/DeletePersonTag.py @@ -9,8 +9,6 @@ from PLC.Auth import Auth from PLC.PersonTags import PersonTag, PersonTags from PLC.Persons import Person, Persons -from PLC.AuthorizeHelpers import AuthorizeHelpers - class DeletePersonTag(Method): """ Deletes the specified person setting @@ -41,13 +39,7 @@ class DeletePersonTag(Method): person=persons[0] # check authorizations - if 'admin' in self.caller['roles']: - pass - # user can change tags on self - 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 + person.caller_may_write_tag(self.api,self.caller,tag_type) person_tag.delete() self.object_ids = [person_tag['person_tag_id']] diff --git a/PLC/Methods/DeleteSiteTag.py b/PLC/Methods/DeleteSiteTag.py index 601b1c0..b63acf4 100644 --- a/PLC/Methods/DeleteSiteTag.py +++ b/PLC/Methods/DeleteSiteTag.py @@ -48,15 +48,8 @@ class DeleteSiteTag(Method): site=sites[0] # check authorizations - if 'admin' in self.caller['roles']: - 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_in_site (self.api, self.caller, site): - pass - else: - raise PLCPermissionDenied, "%s: you must be part of the subject site"%self.name - + site.caller_may_write_tag(self.api,self.caller,tag_type) + site_tag.delete() self.object_ids = [site_tag['site_tag_id']] diff --git a/PLC/Methods/DeleteSliceTag.py b/PLC/Methods/DeleteSliceTag.py index 6cb58c3..e9cb134 100644 --- a/PLC/Methods/DeleteSliceTag.py +++ b/PLC/Methods/DeleteSliceTag.py @@ -10,8 +10,6 @@ from PLC.SliceTags import SliceTag, SliceTags from PLC.Slices import Slice, Slices from PLC.Nodes import Node, Nodes -from PLC.AuthorizeHelpers import AuthorizeHelpers - class DeleteSliceTag(Method): """ Deletes the specified slice or sliver attribute. @@ -50,43 +48,7 @@ class DeleteSliceTag(Method): # 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.caller_may_write_tag(self.api,self.caller,tag_type,node_id_or_hostname,nodegroup_id_or_name) slice_tag.delete() self.event_objects = {'SliceTag': [slice_tag['slice_tag_id']]} diff --git a/PLC/Methods/UpdateInterfaceTag.py b/PLC/Methods/UpdateInterfaceTag.py index 5370f7d..93a645c 100644 --- a/PLC/Methods/UpdateInterfaceTag.py +++ b/PLC/Methods/UpdateInterfaceTag.py @@ -48,15 +48,7 @@ class UpdateInterfaceTag(Method): interface=interfaces[0] # check authorizations - if 'admin' in self.caller['roles']: - 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.interface_belongs_to_person (self.api, interface, self.caller): - pass - else: - raise PLCPermissionDenied, "%s: you must belong in the same site as subject interface"%self.name - + interface.caller_may_write_tag(self.api, self.caller, tag_type) interface_tag['value'] = value interface_tag.sync() diff --git a/PLC/Methods/UpdatePersonTag.py b/PLC/Methods/UpdatePersonTag.py index 176b22e..67fae08 100644 --- a/PLC/Methods/UpdatePersonTag.py +++ b/PLC/Methods/UpdatePersonTag.py @@ -9,8 +9,6 @@ from PLC.Auth import Auth from PLC.PersonTags import PersonTag, PersonTags from PLC.Persons import Person, Persons -from PLC.AuthorizeHelpers import AuthorizeHelpers - class UpdatePersonTag(Method): """ Updates the value of an existing person setting @@ -42,13 +40,7 @@ class UpdatePersonTag(Method): person=persons[0] # check authorizations - if 'admin' in self.caller['roles']: - pass - # user can change tags on self - 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 + person.caller_may_write_tag(self.api,self.caller,tag_type) person_tag['value'] = value person_tag.sync() diff --git a/PLC/Methods/UpdateSiteTag.py b/PLC/Methods/UpdateSiteTag.py index fd8f798..5dc1a8c 100644 --- a/PLC/Methods/UpdateSiteTag.py +++ b/PLC/Methods/UpdateSiteTag.py @@ -11,8 +11,6 @@ from PLC.Nodes import Nodes from PLC.TagTypes import TagType, TagTypes from PLC.SiteTags import SiteTag, SiteTags -from PLC.AuthorizeHelpers import AuthorizeHelpers - class UpdateSiteTag(Method): """ Updates the value of an existing site setting @@ -49,14 +47,7 @@ class UpdateSiteTag(Method): site=sites[0] # check authorizations - if 'admin' in self.caller['roles']: - 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_in_site (self.api, self.caller, site): - pass - else: - raise PLCPermissionDenied, "%s: you must be part of the subject site"%self.name + site.caller_may_write_tag(self.api,self.caller,tag_type) site_tag['value'] = value site_tag.sync() diff --git a/PLC/Methods/UpdateSliceTag.py b/PLC/Methods/UpdateSliceTag.py index 74d0271..a8de812 100644 --- a/PLC/Methods/UpdateSliceTag.py +++ b/PLC/Methods/UpdateSliceTag.py @@ -52,43 +52,7 @@ class UpdateSliceTag(Method): # 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.caller_may_write_tag(self.api,self.caller,tag_type,node_id_or_hostname,nodegroup_id_or_name) if slice_tag['tagname'] in ['initscript']: initscripts = InitScripts(self.api, {'enabled': True, 'name': value}) -- 2.43.0