Index: appengine/monorail/framework/test/permissions_test.py |
diff --git a/appengine/monorail/framework/test/permissions_test.py b/appengine/monorail/framework/test/permissions_test.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f87253667e8219b57117f0fc0206303f10e84812 |
--- /dev/null |
+++ b/appengine/monorail/framework/test/permissions_test.py |
@@ -0,0 +1,1181 @@ |
+# Copyright 2016 The Chromium Authors. All rights reserved. |
+# Use of this source code is govered by a BSD-style |
+# license that can be found in the LICENSE file or at |
+# https://developers.google.com/open-source/licenses/bsd |
+ |
+"""Tests for permissions.py.""" |
+ |
+import time |
+import unittest |
+ |
+import mox |
+ |
+import settings |
+from framework import framework_constants |
+from framework import framework_views |
+from framework import monorailrequest |
+from framework import permissions |
+from proto import project_pb2 |
+from proto import site_pb2 |
+from proto import tracker_pb2 |
+from proto import user_pb2 |
+from proto import usergroup_pb2 |
+from testing import fake |
+from testing import testing_helpers |
+from tracker import tracker_bizobj |
+ |
+ |
+class PermissionSetTest(unittest.TestCase): |
+ |
+ def setUp(self): |
+ self.perms = permissions.PermissionSet(['A', 'b', 'Cc']) |
+ self.proj = project_pb2.Project() |
+ self.proj.contributor_ids.append(111L) |
+ self.proj.contributor_ids.append(222L) |
+ self.proj.extra_perms.append(project_pb2.Project.ExtraPerms( |
+ member_id=111L, perms=['Cc', 'D', 'e', 'Ff'])) |
+ self.proj.extra_perms.append(project_pb2.Project.ExtraPerms( |
+ member_id=222L, perms=['G', 'H'])) |
+ # user 3 used to be a member and had extra perms, but no longer in project. |
+ self.proj.extra_perms.append(project_pb2.Project.ExtraPerms( |
+ member_id=333L, perms=['G', 'H'])) |
+ |
+ def testGetAttr(self): |
+ self.assertTrue(self.perms.a) |
+ self.assertTrue(self.perms.A) |
+ self.assertTrue(self.perms.b) |
+ self.assertTrue(self.perms.Cc) |
+ self.assertTrue(self.perms.CC) |
+ |
+ self.assertFalse(self.perms.z) |
+ self.assertFalse(self.perms.Z) |
+ |
+ def testCanUsePerm_Anonymous(self): |
+ effective_ids = set() |
+ self.assertTrue(self.perms.CanUsePerm('A', effective_ids, self.proj, [])) |
+ self.assertFalse(self.perms.CanUsePerm('D', effective_ids, self.proj, [])) |
+ self.assertFalse(self.perms.CanUsePerm('Z', effective_ids, self.proj, [])) |
+ |
+ def testCanUsePerm_SignedInNoGroups(self): |
+ effective_ids = {111L} |
+ self.assertTrue(self.perms.CanUsePerm('A', effective_ids, self.proj, [])) |
+ self.assertTrue(self.perms.CanUsePerm('D', effective_ids, self.proj, [])) |
+ self.assertTrue(self.perms.CanUsePerm( |
+ 'D', effective_ids, self.proj, ['Restrict-D-A'])) |
+ self.assertFalse(self.perms.CanUsePerm('G', effective_ids, self.proj, [])) |
+ self.assertFalse(self.perms.CanUsePerm('Z', effective_ids, self.proj, [])) |
+ |
+ effective_ids = {222L} |
+ self.assertTrue(self.perms.CanUsePerm('A', effective_ids, self.proj, [])) |
+ self.assertFalse(self.perms.CanUsePerm('D', effective_ids, self.proj, [])) |
+ self.assertTrue(self.perms.CanUsePerm('G', effective_ids, self.proj, [])) |
+ self.assertFalse(self.perms.CanUsePerm('Z', effective_ids, self.proj, [])) |
+ self.assertFalse(self.perms.CanUsePerm( |
+ 'Z', effective_ids, self.proj, ['Restrict-Z-A'])) |
+ |
+ def testCanUsePerm_SignedInWithGroups(self): |
+ effective_ids = {111L, 222L, 333L} |
+ self.assertTrue(self.perms.CanUsePerm('A', effective_ids, self.proj, [])) |
+ self.assertTrue(self.perms.CanUsePerm('D', effective_ids, self.proj, [])) |
+ self.assertTrue(self.perms.CanUsePerm('G', effective_ids, self.proj, [])) |
+ self.assertTrue(self.perms.CanUsePerm( |
+ 'G', effective_ids, self.proj, ['Restrict-G-D'])) |
+ self.assertFalse(self.perms.CanUsePerm('Z', effective_ids, self.proj, [])) |
+ self.assertFalse(self.perms.CanUsePerm( |
+ 'G', effective_ids, self.proj, ['Restrict-G-Z'])) |
+ |
+ def testCanUsePerm_FormerMember(self): |
+ effective_ids = {333L} |
+ self.assertTrue(self.perms.CanUsePerm('A', effective_ids, self.proj, [])) |
+ self.assertFalse(self.perms.CanUsePerm('D', effective_ids, self.proj, [])) |
+ self.assertFalse(self.perms.CanUsePerm('G', effective_ids, self.proj, [])) |
+ self.assertFalse(self.perms.CanUsePerm('Z', effective_ids, self.proj, [])) |
+ |
+ def testHasPerm_InPermSet(self): |
+ self.assertTrue(self.perms.HasPerm('a', 0, None)) |
+ self.assertTrue(self.perms.HasPerm('a', 0, self.proj)) |
+ self.assertTrue(self.perms.HasPerm('A', 0, None)) |
+ self.assertTrue(self.perms.HasPerm('A', 0, self.proj)) |
+ self.assertFalse(self.perms.HasPerm('Z', 0, None)) |
+ self.assertFalse(self.perms.HasPerm('Z', 0, self.proj)) |
+ |
+ def testHasPerm_InExtraPerms(self): |
+ self.assertTrue(self.perms.HasPerm('d', 111L, self.proj)) |
+ self.assertTrue(self.perms.HasPerm('D', 111L, self.proj)) |
+ self.assertTrue(self.perms.HasPerm('Cc', 111L, self.proj)) |
+ self.assertTrue(self.perms.HasPerm('CC', 111L, self.proj)) |
+ self.assertFalse(self.perms.HasPerm('Z', 111L, self.proj)) |
+ |
+ self.assertFalse(self.perms.HasPerm('d', 222L, self.proj)) |
+ self.assertFalse(self.perms.HasPerm('D', 222L, self.proj)) |
+ |
+ # Only current members can have extra permissions |
+ self.proj.contributor_ids = [] |
+ self.assertFalse(self.perms.HasPerm('d', 111L, self.proj)) |
+ |
+ # TODO(jrobbins): also test consider_restrictions=False and |
+ # restriction labels directly in this class. |
+ |
+ def testHasPerm_GrantedPerms(self): |
+ self.assertTrue(self.perms.CanUsePerm( |
+ 'A', {111L}, self.proj, [], granted_perms=['z'])) |
+ self.assertTrue(self.perms.CanUsePerm( |
+ 'a', {111L}, self.proj, [], granted_perms=['z'])) |
+ self.assertTrue(self.perms.CanUsePerm( |
+ 'a', {111L}, self.proj, [], granted_perms=['a'])) |
+ self.assertTrue(self.perms.CanUsePerm( |
+ 'Z', {111L}, self.proj, [], granted_perms=['y', 'z'])) |
+ self.assertTrue(self.perms.CanUsePerm( |
+ 'z', {111L}, self.proj, [], granted_perms=['y', 'z'])) |
+ self.assertFalse(self.perms.CanUsePerm( |
+ 'z', {111L}, self.proj, [], granted_perms=['y'])) |
+ |
+ def testDebugString(self): |
+ self.assertEqual('PermissionSet()', |
+ permissions.PermissionSet([]).DebugString()) |
+ self.assertEqual('PermissionSet(a)', |
+ permissions.PermissionSet(['A']).DebugString()) |
+ self.assertEqual('PermissionSet(a, b, cc)', self.perms.DebugString()) |
+ |
+ def testRepr(self): |
+ self.assertEqual('PermissionSet(frozenset([]))', |
+ permissions.PermissionSet([]).__repr__()) |
+ self.assertEqual('PermissionSet(frozenset([\'a\']))', |
+ permissions.PermissionSet(['A']).__repr__()) |
+ |
+ |
+class PermissionsTest(unittest.TestCase): |
+ |
+ NOW = 1277762224 # Any timestamp will do, we only compare it to itself +/- 1 |
+ COMMITTER_USER_ID = 111L |
+ OWNER_USER_ID = 222L |
+ CONTRIB_USER_ID = 333L |
+ SITE_ADMIN_USER_ID = 444L |
+ |
+ def MakeProject(self, project_name, state, add_members=True, access=None): |
+ args = dict(project_name=project_name, state=state) |
+ if add_members: |
+ args.update(owner_ids=[self.OWNER_USER_ID], |
+ committer_ids=[self.COMMITTER_USER_ID], |
+ contributor_ids=[self.CONTRIB_USER_ID]) |
+ |
+ if access: |
+ args.update(access=access) |
+ |
+ return fake.Project(**args) |
+ |
+ def setUp(self): |
+ self.live_project = self.MakeProject('live', project_pb2.ProjectState.LIVE) |
+ self.archived_project = self.MakeProject( |
+ 'archived', project_pb2.ProjectState.ARCHIVED) |
+ self.other_live_project = self.MakeProject( |
+ 'other_live', project_pb2.ProjectState.LIVE, add_members=False) |
+ self.members_only_project = self.MakeProject( |
+ 's3kr3t', project_pb2.ProjectState.LIVE, |
+ access=project_pb2.ProjectAccess.MEMBERS_ONLY) |
+ |
+ self.nonmember = user_pb2.User() |
+ self.member = user_pb2.User() |
+ self.owner = user_pb2.User() |
+ self.contrib = user_pb2.User() |
+ self.site_admin = user_pb2.User() |
+ self.site_admin.is_site_admin = True |
+ self.borg_user = user_pb2.User(email=settings.borg_service_account) |
+ |
+ self.normal_artifact = tracker_pb2.Issue() |
+ self.normal_artifact.labels.extend(['hot', 'Key-Value']) |
+ self.normal_artifact.reporter_id = 111L |
+ |
+ # Two PermissionSets w/ permissions outside of any project. |
+ self.normal_user_perms = permissions.GetPermissions( |
+ None, {111L}, None) |
+ self.admin_perms = permissions.PermissionSet( |
+ [permissions.ADMINISTER_SITE, |
+ permissions.CREATE_PROJECT]) |
+ |
+ self.mox = mox.Mox() |
+ |
+ def tearDown(self): |
+ self.mox.UnsetStubs() |
+ |
+ def testGetPermissions_Admin(self): |
+ self.assertEqual( |
+ permissions.ADMIN_PERMISSIONSET, |
+ permissions.GetPermissions(self.site_admin, None, None)) |
+ |
+ def testGetPermissions_BorgServiceAccount(self): |
+ self.assertEqual( |
+ permissions.GROUP_IMPORT_BORG_PERMISSIONSET, |
+ permissions.GetPermissions(self.borg_user, None, None)) |
+ |
+ def CheckPermissions(self, perms, expected_list): |
+ expect_view, expect_commit, expect_edit_project = expected_list |
+ self.assertEqual( |
+ expect_view, perms.HasPerm(permissions.VIEW, None, None)) |
+ self.assertEqual( |
+ expect_commit, perms.HasPerm(permissions.COMMIT, None, None)) |
+ self.assertEqual( |
+ expect_edit_project, |
+ perms.HasPerm(permissions.EDIT_PROJECT, None, None)) |
+ |
+ def testAnonPermissions(self): |
+ perms = permissions.GetPermissions(None, set(), self.live_project) |
+ self.CheckPermissions(perms, [True, False, False]) |
+ |
+ perms = permissions.GetPermissions(None, set(), self.members_only_project) |
+ self.CheckPermissions(perms, [False, False, False]) |
+ |
+ def testNonmemberPermissions(self): |
+ perms = permissions.GetPermissions( |
+ self.nonmember, {123}, self.live_project) |
+ self.CheckPermissions(perms, [True, False, False]) |
+ |
+ perms = permissions.GetPermissions( |
+ self.nonmember, {123}, self.members_only_project) |
+ self.CheckPermissions(perms, [False, False, False]) |
+ |
+ def testMemberPermissions(self): |
+ perms = permissions.GetPermissions( |
+ self.member, {self.COMMITTER_USER_ID}, self.live_project) |
+ self.CheckPermissions(perms, [True, True, False]) |
+ |
+ perms = permissions.GetPermissions( |
+ self.member, {self.COMMITTER_USER_ID}, self.other_live_project) |
+ self.CheckPermissions(perms, [True, False, False]) |
+ |
+ perms = permissions.GetPermissions( |
+ self.member, {self.COMMITTER_USER_ID}, self.members_only_project) |
+ self.CheckPermissions(perms, [True, True, False]) |
+ |
+ def testOwnerPermissions(self): |
+ perms = permissions.GetPermissions( |
+ self.owner, {self.OWNER_USER_ID}, self.live_project) |
+ self.CheckPermissions(perms, [True, True, True]) |
+ |
+ perms = permissions.GetPermissions( |
+ self.owner, {self.OWNER_USER_ID}, self.other_live_project) |
+ self.CheckPermissions(perms, [True, False, False]) |
+ |
+ perms = permissions.GetPermissions( |
+ self.owner, {self.OWNER_USER_ID}, self.members_only_project) |
+ self.CheckPermissions(perms, [True, True, True]) |
+ |
+ def testContributorPermissions(self): |
+ perms = permissions.GetPermissions( |
+ self.contrib, {self.CONTRIB_USER_ID}, self.live_project) |
+ self.CheckPermissions(perms, [True, False, False]) |
+ |
+ perms = permissions.GetPermissions( |
+ self.contrib, {self.CONTRIB_USER_ID}, self.other_live_project) |
+ self.CheckPermissions(perms, [True, False, False]) |
+ |
+ perms = permissions.GetPermissions( |
+ self.contrib, {self.CONTRIB_USER_ID}, self.members_only_project) |
+ self.CheckPermissions(perms, [True, False, False]) |
+ |
+ def testLookupPermset_ExactMatch(self): |
+ self.assertEqual( |
+ permissions.USER_PERMISSIONSET, |
+ permissions._LookupPermset( |
+ permissions.USER_ROLE, project_pb2.ProjectState.LIVE, |
+ project_pb2.ProjectAccess.ANYONE)) |
+ |
+ def testLookupPermset_WildcardAccess(self): |
+ self.assertEqual( |
+ permissions.OWNER_ACTIVE_PERMISSIONSET, |
+ permissions._LookupPermset( |
+ permissions.OWNER_ROLE, project_pb2.ProjectState.LIVE, |
+ project_pb2.ProjectAccess.MEMBERS_ONLY)) |
+ |
+ def testGetPermissionKey_AnonUser(self): |
+ self.assertEqual( |
+ (permissions.ANON_ROLE, permissions.UNDEFINED_STATUS, |
+ permissions.UNDEFINED_ACCESS), |
+ permissions._GetPermissionKey(None, None)) |
+ self.assertEqual( |
+ (permissions.ANON_ROLE, project_pb2.ProjectState.LIVE, |
+ project_pb2.ProjectAccess.ANYONE), |
+ permissions._GetPermissionKey(None, self.live_project)) |
+ |
+ def testGetPermissionKey_ExpiredProject(self): |
+ self.archived_project.delete_time = self.NOW |
+ # In an expired project, the user's committe role does not count. |
+ self.assertEqual( |
+ (permissions.USER_ROLE, project_pb2.ProjectState.ARCHIVED, |
+ project_pb2.ProjectAccess.ANYONE), |
+ permissions._GetPermissionKey( |
+ self.COMMITTER_USER_ID, self.archived_project, |
+ expired_before=self.NOW + 1)) |
+ # If not expired yet, the user's committe role still counts. |
+ self.assertEqual( |
+ (permissions.COMMITTER_ROLE, project_pb2.ProjectState.ARCHIVED, |
+ project_pb2.ProjectAccess.ANYONE), |
+ permissions._GetPermissionKey( |
+ self.COMMITTER_USER_ID, self.archived_project, |
+ expired_before=self.NOW - 1)) |
+ |
+ def testGetPermissionKey_DefinedRoles(self): |
+ self.assertEqual( |
+ (permissions.OWNER_ROLE, project_pb2.ProjectState.LIVE, |
+ project_pb2.ProjectAccess.ANYONE), |
+ permissions._GetPermissionKey( |
+ self.OWNER_USER_ID, self.live_project)) |
+ self.assertEqual( |
+ (permissions.COMMITTER_ROLE, project_pb2.ProjectState.LIVE, |
+ project_pb2.ProjectAccess.ANYONE), |
+ permissions._GetPermissionKey( |
+ self.COMMITTER_USER_ID, self.live_project)) |
+ self.assertEqual( |
+ (permissions.CONTRIBUTOR_ROLE, project_pb2.ProjectState.LIVE, |
+ project_pb2.ProjectAccess.ANYONE), |
+ permissions._GetPermissionKey( |
+ self.CONTRIB_USER_ID, self.live_project)) |
+ |
+ def testGetPermissionKey_Nonmember(self): |
+ self.assertEqual( |
+ (permissions.USER_ROLE, project_pb2.ProjectState.LIVE, |
+ project_pb2.ProjectAccess.ANYONE), |
+ permissions._GetPermissionKey( |
+ 999L, self.live_project)) |
+ |
+ def testPermissionsImmutable(self): |
+ self.assertTrue(isinstance( |
+ permissions.EMPTY_PERMISSIONSET.perm_names, frozenset)) |
+ self.assertTrue(isinstance( |
+ permissions.READ_ONLY_PERMISSIONSET.perm_names, frozenset)) |
+ self.assertTrue(isinstance( |
+ permissions.COMMITTER_ACTIVE_PERMISSIONSET.perm_names, frozenset)) |
+ self.assertTrue(isinstance( |
+ permissions.OWNER_ACTIVE_PERMISSIONSET.perm_names, frozenset)) |
+ |
+ def testGetExtraPerms(self): |
+ project = project_pb2.Project() |
+ project.committer_ids.append(222L) |
+ project.extra_perms.append(project_pb2.Project.ExtraPerms( |
+ member_id=222L, perms=['a', 'b', 'c'])) |
+ # User 1 is a former member with left-over extra perms that don't count. |
+ project.extra_perms.append(project_pb2.Project.ExtraPerms( |
+ member_id=111L, perms=['a', 'b', 'c'])) |
+ |
+ self.assertListEqual( |
+ [], |
+ permissions.GetExtraPerms(project, 111L)) |
+ self.assertListEqual( |
+ ['a', 'b', 'c'], |
+ permissions.GetExtraPerms(project, 222L)) |
+ self.assertListEqual( |
+ [], |
+ permissions.GetExtraPerms(project, 333L)) |
+ |
+ def testAnonUsersCannotDelete(self): |
+ perms = permissions.PermissionSet([permissions.DELETE_ANY]) |
+ # No logged in user, no perms specfied. |
+ self.assertFalse(permissions.CanDelete( |
+ framework_constants.NO_USER_SPECIFIED, set(), None, 0, 0, None, [])) |
+ # No logged in user, even with perms from somewhere. |
+ self.assertFalse(permissions.CanDelete( |
+ framework_constants.NO_USER_SPECIFIED, set(), perms, 0, 0, None, [])) |
+ # No logged in user, even if artifact was already deleted. |
+ self.assertFalse(permissions.CanDelete( |
+ framework_constants.NO_USER_SPECIFIED, set(), perms, |
+ 111L, 111L, None, [])) |
+ # No logged in user, even if artifact was already deleted by project owner. |
+ self.assertFalse(permissions.CanDelete( |
+ framework_constants.NO_USER_SPECIFIED, set(), perms, |
+ 111L, 222L, None, [])) |
+ |
+ def testProjectOwnerCanDeleteAnyArtifact(self): |
+ perms = permissions.PermissionSet([permissions.DELETE_ANY]) |
+ # No artifact owner, and not already deleted. |
+ self.assertTrue(permissions.CanDelete( |
+ 111L, {111L}, perms, 0, 0, None, [])) |
+ # I already deleted, can undelete. |
+ self.assertTrue(permissions.CanDelete( |
+ 111L, {111L}, perms, 111L, 0, None, [])) |
+ # I can delete my own thing. |
+ self.assertTrue(permissions.CanDelete( |
+ 111L, {111L}, perms, 0, 111L, None, [])) |
+ # I can also delete another user's artifacts, because I have DELETE_ANY. |
+ self.assertTrue(permissions.CanDelete( |
+ 111L, {111L}, perms, 0, 222L, None, [])) |
+ # I can always undelete, even if another PO deleted it. |
+ self.assertTrue(permissions.CanDelete( |
+ 111L, {111L}, perms, 333L, 222L, None, [])) |
+ |
+ def testUserCanDeleteTheirOwnStuff(self): |
+ perms = permissions.PermissionSet([permissions.DELETE_OWN]) |
+ # I can delete/withdraw my artifact or comment. |
+ self.assertTrue(permissions.CanDelete( |
+ 111L, {111L}, perms, 0, 111L, None, [])) |
+ # I can undelete what I deleted. |
+ self.assertTrue(permissions.CanDelete( |
+ 111L, {111L}, perms, 111L, 111L, None, [])) |
+ # I cannot undelete if someone else deleted my spam. |
+ self.assertFalse(permissions.CanDelete( |
+ 111L, {111L}, perms, 222L, 111L, None, [])) |
+ # I cannot delete other people's stuff. |
+ self.assertFalse(permissions.CanDelete( |
+ 111L, {111L}, perms, 0, 222L, None, [])) |
+ # I cannot undelete what other people withdrew. |
+ self.assertFalse(permissions.CanDelete( |
+ 111L, {111L}, perms, 222L, 222L, None, [])) |
+ |
+ def testCanViewNormalArifact(self): |
+ # Anyone can view a non-restricted artifact. |
+ self.assertTrue(permissions.CanView( |
+ {111L}, permissions.READ_ONLY_PERMISSIONSET, |
+ self.live_project, [])) |
+ |
+ def testCanCreateProject_NoPerms(self): |
+ """Signed out users cannot create projects.""" |
+ self.assertFalse(permissions.CanCreateProject( |
+ permissions.EMPTY_PERMISSIONSET)) |
+ |
+ self.assertFalse(permissions.CanCreateProject( |
+ permissions.READ_ONLY_PERMISSIONSET)) |
+ |
+ def testCanCreateProject_Admin(self): |
+ """Site admins can create projects.""" |
+ self.assertTrue(permissions.CanCreateProject( |
+ permissions.ADMIN_PERMISSIONSET)) |
+ |
+ def testCanCreateProject_RegularUser(self): |
+ """Signed in non-admins can create a project if settings allow ANYONE.""" |
+ try: |
+ orig_restriction = settings.project_creation_restriction |
+ ANYONE = site_pb2.UserTypeRestriction.ANYONE |
+ ADMIN_ONLY = site_pb2.UserTypeRestriction.ADMIN_ONLY |
+ NO_ONE = site_pb2.UserTypeRestriction.NO_ONE |
+ perms = permissions.PermissionSet([permissions.CREATE_PROJECT]) |
+ |
+ settings.project_creation_restriction = ANYONE |
+ self.assertTrue(permissions.CanCreateProject(perms)) |
+ |
+ settings.project_creation_restriction = ADMIN_ONLY |
+ self.assertFalse(permissions.CanCreateProject(perms)) |
+ |
+ settings.project_creation_restriction = NO_ONE |
+ self.assertFalse(permissions.CanCreateProject(perms)) |
+ self.assertFalse(permissions.CanCreateProject( |
+ permissions.ADMIN_PERMISSIONSET)) |
+ finally: |
+ settings.project_creation_restriction = orig_restriction |
+ |
+ def testCanCreateGroup_AnyoneWithCreateGroup(self): |
+ orig_setting = settings.group_creation_restriction |
+ try: |
+ settings.group_creation_restriction = site_pb2.UserTypeRestriction.ANYONE |
+ self.assertTrue(permissions.CanCreateGroup( |
+ permissions.PermissionSet([permissions.CREATE_GROUP]))) |
+ self.assertFalse(permissions.CanCreateGroup( |
+ permissions.PermissionSet([]))) |
+ finally: |
+ settings.group_creation_restriction = orig_setting |
+ |
+ def testCanCreateGroup_AdminOnly(self): |
+ orig_setting = settings.group_creation_restriction |
+ try: |
+ ADMIN_ONLY = site_pb2.UserTypeRestriction.ADMIN_ONLY |
+ settings.group_creation_restriction = ADMIN_ONLY |
+ self.assertTrue(permissions.CanCreateGroup( |
+ permissions.PermissionSet([permissions.ADMINISTER_SITE]))) |
+ self.assertFalse(permissions.CanCreateGroup( |
+ permissions.PermissionSet([permissions.CREATE_GROUP]))) |
+ self.assertFalse(permissions.CanCreateGroup( |
+ permissions.PermissionSet([]))) |
+ finally: |
+ settings.group_creation_restriction = orig_setting |
+ |
+ def testCanCreateGroup_UnspecifiedSetting(self): |
+ orig_setting = settings.group_creation_restriction |
+ try: |
+ settings.group_creation_restriction = None |
+ self.assertFalse(permissions.CanCreateGroup( |
+ permissions.PermissionSet([permissions.ADMINISTER_SITE]))) |
+ self.assertFalse(permissions.CanCreateGroup( |
+ permissions.PermissionSet([permissions.CREATE_GROUP]))) |
+ self.assertFalse(permissions.CanCreateGroup( |
+ permissions.PermissionSet([]))) |
+ finally: |
+ settings.group_creation_restriction = orig_setting |
+ |
+ def testCanEditGroup_HasPerm(self): |
+ self.assertTrue(permissions.CanEditGroup( |
+ permissions.PermissionSet([permissions.EDIT_GROUP]), None, None)) |
+ |
+ def testCanEditGroup_IsOwner(self): |
+ self.assertTrue(permissions.CanEditGroup( |
+ permissions.PermissionSet([]), {111L}, {111L})) |
+ |
+ def testCanEditGroup_Otherwise(self): |
+ self.assertFalse(permissions.CanEditGroup( |
+ permissions.PermissionSet([]), {111L}, {222L})) |
+ |
+ def testCanViewGroup_HasPerm(self): |
+ self.assertTrue(permissions.CanViewGroup( |
+ permissions.PermissionSet([permissions.VIEW_GROUP]), |
+ None, None, None, None, None)) |
+ |
+ def testCanViewGroup_IsMemberOfFriendProject(self): |
+ group_settings = usergroup_pb2.MakeSettings('owners', friend_projects=[890]) |
+ self.assertFalse(permissions.CanViewGroup( |
+ permissions.PermissionSet([]), |
+ {111L}, group_settings, {222L}, {333L}, {789})) |
+ self.assertTrue(permissions.CanViewGroup( |
+ permissions.PermissionSet([]), |
+ {111L}, group_settings, {222L}, {333L}, {789, 890})) |
+ |
+ def testCanViewGroup_VisibleToOwner(self): |
+ group_settings = usergroup_pb2.MakeSettings('owners') |
+ self.assertFalse(permissions.CanViewGroup( |
+ permissions.PermissionSet([]), |
+ {111L}, group_settings, {222L}, {333L}, {789})) |
+ self.assertFalse(permissions.CanViewGroup( |
+ permissions.PermissionSet([]), |
+ {222L}, group_settings, {222L}, {333L}, {789})) |
+ self.assertTrue(permissions.CanViewGroup( |
+ permissions.PermissionSet([]), |
+ {333L}, group_settings, {222L}, {333L}, {789})) |
+ |
+ def testCanViewGroup_IsVisibleToMember(self): |
+ group_settings = usergroup_pb2.MakeSettings('members') |
+ self.assertFalse(permissions.CanViewGroup( |
+ permissions.PermissionSet([]), |
+ {111L}, group_settings, {222L}, {333L}, {789})) |
+ self.assertTrue(permissions.CanViewGroup( |
+ permissions.PermissionSet([]), |
+ {222L}, group_settings, {222L}, {333L}, {789})) |
+ self.assertTrue(permissions.CanViewGroup( |
+ permissions.PermissionSet([]), |
+ {333L}, group_settings, {222L}, {333L}, {789})) |
+ |
+ def testCanViewGroup_AnyoneCanView(self): |
+ group_settings = usergroup_pb2.MakeSettings('anyone') |
+ self.assertTrue(permissions.CanViewGroup( |
+ permissions.PermissionSet([]), |
+ {111L}, group_settings, {222L}, {333L}, {789})) |
+ |
+ def testIsBanned_AnonUser(self): |
+ user_view = framework_views.UserView(None, None, True) |
+ self.assertFalse(permissions.IsBanned(None, user_view)) |
+ |
+ def testIsBanned_NormalUser(self): |
+ user = user_pb2.User() |
+ user_view = framework_views.UserView(None, None, True) |
+ self.assertFalse(permissions.IsBanned(user, user_view)) |
+ |
+ def testIsBanned_BannedUser(self): |
+ user = user_pb2.User() |
+ user.banned = 'spammer' |
+ user_view = framework_views.UserView(None, None, True) |
+ self.assertTrue(permissions.IsBanned(user, user_view)) |
+ |
+ def testIsBanned_BadDomainUser(self): |
+ settings.banned_user_domains = ['spammer.com', 'phisher.com'] |
+ user = user_pb2.User() |
+ user_view = framework_views.UserView(None, None, True) |
+ user_view.domain = 'spammer.com' |
+ self.assertTrue(permissions.IsBanned(user, user_view)) |
+ |
+ def testGetCustomPermissions(self): |
+ project = project_pb2.Project() |
+ self.assertListEqual([], permissions.GetCustomPermissions(project)) |
+ |
+ project.extra_perms.append(project_pb2.Project.ExtraPerms( |
+ perms=['Core', 'Elite', 'Gold'])) |
+ self.assertListEqual(['Core', 'Elite', 'Gold'], |
+ permissions.GetCustomPermissions(project)) |
+ |
+ project.extra_perms.append(project_pb2.Project.ExtraPerms( |
+ perms=['Silver', 'Gold', 'Bronze'])) |
+ self.assertListEqual(['Bronze', 'Core', 'Elite', 'Gold', 'Silver'], |
+ permissions.GetCustomPermissions(project)) |
+ |
+ def testUserCanViewProject(self): |
+ self.mox.StubOutWithMock(time, 'time') |
+ for _ in range(8): |
+ time.time().AndReturn(self.NOW) |
+ self.mox.ReplayAll() |
+ |
+ self.assertTrue(permissions.UserCanViewProject( |
+ self.member, {self.COMMITTER_USER_ID}, self.live_project)) |
+ self.assertTrue(permissions.UserCanViewProject( |
+ None, None, self.live_project)) |
+ |
+ self.archived_project.delete_time = self.NOW + 1 |
+ self.assertFalse(permissions.UserCanViewProject( |
+ None, None, self.archived_project)) |
+ self.assertTrue(permissions.UserCanViewProject( |
+ self.owner, {self.OWNER_USER_ID}, self.archived_project)) |
+ self.assertTrue(permissions.UserCanViewProject( |
+ self.site_admin, {self.SITE_ADMIN_USER_ID}, |
+ self.archived_project)) |
+ |
+ self.archived_project.delete_time = self.NOW - 1 |
+ self.assertFalse(permissions.UserCanViewProject( |
+ None, None, self.archived_project)) |
+ self.assertFalse(permissions.UserCanViewProject( |
+ self.owner, {self.OWNER_USER_ID}, self.archived_project)) |
+ self.assertTrue(permissions.UserCanViewProject( |
+ self.site_admin, {self.SITE_ADMIN_USER_ID}, |
+ self.archived_project)) |
+ |
+ self.mox.VerifyAll() |
+ |
+ def CheckExpired(self, state, expected_to_be_reapable): |
+ proj = project_pb2.Project() |
+ proj.state = state |
+ proj.delete_time = self.NOW + 1 |
+ self.assertFalse(permissions.IsExpired(proj)) |
+ |
+ proj.delete_time = self.NOW - 1 |
+ self.assertEqual(expected_to_be_reapable, permissions.IsExpired(proj)) |
+ |
+ proj.delete_time = self.NOW - 1 |
+ self.assertFalse(permissions.IsExpired(proj, expired_before=self.NOW - 2)) |
+ |
+ def testIsExpired_Live(self): |
+ self.CheckExpired(project_pb2.ProjectState.LIVE, False) |
+ |
+ def testIsExpired_Archived(self): |
+ self.mox.StubOutWithMock(time, 'time') |
+ for _ in range(2): |
+ time.time().AndReturn(self.NOW) |
+ self.mox.ReplayAll() |
+ |
+ self.CheckExpired(project_pb2.ProjectState.ARCHIVED, True) |
+ |
+ self.mox.VerifyAll() |
+ |
+ |
+class PermissionsCheckTest(unittest.TestCase): |
+ |
+ def setUp(self): |
+ self.perms = permissions.PermissionSet(['a', 'b', 'c']) |
+ |
+ self.proj = project_pb2.Project() |
+ self.proj.committer_ids.append(111L) |
+ self.proj.extra_perms.append(project_pb2.Project.ExtraPerms( |
+ member_id=111L, perms=['d'])) |
+ |
+ # Note: z is an example of a perm that the user does not have. |
+ # Note: q is an example of an irrelevant perm that the user does not have. |
+ |
+ def DoCanUsePerm(self, perm, project='default', user_id=None, restrict=''): |
+ """Wrapper function to call CanUsePerm().""" |
+ if project == 'default': |
+ project = self.proj |
+ return self.perms.CanUsePerm( |
+ perm, {user_id or 111L}, project, restrict.split()) |
+ |
+ def testHasPermNoRestrictions(self): |
+ self.assertTrue(self.DoCanUsePerm('a')) |
+ self.assertTrue(self.DoCanUsePerm('A')) |
+ self.assertFalse(self.DoCanUsePerm('z')) |
+ self.assertTrue(self.DoCanUsePerm('d')) |
+ self.assertFalse(self.DoCanUsePerm('d', user_id=222L)) |
+ self.assertFalse(self.DoCanUsePerm('d', project=project_pb2.Project())) |
+ |
+ def testHasPermOperationRestrictions(self): |
+ self.assertTrue(self.DoCanUsePerm('a', restrict='Restrict-a-b')) |
+ self.assertTrue(self.DoCanUsePerm('a', restrict='Restrict-b-z')) |
+ self.assertTrue(self.DoCanUsePerm('a', restrict='Restrict-a-d')) |
+ self.assertTrue(self.DoCanUsePerm('d', restrict='Restrict-d-a')) |
+ self.assertTrue(self.DoCanUsePerm( |
+ 'd', restrict='Restrict-q-z Restrict-q-d Restrict-d-a')) |
+ |
+ self.assertFalse(self.DoCanUsePerm('a', restrict='Restrict-a-z')) |
+ self.assertFalse(self.DoCanUsePerm('d', restrict='Restrict-d-z')) |
+ self.assertFalse(self.DoCanUsePerm( |
+ 'd', restrict='Restrict-d-a Restrict-d-z')) |
+ |
+ def testHasPermOutsideProjectScope(self): |
+ self.assertTrue(self.DoCanUsePerm('a', project=None)) |
+ self.assertTrue(self.DoCanUsePerm( |
+ 'a', project=None, restrict='Restrict-a-c')) |
+ self.assertTrue(self.DoCanUsePerm( |
+ 'a', project=None, restrict='Restrict-q-z')) |
+ |
+ self.assertFalse(self.DoCanUsePerm('z', project=None)) |
+ self.assertFalse(self.DoCanUsePerm( |
+ 'a', project=None, restrict='Restrict-a-d')) |
+ |
+ |
+class CanViewProjectContributorListTest(unittest.TestCase): |
+ |
+ def testCanViewProjectContributorList_NoProject(self): |
+ mr = testing_helpers.MakeMonorailRequest(path='/') |
+ self.assertFalse(permissions.CanViewContributorList(mr)) |
+ |
+ def testCanViewProjectContributorList_NormalProject(self): |
+ project = project_pb2.Project() |
+ mr = testing_helpers.MakeMonorailRequest( |
+ path='/p/proj/', project=project) |
+ self.assertTrue(permissions.CanViewContributorList(mr)) |
+ |
+ def testCanViewProjectContributorList_ProjectWithOptionSet(self): |
+ project = project_pb2.Project() |
+ project.only_owners_see_contributors = True |
+ |
+ for perms in [permissions.READ_ONLY_PERMISSIONSET, |
+ permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET, |
+ permissions.CONTRIBUTOR_INACTIVE_PERMISSIONSET]: |
+ mr = testing_helpers.MakeMonorailRequest( |
+ path='/p/proj/', project=project, perms=perms) |
+ self.assertFalse(permissions.CanViewContributorList(mr)) |
+ |
+ for perms in [permissions.COMMITTER_ACTIVE_PERMISSIONSET, |
+ permissions.COMMITTER_INACTIVE_PERMISSIONSET, |
+ permissions.OWNER_ACTIVE_PERMISSIONSET, |
+ permissions.OWNER_INACTIVE_PERMISSIONSET, |
+ permissions.ADMIN_PERMISSIONSET]: |
+ mr = testing_helpers.MakeMonorailRequest( |
+ path='/p/proj/', project=project, perms=perms) |
+ self.assertTrue(permissions.CanViewContributorList(mr)) |
+ |
+ |
+class ShouldCheckForAbandonmentTest(unittest.TestCase): |
+ |
+ def setUp(self): |
+ self.mr = testing_helpers.Blank( |
+ project=project_pb2.Project(), |
+ auth=monorailrequest.AuthData()) |
+ |
+ def testOwner(self): |
+ self.mr.auth.effective_ids = {111L} |
+ self.mr.perms = permissions.OWNER_ACTIVE_PERMISSIONSET |
+ self.assertTrue(permissions.ShouldCheckForAbandonment(self.mr)) |
+ |
+ def testNonOwner(self): |
+ self.mr.auth.effective_ids = {222L} |
+ self.mr.perms = permissions.COMMITTER_ACTIVE_PERMISSIONSET |
+ self.assertFalse(permissions.ShouldCheckForAbandonment(self.mr)) |
+ self.mr.perms = permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET |
+ self.assertFalse(permissions.ShouldCheckForAbandonment(self.mr)) |
+ self.mr.perms = permissions.USER_PERMISSIONSET |
+ self.assertFalse(permissions.ShouldCheckForAbandonment(self.mr)) |
+ self.mr.perms = permissions.EMPTY_PERMISSIONSET |
+ self.assertFalse(permissions.ShouldCheckForAbandonment(self.mr)) |
+ |
+ def testSiteAdmin(self): |
+ self.mr.auth.effective_ids = {111L} |
+ self.mr.perms = permissions.ADMIN_PERMISSIONSET |
+ self.assertFalse(permissions.ShouldCheckForAbandonment(self.mr)) |
+ |
+ |
+class RestrictionLabelsTest(unittest.TestCase): |
+ |
+ ORIG_SUMMARY = 'this is the orginal summary' |
+ ORIG_LABELS = ['one', 'two'] |
+ |
+ def testGetRestrictions_NoIssue(self): |
+ self.assertEqual([], permissions.GetRestrictions(None)) |
+ |
+ def testGetRestrictions(self): |
+ art = fake.MakeTestIssue( |
+ 789, 1, self.ORIG_SUMMARY, 'New', 0L, labels=self.ORIG_LABELS) |
+ self.assertEquals([], permissions.GetRestrictions(art)) |
+ |
+ art = fake.MakeTestIssue( |
+ 789, 1, self.ORIG_SUMMARY, 'New', 0L, |
+ labels=['Restrict-MissingThirdPart', 'Hot']) |
+ self.assertEquals([], permissions.GetRestrictions(art)) |
+ |
+ art = fake.MakeTestIssue( |
+ 789, 1, self.ORIG_SUMMARY, 'New', 0L, |
+ labels=['Restrict-View-Core', 'Hot']) |
+ self.assertEquals(['restrict-view-core'], permissions.GetRestrictions(art)) |
+ |
+ art = fake.MakeTestIssue( |
+ 789, 1, self.ORIG_SUMMARY, 'New', 0L, |
+ labels=['Restrict-View-Core', 'Hot'], |
+ derived_labels=['Color-Red', 'Restrict-EditIssue-GoldMembers']) |
+ self.assertEquals( |
+ ['restrict-view-core', 'restrict-editissue-goldmembers'], |
+ permissions.GetRestrictions(art)) |
+ |
+ art = fake.MakeTestIssue( |
+ 789, 1, self.ORIG_SUMMARY, 'New', 0L, |
+ labels=['restrict-view-core', 'hot'], |
+ derived_labels=['Color-Red', 'RESTRICT-EDITISSUE-GOLDMEMBERS']) |
+ self.assertEquals( |
+ ['restrict-view-core', 'restrict-editissue-goldmembers'], |
+ permissions.GetRestrictions(art)) |
+ |
+ |
+REPORTER_ID = 111L |
+OWNER_ID = 222L |
+CC_ID = 333L |
+OTHER_ID = 444L |
+ |
+ |
+class IssuePermissionsTest(unittest.TestCase): |
+ |
+ REGULAR_ISSUE = tracker_pb2.Issue() |
+ REGULAR_ISSUE.reporter_id = REPORTER_ID |
+ |
+ DELETED_ISSUE = tracker_pb2.Issue() |
+ DELETED_ISSUE.deleted = True |
+ DELETED_ISSUE.reporter_id = REPORTER_ID |
+ |
+ RESTRICTED_ISSUE = tracker_pb2.Issue() |
+ RESTRICTED_ISSUE.reporter_id = REPORTER_ID |
+ RESTRICTED_ISSUE.owner_id = OWNER_ID |
+ RESTRICTED_ISSUE.cc_ids.append(CC_ID) |
+ RESTRICTED_ISSUE.labels.append('Restrict-View-Commit') |
+ |
+ RESTRICTED_ISSUE2 = tracker_pb2.Issue() |
+ RESTRICTED_ISSUE2.reporter_id = REPORTER_ID |
+ # RESTRICTED_ISSUE2 has no owner |
+ RESTRICTED_ISSUE2.cc_ids.append(CC_ID) |
+ RESTRICTED_ISSUE2.labels.append('Restrict-View-Commit') |
+ |
+ RESTRICTED_ISSUE3 = tracker_pb2.Issue() |
+ RESTRICTED_ISSUE3.reporter_id = REPORTER_ID |
+ RESTRICTED_ISSUE3.owner_id = OWNER_ID |
+ # Restrict to a permission that no one has. |
+ RESTRICTED_ISSUE3.labels.append('Restrict-EditIssue-Foo') |
+ |
+ PROJECT = project_pb2.Project() |
+ |
+ def testCanViewIssue_Deleted(self): |
+ self.assertFalse(permissions.CanViewIssue( |
+ {REPORTER_ID}, permissions.OWNER_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.DELETED_ISSUE)) |
+ self.assertTrue(permissions.CanViewIssue( |
+ {REPORTER_ID}, permissions.OWNER_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.DELETED_ISSUE, allow_viewing_deleted=True)) |
+ self.assertTrue(permissions.CanViewIssue( |
+ {REPORTER_ID}, permissions.OWNER_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ |
+ def testCanViewIssue_Regular(self): |
+ self.assertTrue(permissions.CanViewIssue( |
+ {REPORTER_ID}, permissions.OWNER_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ self.assertTrue(permissions.CanViewIssue( |
+ {REPORTER_ID}, permissions.COMMITTER_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ self.assertTrue(permissions.CanViewIssue( |
+ {REPORTER_ID}, |
+ permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ self.assertTrue(permissions.CanViewIssue( |
+ {REPORTER_ID}, permissions.USER_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ self.assertTrue(permissions.CanViewIssue( |
+ {REPORTER_ID}, permissions.READ_ONLY_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ self.assertTrue(permissions.CanViewIssue( |
+ set(), permissions.READ_ONLY_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ |
+ def testCanViewIssue_Restricted(self): |
+ # Project owner can always view issue. |
+ self.assertTrue(permissions.CanViewIssue( |
+ {OTHER_ID}, permissions.OWNER_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.RESTRICTED_ISSUE)) |
+ # Member can view because they have Commit perm. |
+ self.assertTrue(permissions.CanViewIssue( |
+ {OTHER_ID}, permissions.COMMITTER_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.RESTRICTED_ISSUE)) |
+ # Contributors normally do not have Commit perm. |
+ self.assertFalse(permissions.CanViewIssue( |
+ {OTHER_ID}, permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.RESTRICTED_ISSUE)) |
+ # Non-members do not have Commit perm. |
+ self.assertFalse(permissions.CanViewIssue( |
+ {OTHER_ID}, permissions.USER_PERMISSIONSET, |
+ self.PROJECT, self.RESTRICTED_ISSUE)) |
+ # Anon user's do not have Commit perm. |
+ self.assertFalse(permissions.CanViewIssue( |
+ set(), permissions.READ_ONLY_PERMISSIONSET, |
+ self.PROJECT, self.RESTRICTED_ISSUE)) |
+ |
+ def testCanViewIssue_RestrictedParticipants(self): |
+ # Reporter can always view issue |
+ self.assertTrue(permissions.CanViewIssue( |
+ {REPORTER_ID}, permissions.READ_ONLY_PERMISSIONSET, |
+ self.PROJECT, self.RESTRICTED_ISSUE)) |
+ # Issue owner can always view issue |
+ self.assertTrue(permissions.CanViewIssue( |
+ {OWNER_ID}, permissions.READ_ONLY_PERMISSIONSET, |
+ self.PROJECT, self.RESTRICTED_ISSUE)) |
+ # CC'd user can always view issue |
+ self.assertTrue(permissions.CanViewIssue( |
+ {CC_ID}, permissions.READ_ONLY_PERMISSIONSET, |
+ self.PROJECT, self.RESTRICTED_ISSUE)) |
+ # Non-participants cannot view issue if they don't have the needed perm. |
+ self.assertFalse(permissions.CanViewIssue( |
+ {OTHER_ID}, permissions.READ_ONLY_PERMISSIONSET, |
+ self.PROJECT, self.RESTRICTED_ISSUE)) |
+ # Anon user's do not have Commit perm. |
+ self.assertFalse(permissions.CanViewIssue( |
+ set(), permissions.READ_ONLY_PERMISSIONSET, |
+ self.PROJECT, self.RESTRICTED_ISSUE)) |
+ # Anon user's cannot match owner 0. |
+ self.assertFalse(permissions.CanViewIssue( |
+ set(), permissions.READ_ONLY_PERMISSIONSET, |
+ self.PROJECT, self.RESTRICTED_ISSUE2)) |
+ |
+ def testCannotViewIssueIfCannotViewProject(self): |
+ """Cross-project search should not be a backdoor to viewing issues.""" |
+ # Reporter cannot view issue if they not long have access to the project. |
+ self.assertFalse(permissions.CanViewIssue( |
+ {REPORTER_ID}, permissions.EMPTY_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ # Issue owner cannot always view issue |
+ self.assertFalse(permissions.CanViewIssue( |
+ {OWNER_ID}, permissions.EMPTY_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ # CC'd user cannot always view issue |
+ self.assertFalse(permissions.CanViewIssue( |
+ {CC_ID}, permissions.EMPTY_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ # Non-participants cannot view issue if they don't have the needed perm. |
+ self.assertFalse(permissions.CanViewIssue( |
+ {OTHER_ID}, permissions.EMPTY_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ # Anon user's do not have Commit perm. |
+ self.assertFalse(permissions.CanViewIssue( |
+ set(), permissions.EMPTY_PERMISSIONSET, self.PROJECT, |
+ self.REGULAR_ISSUE)) |
+ # Anon user's cannot match owner 0. |
+ self.assertFalse(permissions.CanViewIssue( |
+ set(), permissions.EMPTY_PERMISSIONSET, self.PROJECT, |
+ self.REGULAR_ISSUE)) |
+ |
+ def testCanEditIssue(self): |
+ # Non-members and contributors cannot edit issues, |
+ # even if they reported them. |
+ self.assertFalse(permissions.CanEditIssue( |
+ {REPORTER_ID}, permissions.READ_ONLY_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ self.assertFalse(permissions.CanEditIssue( |
+ {REPORTER_ID}, permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ |
+ # Project committers and project owners can edit issues, regardless |
+ # of their role in the issue. |
+ self.assertTrue(permissions.CanEditIssue( |
+ {REPORTER_ID}, permissions.COMMITTER_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ self.assertTrue(permissions.CanEditIssue( |
+ {REPORTER_ID}, permissions.OWNER_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ self.assertTrue(permissions.CanEditIssue( |
+ {OWNER_ID}, permissions.COMMITTER_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ self.assertTrue(permissions.CanEditIssue( |
+ {OWNER_ID}, permissions.OWNER_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ self.assertTrue(permissions.CanEditIssue( |
+ {OTHER_ID}, permissions.COMMITTER_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ self.assertTrue(permissions.CanEditIssue( |
+ {OTHER_ID}, permissions.OWNER_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.REGULAR_ISSUE)) |
+ |
+ def testCanEditIssue_Restricted(self): |
+ # Project committers cannot edit issues with a restriction to a custom |
+ # permission that they don't have. |
+ self.assertFalse(permissions.CanEditIssue( |
+ {OTHER_ID}, permissions.COMMITTER_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.RESTRICTED_ISSUE3)) |
+ |
+ # *Issue* owners can always edit the issues that they own, even if |
+ # those issues are restricted to perms that they don't have. |
+ self.assertTrue(permissions.CanEditIssue( |
+ {OWNER_ID}, permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.RESTRICTED_ISSUE3)) |
+ |
+ # Project owners can always edit, they cannot lock themselves out. |
+ self.assertTrue(permissions.CanEditIssue( |
+ {OTHER_ID}, permissions.OWNER_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.RESTRICTED_ISSUE3)) |
+ |
+ # A committer with edit permission but not view permission |
+ # should not be able to edit the issue. |
+ self.assertFalse(permissions.CanEditIssue( |
+ {OTHER_ID}, permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET, |
+ self.PROJECT, self.RESTRICTED_ISSUE2)) |
+ |
+ def testCanCommentIssue_HasPerm(self): |
+ self.assertTrue(permissions.CanCommentIssue( |
+ {111L}, permissions.PermissionSet([permissions.ADD_ISSUE_COMMENT]), |
+ None, None)) |
+ self.assertFalse(permissions.CanCommentIssue( |
+ {111L}, permissions.PermissionSet([]), |
+ None, None)) |
+ |
+ def testCanCommentIssue_HasExtraPerm(self): |
+ project = project_pb2.Project() |
+ project.committer_ids.append(111L) |
+ extra_perm = project_pb2.Project.ExtraPerms( |
+ member_id=111L, perms=[permissions.ADD_ISSUE_COMMENT]) |
+ project.extra_perms.append(extra_perm) |
+ self.assertTrue(permissions.CanCommentIssue( |
+ {111L}, permissions.PermissionSet([]), |
+ project, None)) |
+ self.assertFalse(permissions.CanCommentIssue( |
+ {222L}, permissions.PermissionSet([]), |
+ project, None)) |
+ |
+ def testCanCommentIssue_Restricted(self): |
+ issue = tracker_pb2.Issue(labels=['Restrict-AddIssueComment-CoreTeam']) |
+ # User is granted exactly the perm they need specifically in this issue. |
+ self.assertTrue(permissions.CanCommentIssue( |
+ {111L}, permissions.PermissionSet([]), |
+ None, issue, granted_perms=['addissuecomment'])) |
+ # User is granted CoreTeam, which satifies the restriction, and allows |
+ # them to use the AddIssueComment permission that they have and would |
+ # normally be able to use in an unrestricted issue. |
+ self.assertTrue(permissions.CanCommentIssue( |
+ {111L}, permissions.PermissionSet([permissions.ADD_ISSUE_COMMENT]), |
+ None, issue, granted_perms=['coreteam'])) |
+ # User was granted CoreTeam, but never had AddIssueComment. |
+ self.assertFalse(permissions.CanCommentIssue( |
+ {111L}, permissions.PermissionSet([]), |
+ None, issue, granted_perms=['coreteam'])) |
+ # User has AddIssueComment, but cannot satisfy restriction. |
+ self.assertFalse(permissions.CanCommentIssue( |
+ {111L}, permissions.PermissionSet([permissions.ADD_ISSUE_COMMENT]), |
+ None, issue)) |
+ |
+ def testCanCommentIssue_Granted(self): |
+ self.assertTrue(permissions.CanCommentIssue( |
+ {111L}, permissions.PermissionSet([]), |
+ None, None, granted_perms=['addissuecomment'])) |
+ self.assertFalse(permissions.CanCommentIssue( |
+ {111L}, permissions.PermissionSet([]), |
+ None, None)) |
+ |
+ def testCanViewComponentDef_ComponentAdmin(self): |
+ cd = tracker_pb2.ComponentDef(admin_ids=[111L]) |
+ perms = permissions.PermissionSet([]) |
+ self.assertTrue(permissions.CanViewComponentDef( |
+ {111L}, perms, None, cd)) |
+ self.assertFalse(permissions.CanViewComponentDef( |
+ {999L}, perms, None, cd)) |
+ |
+ def testCanViewComponentDef_NormalUser(self): |
+ cd = tracker_pb2.ComponentDef() |
+ self.assertTrue(permissions.CanViewComponentDef( |
+ {111L}, permissions.PermissionSet([permissions.VIEW]), |
+ None, cd)) |
+ self.assertFalse(permissions.CanViewComponentDef( |
+ {111L}, permissions.PermissionSet([]), |
+ None, cd)) |
+ |
+ def testCanEditComponentDef_ComponentAdmin(self): |
+ cd = tracker_pb2.ComponentDef(admin_ids=[111L], path='Whole') |
+ sub_cd = tracker_pb2.ComponentDef(admin_ids=[222L], path='Whole>Part') |
+ config = tracker_bizobj.MakeDefaultProjectIssueConfig(789) |
+ config.component_defs.append(cd) |
+ config.component_defs.append(sub_cd) |
+ perms = permissions.PermissionSet([]) |
+ self.assertTrue(permissions.CanEditComponentDef( |
+ {111L}, perms, None, cd, config)) |
+ self.assertFalse(permissions.CanEditComponentDef( |
+ {222L}, perms, None, cd, config)) |
+ self.assertFalse(permissions.CanEditComponentDef( |
+ {999L}, perms, None, cd, config)) |
+ self.assertTrue(permissions.CanEditComponentDef( |
+ {111L}, perms, None, sub_cd, config)) |
+ self.assertTrue(permissions.CanEditComponentDef( |
+ {222L}, perms, None, sub_cd, config)) |
+ self.assertFalse(permissions.CanEditComponentDef( |
+ {999L}, perms, None, sub_cd, config)) |
+ |
+ def testCanEditComponentDef_ProjectOwners(self): |
+ cd = tracker_pb2.ComponentDef(path='Whole') |
+ config = tracker_bizobj.MakeDefaultProjectIssueConfig(789) |
+ config.component_defs.append(cd) |
+ self.assertTrue(permissions.CanEditComponentDef( |
+ {111L}, permissions.PermissionSet([permissions.EDIT_PROJECT]), |
+ None, cd, config)) |
+ self.assertFalse(permissions.CanEditComponentDef( |
+ {111L}, permissions.PermissionSet([]), |
+ None, cd, config)) |
+ |
+ def testCanViewFieldDef_FieldAdmin(self): |
+ fd = tracker_pb2.FieldDef(admin_ids=[111L]) |
+ perms = permissions.PermissionSet([]) |
+ self.assertTrue(permissions.CanViewFieldDef( |
+ {111L}, perms, None, fd)) |
+ self.assertFalse(permissions.CanViewFieldDef( |
+ {999L}, perms, None, fd)) |
+ |
+ def testCanViewFieldDef_NormalUser(self): |
+ fd = tracker_pb2.FieldDef() |
+ self.assertTrue(permissions.CanViewFieldDef( |
+ {111L}, permissions.PermissionSet([permissions.VIEW]), |
+ None, fd)) |
+ self.assertFalse(permissions.CanViewFieldDef( |
+ {111L}, permissions.PermissionSet([]), |
+ None, fd)) |
+ |
+ def testCanEditFieldDef_FieldAdmin(self): |
+ fd = tracker_pb2.FieldDef(admin_ids=[111L]) |
+ perms = permissions.PermissionSet([]) |
+ self.assertTrue(permissions.CanEditFieldDef( |
+ {111L}, perms, None, fd)) |
+ self.assertFalse(permissions.CanEditFieldDef( |
+ {999L}, perms, None, fd)) |
+ |
+ def testCanEditFieldDef_ProjectOwners(self): |
+ fd = tracker_pb2.FieldDef() |
+ self.assertTrue(permissions.CanEditFieldDef( |
+ {111L}, permissions.PermissionSet([permissions.EDIT_PROJECT]), |
+ None, fd)) |
+ self.assertFalse(permissions.CanEditFieldDef( |
+ {111L}, permissions.PermissionSet([]), |
+ None, fd)) |
+ |
+ def testCanViewTemplate_TemplateAdmin(self): |
+ td = tracker_pb2.TemplateDef(admin_ids=[111L]) |
+ perms = permissions.PermissionSet([]) |
+ self.assertTrue(permissions.CanViewTemplate( |
+ {111L}, perms, None, td)) |
+ self.assertFalse(permissions.CanViewTemplate( |
+ {999L}, perms, None, td)) |
+ |
+ def testCanViewTemplate_MembersOnly(self): |
+ td = tracker_pb2.TemplateDef(members_only=True) |
+ project = project_pb2.Project(committer_ids=[111L]) |
+ self.assertTrue(permissions.CanViewTemplate( |
+ {111L}, permissions.PermissionSet([]), |
+ project, td)) |
+ self.assertFalse(permissions.CanViewTemplate( |
+ {999L}, permissions.PermissionSet([]), |
+ project, td)) |
+ |
+ def testCanViewTemplate_AnyoneWhoCanViewProject(self): |
+ td = tracker_pb2.TemplateDef() |
+ self.assertTrue(permissions.CanViewTemplate( |
+ {111L}, permissions.PermissionSet([permissions.VIEW]), |
+ None, td)) |
+ self.assertFalse(permissions.CanViewTemplate( |
+ {111L}, permissions.PermissionSet([]), |
+ None, td)) |
+ |
+ def testCanEditTemplate_TemplateAdmin(self): |
+ td = tracker_pb2.TemplateDef(admin_ids=[111L]) |
+ perms = permissions.PermissionSet([]) |
+ self.assertTrue(permissions.CanEditTemplate( |
+ {111L}, perms, None, td)) |
+ self.assertFalse(permissions.CanEditTemplate( |
+ {999L}, perms, None, td)) |
+ |
+ def testCanEditTemplate_ProjectOwners(self): |
+ td = tracker_pb2.TemplateDef() |
+ self.assertTrue(permissions.CanEditTemplate( |
+ {111L}, permissions.PermissionSet([permissions.EDIT_PROJECT]), |
+ None, td)) |
+ self.assertFalse(permissions.CanEditTemplate( |
+ {111L}, permissions.PermissionSet([]), |
+ None, td)) |
+ |
+ |
+if __name__ == '__main__': |
+ unittest.main() |