Example #1
0
def user_workspaces(username, context=None, finder=get_workspaces):
    """
    Get workspaces for username, matching only workspaces for which
    the given user is a member; may be given context or use the
    site root as default context.

    A workspace enumerator/finder other than get_workspaces() may be passed
    (e.g. collective.teamwork.utils.get_projects).
    """
    suffix = '-viewers'
    site = getSite()
    context = context or site
    # get all PAS groups for workspaces contained within context:
    all_workspaces = finder(context)
    if not all_workspaces:
        # context contains no workspaces, even if context itself is workspace
        return []
    _pasgroup = lambda g: g.pas_group()
    _wgroups = lambda w: map(_pasgroup, IWorkspaceRoster(w).groups.values())
    local_groups = set(
        zip(*itertools.chain(*map(_wgroups, all_workspaces)))[0]
        )
    if not local_groups:
        return []
    # get all '-viewers' groups user belongs to, intersect with local:
    user = ISiteMembers(site).get(username)
    usergroups = [name for name in user.getGroups() if name.endswith(suffix)]
    considered = [name for name in local_groups.intersection(usergroups)]
    # each considered group (by suffix convention) is always 1:1 with
    # workspaces, no dupes, so we can map those workspaces:
    return map(group_workspace, set(considered))
Example #2
0
def user_workspaces(username, context=None, finder=get_workspaces):
    """
    Get workspaces for username, matching only workspaces for which
    the given user is a member; may be given context or use the
    site root as default context.

    A workspace enumerator/finder other than get_workspaces() may be passed
    (e.g. collective.teamwork.utils.get_projects).
    """
    suffix = '-viewers'
    site = getSite()
    context = context or site
    # get all PAS groups for workspaces contained within context:
    all_workspaces = finder(context)
    if not all_workspaces:
        # context contains no workspaces, even if context itself is workspace
        return []
    _pasgroup = lambda g: g.pas_group()
    _wgroups = lambda w: map(_pasgroup, IWorkspaceRoster(w).groups.values())
    local_groups = set(
        zip(*itertools.chain(*map(_wgroups, all_workspaces)))[0])
    if not local_groups:
        return []
    # get all '-viewers' groups user belongs to, intersect with local:
    user = ISiteMembers(site).get(username)
    usergroups = [name for name in user.getGroups() if name.endswith(suffix)]
    considered = [name for name in local_groups.intersection(usergroups)]
    # each considered group (by suffix convention) is always 1:1 with
    # workspaces, no dupes, so we can map those workspaces:
    return map(group_workspace, set(considered))
 def __init__(self, context, request):
     if not IWorkspaceContext.providedBy(context):
         raise ValueError('Context not a workspace')
     self.context = context
     self.request = request
     self.portal = getSite()
     self._members = ISiteMembers(self.portal)
     self._roster = IWorkspaceRoster(self.context)
     self._mtool = getToolByName(self.portal, 'portal_membership')
     self._secmgr = None
 def add_project(self, id, title=None):
     project = self.add_check(PROJECT_TYPE, id, IProject, Project)
     members = ISiteMembers(self.portal)
     if self.TEST_MEMBER not in members:
         members.register(self.TEST_MEMBER, send=False)
     assert self.TEST_MEMBER in members
     roster = IWorkspaceRoster(project)
     roster.add(self.TEST_MEMBER)
     assert self.TEST_MEMBER in roster
     return project
Example #5
0
 def add_project(self, id, title=None):
     project = self.add_check(PROJECT_TYPE, id, IProject, Project)
     members = ISiteMembers(self.portal)
     if self.TEST_MEMBER not in members:
         members.register(self.TEST_MEMBER, send=False)
     assert self.TEST_MEMBER in members
     roster = IWorkspaceRoster(project)
     roster.add(self.TEST_MEMBER)
     assert self.TEST_MEMBER in roster
     return project
Example #6
0
def fix_current_user(context):
    """
    When a project is added, the current user context may not yet
    have Manager role added to the generated user object, even if the
    user is technically a member of the group.  This is only an issue
    when we attempt to do something requiring a group membership added
    in the same transation.  This is a workaround.
    """
    current = ISiteMembers(getSite()).current()
    roster = IWorkspaceRoster(context)
    manager_group = roster.groups.get('managers').pas_group()[0]
    current._addGroups((manager_group,))
def handle_workspace_move_or_rename(context, event):
    if IObjectRemovedEvent.providedBy(event):
        return  # not a move with new/old, but a removal -- handled elsewhere
    if IObjectAddedEvent.providedBy(event):
        return  # not an add, but a move of existing
    site = getSite()
    pasgroups = ISiteMembers(site).groups
    roster = WorkspaceRoster(context)
    for workgroup in roster.groups.values():
        groupname, title = workgroup.pas_group()
        if groupname not in pasgroups:
            pasgroups.add(groupname, title=title)
        else:
            pasgroups.get(groupname).title = _u(title)
