Example #1
0
 def __init__(self, context, request):
     self._assignable_roles = []
     self.principal = utils.common.get_request_principal()
     self.context_roles = common.get_context_roles(context, self.principal)
     self.context = removeSecurityProxy(context)
     self.prm = IPrincipalRoleMap(self.context)
     super(UserAssignmentView, self).__init__(context, request)
Example #2
0
    def __init__(self, context, request):
        """self:zope.app.pagetemplate.simpleviewclass.SimpleViewClass -> 
                    templates/workspace-index.pt
           context:bungeni.core.content.Section
        """
        LD = IAnnotations(request)["layer_data"]
        assert interfaces.IWorkspaceSectionLayer.providedBy(request)
        assert LD.get("workspaces") is not None
        super(WorkspaceSectionView, self).__init__(context, request)
        cls_name = self.__class__.__name__
        # NOTE: Zope morphs this class's name to "SimpleViewClass from ..."
        log.debug("%s.__init__ %s context=%s url=%s" %
                  (cls_name, self, self.context, request.getURL()))

        # transfer layer data items, for the view/template
        self.user_id = LD.user_id
        self.user_group_ids = LD.user_group_ids
        self.government_id = LD.government_id  # may be None
        self.ministries = LD.ministries  # may be None
        if self.ministries:
            # then, ONLY if an ancestor container is actually a Ministry,
            # this must be a MinisterWorkspace
            if misc.get_parent_with_interface(self,
                                              model_interfaces.IMinistry):
                interface.alsoProvides(self, interfaces.IMinisterWorkspace)

        # roles are function of the context, so always recalculate
        roles = common.get_context_roles(self.context)
        for role_id in roles:
            iface = self.role_interface_mapping.get(role_id)
            if iface is not None:
                interface.alsoProvides(self, iface)
        log.debug("%s.__init__ %s" % (cls_name, debug.interfaces(self)))
Example #3
0
 def test_context_roles(self, mode):
     """EXPERIMENTAL sample code to get a user's roles and whether is_admin 
     or not -- this is the info needed (in addition to the field's modes) 
     to further filter whether a field is visible or not for a 
     given (user, mode).
     """
     request = common.get_request()
     if request is None:
         context = None
         principal = None
     else:
         context = common.get_traversed_context(request)
         principal = request.principal
     if IUnauthenticatedPrincipal.providedBy(principal):
         roles = None
     else: 
         roles = common.get_context_roles(context)
     print """!+ModelDescriptor TEST_CONTEXT_ROLES [%s]
     PRINCIPAL: %s
     CONTEXT: %s
     MODE: %s
     ROLES: %s
     IS ADMIN: %s""" % (self,
         principal, 
         context,
         mode,
         roles, 
         common.is_admin(context)
     )
Example #4
0
    def __init__(self, context, request):
        """self:zope.app.pagetemplate.simpleviewclass.SimpleViewClass -> 
                    templates/workspace-index.pt
           context:bungeni.core.content.Section
        """
        LD = IAnnotations(request)["layer_data"]
        assert interfaces.IWorkspaceSectionLayer.providedBy(request)
        assert LD.get("workspaces") is not None
        super(WorkspaceSectionView, self).__init__(context, request)
        cls_name = self.__class__.__name__
        # NOTE: Zope morphs this class's name to "SimpleViewClass from ..." 
        log.debug("%s.__init__ %s context=%s url=%s" % (
                            cls_name, self, self.context, request.getURL()))

        # transfer layer data items, for the view/template
        self.user_id = LD.user_id
        self.user_group_ids = LD.user_group_ids
        self.government_id = LD.government_id # may be None
        self.ministries = LD.ministries # may be None
        if self.ministries:
            # then, ONLY if an ancestor container is actually a Ministry, 
            # this must be a MinisterWorkspace
            if misc.get_parent_with_interface(self, model_interfaces.IMinistry):
                interface.alsoProvides(self, interfaces.IMinisterWorkspace)

        # roles are function of the context, so always recalculate
        roles = common.get_context_roles(self.context)
        for role_id in roles:
            iface = self.role_interface_mapping.get(role_id)
            if iface is not None:
                interface.alsoProvides(self, iface)
        log.debug("%s.__init__ %s" % (cls_name, debug.interfaces(self)))
