def existing_users(context):
    """
    Look up the full user details for current workspace members
    """
    members = IWorkspace(context).members
    info = []
    for userid, details in members.items():
        user = api.user.get(userid)
        if user is None:
            continue
        user = user.getUser()
        title = user.getProperty("fullname") or user.getId() or userid
        # XXX tbd, we don't know what a persons description is, yet
        description = _(u"Here we could have a nice status of this person")
        classes = description and "has-description" or "has-no-description"
        portal = api.portal.get()
        portrait = "%s/portal_memberdata/portraits/%s" % (portal.absolute_url(), userid)
        info.append(
            dict(
                id=userid,
                title=title,
                description=description,
                portrait=portrait,
                cls=classes,
                member=True,
                admin="Admins" in details["groups"],
            )
        )

    return info
Esempio n. 2
0
def invitation_accepted(event):
    """
    When an invitation is accepted, add the user to the team
    """
    request = getRequest()
    storage = get_storage()
    if event.token_id not in storage:
        return

    ws_uid, username = storage[event.token_id]
    storage[event.token_id]
    acl_users = api.portal.get_tool("acl_users")
    acl_users.updateCredentials(request, request.response, username, None)
    catalog = api.portal.get_tool(name="portal_catalog")
    brain = catalog.unrestrictedSearchResults(UID=ws_uid)[0]
    with api.env.adopt_roles(["Manager"]):
        ws = IWorkspace(brain.getObject())
        for name in ws.members:
            member = api.user.get(username=name)
            if member is not None:
                if member.getUserName() == username:
                    api.portal.show_message(_("Oh boy, oh boy, you are already a member"), request)
                    break
        else:
            ws.add_to_team(user=username)
            api.portal.show_message(_("Welcome to our family, Stranger"), request)
Esempio n. 3
0
    def test_sidebar_existing_users(self):

        ws = self.create_workspace()
        user = api.user.create(email="*****@*****.**", username="******")
        user_id = user.getId()

        self.assertNotIn(user_id, IWorkspace(ws).members, "Id already present")

        IWorkspace(ws).add_to_team(user=user_id)
        provideAdapter(
            SidebarSettingsMembers,
            (Interface, Interface),
            IBasicTile,
            name=u"sidebarSettingsMember.default",
        )

        # Commenting out because they aren't (yet?) being used.
        # sidebarSettingsMembers = getMultiAdapter(
        #     (ws, ws.REQUEST), name=u"sidebarSettingsMember.default")
        # existing_users = sidebarSettingsMembers.existing_users()

        self.assertIn(
            user_id,
            IWorkspace(ws).members,
            "Id not found in worskpace member Ids",
        )
Esempio n. 4
0
def existing_users(context):
    """
    Look up the full user details for current workspace members
    """
    members = IWorkspace(context).members
    info = []
    for userid, details in members.items():
        user = api.user.get(userid)
        if user is None:
            continue
        user = user.getUser()
        title = user.getProperty('fullname') or user.getId() or userid
        # XXX tbd, we don't know what a persons description is, yet
        description = ''
        classes = description and 'has-description' or 'has-no-description'
        portal = api.portal.get()
        portrait = '%s/@@avatars/%s' % \
                   (portal.absolute_url(), userid)
        info.append(
            dict(
                id=userid,
                title=title,
                description=description,
                portrait=portrait,
                cls=classes,
                member=True,
                admin='Admins' in details['groups'],
            )
        )

    return info
Esempio n. 5
0
def existing_users(context):
    """
    Look up the full user details for current workspace members
    """
    members = IWorkspace(context).members
    info = []
    for userid, details in members.items():
        user = api.user.get(userid)
        if user is None:
            continue
        user = user.getUser()
        title = user.getProperty('fullname') or user.getId() or userid
        # XXX tbd, we don't know what a persons description is, yet
        description = ''
        classes = description and 'has-description' or 'has-no-description'
        portal = api.portal.get()
        portrait = '%s/@@avatars/%s' % \
                   (portal.absolute_url(), userid)
        info.append(
            dict(
                id=userid,
                title=title,
                description=description,
                portrait=portrait,
                cls=classes,
                member=True,
                admin='Admins' in details['groups'],
            ))

    return info
Esempio n. 6
0
def invitation_accepted(event):
    """
    When an invitation is accepted, add the user to the team
    """
    request = getRequest()
    storage = get_storage()
    if event.token_id not in storage:
        return

    ws_uid, username = storage[event.token_id]
    storage[event.token_id]
    acl_users = api.portal.get_tool('acl_users')
    acl_users.updateCredentials(request, request.response, username, None)
    catalog = api.portal.get_tool(name="portal_catalog")
    brain = catalog.unrestrictedSearchResults(UID=ws_uid)[0]
    with api.env.adopt_roles(["Manager"]):
        ws = IWorkspace(brain.getObject())
        for name in ws.members:
            member = api.user.get(username=name)
            if member is not None:
                if member.getUserName() == username:
                    api.portal.show_message(
                        _('Oh boy, oh boy, you are already a member'),
                        request,
                    )
                    break
        else:
            ws.add_to_team(user=username)
            api.portal.show_message(
                _('Welcome to our family, Stranger'),
                request,
            )
Esempio n. 7
0
    def get_principal_roles(self, principal):
        ''' Get the description for this principalid
        '''
        adapter = IWorkspace(self.context)
        if hasattr(principal, 'getGroupId'):
            groups = adapter.get(principal.getGroupId()).groups
        else:
            groups = adapter.get(principal.getId()).groups

        if 'Admins' in groups:
            return ['Admin']

        # The policies are ordered from the less permissive to the most
        # permissive. We reverse them
        for policy in reversed(PARTICIPANT_POLICY):
            # BBB: code copied from the workspacefolder existing_users function
            # at 58c758d20a820dcb9f691168a9215bfc9741b00e
            # not really clear to me why we are skipping the current policy
            if policy != self.context.participant_policy:
                if policy.title() in groups:
                    # According to the design there is at most one extra role
                    # per user, so we go with the first one we find. This may
                    # not be enforced in the backend though.
                    return [PARTICIPANT_POLICY[policy]['title']]

        if groups == {'Guests'}:
            return ['Guest']
        return []
