From 2c29335528503f581ecdef4ae865384f892fcd08 Mon Sep 17 00:00:00 2001 From: Jean-Paul Smets <jp@nexedi.com> Date: Sun, 30 Oct 2005 16:48:24 +0000 Subject: [PATCH] Added PAS patch git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@4174 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5Type/ZopePatch.py | 180 ++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) diff --git a/product/ERP5Type/ZopePatch.py b/product/ERP5Type/ZopePatch.py index b7f0435094..ddd33385e6 100755 --- a/product/ERP5Type/ZopePatch.py +++ b/product/ERP5Type/ZopePatch.py @@ -1978,3 +1978,183 @@ try: AttrDict.has_key = AttrDict_has_key except ImportError: pass + + +############################################################################ +# Locale roles acquisition patch for PAS + +from Acquisition import aq_inner, aq_parent + +try: + from PluggableAuthService.PropertiedUser import PropertiedUser +except ImportError: + PropertiedUser = None + +def getRolesInContext( self, object ): + + """ Return the list of roles assigned to the user. + + o Include local roles assigned in context of the passed-in object. + + o Include *both* local roles assigned directly to us *and* those + assigned to our groups. + + o Ripped off from AccessControl.User.BasicUser, which provides + no other extension mechanism. :( + """ + user_id = self.getId() + # [ x.getId() for x in self.getGroups() ] + group_ids = self.getGroups() + + principal_ids = list( group_ids ) + principal_ids.insert( 0, user_id ) + + local ={} + object = aq_inner( object ) + + while 1: + + local_roles = getattr( object, '__ac_local_roles__', None ) + + if local_roles: + + if callable( local_roles ): + local_roles = local_roles() + + dict = local_roles or {} + + for principal_id in principal_ids: + for role in dict.get( principal_id, [] ): + local[ role ] = 1 + + # patch by Klaus for LocalRole blocking + if hasattr(object, '_getAcquireLocalRoles'): + if not object._getAcquireLocalRoles(): + break + + inner = aq_inner( object ) + parent = aq_parent( inner ) + + if parent is not None: + object = parent + continue + + new = getattr( object, 'im_self', None ) + + if new is not None: + + object = aq_inner( new ) + continue + + break + + return list( self.getRoles() ) + local.keys() + +def allowed( self, object, object_roles=None ): + + """ Check whether the user has access to object. + + o The user must have one of the roles in object_roles to allow access. + + o Include *both* local roles assigned directly to us *and* those + assigned to our groups. + + o Ripped off from AccessControl.User.BasicUser, which provides + no other extension mechanism. :( + """ + if object_roles is _what_not_even_god_should_do: + return 0 + + # Short-circuit the common case of anonymous access. + if object_roles is None or 'Anonymous' in object_roles: + return 1 + + # Provide short-cut access if object is protected by 'Authenticated' + # role and user is not nobody + if 'Authenticated' in object_roles and ( + self.getUserName() != 'Anonymous User'): + return 1 + + # Check for ancient role data up front, convert if found. + # This should almost never happen, and should probably be + # deprecated at some point. + if 'Shared' in object_roles: + object_roles = self._shared_roles(object) + if object_roles is None or 'Anonymous' in object_roles: + return 1 + + # Check for a role match with the normal roles given to + # the user, then with local roles only if necessary. We + # want to avoid as much overhead as possible. + user_roles = self.getRoles() + for role in object_roles: + if role in user_roles: + if self._check_context(object): + return 1 + return None + + # Still have not found a match, so check local roles. We do + # this manually rather than call getRolesInContext so that + # we can incur only the overhead required to find a match. + inner_obj = aq_inner( object ) + user_id = self.getId() + # [ x.getId() for x in self.getGroups() ] + group_ids = self.getGroups() + + principal_ids = list( group_ids ) + principal_ids.insert( 0, user_id ) + + while 1: + + local_roles = getattr( inner_obj, '__ac_local_roles__', None ) + + if local_roles: + + if callable( local_roles ): + local_roles = local_roles() + + dict = local_roles or {} + + for principal_id in principal_ids: + + local_roles = dict.get( principal_id, [] ) + + for role in object_roles: + + if role in local_roles: + + if self._check_context( object ): + return 1 + + return 0 + + # patch by Klaus for LocalRole blocking + if hasattr(object, '_getAcquireLocalRoles'): + if not object._getAcquireLocalRoles(): + break + + inner = aq_inner( inner_obj ) + parent = aq_parent( inner ) + + if parent is not None: + inner_obj = parent + continue + + new = getattr( inner_obj, 'im_self', None ) + + if new is not None: + inner_obj = aq_inner( new ) + continue + + break + + return None + +if PropertiedUser is not None: + PropertiedUser.getRolesInContext = getRolesInContext + PropertiedUser.allowed = allowed + + + + + \ No newline at end of file -- 2.30.9