Merge lp:~adeuring/launchpad/revokeAccessGrants_specs into lp:launchpad

Proposed by Abel Deuring on 2012-09-25
Status: Merged
Approved by: Abel Deuring on 2012-09-25
Approved revision: no longer in the source branch.
Merged at revision: 16036
Proposed branch: lp:~adeuring/launchpad/revokeAccessGrants_specs
Merge into: lp:launchpad
Diff against target: 231 lines (+71/-15)
3 files modified
lib/lp/registry/interfaces/sharingservice.py (+3/-1)
lib/lp/registry/services/sharingservice.py (+6/-3)
lib/lp/registry/services/tests/test_sharingservice.py (+62/-11)
To merge this branch: bzr merge lp:~adeuring/launchpad/revokeAccessGrants_specs
Reviewer Review Type Date Requested Status
Richard Harding (community) 2012-09-25 Approve on 2012-09-25
Review via email: mp+126261@code.launchpad.net

Commit Message

SharingService.revokeAccessGrants() extended for specifications.

Description of the Change

This branch extends the method SharingService.revokeAccessGrants() to
handle specifications too.

The changes mostly copy the pattern already used for bugs and branches.

test: ./bin/test -vvt lp.registry.services.tests.test_sharingservice

no lint

To post a comment you must log in.
Richard Harding (rharding) wrote :