Esempio n. 8
0
    def existing_users(self):
        """
        Look up the full user details for current workspace members
        """
        members = IWorkspace(self).members
        info = []
        for userid, details in members.items():
            user = api.user.get(userid)
            if user is None:
                continue
            user = user.getUser()
            title = user.getProperty('fullname') or user.getId() or userid
            # XXX tbd, we don't know what a persons description is, yet
            description = MessageFactory(u'Here we could have a nice status of'
                                         u' this person')
            classes = description and 'has-description' or 'has-no-description'
            portrait = pi_api.userprofile.avatar_url(userid)
            info.append(
                dict(
                    id=userid,
                    title=title,
                    description=description,
                    portrait=portrait,
                    cls=classes,
                    member=True,
                    admin='Admins' in details['groups'],
                )
            )

        return info
Esempio n. 9
0
 def guest_ids(self):
     ''' Get the valid member ids through IWorkspace
     '''
     adapter = IWorkspace(self.context)
     return [
         principalid for principalid in self.member_ids
         if adapter.get(principalid).groups == {'Guests'}
     ]
def participation_policy_changed(ob, event):
    """ Move all the existing users to a new group """
    workspace = IWorkspace(ob)
    old_group_name = workspace.group_for_policy(event.old_policy)
    old_group = api.group.get(old_group_name)
    for member in old_group.getAllGroupMembers():
        groups = workspace.get(member.getId()).groups
        groups -= set([event.old_policy.title()])
        groups.add(event.new_policy.title())
Esempio n. 11
0
    def test_policy_exceptions(self):
        self.login_as_portal_owner()
        workspace = api.content.create(
            self.workspace_container,
            'ploneintranet.workspace.workspacefolder',
            'workspace'
        )
        # set default policy to producers
        workspace.participant_policy = 'producers'

        # create some members and add to workspace
        username = '******'
        username2 = 'member_username2'
        api.user.create(username=username, email='*****@*****.**')
        self.add_user_to_workspace(username, workspace)
        api.user.create(username=username2, email='*****@*****.**')
        self.add_user_to_workspace(username2, workspace)

        # Make an exception of username2
        # by moving them to a non-default group
        IWorkspace(workspace).add_to_team(username2, groups={'Consume'})

        group = api.group.get('Producers:' + api.content.get_uuid(workspace))
        # username should be in the default group
        self.assertIn(
            api.user.get(username=username),
            group.getAllGroupMembers()
        )
        # username two should *not* be in the default group
        self.assertNotIn(
            api.user.get(username=username2),
            group.getAllGroupMembers()
        )

        # update default policy
        workspace.participant_policy = 'moderators'

        group = api.group.get('Moderators:' + api.content.get_uuid(workspace))
        # username should have been moved to the new group
        self.assertIn(
            api.user.get(username=username),
            group.getAllGroupMembers()
        )
        # username2 two should *not* be in the new default group
        self.assertNotIn(
            api.user.get(username=username2),
            group.getAllGroupMembers()
        )

        # remove username2 as an exception by re-setting their groups
        IWorkspace(workspace).add_to_team(username2)
        self.assertIn(
            api.user.get(username=username2),
            group.getAllGroupMembers()
        )
 def setUp(self):
     self.app = self.layer['app']
     self.portal = self.layer['portal']
     self.request = self.layer['request']
     z2.login(self.app['acl_users'], SITE_OWNER_NAME)
     self.user1 = api.user.create(email='*****@*****.**',
                                  username='******',
                                  password='******')
     self.workspace = api.content.create(container=self.portal,
                                         type='Workspace',
                                         id='a-workspace')
     self.ws = IWorkspace(self.workspace)
Esempio n. 13
0
 def setUp(self):
     self.app = self.layer["app"]
     self.portal = self.layer["portal"]
     self.request = self.layer["request"]
     zope.login(self.app["acl_users"], SITE_OWNER_NAME)
     self.user1 = api.user.create(
         email="*****@*****.**", username="******", password="******"
     )
     self.workspace = api.content.create(
         container=self.portal, type="Workspace", id="a-workspace"
     )
     self.ws = IWorkspace(self.workspace)
Esempio n. 14
0
    def test_invitation_send_but_user_became_a_member_not_via_link(self):
        email = "*****@*****.**"
        username = '******'
        api.user.create(
            email=email,
            username=username,
            password='******',
        )
        # there shouldn't be any minus admin user in workspace
        self.assertEqual(0, len(list(IWorkspace(self.ws).members)) - 1)

        request = self.make_request(username=username)
        form = api.content.get_view(
            'invite',
            context=self.ws,
            request=request,
        )

        form.update()
        data, errors = form.extractData()
        self.assertEqual(len(errors), 0)
        # no errors on the widget?
        self.assertEqual(form.widgets['user'].error, None)
        # our mock mail host received one email?
        self.assertEqual(len(self.mailhost.messages), 1)
        msg = message_from_string(self.mailhost.messages[0])
        # mail is actually received by correct recipient

        # now lets add this user to workspace via other channels
        self.add_user_to_workspace(username, self.ws)

        self.assertEqual(msg['To'], email)
        body = msg.get_payload()
        url_match = re.search("(?P<url>http://[0-9a-z:/@-]+)(?=\n)", body)
        self.assertNotEqual(url_match, None)
        url = url_match.groupdict("url").get("url")

        self.mailhost.reset()
        import transaction
        transaction.commit()

        browser = Browser(self.app)
        browser.open(url)
        self.assertIn('userrole-authenticated', browser.contents,
                      'User was not authenticated after accepting token')
        # check that user is added to workspace
        self.assertEqual(1, len(list(IWorkspace(self.ws).members)) - 1)
        self.assertIn("Oh boy, oh boy, you are already a member",
                      browser.contents)
