def test_unknown_userid(self): # note: testing add/remove typically tests known user # ids, the point of this test is to ensure the # right things happen when an unknown user is used. unknown = '*****@*****.**' members = SiteMembers(self.portal) assert unknown not in members assert members.get(unknown) is None self.assertRaises(KeyError, lambda: members[unknown]) self.assertRaises(KeyError, lambda: members.__delitem__(unknown)) self.assertRaises(KeyError, lambda: members.roles_for(self.portal, unknown)) self.assertRaises(KeyError, lambda: members.groups_for(unknown))
def test_add_user(self): _ID = '*****@*****.**' adapter = SiteMembers(self.portal) adapter.register(_ID, send=False) orig_len = len(adapter) self.assertIn(_ID, adapter) self.assertIn(_ID, adapter.keys()) self.assertIn(_ID, list(iter(adapter))) # now do the same with a non-email id and email kwarg _ID = 'metoo' _EMAIL = '*****@*****.**' adapter.register(_ID, email=_EMAIL, send=False) self.assertEqual(len(adapter), orig_len + 1) self.assertIn(_ID, adapter) self.assertIn(_ID, adapter.keys()) self.assertIn(_ID, list(iter(adapter))) self.assertEqual(adapter.get(_ID).getProperty('email'), _EMAIL) # check length again, potentially cached: self.assertEqual(len(adapter), orig_len + 1) # following is only true by convention and the fact that # the email is lower-case only: self.assertEqual(adapter.get(_ID).getProperty('email'), _EMAIL)
def trim_users(site): known = all_workspace_users(site) members = SiteMembers(site) orig = list(members) removed = [] for username in list(members): if username not in known: del(members[username]) removed.append(username) site.acl_users.portal_role_manager.assignRolesToPrincipal( ['Member'], members.get(username)._id, ) print 'Removed %s users ununsed of %s' % (len(removed), len(orig))
def trim_users(site): known = all_workspace_users(site) members = SiteMembers(site) orig = list(members) removed = [] for username in list(members): if username not in known: del (members[username]) removed.append(username) site.acl_users.portal_role_manager.assignRolesToPrincipal( ['Member'], members.get(username)._id, ) print 'Removed %s users ununsed of %s' % (len(removed), len(orig))
def test_registration_mixedcase(self, email=None): email = email or '*****@*****.**' expected_username = email.lower() adapter = SiteMembers(self.portal) self.assertEqual( adapter._uf.applyTransform(email), expected_username, ) adapter.register(email, send=False, email=email) # case-insensitive, not just case-normalizing: self.assertIn(email, adapter) self.assertIn(expected_username, adapter) self.assertIn(expected_username, adapter.keys()) user = adapter.get(expected_username) self.assertEqual(user.getProperty('email'), email)
def test_unknown_userid(self): # note: testing add/remove typically tests known user # ids, the point of this test is to ensure the # right things happen when an unknown user is used. unknown = '*****@*****.**' members = SiteMembers(self.portal) assert unknown not in members assert members.get(unknown) is None self.assertRaises(KeyError, lambda: members[unknown]) self.assertRaises(KeyError, lambda: members.__delitem__(unknown)) self.assertRaises( KeyError, lambda: members.roles_for(self.portal, unknown) ) self.assertRaises(KeyError, lambda: members.groups_for(unknown))
class WorkgroupAdaptersTest(unittest.TestCase): """Test workgroup roster/membership management adapters""" THEME = 'Sunburst Theme' layer = DEFAULT_PROFILE_TESTING def setUp(self): self.portal = self.layer['portal'] self.wftool = getToolByName(self.portal, 'portal_workflow') setRoles(self.portal, TEST_USER_ID, ['Manager']) self._users = self.portal.acl_users self.groups_plugin = self._users.source_groups self.site_members = SiteMembers(self.portal) self.user1 = '*****@*****.**' self.user2 = '*****@*****.**' self.site_members.register(self.user1, send=False) self.site_members.register(self.user2, send=False) self._fixtures() def _fixtures(self): adapter = CreateContentFixtures(self, self.layer) # noqa adapter.create() self.some_user = adapter.TEST_MEMBER def _base_fixtures(self): """ Simple membership, workspace, and roster fixture, for DRY reasons. """ if not getattr(self, '_workspace', None): self._workspace = self.portal['project1'] if not getattr(self, '_roster', None): self._roster = IWorkspaceRoster(self._workspace) return (self._workspace, self._roster) def test_group_parent_ref(self): """Role group __parent__ reference is roster, roster has no parent""" workspace, roster = self._base_fixtures() group = roster.groups.get('managers') self.assertEqual(group.__parent__, roster) self.assertIsNone(roster.__parent__) def test_group_name(self): """Role group __name__ matches key in roster""" workspace, roster = self._base_fixtures() name = 'managers' group = roster.groups.get(name) self.assertEqual(group.__name__, name) def test_workspace_namespace(self): """Workgroup namespace uses content UUID""" workspace, roster = self._base_fixtures() from plone.uuid.interfaces import IUUID self.assertEqual(roster.namespace, IUUID(workspace)) def test_pas_groupname(self): """Test PAS groupname construction for groups in roster""" workspace, roster = self._base_fixtures() namespace = IUUID(workspace) for name, group in roster.groups.items(): self.assertEqual(name, group.__name__) expected_groupname = namespace + '-' + name self.assertEqual(expected_groupname, group.pas_group()[0]) def test_user_add_and_containment(self): """ Test user addition, containment matches containment in associated group """ workspace, roster = self._base_fixtures() # add a user to the roster, then to the 'managers' group; # test containment/success of both in roster, workgroup, and PAS # group. username = '******' self.site_members.register(username, send=False) original_membercount = len(roster) roster.add(username) roster.groups['managers'].add(username) assert username in roster assert username in roster.groups['managers'] # get PAS group, via IGroup: pas_group = GroupInfo(roster.groups['managers'].pas_group()[0]) assert username in pas_group self.assertEqual(len(roster), original_membercount + 1) def test_get_user(self): """Get user from roster""" username = self.some_user workspace, roster = self._base_fixtures() assert username in roster # was added by fixture group = GroupInfo(roster.groups['viewers'].pas_group()[0]) assert username in group # equal propertied user objects: self.assertEqual(group.get(username)._id, roster.get(username)._id) self.assertEqual( group.get(username)._login, roster.get(username)._login) def test_stored_group(self): attr = '_group' workspace, roster = self._base_fixtures() group = getattr(roster, attr, None) self.assertIsNotNone(group) self.assertIn(roster.__name__, group.name) self.assertTrue(group.name.startswith(IUUID(workspace))) def test_add_user_already_added(self): """Attempt to add user already added""" workspace, roster = self._base_fixtures() self.assertIn(self.some_user, roster) # added by fixture try: roster.add(self.some_user) except: raise AssertionError('Add existing user; unexpected exception') def test_assign_bogus_to_group(self): """ Test that addition of user to group is disallowed if not in roster (via 'viewers' role group). """ username = '******' # note about case: register case-normalizing, containment insensitive self.site_members.register(username, send=False) self.assertIn(username, self.site_members) workspace, roster = self._base_fixtures() self.assertRaises( RuntimeError, roster.groups.get('managers').add, username, ) def test_assign_invalid_user(self): """Assigning invalid username fails with exception""" non_existent_user = '******' workspace, roster = self._base_fixtures() self.assertRaises( RuntimeError, roster.add, non_existent_user, ) def test_unassign_user_from_workgroup(self): """Unassign user from workgroup, basic case.""" workspace, roster = self._base_fixtures() username = '******' self.site_members.register(username, send=False) workspace, roster = self._base_fixtures() self.assertNotIn(username, roster) roster.add(username) self.assertIn(username, roster) roster.unassign(username) self.assertNotIn(username, roster) def test_assign_unassign_recursive(self): """Unassigning user from project removes from contained workspaces""" workspace, roster = self._base_fixtures() username = '******' self.site_members.register(username, send=False) project, project_roster = self._base_fixtures() team = project['team1'] team_roster = IWorkspaceRoster(team) subteam = team['subteam'] subteam_roster = IWorkspaceRoster(subteam) self.assertNotIn(username, project_roster) self.assertNotIn(username, team_roster) self.assertNotIn(username, subteam_roster) # add recursively adds to parent workspaces, walking upward: subteam_roster.add(username) self.assertIn(username, subteam_roster) self.assertIn(username, team_roster) self.assertIn(username, project_roster) # remove recursively removes from contained workspaces: project_roster.unassign(username) self.assertNotIn(username, project_roster) self.assertNotIn(username, team_roster) self.assertNotIn(username, subteam_roster) def test_unassign_groups(self): """ Unassigning from 'viewers' group or roster, via IWorkspaceRoster removes user from other groups in workpace. """ workspace, roster = self._base_fixtures() username = '******' self.site_members.register(username, send=False) roster.add(username) roster.groups['managers'].add(username) self.assertIn(username, roster) self.assertIn(username, roster.groups['managers']) roster.unassign(username) self.assertNotIn(username, roster) self.assertNotIn(username, roster.groups['managers']) def test_unassign_single_secondary_group(self): """Unassign a single non-viewer role group from user""" workspace, roster = self._base_fixtures() username = '******' self.site_members.register(username, send=False) roster.add(username) roster.groups['managers'].add(username) self.assertIn(username, roster) self.assertIn(username, roster.groups['managers']) roster.unassign(username, 'managers') # still assigned to roster, but not to managers group: self.assertIn(username, roster) self.assertNotIn(username, roster.groups['managers']) def test_unassign_contained_secondary(self): """Unassign from workgroup, removed from secondary contained""" project, roster = self._base_fixtures() team = project['team1'] team_roster = IWorkspaceRoster(team) username = '******' self.site_members.register(username, send=False) roster.add(username) team_roster.add(username) team_roster.groups['managers'].add(username) self.assertIn(username, roster) self.assertIn(username, team_roster) self.assertIn(username, team_roster.groups['managers']) roster.unassign(username) self.assertNotIn(username, roster) self.assertNotIn(username, team_roster) self.assertNotIn(username, team_roster.groups['managers']) def test_unassign_base_group_removes_secondary(self): """Unassign from base group, get removed from others.""" workspace, roster = self._base_fixtures() username = '******' self.site_members.register(username, send=False) roster.add(username) roster.groups['contributors'].add(username) self.assertIn(username, roster) self.assertIn(username, roster.groups['viewers']) self.assertIn(username, roster.groups['contributors']) # removing from the base group ought to remove all traces of user # from the workspace roster and groups: roster.groups['viewers'].unassign(username) self.assertNotIn(username, roster) self.assertNotIn(username, roster.groups['viewers']) self.assertNotIn(username, roster.groups['contributors']) def test_can_purge(self): """Testing IWorkspaceRoster.can_purge()""" project1, roster1 = self._base_fixtures() project2 = self.portal['project2'] roster2 = IWorkspaceRoster(project2) user_oneproject = '*****@*****.**' user_twoprojects = '*****@*****.**' self.site_members.register(user_oneproject, send=False) self.site_members.register(user_twoprojects, send=False) roster1.add(user_oneproject) roster1.add(user_twoprojects) roster2.add(user_twoprojects) self.assertTrue(roster1.can_purge(user_oneproject)) self.assertFalse(roster1.can_purge(user_twoprojects)) # disallowed self.assertFalse(roster2.can_purge(user_twoprojects)) # here too. self.assertFalse(roster2.can_purge(user_oneproject)) # not in here # cannot purge from a team, even with otherwise purgeable user: self.assertFalse( IWorkspaceRoster(project1['team1']).can_purge(user_oneproject)) def test_purge_exceptions(self): """Test for expected failure on disallowed purge of user""" project1, roster1 = self._base_fixtures() project2 = self.portal['project2'] roster2 = IWorkspaceRoster(project2) username = '******' self.site_members.register(username, send=False) roster1.add(username) roster2.add(username) # user cannot be purged because of membership elsewhere: self.assertRaises( RuntimeError, roster2.purge_user, username, ) # user not in roster self.assertRaises( RuntimeError, roster2.purge_user, '*****@*****.**', ) def test_purge_success(self): """Allowed purge of user succeeds.""" project1, roster1 = self._base_fixtures() username = '******' self.site_members.register(username, send=False) roster1.add(username) self.assertIn(username, self.site_members) self.assertIn(username, roster1) self.assertTrue(roster1.can_purge(username)) roster1.purge_user(username) self.assertNotIn(username, self.site_members) self.assertNotIn(username, roster1) def _test_roles(self, username, role, permissions, group=None): """ Test local roles and permissions for user in context: viewer; this indirectly tests both the local role plugin and the workflow used in this package. """ workspace, roster = self._base_fixtures() self.site_members.register(username, send=False) user = self.site_members.get(username) # IPropertiedUser userid = self.site_members.userid_for(username) self.assertNotIn( role, user.getRolesInContext(workspace), ) pmap = workspace.manage_getUserRolesAndPermissions(userid) self.assertNotIn(role, pmap['roles_in_context']) for permission in permissions: self.assertNotIn( permission, pmap['allowed_permissions'], ) roster.add(username) if group is not None: roster.groups[group].add(username) # we need to get a new IPropertiedUser, because previous unaware # of new group assignments... user = self.site_members.get(username) # IPropertiedUser self.assertIn( role, user.getRolesInContext(workspace), ) pmap = workspace.manage_getUserRolesAndPermissions(userid) self.assertIn(role, pmap['roles_in_context']) for permission in permissions: self.assertIn( permission, pmap['allowed_permissions'], ) # unassign from group: roster.unassign(username, group) # again, get new propertied user to avoid cached group membership: user = self.site_members.get(username) # IPropertiedUser self.assertNotIn( role, user.getRolesInContext(workspace), ) pmap = workspace.manage_getUserRolesAndPermissions(userid) self.assertNotIn(role, pmap['roles_in_context']) for permission in permissions: self.assertNotIn( permission, pmap['allowed_permissions'], ) def test_roles_viewer(self): username = '******' return self._test_roles(username, 'Workspace Viewer', ('View', )) def test_roles_manager(self): """Test local roles and permissions for user in context: manager""" username = '******' role = 'Manager' permissions = ('Manage users', 'Modify portal content') return self._test_roles(username, role, permissions, group='managers') def test_roles_contributor(self): """Test local roles and permissions for user in context: contributor""" username = '******' role = 'Workspace Contributor' permissions = ('Add portal content', ) group = 'contributors' return self._test_roles(username, role, permissions, group) def test_mixedcase_email(self): """Some basic tests for mixed-case email""" username = '******' # note about case: register case-normalizing, containment insensitive self.site_members.register(username, send=False) self.assertIn(username, self.site_members) self.assertIn(username.lower(), self.site_members.keys()) workspace, roster = self._base_fixtures() roster.add(username) # case-normalized: self.assertIn(username.lower(), roster.keys()) # case-insensitive containment: self.assertIn(username, roster) self.assertIn(username.lower(), roster) self.assertTrue(roster.get(username) is not None) self.assertTrue(roster[username] is not None) def test_bulk_modification(self): workspace, roster = self._base_fixtures() config = queryUtility(IWorkgroupTypes) bulk = IMembershipModifications(workspace) self.assertTrue(IMembershipModifications.providedBy(bulk)) self.assertTrue(bulk.context is workspace) for rolegroup in config: self.assertIn(rolegroup, bulk.planned_assign) self.assertIn(rolegroup, bulk.planned_unassign) # order does not matter for queuing, something slightly askew but ok: email1 = '*****@*****.**' self.site_members.register(email1, send=False) bulk.assign(email1, 'contributors') bulk.assign(email1) # group of 'viewers' implied by default self.assertIn(email1, bulk.planned_assign['viewers']) self.assertIn(email1, bulk.planned_assign['contributors']) # not yet applied: self.assertNotIn(email1, roster) self.assertNotIn(email1, roster.groups['contributors']) # assign another user: email2 = '*****@*****.**' self.site_members.register(email2, send=False) bulk.assign(email2, 'viewers') self.assertIn(email2, bulk.planned_assign['viewers']) self.assertNotIn(email2, roster) # not yet applied. self.assertTrue(len(bulk.planned_assign['viewers']) == 2) # assign and unassign (yes, contradictory, but we handle gracefully): email3 = '*****@*****.**' self.site_members.register(email3, send=False) bulk.assign(email3, 'viewers') self.assertIn(email3, bulk.planned_assign['viewers']) self.assertNotIn(email3, roster) # not yet applied. self.assertTrue(len(bulk.planned_assign['viewers']) == 3) bulk.unassign(email3) self.assertIn(email3, bulk.planned_unassign['viewers']) # now, let's apply all this: bulk.apply() # check worklists are empty: self.assertTrue(len(bulk.planned_assign['viewers']) == 0) self.assertTrue(len(bulk.planned_assign['contributors']) == 0) # check email1, email2 in respective expected groups/roster: self.assertIn(email1, roster) self.assertIn(email1, roster.groups['contributors']) self.assertIn(email2, roster) # check that email3, which was added, then removed is gone: self.assertNotIn(email3, roster) # now check that we can gracefully unassign in arbitrary order # by unassigning email1 from viewers first, then contributors. bulk.unassign(email1) bulk.unassign(email1, 'contributors') try: bulk.apply() except ValueError: raise AssertionError('Bulk application failed multiple unassign')
class WorkgroupAdaptersTest(unittest.TestCase): """Test workgroup roster/membership management adapters""" THEME = 'Sunburst Theme' layer = DEFAULT_PROFILE_TESTING def setUp(self): self.portal = self.layer['portal'] self.wftool = getToolByName(self.portal, 'portal_workflow') setRoles(self.portal, TEST_USER_ID, ['Manager']) self._users = self.portal.acl_users self.groups_plugin = self._users.source_groups self.site_members = SiteMembers(self.portal) self.user1 = '*****@*****.**' self.user2 = '*****@*****.**' self.site_members.register(self.user1, send=False) self.site_members.register(self.user2, send=False) self._fixtures() def _fixtures(self): adapter = CreateContentFixtures(self, self.layer) # noqa adapter.create() self.some_user = adapter.TEST_MEMBER def _base_fixtures(self): """ Simple membership, workspace, and roster fixture, for DRY reasons. """ if not getattr(self, '_workspace', None): self._workspace = self.portal['project1'] if not getattr(self, '_roster', None): self._roster = IWorkspaceRoster(self._workspace) return (self._workspace, self._roster) def test_group_parent_ref(self): """Role group __parent__ reference is roster, roster has no parent""" workspace, roster = self._base_fixtures() group = roster.groups.get('managers') self.assertEqual(group.__parent__, roster) self.assertIsNone(roster.__parent__) def test_group_name(self): """Role group __name__ matches key in roster""" workspace, roster = self._base_fixtures() name = 'managers' group = roster.groups.get(name) self.assertEqual(group.__name__, name) def test_workspace_namespace(self): """Workgroup namespace uses content UUID""" workspace, roster = self._base_fixtures() from plone.uuid.interfaces import IUUID self.assertEqual(roster.namespace, IUUID(workspace)) def test_pas_groupname(self): """Test PAS groupname construction for groups in roster""" workspace, roster = self._base_fixtures() namespace = IUUID(workspace) for name, group in roster.groups.items(): self.assertEqual(name, group.__name__) expected_groupname = namespace + '-' + name self.assertEqual(expected_groupname, group.pas_group()[0]) def test_user_add_and_containment(self): """ Test user addition, containment matches containment in associated group """ workspace, roster = self._base_fixtures() # add a user to the roster, then to the 'managers' group; # test containment/success of both in roster, workgroup, and PAS # group. username = '******' self.site_members.register(username, send=False) original_membercount = len(roster) roster.add(username) roster.groups['managers'].add(username) assert username in roster assert username in roster.groups['managers'] # get PAS group, via IGroup: pas_group = GroupInfo(roster.groups['managers'].pas_group()[0]) assert username in pas_group self.assertEqual(len(roster), original_membercount + 1) def test_get_user(self): """Get user from roster""" username = self.some_user workspace, roster = self._base_fixtures() assert username in roster # was added by fixture group = GroupInfo(roster.groups['viewers'].pas_group()[0]) assert username in group # equal propertied user objects: self.assertEqual(group.get(username)._id, roster.get(username)._id) self.assertEqual( group.get(username)._login, roster.get(username)._login ) def test_stored_group(self): attr = '_group' workspace, roster = self._base_fixtures() group = getattr(roster, attr, None) self.assertIsNotNone(group) self.assertIn(roster.__name__, group.name) self.assertTrue(group.name.startswith(IUUID(workspace))) def test_add_user_already_added(self): """Attempt to add user already added""" workspace, roster = self._base_fixtures() self.assertIn(self.some_user, roster) # added by fixture try: roster.add(self.some_user) except: raise AssertionError('Add existing user; unexpected exception') def test_assign_bogus_to_group(self): """ Test that addition of user to group is disallowed if not in roster (via 'viewers' role group). """ username = '******' # note about case: register case-normalizing, containment insensitive self.site_members.register(username, send=False) self.assertIn(username, self.site_members) workspace, roster = self._base_fixtures() self.assertRaises( RuntimeError, roster.groups.get('managers').add, username, ) def test_assign_invalid_user(self): """Assigning invalid username fails with exception""" non_existent_user = '******' workspace, roster = self._base_fixtures() self.assertRaises( RuntimeError, roster.add, non_existent_user, ) def test_unassign_user_from_workgroup(self): """Unassign user from workgroup, basic case.""" workspace, roster = self._base_fixtures() username = '******' self.site_members.register(username, send=False) workspace, roster = self._base_fixtures() self.assertNotIn(username, roster) roster.add(username) self.assertIn(username, roster) roster.unassign(username) self.assertNotIn(username, roster) def test_assign_unassign_recursive(self): """Unassigning user from project removes from contained workspaces""" workspace, roster = self._base_fixtures() username = '******' self.site_members.register(username, send=False) project, project_roster = self._base_fixtures() team = project['team1'] team_roster = IWorkspaceRoster(team) subteam = team['subteam'] subteam_roster = IWorkspaceRoster(subteam) self.assertNotIn(username, project_roster) self.assertNotIn(username, team_roster) self.assertNotIn(username, subteam_roster) # add recursively adds to parent workspaces, walking upward: subteam_roster.add(username) self.assertIn(username, subteam_roster) self.assertIn(username, team_roster) self.assertIn(username, project_roster) # remove recursively removes from contained workspaces: project_roster.unassign(username) self.assertNotIn(username, project_roster) self.assertNotIn(username, team_roster) self.assertNotIn(username, subteam_roster) def test_unassign_groups(self): """ Unassigning from 'viewers' group or roster, via IWorkspaceRoster removes user from other groups in workpace. """ workspace, roster = self._base_fixtures() username = '******' self.site_members.register(username, send=False) roster.add(username) roster.groups['managers'].add(username) self.assertIn(username, roster) self.assertIn(username, roster.groups['managers']) roster.unassign(username) self.assertNotIn(username, roster) self.assertNotIn(username, roster.groups['managers']) def test_unassign_single_secondary_group(self): """Unassign a single non-viewer role group from user""" workspace, roster = self._base_fixtures() username = '******' self.site_members.register(username, send=False) roster.add(username) roster.groups['managers'].add(username) self.assertIn(username, roster) self.assertIn(username, roster.groups['managers']) roster.unassign(username, 'managers') # still assigned to roster, but not to managers group: self.assertIn(username, roster) self.assertNotIn(username, roster.groups['managers']) def test_unassign_contained_secondary(self): """Unassign from workgroup, removed from secondary contained""" project, roster = self._base_fixtures() team = project['team1'] team_roster = IWorkspaceRoster(team) username = '******' self.site_members.register(username, send=False) roster.add(username) team_roster.add(username) team_roster.groups['managers'].add(username) self.assertIn(username, roster) self.assertIn(username, team_roster) self.assertIn(username, team_roster.groups['managers']) roster.unassign(username) self.assertNotIn(username, roster) self.assertNotIn(username, team_roster) self.assertNotIn(username, team_roster.groups['managers']) def test_unassign_base_group_removes_secondary(self): """Unassign from base group, get removed from others.""" workspace, roster = self._base_fixtures() username = '******' self.site_members.register(username, send=False) roster.add(username) roster.groups['contributors'].add(username) self.assertIn(username, roster) self.assertIn(username, roster.groups['viewers']) self.assertIn(username, roster.groups['contributors']) # removing from the base group ought to remove all traces of user # from the workspace roster and groups: roster.groups['viewers'].unassign(username) self.assertNotIn(username, roster) self.assertNotIn(username, roster.groups['viewers']) self.assertNotIn(username, roster.groups['contributors']) def test_can_purge(self): """Testing IWorkspaceRoster.can_purge()""" project1, roster1 = self._base_fixtures() project2 = self.portal['project2'] roster2 = IWorkspaceRoster(project2) user_oneproject = '*****@*****.**' user_twoprojects = '*****@*****.**' self.site_members.register(user_oneproject, send=False) self.site_members.register(user_twoprojects, send=False) roster1.add(user_oneproject) roster1.add(user_twoprojects) roster2.add(user_twoprojects) self.assertTrue(roster1.can_purge(user_oneproject)) self.assertFalse(roster1.can_purge(user_twoprojects)) # disallowed self.assertFalse(roster2.can_purge(user_twoprojects)) # here too. self.assertFalse(roster2.can_purge(user_oneproject)) # not in here # cannot purge from a team, even with otherwise purgeable user: self.assertFalse( IWorkspaceRoster(project1['team1']).can_purge(user_oneproject) ) def test_purge_exceptions(self): """Test for expected failure on disallowed purge of user""" project1, roster1 = self._base_fixtures() project2 = self.portal['project2'] roster2 = IWorkspaceRoster(project2) username = '******' self.site_members.register(username, send=False) roster1.add(username) roster2.add(username) # user cannot be purged because of membership elsewhere: self.assertRaises( RuntimeError, roster2.purge_user, username, ) # user not in roster self.assertRaises( RuntimeError, roster2.purge_user, '*****@*****.**', ) def test_purge_success(self): """Allowed purge of user succeeds.""" project1, roster1 = self._base_fixtures() username = '******' self.site_members.register(username, send=False) roster1.add(username) self.assertIn(username, self.site_members) self.assertIn(username, roster1) self.assertTrue(roster1.can_purge(username)) roster1.purge_user(username) self.assertNotIn(username, self.site_members) self.assertNotIn(username, roster1) def _test_roles(self, username, role, permissions, group=None): """ Test local roles and permissions for user in context: viewer; this indirectly tests both the local role plugin and the workflow used in this package. """ workspace, roster = self._base_fixtures() self.site_members.register(username, send=False) user = self.site_members.get(username) # IPropertiedUser userid = self.site_members.userid_for(username) self.assertNotIn( role, user.getRolesInContext(workspace), ) pmap = workspace.manage_getUserRolesAndPermissions(userid) self.assertNotIn( role, pmap['roles_in_context'] ) for permission in permissions: self.assertNotIn( permission, pmap['allowed_permissions'], ) roster.add(username) if group is not None: roster.groups[group].add(username) # we need to get a new IPropertiedUser, because previous unaware # of new group assignments... user = self.site_members.get(username) # IPropertiedUser self.assertIn( role, user.getRolesInContext(workspace), ) pmap = workspace.manage_getUserRolesAndPermissions(userid) self.assertIn( role, pmap['roles_in_context'] ) for permission in permissions: self.assertIn( permission, pmap['allowed_permissions'], ) # unassign from group: roster.unassign(username, group) # again, get new propertied user to avoid cached group membership: user = self.site_members.get(username) # IPropertiedUser self.assertNotIn( role, user.getRolesInContext(workspace), ) pmap = workspace.manage_getUserRolesAndPermissions(userid) self.assertNotIn( role, pmap['roles_in_context'] ) for permission in permissions: self.assertNotIn( permission, pmap['allowed_permissions'], ) def test_roles_viewer(self): username = '******' return self._test_roles(username, 'Workspace Viewer', ('View',)) def test_roles_manager(self): """Test local roles and permissions for user in context: manager""" username = '******' role = 'Manager' permissions = ('Manage users', 'Modify portal content') return self._test_roles(username, role, permissions, group='managers') def test_roles_contributor(self): """Test local roles and permissions for user in context: contributor""" username = '******' role = 'Workspace Contributor' permissions = ('Add portal content',) group = 'contributors' return self._test_roles(username, role, permissions, group) def test_mixedcase_email(self): """Some basic tests for mixed-case email""" username = '******' # note about case: register case-normalizing, containment insensitive self.site_members.register(username, send=False) self.assertIn(username, self.site_members) self.assertIn(username.lower(), self.site_members.keys()) workspace, roster = self._base_fixtures() roster.add(username) # case-normalized: self.assertIn(username.lower(), roster.keys()) # case-insensitive containment: self.assertIn(username, roster) self.assertIn(username.lower(), roster) self.assertTrue(roster.get(username) is not None) self.assertTrue(roster[username] is not None) def test_bulk_modification(self): workspace, roster = self._base_fixtures() config = queryUtility(IWorkgroupTypes) bulk = IMembershipModifications(workspace) self.assertTrue(IMembershipModifications.providedBy(bulk)) self.assertTrue(bulk.context is workspace) for rolegroup in config: self.assertIn(rolegroup, bulk.planned_assign) self.assertIn(rolegroup, bulk.planned_unassign) # order does not matter for queuing, something slightly askew but ok: email1 = '*****@*****.**' self.site_members.register(email1, send=False) bulk.assign(email1, 'contributors') bulk.assign(email1) # group of 'viewers' implied by default self.assertIn(email1, bulk.planned_assign['viewers']) self.assertIn(email1, bulk.planned_assign['contributors']) # not yet applied: self.assertNotIn(email1, roster) self.assertNotIn(email1, roster.groups['contributors']) # assign another user: email2 = '*****@*****.**' self.site_members.register(email2, send=False) bulk.assign(email2, 'viewers') self.assertIn(email2, bulk.planned_assign['viewers']) self.assertNotIn(email2, roster) # not yet applied. self.assertTrue(len(bulk.planned_assign['viewers']) == 2) # assign and unassign (yes, contradictory, but we handle gracefully): email3 = '*****@*****.**' self.site_members.register(email3, send=False) bulk.assign(email3, 'viewers') self.assertIn(email3, bulk.planned_assign['viewers']) self.assertNotIn(email3, roster) # not yet applied. self.assertTrue(len(bulk.planned_assign['viewers']) == 3) bulk.unassign(email3) self.assertIn(email3, bulk.planned_unassign['viewers']) # now, let's apply all this: bulk.apply() # check worklists are empty: self.assertTrue(len(bulk.planned_assign['viewers']) == 0) self.assertTrue(len(bulk.planned_assign['contributors']) == 0) # check email1, email2 in respective expected groups/roster: self.assertIn(email1, roster) self.assertIn(email1, roster.groups['contributors']) self.assertIn(email2, roster) # check that email3, which was added, then removed is gone: self.assertNotIn(email3, roster)