from AccessControl import ClassSecurityInfo from ExtensionClass import Base from Acquisition import Implicit from Acquisition import aq_base, aq_parent, aq_inner import re security = ClassSecurityInfo() def getCertificateObject(self,st_entry): try: return getattr(getattr(getattr(self.portal_url.getPortalObject().campus.academics,st_entry.faculty), st_entry.department).certificates,st_entry.course) except: return None 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 # if re.match(r'\D\d\d\d\d\d\d',name): # break #if len(name) != 7: # break #try: # int(name[1:]) #except: # break o = ord(name[1]) if o >= 48 and o <= 57: 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", "StudentCourseResult", ): 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 in ("StudentStudyLevel","StudentCourseResult"): # res_cert = self.portal_catalog(id = st_entry.course) # if len(res_cert) != 1: # break # certificate_brain = res_cert[0] # certificate_obj = certificate_brain.getObject() certificate_obj = getCertificateObject(self,st_entry) if certificate_obj is None: #from pdb import set_trace;set_trace() break if real_object.meta_type.endswith('Folder'): # it is a proxy object = real_object else: object = real_object.aq_parent if real_object.portal_type == "StudentStudyLevel": level = object.getId() elif real_object.portal_type == "StudentCourseResult": level = object.aq_parent.getId() context_obj = getattr(certificate_obj,level,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 certificate_obj = getCertificateObject(self,st_entry) if certificate_obj is None: #from pdb import set_trace;set_trace() break 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=st_entry.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