Esempio n. 15
0
    def test_sidebar_existing_users(self):

        ws = self.create_workspace()
        user = api.user.create(email="*****@*****.**", username="******")
        user_id = user.getId()

        self.assertNotIn(user_id, IWorkspace(ws).members, "Id already present")

        IWorkspace(ws).add_to_team(user=user_id)

        self.assertIn(
            user_id,
            IWorkspace(ws).members,
            "Id not found in worskpace member Ids",
        )
Esempio n. 16
0
 def test_viewlet_invisible_if_user_is_member(self):
     self.workspace.join_policy = 'self'
     self.workspace.visibility = 'open'
     viewlet = JoinViewlet(self.folder, self.request, None, None)
     IWorkspace(self.workspace).add_to_team(user='******')
     self.login('demo')
     self.assertFalse(viewlet.visible())
Esempio n. 17
0
def find_workspace(context):
    while hasattr(context, "context"):
        context = context.context
    for context in aq_chain(context):
        workspace = IWorkspace(context, None)
        if workspace is not None:
            return workspace
Esempio n. 18
0
    def test_add_admin_to_workspace(self):
        """ check that site admin can add team admin to the workspace """
        self.login_as_portal_owner()
        ws = self._create_unadapted_workspace()
        user = self._create_user()
        groups = api.group.get_groups()
        group_names = [x.getName() for x in groups]
        group_name = 'Admins:%s' % (api.content.get_uuid(ws))
        self.assertIn(group_name, group_names)
        workspace = IWorkspace(ws)
        workspace.add_to_team(user=user.getId(), groups=set([u"Admins"]))

        portal = api.portal.get()
        pgroups = portal.portal_groups.getGroupById(group_name)
        member_ids = pgroups.getGroup().getMemberIds()
        self.assertIn(user.getId(), member_ids)
    def existing_users(self):
        members = IWorkspace(self.context).members
        info = []
        for userid, details in members.items():
            user = api.user.get(userid).getUser()
            title = user.getProperty('fullname') or user.getId() or userid
            info.append(
                dict(
                    id=userid,
                    title=title,
                    member=True,
                    admin='Admins' in details['groups'],
                )
            )

        return info
Esempio n. 20
0
    def __call__(self):
        q = self.request.get('q', '').lower()

        groups = self.get_groups()

        group_details = []
        ws = IWorkspace(self.context)
        for group in groups:
            groupid = group.getId()
            # XXX Filter out groups representing workspace roles. Review
            # whether we need/want this and/or can do it more efficiently.
            if (groupid == self.context.id or  # don't add group to itself
                    group.getProperty('state') == 'secret' or
                    groupid.partition(':')[0] in ws.available_groups):
                continue
            title = group.getProperty('title') or groupid
            email = group.getProperty('email')
            if email:
                title = '%s <%s>' % (title, email)
            description = group.getProperty('description') or ''
            if q in title.lower() or q in description.lower():
                group_details.append({
                    'text': title,
                    'id': groupid,
                })
        return dumps(group_details)
Esempio n. 21
0
    def test_acquired_roles_from_policy_settings(self):
        self.login_as_portal_owner()
        policy = "moderators"
        self.workspace.participant_policy = policy
        ws = IWorkspace(self.workspace)
        ws.add_to_team(user=self.user.getUserName())
        roles = ws.available_groups.get(policy.title())
        self.request.form = {'form.button.Search': 'Search',
                             'search_term': 'demo'}
        view = SharingView(self.workspace, self.request)
        results = view.user_search_results()

        self.assertEqual(len(results), 1)
        self.assertTrue(
            all([results[0]["roles"][role] == "acquired" for role in roles]),
            "Acquired roles were not set correctly")
Esempio n. 22
0
    def _getWorkspace(self, uid):
        catalog = getToolByName(self, 'portal_catalog')
        res = catalog.unrestrictedSearchResults(
            object_provides=WORKSPACE_INTERFACE, UID=uid)
        if not res:
            return

        return IWorkspace(res[0]._unrestrictedGetObject())
Esempio n. 23
0
 def _create_workspace(self):
     """ returns adapted workspace folder"""
     workspace_folder = api.content.create(
         self.workspace_container,
         'ploneintranet.workspace.workspacefolder',
         'example-workspace',
         title='Welcome to my workspace')
     return IWorkspace(workspace_folder)
 def setUp(self):
     self.app = self.layer["app"]
     self.portal = self.layer["portal"]
     self.request = self.layer["request"]
     z2.login(self.app["acl_users"], SITE_OWNER_NAME)
     self.user1 = api.user.create(email="*****@*****.**", username="******", password="******")
     self.workspace = api.content.create(container=self.portal, type="Workspace", id="a-workspace")
     self.ws = IWorkspace(self.workspace)
Esempio n. 25
0
 def test_member_is_added_to_user_title_if_user_is_a_member(self):
     self.login_as_portal_owner()
     IWorkspace(self.workspace).add_to_team(user=self.user.getUserName())
     self.request.form = {
         'form.button.Search': 'Search',
         'search_term': 'demo'
     }
     view = SharingView(self.workspace, self.request)
     self.assertIn('%s [member]' % (self.user.getUserName(), ), view())
Esempio n. 26
0
    def test_acquired_roles_from_policy_settings(self):
        self.login_as_portal_owner()
        policy = "moderators"
        self.workspace.participant_policy = policy
        ws = IWorkspace(self.workspace)
        ws.add_to_team(user=self.user.getUserName())
        roles = ws.available_groups.get(policy.title())
        self.request.form = {
            'form.button.Search': 'Search',
            'search_term': 'demo'
        }
        view = SharingView(self.workspace, self.request)
        results = view.user_search_results()

        self.assertEqual(len(results), 1)
        self.assertTrue(
            all([results[0]["roles"][role] == "acquired" for role in roles]),
            "Acquired roles were not set correctly")
