Merge lp:~cjwatson/launchpad/git-grant-limitedview into lp:launchpad

Proposed by Colin Watson
Status: Merged
Merged at revision: 18797
Proposed branch: lp:~cjwatson/launchpad/git-grant-limitedview
Merge into: lp:launchpad
Prerequisite: lp:~cjwatson/launchpad/git-permissions-notifications
Diff against target: 122 lines (+57/-3)
4 files modified
lib/lp/code/interfaces/gitcollection.py (+7/-1)
lib/lp/code/model/gitcollection.py (+15/-1)
lib/lp/registry/tests/test_private_team_visibility.py (+28/-1)
lib/lp/security.py (+7/-0)
To merge this branch: bzr merge lp:~cjwatson/launchpad/git-grant-limitedview
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+355607@code.launchpad.net

Commit message

Grant LimitedView on teams to people who own Git repositories with grants for them.

Description of the change

This means that we don't get stuck in situations where somebody can't modify the grants on a repository they own (e.g. using the proposed first-pass webservice interface where they need to supply a full replacement permission structure); and in general we want people to be able to see who can write to repositories they own, even if it was configured by another member of the owning team.

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/code/interfaces/gitcollection.py'
2--- lib/lp/code/interfaces/gitcollection.py 2016-05-05 07:22:32 +0000
3+++ lib/lp/code/interfaces/gitcollection.py 2018-10-16 11:50:42 +0000
4@@ -1,4 +1,4 @@
5-# Copyright 2015-2016 Canonical Ltd. This software is licensed under the
6+# Copyright 2015-2018 Canonical Ltd. This software is licensed under the
7 # GNU Affero General Public License version 3 (see the file LICENSE).
8
9 """A collection of Git repositories.
10@@ -116,6 +116,12 @@
11 states are returned.
12 """
13
14+ def getRuleGrantsForGrantee(grantee):
15+ """Return a result set of access grants to the given grantee.
16+
17+ :param grantee: An `IPerson`.
18+ """
19+
20 def getTeamsWithRepositories(person):
21 """Return the teams that person is a member of that have
22 repositories."""
23
24=== modified file 'lib/lp/code/model/gitcollection.py'
25--- lib/lp/code/model/gitcollection.py 2016-10-12 23:24:24 +0000
26+++ lib/lp/code/model/gitcollection.py 2018-10-16 11:50:42 +0000
27@@ -1,4 +1,4 @@
28-# Copyright 2015-2016 Canonical Ltd. This software is licensed under the
29+# Copyright 2015-2018 Canonical Ltd. This software is licensed under the
30 # GNU Affero General Public License version 3 (see the file LICENSE).
31
32 """Implementations of `IGitCollection`."""
33@@ -49,6 +49,7 @@
34 get_git_repository_privacy_filter,
35 GitRepository,
36 )
37+from lp.code.model.gitrule import GitRuleGrant
38 from lp.code.model.gitsubscription import GitSubscription
39 from lp.registry.enums import EXCLUSIVE_TEAM_POLICY
40 from lp.registry.model.distribution import Distribution
41@@ -408,6 +409,19 @@
42 proposals.order_by(Desc(CodeReviewComment.vote))
43 return proposals
44
45+ def getRuleGrantsForGrantee(self, grantee):
46+ """See `IGitCollection`."""
47+ expressions = [
48+ GitRuleGrant.grantee == grantee,
49+ GitRuleGrant.repository_id.is_in(self._getRepositorySelect()),
50+ ]
51+ visibility = self._getRepositoryVisibilityExpression()
52+ if visibility:
53+ expressions.append(
54+ GitRuleGrant.repository_id.is_in(
55+ Select(GitRepository.id, visibility)))
56+ return self.store.find(GitRuleGrant, *expressions)
57+
58 def getTeamsWithRepositories(self, person):
59 """See `IGitCollection`."""
60 # This method doesn't entirely fit with the intent of the
61
62=== modified file 'lib/lp/registry/tests/test_private_team_visibility.py'
63--- lib/lp/registry/tests/test_private_team_visibility.py 2016-01-26 15:47:37 +0000
64+++ lib/lp/registry/tests/test_private_team_visibility.py 2018-10-16 11:50:42 +0000
65@@ -1,4 +1,4 @@
66-# Copyright 2011-2012 Canonical Ltd. This software is licensed under the
67+# Copyright 2011-2018 Canonical Ltd. This software is licensed under the
68 # GNU Affero General Public License version 3 (see the file LICENSE).
69
70 """Tests for visibility of private teams.
71@@ -275,6 +275,33 @@
72 def test_teams_with_private_branch_review_requests(self, private=True):
73 self._test_teams_with_branch_review_requests()
74
75+ def _test_git_repository_grantee(self, private):
76+ # Users who own Git repositories can see private teams that have
77+ # been granted some kind of write access to those repositories.
78+ some_person = self.factory.makePerson()
79+ self._check_permission(some_person, False)
80+ login_person(some_person)
81+ project = self.factory.makeProduct()
82+ if private:
83+ information_type = InformationType.USERDATA
84+ else:
85+ information_type = InformationType.PUBLIC
86+ repository = self.factory.makeGitRepository(
87+ owner=some_person, target=project,
88+ information_type=information_type)
89+ self.factory.makeGitRuleGrant(
90+ repository=repository, grantee=self.priv_team)
91+ # The team is now visible to the repository owner.
92+ self._check_permission(some_person, True)
93+ # The team is still invisible to other users.
94+ self._check_permission(self.factory.makePerson(), False)
95+
96+ def test_public_git_repository_grantee(self):
97+ self._test_git_repository_grantee(private=False)
98+
99+ def test_private_git_repository_grantee(self):
100+ self._test_git_repository_grantee(private=True)
101+
102 def test_private_ppa_subscriber(self):
103 # Subscribers to the team's private PPA have limited view permission.
104 login_person(self.priv_owner)
105
106=== modified file 'lib/lp/security.py'
107--- lib/lp/security.py 2018-10-15 14:44:25 +0000
108+++ lib/lp/security.py 2018-10-16 11:50:42 +0000
109@@ -1054,6 +1054,13 @@
110 if not team_repositories.visibleByUser(user.person).is_empty():
111 return True
112
113+ # Grant visibility to people who own Git repositories that grant
114+ # some kind of write access to the private team.
115+ owned_repositories = IGitCollection(user.person)
116+ grants = owned_repositories.getRuleGrantsForGrantee(self.obj)
117+ if not grants.is_empty():
118+ return True
119+
120 # Grant visibility to users in a team that has the private team as
121 # a member, so that they can see the team properly in member
122 # listings.