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