Esempio n. 27
0
    def __call__(self):
        if not self.context.join_policy == "self":
            msg = _(u"Workspace join policy doesn't allow self join")
            raise Unauthorized(msg)

        field = "button.join"
        req_method = self.request.method.lower()
        if req_method == "post" and field in self.request.form:
            user = api.user.get_current()
            workspace = IWorkspace(self.context)
            workspace.add_to_team(user=user.getId())
            msg = _(u"You are a member of this workspace now")
            api.portal.show_message(message=_(msg), request=self.request)

        referer = self.request.get("HTTP_REFERER", "").strip()
        if not referer:
            referer = self.context.absolute_url()
        return self.request.response.redirect(referer)
Esempio n. 28
0
    def __call__(self):
        if not self.context.join_policy == "self":
            msg = _(u"Workspace join policy doesn't allow self join")
            raise Unauthorized(msg)

        field = "button.join"
        req_method = self.request.method.lower()
        if req_method == "post" and field in self.request.form:
            user = api.user.get_current()
            workspace = IWorkspace(self.context)
            workspace.add_to_team(user=user.getId())
            msg = _(u"You are a member of this workspace now")
            api.portal.show_message(message=_(msg),
                                    request=self.request)

        referer = self.request.get("HTTP_REFERER", "").strip()
        if not referer:
            referer = self.context.absolute_url()
        return self.request.response.redirect(referer)
Esempio n. 29
0
def invitation_accepted(event):
    """
    When an invitation is accepted, add the user to the team.
    This apparently is NOT a ploneintranet.invitations invitation,
    but by ploneintranet.workspace.browser.forms.InviteForm.
    """
    request = getRequest()
    storage = get_storage()
    if event.token_id not in storage:
        return

    ws_uid, userid = storage[event.token_id]
    # in a email_as_login setting (see #1043)
    # .userid == .username but .username != .getUserName() ... :-(
    username = api.user.get(userid=userid).getUserName()
    acl_users = api.portal.get_tool('acl_users')
    acl_users.updateCredentials(
        request,
        request.response,
        username,  # the login, not the userid
        None
    )
    catalog = api.portal.get_tool(name="portal_catalog")
    brain = catalog.unrestrictedSearchResults(UID=ws_uid)[0]
    with api.env.adopt_roles(["Manager"]):
        ws = IWorkspace(brain.getObject())
        # collective.workspace .members returns userid iterator
        for member_id in ws.members:  # don't clobber userid variable
            member = api.user.get(userid=member_id)
            if member is not None:
                if member.getId() == userid:
                    api.portal.show_message(
                        _('Oh boy, oh boy, you are already a member'),
                        request,
                    )
                    break
        else:
            # 'user' in this API is actually userid
            ws.add_to_team(user=userid)
            api.portal.show_message(
                _('Welcome to our family, Stranger'),
                request,
            )
Esempio n. 30
0
 def test_user_redirected_if_method_get(self):
     self.open_workspace()
     self.request.method = 'GET'
     self.request.form = {'button.join': True}
     self.request['HTTP_REFERER'] = 'someurl'
     self.login('demo')
     view = JoinView(self.workspace, self.request)
     response = view()
     self.assertEqual('someurl', response)
     self.assertNotIn('demo', IWorkspace(self.workspace).members)
Esempio n. 31
0
    def test_user_deletion_from_site_removes_from_workspace(self):
        username = "******"
        api.user.create(
            email="*****@*****.**",
            username=username,
            password="******",
        )

        # there shouldn't be any minus admin user in workspace
        self.assertEqual(0, len(list(IWorkspace(self.ws).members)) - 1)

        # lets add one user
        self.add_user_to_workspace(username, self.ws)
        self.assertEqual(1, len(list(IWorkspace(self.ws).members)) - 1)

        # now lets remove a user from the site
        api.user.delete(username)

        # and this user should be gone from workspace as well
        self.assertEqual(0, len(list(IWorkspace(self.ws).members)) - 1)
Esempio n. 32
0
    def test_add_admin_to_workspace(self):
        """ check that site admin can add team admin to the workspace """
        self.login_as_portal_owner()
        ws = self.create_unadapted_workspace()
        user = self.create_user()
        groups = api.group.get_groups()
        group_names = [x.getName() for x in groups]
        group_name = 'Admins:%s' % (api.content.get_uuid(ws))
        self.assertIn(
            group_name,
            group_names
        )
        workspace = IWorkspace(ws)
        workspace.add_to_team(user=user.getId(), groups=set([u"Admins"]))

        portal = api.portal.get()
        pgroups = portal.portal_groups.getGroupById(group_name)
        member_ids = pgroups.getGroup().getMemberIds()
        self.assertIn(user.getId(),
                      member_ids)
Esempio n. 33
0
 def participant_policy(self, value):
     """ Changing participation policy fires a
     "ParticipationPolicyChanged" event
     """
     old_policy = self.participant_policy
     new_policy = value
     self._participant_policy = new_policy
     IWorkspace(self).update_participant_policy_groups(
         old_policy,
         new_policy,
     )
     notify(ParticipationPolicyChangedEvent(self, old_policy, new_policy))
Esempio n. 34
0
def workspace_added(ob, event):
    """
    when a workspace is created, we add the creator to
    the admin group. We then setup our placeful workflow

    """
    is_case = ICase.providedBy(ob)
    preserve_template_ownership = api.portal.get_registry_record(
        'ploneintranet.workspace.preserve_template_ownership',
        default=False,
    )
    userid = api.user.get_current().id

    # If not stated otherwise through the registry record:
    # ploneintranet.workspace.preserve_template_ownership
    # whoever creates the workspace should be added as an Admin
    # When copying a template, that is the current user
    # (not the one who created the original template)
    if (not is_case) or (not preserve_template_ownership):
        ob.setCreators([userid])
        IWorkspace(ob).add_to_team(
            user=userid,
            groups=set(['Admins']),
        )
    # During workspace creation, various functions
    # are called (renaming / workflow transitions) which do
    # low-level AccessControl checks.
    # Unfortunately these checks never re-ask PAS for a user's roles
    # or groups during a request, so we have to manually re-initialise
    # the security context for the current user.
    # ref: https://github.com/ploneintranet/ploneintranet/pull/438
    _reset_security_context(userid, ob.REQUEST)

    if is_case:
        """Case Workspaces have their own custom workflows
        """
        return

    # Configure our placeful workflow
    cmfpw = 'CMFPlacefulWorkflow'

    try:
        ob.manage_addProduct[cmfpw].manage_addWorkflowPolicyConfig()
    except BadRequest:
        # 'The id ".wf_policy_config" is invalid - it is already in use.'
        # copying a template workspace which already has a policy defined
        return

    # Set the policy for the config
    pc = getattr(ob, WorkflowPolicyConfig_id)
    pc.setPolicyIn('')
    pc.setPolicyBelow('ploneintranet_policy')
