Example #1
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)
Example #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,
            )
Example #3
0
    def update_case_access(self):
        """
        Iterate over all tasks inside the case.
        - If a member is assigned to a task and the task in the current
          milestone:
          Grant Guest access, if the user is not a regular member of the Case
        - If a member has Guest access, but is not an assignee in any
          task of the current milestone:
          Remove Guest access
        """
        # First of all we take the set of the todo assignees
        pc = api.portal.get_tool('portal_catalog')
        review_state = api.content.get_state(self)
        brains = pc.unrestrictedSearchResults(
            path='/'.join(self.getPhysicalPath()),
            portal_type='todo',
        )
        objs = filter(
            lambda obj: obj.assignee and obj.milestone == review_state,
            (brain._unrestrictedGetObject() for brain in brains))
        assignees = {obj.assignee for obj in objs}

        # now we make a partition of the user associated to this context
        existing_users = self.existing_users()

        existing_guests = set([])
        non_guests = set([])
        for user in existing_users:
            if user.get('role') == 'Guest':
                existing_guests.add(user['id'])
            else:
                non_guests.add(user['id'])

        # We find out which assignees are guests
        entitled_guests = assignees.difference(non_guests)

        workspace = IWorkspace(self)
        # We have some stale guests that should be removed from this context
        stale_guests = existing_guests.difference(entitled_guests)
        for user_id in stale_guests:
            workspace.remove_from_team(user_id)

        # We have some new guests that should be added to this context
        new_guests = entitled_guests.difference(existing_guests)
        for user_id in new_guests:
            workspace.add_to_team(user_id, groups=['Guests'])

        # If roles were changed, throw the required event
        if len(stale_guests) + len(new_guests):
            notify(WorkspaceRosterChangedEvent(self))
    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")
Example #5
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)
Example #6
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")
Example #7
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)
Example #8
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,
            )
Example #9
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)
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))
    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)
Example #12
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)
Example #13
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 userid in ws.members:
            user = api.user.get(userid=userid)
            if user is not None:
                user_id = user.getId()
                other_ws.add_to_team(user=user_id)
            removable.append(userid)

        if move:
            for userid in removable:
                factory = ws.membership_factory(ws, {"user": userid})
                factory.remove_from_team()

        self.updateWidgets()
        self.status = "Members transfered."
Example #14
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)
Example #15
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."
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))
Example #17
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()
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()
Example #19
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()
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())
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()
Example #22
0
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"]
        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)

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