Example #5
0
def get_user_context_roles():
    """Get the list of user's roles (including whether admin or not)--this 
    is the info needed (in addition to the field's modes) to further 
    filter whether a field is visible or not for a given (user, mode).
    
    Wraps common.get_context_roles(context), with the following differcnes: 
    - auto retrieves the context, needed param by common.get_context_roles()
    - handles case when user is not authenticated
    - handles case for when user is "admin"
    """
    request = common.get_request()
    if request is None:
        context = None
        principal = None
    else:
        context = common.get_traversed_context(request)
        principal = request.principal
    if IUnauthenticatedPrincipal.providedBy(principal):
        roles = ["bungeni.Anonymous"]
    else: 
        roles = common.get_context_roles(context)
        if common.is_admin(context):
            roles.append("bungeni.Admin")
    log.debug(""" [get_user_context_roles]
    PRINCIPAL: %s
    CONTEXT: %s
    ROLES: %s
    """ % (principal, context, roles))
    return roles
Example #6
0
def get_user_context_roles():
    """Get the list of user's roles (including whether admin or not)--this 
    is the info needed (in addition to the field's modes) to further 
    filter whether a field is visible or not for a given (user, mode).
    
    Wraps common.get_context_roles(context), with the following differcnes: 
    - auto retrieves the context, needed param by common.get_context_roles()
    - handles case when user is not authenticated
    - handles case for when user is "admin"
    """
    request = common.get_request()
    if request is None:
        context = None
        principal = None
    else:
        context = common.get_traversed_context(request)
        principal = request.principal
    if IUnauthenticatedPrincipal.providedBy(principal):
        roles = ["bungeni.Anonymous"]
    else:
        roles = common.get_context_roles(context)
        if common.is_admin(context):
            roles.append("bungeni.Admin")
    log.debug(""" [get_user_context_roles]
    PRINCIPAL: %s
    CONTEXT: %s
    ROLES: %s
    """ % (principal, context, roles))
    return roles
 def __init__(self, context, request):
     self._assignable_roles = []
     self.principal = utils.common.get_request_principal()
     self.context_roles = common.get_context_roles(context, self.principal)
     self.context = removeSecurityProxy(context)
     self.prm = IPrincipalRoleMap(self.context)
     super(UserAssignmentView, self).__init__(context, request)
Example #8
0
 def get_principal_roles(self, principal):
     """Returns roles associated with groups.
     """
     session = Session()
     roles = []
     for group_id in principal.groups.keys():
         result = session.query(domain.Group).filter(
             domain.Group.group_principal_id == group_id).first()
         if result:
             roles.extend(
                 get_context_roles(get_group_context(result), principal))
     return roles
Example #9
0
 def get_principal_roles(self, principal):
     """Returns roles associated with groups.
     """
     session = Session()
     roles = []
     for group_id in principal.groups.keys():
         result = session.query(domain.Group).filter(
                         domain.Group.group_principal_id == group_id).first()
         if result:
             roles.extend(get_context_roles(
                                       get_group_context(result), principal))
     return roles
Example #10
0
 def test_context_roles(self, mode):
     """EXPERIMENTAL sample code to get a user's roles and whether is_admin 
     or not -- this is the info needed (in addition to the field's modes) 
     to further filter whether a field is visible or not for a 
     given (user, mode).
     """
     request = common.get_request()
     if request is None:
         context = None
         principal = None
     else:
         context = common.get_traversed_context(request)
         principal = request.principal
     if IUnauthenticatedPrincipal.providedBy(principal):
         roles = None
     else:
         roles = common.get_context_roles(context)
     print """!+ModelDescriptor TEST_CONTEXT_ROLES [%s]
     PRINCIPAL: %s
     CONTEXT: %s
     MODE: %s
     ROLES: %s
     IS ADMIN: %s""" % (self, principal, context, mode, roles,
                        common.is_admin(context))