Example #8
0
def handle_workspace_move_or_rename(context, event):
    if IObjectRemovedEvent.providedBy(event):
        return  # not a move with new/old, but a removal -- handled elsewhere
    if IObjectAddedEvent.providedBy(event):
        return  # not an add, but a move of existing
    site = getSite()
    pasgroups = ISiteMembers(site).groups
    roster = WorkspaceRoster(context)
    for workgroup in roster.groups.values():
        groupname, title = workgroup.pas_group()
        if groupname not in pasgroups:
            pasgroups.add(groupname, title=title)
        else:
            pasgroups.get(groupname).title = _u(title)
def handle_workspace_removal(context, event):
    """Handler for IObjectRemovedEvent on a workspace"""
    site = getSite()
    if site is None:
        return  # in case of recursive plone site removal, ignore
    pasgroups = ISiteMembers(site).groups
    roster = WorkspaceRoster(context)
    for group in roster.groups.values():
        groupname = group.pas_group()[0]
        if groupname in pasgroups:
            pasgroups.remove(groupname)
    # remove group names for nested workspaces (also, by implication,
    #   removed from the PAS group manager plugin).
    for workspace in get_workspaces(context):
        handle_workspace_removal(workspace, event=event)
Example #10
0
def handle_workspace_removal(context, event):
    """Handler for IObjectRemovedEvent on a workspace"""
    site = getSite()
    if site is None:
        return  # in case of recursive plone site removal, ignore
    pasgroups = ISiteMembers(site).groups
    roster = WorkspaceRoster(context)
    for group in roster.groups.values():
        groupname = group.pas_group()[0]
        if groupname in pasgroups:
            pasgroups.remove(groupname)
    # remove group names for nested workspaces (also, by implication,
    #   removed from the PAS group manager plugin).
    for workspace in get_workspaces(context):
        handle_workspace_removal(workspace, event=event)
 def __init__(self, context, request):
     if not IWorkspaceContext.providedBy(context):
         raise ValueError('Context not a workspace')
     self.context = context
     self.request = request
     self.portal = getSite()
     self._members = ISiteMembers(self.portal)
     self._roster = IWorkspaceRoster(self.context)
     self._mtool = getToolByName(self.portal, 'portal_membership')
     self._secmgr = None
def create_workspace_groups_roles(context):
    site = getSite()
    members = ISiteMembers(site)
    pasgroups = members.groups
    roster = WorkspaceRoster(context)
    for group in roster.groups.values():
        groupname, title = group.pas_group()
        if groupname not in pasgroups:
            pasgroups.add(groupname, title=title)
        else:
            # update title of previously existing group (edge case)
            pasgroups.get(groupname).title = _u(title)
        # bind local roles, mapping group to roles from config
        sync_group_roles(context, groupname)
    if INavigationRoot.providedBy(context):
        # for newly added top-level (nav root workspaces or
        # projects), add owner/creator as a manager.
        authuser = members.current()
        if authuser is not None:
            authuser = authuser.getUserName()
            if authuser in members:
                roster.add(authuser)
                roster.groups['managers'].add(authuser)
Example #13
0
def create_workspace_groups_roles(context):
    site = getSite()
    members = ISiteMembers(site)
    pasgroups = members.groups
    roster = WorkspaceRoster(context)
    for group in roster.groups.values():
        groupname, title = group.pas_group()
        if groupname not in pasgroups:
            pasgroups.add(groupname, title=title)
        else:
            # update title of previously existing group (edge case)
            pasgroups.get(groupname).title = _u(title)
        # bind local roles, mapping group to roles from config
        sync_group_roles(context, groupname)
    if INavigationRoot.providedBy(context):
        # for newly added top-level (nav root workspaces or
        # projects), add owner/creator as a manager.
        authuser = members.current()
        if authuser is not None:
            authuser = authuser.getUserName()
            if authuser in members:
                roster.add(authuser)
                roster.groups['managers'].add(authuser)
Example #14
0
 def test_adapter_registration(self):
     self.assertIsInstance(ISiteMembers(self.portal), SiteMembers)
     self.assertEqual(ISiteMembers(self.portal).context, self.portal)