Esempio n. 35
0
    def user_search_results(self):
        """ Add [member] to a user title if user is a member
        of current workspace
        """
        results = super(SharingView, self).user_search_results()
        ws = IWorkspace(self.context)
        roles_mapping = ws.available_groups
        roles = roles_mapping.get(self.context.participant_policy.title())

        for result in results:
            if result["id"] in ws.members:
                groups = ws.get(result["id"]).groups
                for role in roles:
                    result["roles"][role] = "acquired"
                if "Admins" in groups:
                    title = "administrator"
                    result["roles"]["TeamManager"] = "acquired"
                else:
                    title = "member"
                result["title"] = "%s [%s]" % (result["title"], title)

        return results
Esempio n. 36
0
    def user_search_results(self):
        """ Add [member] to a user title if user is a member
        of current workspace
        """
        results = super(SharingView, self).user_search_results()
        ws = IWorkspace(self.context)
        roles_mapping = ws.available_groups
        roles = roles_mapping.get(self.context.participant_policy.title())

        for result in results:
            if result["id"] in ws.members:
                groups = ws.get(result["id"]).groups
                for role in roles:
                    result["roles"][role] = "acquired"
                if "Admins" in groups:
                    title = "administrator"
                    result["roles"]["TeamManager"] = "acquired"
                else:
                    title = "member"
                result["title"] = "%s [%s]" % (result["title"], title)

        return results
Esempio n. 37
0
 def test_administrator_is_added_to_administrator(self):
     """ Test that [administrator] is added to the workspace
     administrator """
     self.login_as_portal_owner()
     IWorkspace(self.workspace).add_to_team(user=self.user.getId(),
                                            groups=set(["Admins"]))
     self.request.form = {
         'form.button.Search': 'Search',
         'search_term': 'demo'
     }
     view = SharingView(self.workspace, self.request)
     self.assertIn('%s [administrator]' % (self.user.getId(), ), view())
     self.assertNotIn("%s [member]" % (self.user.getId(), ), view())
Esempio n. 38
0
    def execute_batch_function(self):
        if not self.can_manage_roster():
            msg = _(u'You do not have permission to change the workspace '
                    u'policy')
            raise Unauthorized(msg)

        form = self.request.form
        user_ids = form.get('user_id')
        if not user_ids:
            return

        if isinstance(user_ids, basestring):
            user_ids = user_ids.split(',')

        ws = self.workspace()
        batch_function = form.get('batch-function')
        if batch_function == 'add':
            for user_id in user_ids:
                IWorkspace(ws).add_to_team(user=user_id)
            msg = _(u'Member(s) added')
            msg_type = 'success'
        elif batch_function == 'remove':
            for user_id in user_ids:
                IWorkspace(ws).remove_from_team(user=user_id)
            msg = _(u'Member(s) removed')
            msg_type = 'success'
        elif batch_function == 'role':
            role = self.request.get('role')
            groups = role and {role} or None
            for user_id in user_ids:
                IWorkspace(ws).add_to_team(user=user_id, groups=groups)
            msg = _(u'Role updated')
            msg_type = 'success'
        else:
            msg = _(u'Unknown function')
            msg_type = 'error'

        api.portal.show_message(msg, self.request, msg_type)
        notify(WorkspaceRosterChangedEvent(self.context))
Esempio n. 39
0
    def test_update_users_add_member(self):
        view = getMultiAdapter((self.workspace, self.request),
                               name='edit-roster')
        settings = [
            {
                'id': 'wsmember2',
                'member': True,
            },
        ]

        view.update_users(settings)
        members = IWorkspace(self.workspace).members
        self.assertIn('wsmember2', members)
Esempio n. 40
0
    def test_update_users_remove_admin(self):
        """
        Remove admin role from workspace as manager
        """
        view = getMultiAdapter((self.workspace, self.request),
                               name='edit-roster')
        settings = [{
            'id': 'wsadmin',
            'member': True,
            'admin': False,
        }, {
            'id': 'wsmember',
            'member': True,
        }]

        view.update_users(settings)
        members = IWorkspace(self.workspace).members
        self.assertIn('wsadmin', members)
        self.assertNotIn(
            'Admins',
            IWorkspace(self.workspace).get('wsadmin').groups,
        )
Esempio n. 41
0
    def update_users(self, entries):
        """Update user properties on the roster """
        ws = IWorkspace(self.context)
        members = ws.members

        # check user permissions against join policy
        join_policy = self.context.join_policy
        if (join_policy == "admin" and not checkPermission(
                "ploneintranet.workspace: Manage workspace", self.context)):
            raise Unauthorized("You are not allowed to add users here")

        for entry in entries:
            id = entry.get('id')
            is_member = bool(entry.get('member'))
            is_admin = bool(entry.get('admin'))

            # Existing members
            if id in members:
                member = members[id]
                if not is_member:
                    if checkPermission(
                            "ploneintranet.workspace: Manage workspace",
                            self.context):
                        ws.membership_factory(ws, member).remove_from_team()
                    else:
                        raise Unauthorized(
                            "Only team managers can remove members")
                elif not is_admin:
                    ws.membership_factory(ws, member).groups -= {'Admins'}
                else:
                    ws.membership_factory(ws, member).groups |= {'Admins'}

            # New members
            elif id not in members and (is_member or is_admin):
                groups = set()
                if is_admin:
                    groups.add('Admins')
                ws.add_to_team(user=id, groups=groups)