Example #11
0
def prepare_user_workspaces(event):
    """Determine the current principal's workspaces, depending on roles and
    group memberships. 
    
    "bungeni.Clerk", "bungeni.Speaker", "bungeni.MP"
        these roles get a parliament-level workspace
    
    "bungeni.Minister"
        "implied" role (by being a member of a ministry group) 
        gets a ministry-level workspace (for each ministry)
    
    "zope.Manager", "bungeni.Admin", "bungeni.Owner", "bungeni.Authenticated", 
    "bungeni.Anonymous"
        not relevant for user workspaces, no workspaces
        !+ should these get an owner-level (user) workspace?
    
    """
    request = event.request
    application = event.object  # is bungeni.core.app.BungeniApp
    destination_url_path = url.get_destination_url_path(request)

    def need_to_prepare_workspaces(obj, req):
        return (
            # need only to do it when traversing "/",
            # obj should be the BungeniApplication
            model_interfaces.IBungeniApplication.providedBy(obj) and
            # user is logged in
            interfaces.IBungeniAuthenticatedSkin.providedBy(req) and (
                # either the request should be for a view within /workspace
                # note: IWorkspaceSectionLayer is applied to the request by
                # publication.apply_request_layer_by_url() that therefore must
                # have already been called
                interfaces.IWorkspaceSectionLayer.providedBy(req) or
                interfaces.IWorkspaceSchedulingSectionLayer.providedBy(req) or
                # or the request is for *the* Home Page (as in this case
                # we still need to know the user workspaces to be able to
                # redirect appropriately)
                interfaces.IHomePageLayer.providedBy(req)))

    if not need_to_prepare_workspaces(application, request):
        return

    # initialize a layer data object, for the views in the layer
    LD = IAnnotations(request)["layer_data"] = misc.bunch(
        workspaces=[],  # workspace containers !+ unique?
        # !+ role-based workspaces: (role|group, workspace_container)
        # these are needed by the views, as we need them also here, we just
        # remember them to not need to calculate them again
        user_id=None,
        user_group_ids=None,
        government_id=None,
        ministries=None,  # list of ministries (that are also workspaces)
    )

    LD.user_id = get_db_user_id()
    try:
        parliament = get_current_parliament(None)
        assert parliament is not None  # force exception
        # we do get_context_roles under the current parliament as context, but
        # we must also ensure that the BungeniApp is present somewhere along
        # the __parent__ stack:
        parliament.__parent__ = application
        roles = common.get_context_roles(parliament)
        # "bungeni.Clerk", "bungeni.Speaker", "bungeni.MP"
        for role_id in roles:
            if role_id in ("bungeni.Clerk", "bungeni.Speaker", "bungeni.MP"):
                log.debug("adding parliament workspace %s (for role %s)" %
                          (parliament, role_id))
                LD.workspaces.append(parliament)

        # "bungeni.Minister"
        # need to check for ministry groups to which the principal belongs, and
        # for each such ministry assign a ministry workspace
        LD.user_group_ids = get_group_ids_for_user_in_parliament(
            LD.user_id, parliament.group_id)
        LD.government_id = get_current_parliament_governments(
            parliament)[0].group_id  # IndexError
        LD.ministries = get_ministries_for_user_in_government(
            LD.user_id, LD.government_id)
        log.debug(
            """ [prepare_user_workspaces]
            user_id:%s
            roles:%s
            parliament:(%s, %s) 
            government_id:%s
            ministries:%s""" %
            (LD.user_id, roles, parliament.full_name, parliament.group_id,
             LD.government_id, [(m.full_name, m.group_id)
                                for m in LD.ministries]))
        for ministry in LD.ministries:
            log.debug("adding ministry workspace %s" % ministry)
            LD.workspaces.append(ministry)
    except (Exception, ):
        debug.log_exc_info(sys.exc_info(), log_handler=log.info)

    # ensure unique workspaces, preserving order, retaining same list obj ref
    LD.workspaces[:] = [
        workspace for i, workspace in enumerate(LD.workspaces)
        if LD.workspaces.index(workspace) == i
    ]

    # mark each workspace container with IWorkspaceContainer
    for workspace in LD.workspaces:
        interface.alsoProvides(workspace, interfaces.IWorkspaceContainer)
        log.debug(debug.interfaces(workspace))

    log.debug(" [prepare_user_workspaces] %s" % debug.interfaces(request))
    log.info(""" [prepare_user_workspaces] DONE:
        for: [request=%s][path=%s][path_info=%s]
        request.layer_data: %s""" %
             (id(request), destination_url_path, request.get("PATH_INFO"),
              IAnnotations(request).get("layer_data", None)))
