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): """Get the list of roles assigned to the user. This includes local roles assigned in the context of the passed in object. Knows about local roles blocking (roles starting with '-'). """ name = self.getUserName() roles = self.getRoles() # deal with groups groups = self.getComputedGroups() # end groups local = {} stop_loop = 0 real_object = object object = aq_inner(object) 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 if hasattr(object, 'aq_parent'): object = aq_inner(object.aq_parent) continue if hasattr(object, 'im_self'): object = aq_inner(object.im_self) 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 while 1: if self.isStudent(): break groups = self.portal_membership.getAuthenticatedMember().getGroups() if not ("ClearanceOfficers" in groups or "CourseAdvisers" in groups): break if callable(real_object) and hasattr(real_object,'im_self'): real_object = real_object.im_self if real_object is None: break if hasattr(real_object,'portal_type') and\ real_object.portal_type not in ("Student", "StudentClearance", "StudentStudyLevel"): break # don't test if it is not a proxy #if real_object.portal_type == real_object.meta_type: # break # can be later simplified by replacing by students_catalog values - Henrik # getattr works always because of acquisition ?! Henrik sc = getattr(real_object,'study_course',None) if sc is None: break sc_obj = sc.getContent() cert_id = sc_obj.study_course res_cert = self.portal_catalog(id = cert_id) if len(res_cert) != 1: break certificate_brain = res_cert[0] certificate_obj = certificate_brain.getObject() cert_path = certificate_brain.getPath().split('/') fac_id = cert_path[-4] dep_id = cert_path[-3] # temporary self-healing function # deprecated after reindexing the students_catalog student_id = self.getStudentId() res = self.students_catalog(id=student_id) if len(res) != 1: break st_entry = res[0] if st_entry.faculty != fac_id or\ st_entry.department != dep_id or\ st_entry.course != cert_id: self.students_catalog.modifyRecord(id = student_id, faculty = fac_id, department = dep_id, course = cert_id ) if real_object.portal_type == "StudentStudyLevel": if real_object.meta_type != "StudentStudyLevel": context_obj = getattr(certificate_obj,real_object.getId(),None) else: context_obj = getattr(certificate_obj,real_object.aq_parent.getId(),None) if context_obj is None: #from pdb import set_trace;set_trace() break allowed = set(('CourseAdviser', 'SectionManager')) elif real_object.portal_type == "Student" and "CourseAdvisers" in groups: #we need some special processing since CourseAdvisers are only #specified per StudyLevel allowed = set(('CourseAdviser', 'SectionManager')) for context_obj in certificate_obj.objectValues(): dynamic_roles = set(self.getRolesInContext(context_obj)) intersect = dynamic_roles & allowed if intersect: roles.extend(list(intersect)) break else: res = self.portal_catalog(portal_type="Department",id=dep_id) allowed = set(('ClearanceOfficer', 'SectionManager')) if len(res) != 1: break context_obj = res[0].getObject() dynamic_roles = set(self.getRolesInContext(context_obj)) intersect = dynamic_roles & allowed if intersect: roles.extend(list(intersect)) break return roles from Products.CPSUserFolder.CPSUserFolder import CPSUser CPSUser.getRolesInContext = getRolesInContext