from AccessControl import ClassSecurityInfo from ExtensionClass import Base from Acquisition import Implicit from Acquisition import aq_base, aq_parent, aq_inner security = ClassSecurityInfo() security.declarePublic('getRolesInContext') def getRolesInContext(self, object): """Return the list of roles assigned to the user, including local roles assigned in context of the passed in object.""" name = self.getUserName() roles = self.getRoles() groups = self.getGroups() + ('role:Anonymous',) if 'Authenticated' in roles: groups = groups + ('role:Authenticated',) local = {} stop_loop = 0 object = aq_inner(object) import pdb; pdb.set_trace() while 1: # Collect all roles info lrd = {} local_roles = getattr(object, '__ac_local_roles__', None) if local_roles: if callable(local_roles): local_roles = local_roles() or {} for r in local_roles.get(name, ()): if r: lrd[r] = None local_group_roles = getattr(object, '__ac_local_group_roles__', None) if local_group_roles: if callable(local_group_roles): local_group_roles = local_group_roles() or {} for g in groups: for r in local_group_roles.get(g, ()): if r: lrd[r] = None lr = lrd.keys() # Positive role assertions for r in lr: if r[0] != '-': if not local.has_key(r): local[r] = 1 # acquired role # Negative (blocking) role assertions for r in lr: if r[0] == '-': r = r[1:] if not r: # role '-' blocks all acquisition stop_loop = 1 break if not local.has_key(r): local[r] = 0 # blocked role if stop_loop: break inner = getattr(object, 'aq_inner', object) parent = getattr(inner, 'aq_parent', None) if parent is not None: object = parent continue if hasattr(object, 'im_self'): object = object.im_self object = getattr(object, 'aq_inner', object) continue break roles = list(roles) for r, v in local.items(): if v: # only if not blocked roles.append(r) ## patch to assign dynamic roles for WAeUP info = self.getStudentInfo() while 1: if info is None: break if info['course'] is None: break res = self.portal_catalog(portal_type="Department",id=info['course_doc'].department) if len(res) != 1: break dynamic_roles = self.getRolesInContext(res[0].getObject()) for dr in self.getDynamicRoles(): if dr in dynamic_roles: roles.append(dr) break return roles security.declarePublic('allowed') def allowed(self, object, object_roles=None): """Check whether the user has access to object. The user must have one of the roles in object_roles to allow access.""" 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 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 # Check local roles, calling getRolesInContext to avoid too much # complexity, at the expense of speed. for role in self.getRolesInContext(object): if role in object_roles: return 1 return None from Products.CPSUserFolder.UserFolderWithGroups import PatchBasicUser PatchBasicUser.getRolesInContext = getRolesInContext PatchBasicUser.allowed = allowed