Example #12
0
    def workspace_search(self):
        """ Search in workspace section, based on views from bungeni.ui.viewlets.workspace
        """
        application = common.get_application()
        parliament = get_current_parliament(None)
        parliament.__parent__ = application
        principal = get_principal()
        roles = common.get_context_roles(parliament, principal)

        # minister role, filtering by states and object_type and ministry_id
        if not roles:
            user_id = get_db_user_id()
            government_id = get_current_parliament_governments(
                parliament)[0].group_id
            ministries = get_ministries_for_user_in_government(
                user_id, government_id)
            if ministries:
                states = workspace.MinistryArchiveViewlet.states + \
                         workspace.OralMinistryQuestionsViewlet.states + \
                         workspace.WrittenMinistryQuestionsViewlet.states + \
                         workspace.InProgressMinistryItemsViewlet.states
                states = set(states)

                ministry_ids = [m.group_id for m in ministries]

                # filter by object_type (questions only)
                type_query = self.searcher.query_field('object_type',
                                                       "Question")
                query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, type_query,))

                subqueries = []

                for state in states:
                    subqueries.append(
                        self.searcher.query_field('status', state))

                state_query = self.searcher.query_composite(
                    self.searcher.OP_OR, subqueries)
                query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                           (query, state_query,))

                #filter for ministries
                ministries_queries = []

                for mid in ministry_ids:
                    ministries_queries.append(
                        self.searcher.query_field('ministry_id', str(mid)))

                m_query = self.searcher.query_composite(
                    self.searcher.OP_OR, ministries_queries)
                query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                           (query, m_query,))

                try:
                    results = self.searcher.search(
                        query, 0, self.searcher.get_doccount())
                except:
                    results = []

                return list(results)

        # filtering by states and owner
        if 'bungeni.MP' in roles:
            states = workspace.MPItemActionRequiredViewlet.states + \
                     workspace.MPItemDraftViewlet.states + \
                     workspace.MPItemInProgressViewlet.states + \
                     workspace.ItemArchiveViewlet.states
            states = set(states)
            # filter by owner of PI
            owner_query = self.searcher.query_field('owner',
                                                    str(get_db_user_id()))
            query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, owner_query,))

            subqueries = []

            for state in states:
                subqueries.append(self.searcher.query_field('status', state))

            state_query = self.searcher.query_composite(
                self.searcher.OP_OR, subqueries)
            query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (query, state_query,))

            try:
                results = self.searcher.search(query, 0,
                                               self.searcher.get_doccount())
            except:
                results = []

            return list(results)

        # filtering by states
        if 'bungeni.Clerk' in roles:
            states = workspace.ClerkItemActionRequiredViewlet.states + \
                     workspace.ClerkItemsWorkingDraftViewlet.states + \
                     workspace.ClerkReviewedItemViewlet.states + \
                     workspace.ItemsApprovedViewlet.states + \
                     workspace.ItemsPendingScheduleViewlet.states + \
                     workspace.ItemsScheduledViewlet.states + \
                     workspace.AllItemArchiveViewlet.states

            states = set(states)

            subqueries = []

            for state in states:
                subqueries.append(self.searcher.query_field('status', state))

            state_query = self.searcher.query_composite(
                self.searcher.OP_OR, subqueries)
            query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, state_query,))

            try:
                results = self.searcher.search(query, 0,
                                               self.searcher.get_doccount())
            except:
                results = []

            return list(results)
        # no results
        return False
