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)
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)))
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) )
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)))
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 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
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
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))
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)))
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
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)))
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