class UserInfo(object):
    """
    View for user information -- for a single user.

    May be used for either display of a single user in an overlay
    or for a macro listing multiple users (see template).
    """

    RESTRICTED_PROPS = ('last_login_time', )

    def __init__(self, context, request):
        if not IWorkspaceContext.providedBy(context):
            raise ValueError('Context not a workspace')
        self.context = context
        self.request = request
        self.portal = getSite()
        self._members = ISiteMembers(self.portal)
        self._roster = IWorkspaceRoster(self.context)
        self._mtool = getToolByName(self.portal, 'portal_membership')
        self._secmgr = None

    def linked_workspaces(self, username):
        if self._secmgr is None:
            self._secmgr = getSecurityManager()
        # get all workspaces for user in the current context
        workspaces = user_workspaces(username, self.context)
        _you_can_see = lambda w: self._secmgr.checkPermission('View', w)
        _nolink = lambda w: {'absolute_url': '#', 'Title': w.Title()}
        # only provide links to workspaces the current auth. user can View:
        return [(w if _you_can_see(w) else _nolink(w)) for w in workspaces]

    def user_display_info(self, username):
        """
        Given username, get information for that user, returning
        it as a dict of portrait_url (if existing), properties,
        assignments (in this workspace), and memberships (in
        contained workspaces).
        """
        if self._secmgr is None:
            self._secmgr = getSecurityManager()
        roster = self._roster
        data = {}  # use dict in lieu of object, simple
        user = self._members.get(username, None)
        if user is None or username not in roster:
            return data  # empty if no user data or user not in workspace
        portrait = self._members.portrait_for(username)
        if portrait is not None:
            data['portrait_url'] = portrait.absolute_url()
        propkeys = {
            'fullname': 'Full name',
            'email': 'Email',
            'description': 'User info',
            'location': 'Location',
            'home_page': 'Home page',
            'last_login_time': 'Last login',
        }
        restricted = self.RESTRICTED_PROPS
        if self._secmgr.checkPermission('Manage users', self.context):
            restricted = ()  # manager can see these properties
        if self._mtool.getAuthenticatedMember().getId() == username:
            restricted = ()  # user can see own restricted properties
        props = {}
        for name, title in propkeys.items():
            if name in restricted:
                continue
            v = user.getProperty(name)
            if v:
                props[title] = v
        if props:
            data['properties'] = props
        groups = roster.groups.values()
        data['assignments'] = [g.title for g in groups if username in g]
        workspaces = self.linked_workspaces(username)
        if workspaces:
            data['workspaces'] = workspaces
        return data
class UserInfo(object):
    """
    View for user information -- for a single user.

    May be used for either display of a single user in an overlay
    or for a macro listing multiple users (see template).
    """

    RESTRICTED_PROPS = (
        'last_login_time',
        )

    def __init__(self, context, request):
        if not IWorkspaceContext.providedBy(context):
            raise ValueError('Context not a workspace')
        self.context = context
        self.request = request
        self.portal = getSite()
        self._members = ISiteMembers(self.portal)
        self._roster = IWorkspaceRoster(self.context)
        self._mtool = getToolByName(self.portal, 'portal_membership')
        self._secmgr = None

    def linked_workspaces(self, username):
        if self._secmgr is None:
            self._secmgr = getSecurityManager()
        # get all workspaces for user in the current context
        workspaces = user_workspaces(username, self.context)
        _you_can_see = lambda w: self._secmgr.checkPermission('View', w)
        _nolink = lambda w: {'absolute_url': '#', 'Title': w.Title()}
        # only provide links to workspaces the current auth. user can View:
        return [
            (w if _you_can_see(w) else _nolink(w)) for w in workspaces
            ]

    def user_display_info(self, username):
        """
        Given username, get information for that user, returning
        it as a dict of portrait_url (if existing), properties,
        assignments (in this workspace), and memberships (in
        contained workspaces).
        """
        if self._secmgr is None:
            self._secmgr = getSecurityManager()
        roster = self._roster
        data = {}  # use dict in lieu of object, simple
        user = self._members.get(username, None)
        if user is None or username not in roster:
            return data  # empty if no user data or user not in workspace
        portrait = self._members.portrait_for(username)
        if portrait is not None:
            data['portrait_url'] = portrait.absolute_url()
        propkeys = {
            'fullname': 'Full name',
            'email': 'Email',
            'description': 'User info',
            'location': 'Location',
            'home_page': 'Home page',
            'last_login_time': 'Last login',
            }
        restricted = self.RESTRICTED_PROPS
        if self._secmgr.checkPermission('Manage users', self.context):
            restricted = ()  # manager can see these properties
        if self._mtool.getAuthenticatedMember().getId() == username:
            restricted = ()  # user can see own restricted properties
        props = {}
        for name, title in propkeys.items():
            if name in restricted:
                continue
            v = user.getProperty(name)
            if v:
                props[title] = v
        if props:
            data['properties'] = props
        groups = roster.groups.values()
        data['assignments'] = [g.title for g in groups if username in g]
        workspaces = self.linked_workspaces(username)
        if workspaces:
            data['workspaces'] = workspaces
        return data
Example #17
0
 def _members_adapter(self, members=None):
     return members if members is not None else ISiteMembers(self._site)