Example #13
0
def prepare_user_workspaces(event):
    """Determine the current principal's workspaces, depending on roles and
    group memberships. 
    
    "bungeni.Clerk", "bungeni.Speaker", "bungeni.MP"
        these roles get a parliament-level workspace
    
    "bungeni.Minister"
        "implied" role (by being a member of a ministry group) 
        gets a ministry-level workspace (for each ministry)
    
    "zope.Manager", "bungeni.Admin", "bungeni.Owner", "bungeni.Everybody", 
    "bungeni.Anybody"
        not relevant for user workspaces, no workspaces
        !+ should these get an owner-level (user) workspace?
    
    """
    request = event.request
    application = event.object # is bungeni.core.app.BungeniApp
    destination_url_path = url.get_destination_url_path(request)
    def need_to_prepare_workspaces(obj, req):
        return (
            # need only to do it when traversing "/", 
            # obj should be the BungeniApplication
            model_interfaces.IBungeniApplication.providedBy(obj)
            and
            # user is logged in
            interfaces.IBungeniAuthenticatedSkin.providedBy(req)
            and (
                # either the request should be for a view within /workspace
                # note: IWorkspaceSectionLayer is applied to the request by 
                # publication.apply_request_layer_by_url() that therefore must 
                # have already been called
                interfaces.IWorkspaceSectionLayer.providedBy(req)
                or
                interfaces.IWorkspaceSchedulingSectionLayer.providedBy(req)
                or
                # or the request is for *the* Home Page (as in this case
                # we still need to know the user workspaces to be able to 
                # redirect appropriately)
                interfaces.IHomePageLayer.providedBy(req)
            )
        )
    if not need_to_prepare_workspaces(application, request):
        return

    # initialize a layer data object, for the views in the layer
    LD = IAnnotations(request)["layer_data"] = misc.bunch(
        workspaces=[], # workspace containers !+ unique?
        # !+ role-based workspaces: (role|group, workspace_container)
        # these are needed by the views, as we need them also here, we just
        # remember them to not need to calculate them again
        user_id=None,
        user_group_ids=None,
        government_id=None,
        ministries=None, # list of ministries (that are also workspaces)
    )

    LD.user_id = get_db_user_id()
    try:
        parliament = get_current_parliament(None)
        assert parliament is not None # force exception
        # we do get_context_roles under the current parliament as context, but
        # we must also ensure that the BungeniApp is present somewhere along 
        # the __parent__ stack:
        parliament.__parent__ = application
        roles = common.get_context_roles(parliament)
        # "bungeni.Clerk", "bungeni.Speaker", "bungeni.MP"
        for role_id in roles:
            if role_id in ("bungeni.Clerk", "bungeni.Speaker", "bungeni.MP"):
                log.debug("adding parliament workspace %s (for role %s)" % (
                                                        parliament, role_id))
                LD.workspaces.append(parliament)

        # "bungeni.Minister"
        # need to check for ministry groups to which the principal belongs, and 
        # for each such ministry assign a ministry workspace
        LD.user_group_ids = get_group_ids_for_user_in_parliament(
                                    LD.user_id, parliament.group_id)
        LD.government_id = get_current_parliament_governments(
                                    parliament)[0].group_id # IndexError
        LD.ministries = get_ministries_for_user_in_government(
                                            LD.user_id, LD.government_id)
        log.debug(""" [prepare_user_workspaces]
            user_id:%s
            roles:%s
            parliament:(%s, %s) 
            government_id:%s
            ministries:%s""" % (
                LD.user_id,
                roles,
                parliament.full_name, parliament.group_id,
                LD.government_id,
                [(m.full_name, m.group_id) for m in LD.ministries]))
        for ministry in LD.ministries:
            log.debug("adding ministry workspace %s" % ministry)
            LD.workspaces.append(ministry)
    except (Exception,):
        debug.log_exc_info(sys.exc_info(), log_handler=log.info)

    # ensure unique workspaces, preserving order, retaining same list obj ref
    LD.workspaces[:] = [ workspace for i, workspace in enumerate(LD.workspaces)
                         if LD.workspaces.index(workspace) == i ]

    # mark each workspace container with IWorkspaceContainer
    for workspace in LD.workspaces:
        interface.alsoProvides(workspace, interfaces.IWorkspaceContainer)
        log.debug(debug.interfaces(workspace))

    log.debug(" [prepare_user_workspaces] %s" % debug.interfaces(request))
    log.info(""" [prepare_user_workspaces] DONE:
        for: [request=%s][path=%s][path_info=%s]
        request.layer_data: %s""" % (
            id(request), destination_url_path, request.get("PATH_INFO"),
            IAnnotations(request).get("layer_data", None)))