Esempio n. 42
0
    def handleApply(self, action):
        data = self.extractData()[0]

        ws = IWorkspace(self.context)
        other_ws_id = data.get("workspace")
        other_ws = IWorkspace(api.content.get(UID=other_ws_id))
        move = data.get("move", False)
        removable = []
        for member in ws.members:
            user = api.user.get(username=member)
            if user is not None:
                user_id = user.getId()
                other_ws.add_to_team(user=user_id)
            removable.append(member)

        if move:
            func = lambda member: ws.membership_factory(
                ws,
                {"user": member}).remove_from_team()
            map(func, removable)

        self.updateWidgets()
        self.status = "Members transfered."
 def setUp(self):
     self.app = self.layer['app']
     self.portal = self.layer['portal']
     self.request = self.layer['request']
     z2.login(self.app['acl_users'], SITE_OWNER_NAME)
     self.user1 = api.user.create(
         email='*****@*****.**',
         username='******',
         password='******'
     )
     self.workspace = api.content.create(
         container=self.portal,
         type='Workspace',
         id='a-workspace'
     )
     self.ws = IWorkspace(self.workspace)
Esempio n. 44
0
    def update_users(self, entries):
        """Update user properties on the roster """
        ws = IWorkspace(self.context)
        members = ws.members

        # check user permissions against join policy
        join_policy = self.context.join_policy
        if (join_policy == "admin"
            and not checkPermission(
                "collective.workspace: Manage roster",
                self.context)):
            raise Unauthorized("You are not allowed to add users here")

        for entry in entries:
            id = entry.get('id')
            is_member = bool(entry.get('member'))
            is_admin = bool(entry.get('admin'))

            # Existing members
            if id in members:
                member = members[id]
                if not is_member:
                    if checkPermission(
                            "ploneintranet.workspace: Manage workspace",
                            self.context):
                        ws.membership_factory(ws, member).remove_from_team()
                    else:
                        raise Unauthorized(
                            "Only team managers can remove members")
                elif not is_admin:
                    ws.membership_factory(ws, member).groups -= {'Admins'}
                else:
                    ws.membership_factory(ws, member).groups |= {'Admins'}

            # New members
            elif id not in members and (is_member or is_admin):
                groups = set()
                if is_admin:
                    groups.add('Admins')
                ws.add_to_team(user=id, groups=groups)
class TestWorkspace(unittest.TestCase):
    layer = COLLECTIVE_WORKSPACE_INTEGRATION_TESTING

    def setUp(self):
        self.app = self.layer["app"]
        self.portal = self.layer["portal"]
        self.request = self.layer["request"]
        z2.login(self.app["acl_users"], SITE_OWNER_NAME)
        self.user1 = api.user.create(email="*****@*****.**", username="******", password="******")
        self.workspace = api.content.create(container=self.portal, type="Workspace", id="a-workspace")
        self.ws = IWorkspace(self.workspace)

    def test_add_to_team(self):
        self.ws.add_to_team(user=self.user1.getId())
        self.assertIn(self.user1.getId(), list(self.ws.members))

    def test_remove_from_team(self):
        self.ws.add_to_team(user=self.user1.getId())
        self.ws.remove_from_team(user=self.user1.getId())
        self.assertNotIn(self.user1.getId(), list(self.ws.members))