Thanks Abel, just one typo in #164 of the diff. Subscibing...

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/interfaces/sharingservice.py'
2--- lib/lp/registry/interfaces/sharingservice.py 2012-09-25 06:16:36 +0000
3+++ lib/lp/registry/interfaces/sharingservice.py 2012-09-26 08:35:24 +0000
4@@ -306,7 +306,8 @@
5 branches=List(
6 Reference(schema=IBranch), title=_('Branches'), required=False))
7 @operation_for_version('devel')
8- def revokeAccessGrants(pillar, grantee, user, branches=None, bugs=None):
9+ def revokeAccessGrants(pillar, grantee, user, branches=None, bugs=None,
10+ specifications=None):
11 """Remove a grantee's access to the specified artifacts.
12
13 :param pillar: the pillar from which to remove access
14@@ -314,6 +315,7 @@
15 :param user: the user making the request
16 :param bugs: the bugs for which to revoke access
17 :param branches: the branches for which to revoke access
18+ :param specifications: the specifications for which to revoke access
19 """
20
21 @export_write_operation()
22
23=== modified file 'lib/lp/registry/services/sharingservice.py'
24--- lib/lp/registry/services/sharingservice.py 2012-09-25 17:47:36 +0000
25+++ lib/lp/registry/services/sharingservice.py 2012-09-26 08:35:24 +0000
26@@ -670,17 +670,20 @@
27
28 @available_with_permission('launchpad.Edit', 'pillar')
29 def revokeAccessGrants(self, pillar, grantee, user, branches=None,
30- bugs=None):
31+ bugs=None, specifications=None):
32 """See `ISharingService`."""
33
34- if not branches and not bugs:
35- raise ValueError("Either bugs or branches must be specified")
36+ if not branches and not bugs and not specifications:
37+ raise ValueError(
38+ "Either bugs, branches or specifications must be specified")
39
40 artifacts = []
41 if branches:
42 artifacts.extend(branches)
43 if bugs:
44 artifacts.extend(bugs)
45+ if specifications:
46+ artifacts.extend(specifications)
47 # Find the access artifacts associated with the bugs and branches.
48 accessartifact_source = getUtility(IAccessArtifactSource)
49 artifacts_to_delete = accessartifact_source.find(artifacts)
50
51=== modified file 'lib/lp/registry/services/tests/test_sharingservice.py'
52--- lib/lp/registry/services/tests/test_sharingservice.py 2012-09-25 17:47:36 +0000
53+++ lib/lp/registry/services/tests/test_sharingservice.py 2012-09-26 08:35:24 +0000
54@@ -888,12 +888,15 @@
55 self._assert_deleteGranteeRemoveSubscriptions(
56 [InformationType.USERDATA])
57
58- def _assert_revokeAccessGrants(self, pillar, bugs, branches):
59+ def _assert_revokeAccessGrants(self, pillar, bugs, branches,
60+ specifications):
61 artifacts = []
62 if bugs:
63 artifacts.extend(bugs)
64 if branches:
65 artifacts.extend(branches)
66+ if specifications:
67+ artifacts.extend(specifications)
68 policy = self.factory.makeAccessPolicy(pillar=pillar)
69 # Grant access to a grantee and another person.
70 grantee = self.factory.makePerson()
71@@ -918,6 +921,8 @@
72 branch.subscribe(person,
73 BranchSubscriptionNotificationLevel.NOEMAIL, None,
74 CodeReviewNotificationLevel.NOEMAIL, pillar.owner)
75+ for spec in specifications or []:
76+ spec.subscribe(person)
77
78 # Check that grantee has expected access grants.
79 accessartifact_grant_source = getUtility(IAccessArtifactGrantSource)
80@@ -927,7 +932,8 @@
81 self.assertEqual(1, grants.count())
82
83 self.service.revokeAccessGrants(
84- pillar, grantee, pillar.owner, bugs=bugs, branches=branches)
85+ pillar, grantee, pillar.owner, bugs=bugs, branches=branches,
86+ specifications=specifications)
87 with block_on_job(self):
88 transaction.commit()
89
90@@ -941,6 +947,8 @@
91 self.assertNotIn(grantee, bug.getDirectSubscribers())
92 for branch in branches or []:
93 self.assertNotIn(grantee, branch.subscribers)
94+ for spec in specifications or []:
95+ self.assertNotIn(grantee, spec.subscribers)
96
97 # Someone else still has access to the bugs and branches.
98 grants = accessartifact_grant_source.findByArtifact(
99@@ -951,6 +959,8 @@
100 self.assertIn(someone, bug.getDirectSubscribers())
101 for branch in branches or []:
102 self.assertIn(someone, branch.subscribers)
103+ for spec in specifications or []:
104+ self.assertIn(someone, spec.subscribers)
105
106 def test_revokeAccessGrantsBugs(self):
107 # Users with launchpad.Edit can delete all access for a grantee.
108@@ -960,7 +970,7 @@
109 bug = self.factory.makeBug(
110 target=distro, owner=owner,
111 information_type=InformationType.USERDATA)
112- self._assert_revokeAccessGrants(distro, [bug], None)
113+ self._assert_revokeAccessGrants(distro, [bug], None, None)
114
115 def test_revokeAccessGrantsBranches(self):
116 owner = self.factory.makePerson()
117@@ -969,14 +979,30 @@
118 branch = self.factory.makeBranch(
119 product=product, owner=owner,
120 information_type=InformationType.USERDATA)
121- self._assert_revokeAccessGrants(product, None, [branch])
122-
123- def _assert_revokeTeamAccessGrants(self, pillar, bugs, branches):
124+ self._assert_revokeAccessGrants(product, None, [branch], None)
125+
126+ def test_revokeAccessGrantsSpecifications(self):
127+ owner = self.factory.makePerson()
128+ product = self.factory.makeProduct(
129+ owner=owner, specification_sharing_policy=(
130+ SpecificationSharingPolicy.EMBARGOED_OR_PROPRIETARY))
131+ self.factory.makeAccessPolicy(
132+ pillar=product, type=InformationType.EMBARGOED)
133+ login_person(owner)
134+ specification = self.factory.makeSpecification(
135+ product=product, owner=owner,
136+ information_type=InformationType.EMBARGOED)
137+ self._assert_revokeAccessGrants(product, None, None, [specification])
138+
139+ def _assert_revokeTeamAccessGrants(self, pillar, bugs, branches,
140+ specifications):
141 artifacts = []
142 if bugs:
143 artifacts.extend(bugs)
144 if branches:
145 artifacts.extend(branches)
146+ if specifications:
147+ artifacts.extend(specifications)
148 policy = self.factory.makeAccessPolicy(pillar=pillar)
149
150 person_grantee = self.factory.makePerson()
151@@ -984,7 +1010,7 @@
152 team_grantee = self.factory.makeTeam(
153 owner=team_owner,
154 membership_policy=TeamMembershipPolicy.RESTRICTED,
155- members=[person_grantee])
156+ members=[person_grantee], email='team@example.org')
157
158 # Subscribe the team and person grantees to the artifacts.
159 for person in [team_grantee, person_grantee]:
160@@ -1000,19 +1026,29 @@
161 branch.subscribe(
162 person, BranchSubscriptionNotificationLevel.NOEMAIL,
163 None, CodeReviewNotificationLevel.NOEMAIL, pillar.owner)
164+ # Subscribing somebody to a specification does not yet imply
165+ # granting access to this person.
166+ if specifications:
167+ self.service.ensureAccessGrants(
168+ [person], pillar.owner, specifications=specifications)
169+ for spec in specifications or []:
170+ spec.subscribe(person)
171
172 # Check that grantees have expected access grants and subscriptions.
173 for person in [team_grantee, person_grantee]:
174 visible_bugs, visible_branches, visible_specs = (
175- self.service.getVisibleArtifacts(person, branches, bugs))
176+ self.service.getVisibleArtifacts(
177+ person, branches, bugs, specifications))
178 self.assertContentEqual(bugs or [], visible_bugs)
179 self.assertContentEqual(branches or [], visible_branches)
180+ self.assertContentEqual(specifications or [], visible_specs)
181 for person in [team_grantee, person_grantee]:
182 for bug in bugs or []:
183 self.assertIn(person, bug.getDirectSubscribers())
184
185 self.service.revokeAccessGrants(
186- pillar, team_grantee, pillar.owner, bugs=bugs, branches=branches)
187+ pillar, team_grantee, pillar.owner, bugs=bugs, branches=branches,
188+ specifications=specifications)
189 with block_on_job(self):
190 transaction.commit()
191
192@@ -1031,6 +1067,7 @@
193 self.service.getVisibleArtifacts(person, branches, bugs))
194 self.assertContentEqual([], visible_bugs)
195 self.assertContentEqual([], visible_branches)
196+ self.assertContentEqual([], visible_specs)
197
198 def test_revokeTeamAccessGrantsBugs(self):
199 # Users with launchpad.Edit can delete all access for a grantee.
200@@ -1040,7 +1077,7 @@
201 bug = self.factory.makeBug(
202 target=distro, owner=owner,
203 information_type=InformationType.USERDATA)
204- self._assert_revokeTeamAccessGrants(distro, [bug], None)
205+ self._assert_revokeTeamAccessGrants(distro, [bug], None, None)
206
207 def test_revokeTeamAccessGrantsBranches(self):
208 # Users with launchpad.Edit can delete all access for a grantee.
209@@ -1049,7 +1086,21 @@
210 login_person(owner)
211 branch = self.factory.makeBranch(
212 owner=owner, information_type=InformationType.USERDATA)
213- self._assert_revokeTeamAccessGrants(product, None, [branch])
214+ self._assert_revokeTeamAccessGrants(product, None, [branch], None)
215+
216+ def test_revokeTeamAccessGrantsSpecifications(self):
217+ # Users with launchpad.Edit can delete all access for a grantee.
218+ owner = self.factory.makePerson()
219+ product = self.factory.makeProduct(
220+ owner=owner, specification_sharing_policy=(
221+ SpecificationSharingPolicy.EMBARGOED_OR_PROPRIETARY))
222+ self.factory.makeAccessPolicy(product, InformationType.EMBARGOED)
223+ login_person(owner)
224+ specification = self.factory.makeSpecification(
225+ product=product, owner=owner,
226+ information_type=InformationType.EMBARGOED)
227+ self._assert_revokeTeamAccessGrants(
228+ product, None, None, [specification])
229
230 def _assert_revokeAccessGrantsUnauthorized(self):
231 # revokeAccessGrants raises an Unauthorized exception if the user