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 not hasattr(real_object,'portal_type'):
            break
        if real_object.portal_type not in ("Student","StudentClearance"):
            break
        sc = getattr(real_object,'study_course',None)
        if sc is None:
            break
        dep_id = real_object.study_course.getContent().department
        res = self.portal_catalog(portal_type="Department",id=dep_id)
        if len(res) != 1:
            break
        dynamic_roles = self.getRolesInContext(res[0].getObject())
        #import pdb;pdb.set_trace()
        for dr in self.getDynamicRoles():
            if dr in dynamic_roles:
                roles.append(dr)
        break
    return roles

from Products.CPSUserFolder.CPSUserFolder import CPSUser
CPSUser.getRolesInContext = getRolesInContext