class TestWorkspace(unittest.TestCase):
    layer = COLLECTIVE_WORKSPACE_INTEGRATION_TESTING

    def setUp(self):
        self.app = self.layer['app']
        self.portal = self.layer['portal']
        self.request = self.layer['request']
        z2.login(self.app['acl_users'], SITE_OWNER_NAME)
        self.user1 = api.user.create(
            email='*****@*****.**',
            username='******',
            password='******'
        )
        self.workspace = api.content.create(
            container=self.portal,
            type='Workspace',
            id='a-workspace'
        )
        self.ws = IWorkspace(self.workspace)

    def _get_roles_in_workspace(self):
        pmt = api.portal.get_tool('portal_membership')
        member = pmt.getMemberById(self.user1.getId())
        return member.getRolesInContext(self.workspace)

    def test_adding_workspace_creates_groups(self):
        group = self.portal.portal_groups.getGroupById(
            'Admins:' + self.workspace.UID())
        self.assertIsNotNone(group)

    def test_renaming_workspace_updates_group_titles(self):
        self.workspace.setTitle('new title')
        from zope.lifecycleevent import modified
        modified(self.workspace)
        group = self.portal.portal_groups.getGroupById(
            'Admins:' + self.workspace.UID())
        self.assertEqual(group.getProperty('title'), 'Admins: new title')

    def test_removing_workspace_removes_groups(self):
        self.portal.manage_delObjects(['a-workspace'])
        group = self.portal.portal_groups.getGroupById(
            'Admins:' + self.workspace.UID())
        self.assertIsNone(group)

    def test_add_to_team(self):
        self.ws.add_to_team(
            user=self.user1.getId()
        )
        self.assertIn(self.user1.getId(), list(self.ws.members))

    def test_adding_team_member_updates_groups(self):
        self.ws.add_to_team(
            user=self.user1.getId(),
            groups=(u'Admins',),
            )
        self.assertIn(
            self.user1.getId(),
            self.portal.portal_groups.getGroupMembers(
                'Members:' + self.workspace.UID()),
        )
        self.assertIn(
            self.user1.getId(),
            self.portal.portal_groups.getGroupMembers(
                'Admins:' + self.workspace.UID()),
        )

    def test_updating_team_member_updates_groups(self):
        self.ws.add_to_team(
            user=self.user1.getId()
        )
        self.ws[self.user1.getId()].update({'groups': set([u'Admins'])})
        self.assertIn(
            self.user1.getId(),
            self.portal.portal_groups.getGroupMembers(
                'Members:' + self.workspace.UID()),
        )
        self.assertIn(
            self.user1.getId(),
            self.portal.portal_groups.getGroupMembers(
                'Admins:' + self.workspace.UID()),
        )

    def test_direct_set_of_membership_property_is_blocked(self):
        self.ws.add_to_team(
            user=self.user1.getId()
        )
        try:
            self.ws[self.user1.getId()].position = u'Tester'
        except Exception as e:
            self.assertEqual(
                str(e),
                'Setting membership properties directly is not supported. '
                'Use the `update` method instead.'
            )
        else:
            self.fail('Expected exception')

    def test_local_role_team_member(self):
        self.ws.add_to_team(
            user=self.user1.getId()
        )
        self.assertIn('TeamMember', self._get_roles_in_workspace())

    def test_remove_from_team(self):
        self.ws.add_to_team(
            user=self.user1.getId()
        )
        self.ws.remove_from_team(
            user=self.user1.getId()
        )
        self.assertNotIn(self.user1.getId(), list(self.ws.members))

    def test_removing_team_member_updates_groups(self):
        self.ws.add_to_team(
            user=self.user1.getId(),
            groups=(u'Admins',),
        )
        self.ws.remove_from_team(
            user=self.user1.getId()
        )
        self.assertNotIn(
            self.user1.getId(),
            self.portal.portal_groups.getGroupMembers(
                'Members:' + self.workspace.UID()),
        )
        self.assertNotIn(
            self.user1.getId(),
            self.portal.portal_groups.getGroupMembers(
                'Admins:' + self.workspace.UID()),
        )

    def test_reparent_team_member(self):
        self.ws.add_to_team(
            user=self.user1.getId(),
            groups=(u'Admins',),
            )
        user2 = api.user.create(
            email='*****@*****.**',
            username='******',
            password='******'
        )
        self.ws[self.user1.getId()].update({'user': user2.getId()})
        self.assertNotIn(self.user1.getId(), self.workspace._team)
        self.assertIn(user2.getId(), self.workspace._team)
        self.assertEqual(self.ws[user2.getId()].user, user2.getId())
        self.assertNotIn(
            self.user1.getId(),
            self.portal.portal_groups.getGroupMembers(
                'Admins:' + self.workspace.UID()),
        )
        self.assertIn(
            user2.getId(),
            self.portal.portal_groups.getGroupMembers(
                'Admins:' + self.workspace.UID()),
        )

    def test_removing_user_removes_workspace_memberships(self):
        userid = self.user1.getId()
        self.ws.add_to_team(user=userid)
        self.assertIn(userid, self.ws.members)
        api.user.delete(userid)
        self.assertNotIn(userid, self.ws.members)
        self.assertNotIn(
            userid,
            self.portal.portal_groups.getGroupMembers(
                'Members:' + self.workspace.UID()),
        )

    def test_copying_workspace_clears_roster(self):
        cookie = self.portal.manage_copyObjects(ids=('a-workspace',))
        self.portal.manage_pasteObjects(cookie)

        self.assertTrue('copy_of_a-workspace' in self.portal)
        workspace = self.portal['copy_of_a-workspace']
        self.assertEqual(len(workspace._team), 0)
        self.assertEqual(workspace._counters['members'](), 0)

    def test_add_guest_to_team(self):
        self.ws.add_to_team(
            user=self.user1.getId(), groups=['Guests']
        )
        self.assertIn(self.user1.getId(), list(self.ws.members))

    def test_guest_has_no_team_member_role(self):
        self.ws.add_to_team(
            user=self.user1.getId(), groups=['Guests']
        )
        pmt = api.portal.get_tool('portal_membership')
        member = pmt.getMemberById(self.user1.getId())
        roles = member.getRolesInContext(self.workspace)
        self.assertIn('TeamGuest', roles)
        self.assertNotIn('TeamMember', roles)

    def test_creating_and_removing_plone_groups_is_possible(self):
        test_group_id = 'My workspace testers'
        self.assertIsNone(api.group.get(test_group_id))
        api.group.create(test_group_id)
        group = api.group.get(test_group_id)
        self.assertEquals(group.getId(), test_group_id)
        api.group.delete(test_group_id)
        self.assertIsNone(api.group.get(test_group_id))

    def test_update_membership_groups(self):
        ''' Test that calling _update_groups will always add
        the Members group, unless the user is also in the Guests group
        '''
        self.assertNotIn('TeamMember', self._get_roles_in_workspace())

        # Adding the user to the workspace will grant the TeamMember role
        membership = self.ws.add_to_team(user=self.user1.getId())
        self.assertIn('TeamMember', self._get_roles_in_workspace())

        # groups should be untouched
        old = set()
        new = set()
        membership._update_groups(old, new)
        self.assertIn('TeamMember', self._get_roles_in_workspace())

        # groups should be untouched because user is already a member
        old = set()
        new = set(['Members'])
        membership._update_groups(old, new)
        self.assertIn('TeamMember', self._get_roles_in_workspace())

        # Removing the automatic group will not actually remove it
        # because it is an automatic group
        old = set(['Members'])
        new = set()
        membership._update_groups(old, new)
        self.assertIn('TeamMember', self._get_roles_in_workspace())

        # Removing the automatic group will have no effect
        old = set(['Members'])
        new = set()
        membership._update_groups(old, new)
        self.assertIn('TeamMember', self._get_roles_in_workspace())

        # Adding the user to the Guests group will remove it from the Members
        # because the condition will not be satisifed
        old = set()
        new = set(['Guests'])
        membership._update_groups(old, new)
        self.assertIn('TeamGuest', self._get_roles_in_workspace())
        self.assertNotIn('TeamMember', self._get_roles_in_workspace())

    def test_membership_remove_all_groups(self):
        ''' Test that calling _remove_all_groups does so
        '''
        self.assertNotIn('TeamMember', self._get_roles_in_workspace())

        # Adding the user to the workspace will grant the TeamMember role
        membership = self.ws.add_to_team(user=self.user1.getId())
        self.assertIn('TeamMember', self._get_roles_in_workspace())

        # groups should be removed
        membership._remove_all_groups()
        self.assertNotIn('TeamMember', self._get_roles_in_workspace())