Example #14
0
    def workspace_search(self):
        """ Search in workspace section, based on views from bungeni.ui.viewlets.workspace
        """
        application = common.get_application()
        parliament = get_current_parliament(None)
        parliament.__parent__ = application
        principal = get_principal()
        roles = common.get_context_roles(parliament, principal)

        # minister role, filtering by states and object_type and ministry_id
        if not roles:
            user_id = get_db_user_id()
            government_id = get_current_parliament_governments(parliament)[0].group_id
            ministries = get_ministries_for_user_in_government(user_id, government_id)
            if ministries:
                states = workspace.MinistryArchiveViewlet.states + \
                         workspace.OralMinistryQuestionsViewlet.states + \
                         workspace.WrittenMinistryQuestionsViewlet.states + \
                         workspace.InProgressMinistryItemsViewlet.states
                states = set(states)
                
                ministry_ids = [m.group_id for m in ministries]
                
                # filter by object_type (questions only)
                type_query = self.searcher.query_field('object_type', "Question")
                query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, type_query,))
                
                subqueries = []

                for state in states:
                    subqueries.append(self.searcher.query_field('status', state))
                    
                state_query = self.searcher.query_composite(self.searcher.OP_OR, subqueries)
                query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                           (query, state_query,))
                
                #filter for ministries
                ministries_queries = []
                
                for mid in ministry_ids:
                    ministries_queries.append(self.searcher.query_field('ministry_id', str(mid)))
                    
                m_query = self.searcher.query_composite(self.searcher.OP_OR, ministries_queries)
                query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                           (query, m_query,))
                
                try:
                    results = self.searcher.search(query, 0, self.searcher.get_doccount())
                except:
                    results = []
                
                return list(results)
        
        # filtering by states and owner
        if 'bungeni.MP' in roles:
            states = workspace.MPItemActionRequiredViewlet.states + \
                     workspace.MPItemDraftViewlet.states + \
                     workspace.MPItemInProgressViewlet.states + \
                     workspace.ItemArchiveViewlet.states
            states = set(states)
            # filter by owner of PI
            owner_query = self.searcher.query_field('owner', str(get_db_user_id()))
            query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, owner_query,))
            
            subqueries = []

            for state in states:
                subqueries.append(self.searcher.query_field('status', state))
                
            state_query = self.searcher.query_composite(self.searcher.OP_OR, subqueries)
            query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (query, state_query,))
            
            try:
                results = self.searcher.search(query, 0,
                self.searcher.get_doccount())
            except:
                results = []
                
            return list(results)
            
        # filtering by states
        if 'bungeni.Clerk' in roles:
            states = workspace.ClerkItemActionRequiredViewlet.states + \
                     workspace.ClerkItemsWorkingDraftViewlet.states + \
                     workspace.ClerkReviewedItemViewlet.states + \
                     workspace.ItemsApprovedViewlet.states + \
                     workspace.ItemsPendingScheduleViewlet.states + \
                     workspace.ItemsScheduledViewlet.states + \
                     workspace.AllItemArchiveViewlet.states
                     
            states = set(states)
            
            subqueries = []

            for state in states:
                subqueries.append(self.searcher.query_field('status', state))
                
            state_query = self.searcher.query_composite(self.searcher.OP_OR, subqueries)
            query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, state_query,))
            
            try:
                results = self.searcher.search(query, 0,
                self.searcher.get_doccount())
            except:
                results = []
                
            return list(results)
        # no results
        return False