Esempio n. 47
0
class TeamMemberEditForm(AutoExtensibleForm, EditForm):

    def __init__(self, context, request):
        self.context = context
        self.request = request
        self.workspace = IWorkspace(self.context)

    key = None

    def publishTraverse(self, request, name):
        self.key = name
        return self

    @lazy_property
    def schema(self):
        return self.workspace.membership_schema

    def updateFields(self):
        super(TeamMemberEditForm, self).updateFields()
        # don't show the user field if we are editing
        if self.key:
            del self.fields['user']

    @lazy_property
    def ignoreContext(self):
        return not bool(self.key)

    @lazy_property
    def label(self):
        if self.key:
            return self.getContent()._title
        else:
            return _(u'Add Person to Roster')

    @lazy_property
    def _content(self):
        if not self.key:
            return self.context
        workspace = self.workspace
        memberdata = workspace.members[self.key]
        return workspace.membership_factory(workspace, memberdata)

    def getContent(self):
        return self._content

    def validateInvariants(self, membership):
        pass

    @button.buttonAndHandler(_(u'Save'))
    def handleSave(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        status = _(u'Changes saved')

        if self.key:
            membership = self.getContent()
            membership.update(data)
        else:
            # Add new roster member
            membership = self.workspace.add_to_team(**data)
            status = _(u'User added')

        try:
            self.validateInvariants(membership)
        except ActionExecutionError:
            # make sure above changes won't be persisted
            transaction.abort()
            raise

        self._finished = True
        IStatusMessage(self.request).addStatusMessage(status, 'info')

    @property
    def can_remove(self):
        return self.key

    @button.buttonAndHandler(
        _(u'Remove'), condition=lambda self: self.can_remove)
    def handleRemove(self, action):
        membership = self.getContent()
        membership.remove_from_team()
        self._finished = True
        IStatusMessage(self.request).addStatusMessage(
            _(u"User removed"), "info")

    _finished = False

    def render(self):
        if self._finished:
            return ' '
        return super(TeamMemberEditForm, self).render()
Esempio n. 48
0
    def existing_users(self):
        """
        Look up the full user details for current workspace members
        """
        members = IWorkspace(self).members
        info = []

        for user_or_group_id, details in members.items():
            user = api.user.get(user_or_group_id)
            if user is not None:
                user = user.getUser()
                title = (user.getProperty('fullname') or user.getId() or
                         user_or_group_id)
                # XXX tbd, we don't know what a persons description is, yet
                description = ''
                classes = 'user ' + (description and 'has-description'
                                     or 'has-no-description')
                portrait = pi_api.userprofile.avatar_url(user_or_group_id)
            else:
                group = api.group.get(user_or_group_id)
                if group is None:
                    continue
                title = (group.getProperty('title') or group.getId() or
                         user_or_group_id)
                description = _(
                    u"number_of_members",
                    default=u'${no_members} Members',
                    mapping={
                        u'no_members': len(group.getAllGroupMemberIds())})
                classes = 'user-group has-description'
                portrait = ''

            # User's 'role' is any group they are a member of
            # that is not the default participation policy group
            # (including Admins group)
            role = None
            groups = details['groups']
            if 'Admins' in groups:
                role = 'Admin'
            for policy in PARTICIPANT_POLICY:
                if policy == self.participant_policy:
                    continue
                if policy.title() in groups:
                    role = PARTICIPANT_POLICY[policy]['title']
                    # According to the design there is at most one extra role
                    # per user, so we go with the first one we find. This may
                    # not be enforced in the backend though.
                    break
            if role:
                classes += ' has-label'

            info.append(
                dict(
                    id=user_or_group_id,
                    title=title,
                    description=description,
                    portrait=portrait,
                    cls=classes,
                    member=True,
                    admin='Admins' in details['groups'],
                    role=role,
                )
            )

        return info
Esempio n. 49
0
class TeamMemberEditForm(AutoExtensibleForm, EditForm):

    def __init__(self, context, request):
        self.context = context
        self.request = request
        self.workspace = IWorkspace(self.context)

    user_id = None

    def publishTraverse(self, request, name):
        self.user_id = name
        return self

    @lazy_property
    def schema(self):
        return self.workspace.membership_schema

    def updateFields(self):
        super(TeamMemberEditForm, self).updateFields()
        # don't show the user field if we are editing
        if self.user_id:
            del self.fields['user']

    @lazy_property
    def ignoreContext(self):
        return not bool(self.user_id)

    @lazy_property
    def label(self):
        if self.user_id:
            mtool = getToolByName(self.context, 'portal_membership')
            member = mtool.getMemberById(self.user_id)
            if member is not None:
                return member.getProperty('fullname') or self.user_id
            else:
                return self.user_id
        else:
            return u'Add Person to Roster'

    @lazy_property
    def _content(self):
        if not self.user_id:
            return self.context
        workspace = self.workspace
        memberdata = workspace.members[self.user_id]
        return workspace.membership_factory(workspace, memberdata)

    def getContent(self):
        return self._content

    def validateInvariants(self, membership):
        pass

    @button.buttonAndHandler(u'Save')
    def handleSave(self, action):
        data, errors = self.extractData()
        if errors:
            return

        if self.user_id:
            membership = self.getContent()
            membership.update(data)
        else:
            # Add new roster member
            membership = self.workspace.add_to_team(**data)

        try:
            self.validateInvariants(membership)
        except ActionExecutionError:
            # make sure above changes won't be persisted
            transaction.abort()
            raise

        self._finished = True

    @property
    def can_remove(self):
        return self.user_id

    @button.buttonAndHandler(u'Remove', condition=lambda self: self.can_remove)
    def handleRemove(self, action):
        membership = self.getContent()
        membership.remove_from_team()
        self._finished = True

    _finished = False

    def render(self):
        if self._finished:
            return ' '
        return super(TeamMemberEditForm, self).render()
Esempio n. 50
0
 def __init__(self, context, request):
     self.context = context
     self.request = request
     self.workspace = IWorkspace(self.context)