Merge lp:~stevenk/launchpad/product-distribution-accesspolicy into lp:launchpad

Proposed by Steve Kowalik on 2012-03-08
Status: Merged
Approved by: Steve Kowalik on 2012-03-08
Approved revision: no longer in the source branch.
Merged at revision: 14935
Proposed branch: lp:~stevenk/launchpad/product-distribution-accesspolicy
Merge into: lp:launchpad
Diff against target: 359 lines (+66/-56)
9 files modified
database/schema/security.cfg (+2/-0)
lib/lp/bugs/tests/test_bug_mirror_access_triggers.py (+1/-21)
lib/lp/registry/model/distribution.py (+6/-1)
lib/lp/registry/model/product.py (+9/-0)
lib/lp/registry/services/sharingservice.py (+0/-8)
lib/lp/registry/services/tests/test_sharingservice.py (+5/-11)
lib/lp/registry/tests/test_accesspolicy.py (+21/-14)
lib/lp/registry/tests/test_distribution.py (+11/-1)
lib/lp/registry/tests/test_product.py (+11/-0)
To merge this branch: bzr merge lp:~stevenk/launchpad/product-distribution-accesspolicy
Reviewer Review Type Date Requested Status
Ian Booth (community) 2012-03-08 Approve on 2012-03-08
Review via email: mp+96499@code.launchpad.net

Commit Message

Create default accesspolicies on creation of a new product or distribution.

Description of the Change

Create default accesspolicies on creation of a new product or distribution.

To post a comment you must log in.
Ian Booth (wallyworld) wrote :

Excellent Smithers

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'database/schema/security.cfg'
2--- database/schema/security.cfg 2012-03-07 22:48:03 +0000
3+++ database/schema/security.cfg 2012-03-12 06:35:22 +0000
4@@ -1108,6 +1108,7 @@
5 type=user
6
7 [write]
8+public.accesspolicy = SELECT, INSERT
9 public.account = SELECT, INSERT, UPDATE
10 public.archive = SELECT, INSERT, UPDATE
11 public.archivearch = SELECT, INSERT, UPDATE, DELETE
12@@ -1916,6 +1917,7 @@
13
14 [updateremoteproduct]
15 groups=script
16+public.accesspolicy = SELECT, INSERT
17 public.account = SELECT, INSERT, UPDATE
18 public.bug = SELECT, INSERT, UPDATE
19 public.bugaffectsperson = SELECT, INSERT, UPDATE, DELETE
20
21=== modified file 'lib/lp/bugs/tests/test_bug_mirror_access_triggers.py'
22--- lib/lp/bugs/tests/test_bug_mirror_access_triggers.py 2012-03-07 00:23:37 +0000
23+++ lib/lp/bugs/tests/test_bug_mirror_access_triggers.py 2012-03-12 06:35:22 +0000
24@@ -78,13 +78,8 @@
25 # properly.
26 return grant_count, policy_count
27
28- def makeBugAndPolicies(self, private=False, policy_types=None):
29- if policy_types is None:
30- policy_types = [
31- InformationType.USERDATA, InformationType.EMBARGOEDSECURITY]
32+ def makeBugAndPolicies(self, private=False):
33 product = self.factory.makeProduct()
34- for policy_type in policy_types:
35- self.factory.makeAccessPolicy(pillar=product, type=policy_type)
36 bug = self.factory.makeBug(private=private, product=product)
37 return removeSecurityProxy(bug)
38
39@@ -124,9 +119,6 @@
40 def test_add_task(self):
41 # Adding a task on a new product links its policy.
42 product = self.factory.makeProduct()
43- self.factory.makeAccessPolicy(
44- pillar=product, type=InformationType.USERDATA)
45-
46 bug = self.makeBugAndPolicies(private=True)
47 bug.addTask(bug.owner, product)
48 self.assertEqual((1, 2), self.assertMirrored(bug))
49@@ -134,9 +126,6 @@
50 def test_remove_task(self):
51 # Removing a task removes its policy.
52 product = self.factory.makeProduct()
53- self.factory.makeAccessPolicy(
54- pillar=product, type=InformationType.USERDATA)
55-
56 bug = self.makeBugAndPolicies(private=True)
57 task = bug.addTask(bug.owner, product)
58 Store.of(bug).flush()
59@@ -178,9 +167,6 @@
60 def test_productseries_task(self):
61 # A productseries task causes a link to its product's policy.
62 productseries = self.factory.makeProductSeries()
63- self.factory.makeAccessPolicy(
64- pillar=productseries.product, type=InformationType.USERDATA)
65-
66 bug = self.makeBugAndPolicies(private=True)
67 bug.addTask(bug.owner, productseries)
68 self.assertEqual((1, 2), self.assertMirrored(bug))
69@@ -191,9 +177,6 @@
70 def test_distribution_task(self):
71 # A distribution task causes a link to its policy.
72 distro = self.factory.makeDistribution()
73- self.factory.makeAccessPolicy(
74- pillar=distro, type=InformationType.USERDATA)
75-
76 bug = self.makeBugAndPolicies(private=True)
77 bug.addTask(bug.owner, distro)
78 self.assertEqual((1, 2), self.assertMirrored(bug))
79@@ -202,9 +185,6 @@
80 # A distroseries task causes a link to its distribution's
81 # policy.
82 distroseries = self.factory.makeDistroSeries()
83- self.factory.makeAccessPolicy(
84- pillar=distroseries.distribution, type=InformationType.USERDATA)
85-
86 bug = self.makeBugAndPolicies(private=True)
87 bug.addTask(bug.owner, distroseries)
88 self.assertEqual((1, 2), self.assertMirrored(bug))
89
90=== modified file 'lib/lp/registry/model/distribution.py'
91--- lib/lp/registry/model/distribution.py 2012-02-08 06:00:46 +0000
92+++ lib/lp/registry/model/distribution.py 2012-03-12 06:35:22 +0000
93@@ -27,7 +27,6 @@
94 from storm.locals import (
95 And,
96 Desc,
97- Int,
98 Join,
99 Max,
100 Or,
101@@ -97,7 +96,9 @@
102 from lp.code.interfaces.seriessourcepackagebranch import (
103 IFindOfficialBranchLinks,
104 )
105+from lp.registry.enums import InformationType
106 from lp.registry.errors import NoSuchDistroSeries
107+from lp.registry.interfaces.accesspolicy import IAccessPolicySource
108 from lp.registry.interfaces.distribution import (
109 IBaseDistribution,
110 IDerivativeDistribution,
111@@ -1764,6 +1765,10 @@
112 icon=icon)
113 getUtility(IArchiveSet).new(distribution=distro,
114 owner=owner, purpose=ArchivePurpose.PRIMARY)
115+ policies = itertools.product(
116+ (distro,), (InformationType.USERDATA,
117+ InformationType.EMBARGOEDSECURITY))
118+ getUtility(IAccessPolicySource).create(policies)
119 return distro
120
121 def getCurrentSourceReleases(self, distro_source_packagenames):
122
123=== modified file 'lib/lp/registry/model/product.py'
124--- lib/lp/registry/model/product.py 2012-03-09 18:29:32 +0000
125+++ lib/lp/registry/model/product.py 2012-03-12 06:35:22 +0000
126@@ -15,6 +15,7 @@
127 import calendar
128 import datetime
129 import httplib
130+import itertools
131 import operator
132
133 from lazr.delegates import delegates
134@@ -114,7 +115,9 @@
135 )
136 from lp.code.model.sourcepackagerecipe import SourcePackageRecipe
137 from lp.code.model.sourcepackagerecipedata import SourcePackageRecipeData
138+from lp.registry.enums import InformationType
139 from lp.registry.errors import CommercialSubscribersOnly
140+from lp.registry.interfaces.accesspolicy import IAccessPolicySource
141 from lp.registry.interfaces.oopsreferences import IHasOOPSReferences
142 from lp.registry.interfaces.person import (
143 IPersonSet,
144@@ -1486,6 +1489,12 @@
145 'called MAIN or HEAD.'))
146 product.development_focus = trunk
147
148+ # Add default AccessPolicies.
149+ policies = itertools.product(
150+ (product,), (InformationType.USERDATA,
151+ InformationType.EMBARGOEDSECURITY))
152+ getUtility(IAccessPolicySource).create(policies)
153+
154 return product
155
156 def forReview(self, search_text=None, active=None,
157
158=== modified file 'lib/lp/registry/services/sharingservice.py'
159--- lib/lp/registry/services/sharingservice.py 2012-03-08 04:26:43 +0000
160+++ lib/lp/registry/services/sharingservice.py 2012-03-12 06:35:22 +0000
161@@ -115,16 +115,8 @@
162 pillar_info_types = [
163 (pillar, information_type)
164 for information_type in information_types]
165-
166- # Create any missing pillar access policies.
167 policy_source = getUtility(IAccessPolicySource)
168 pillar_policies = list(policy_source.find(pillar_info_types))
169- existing_policy_types = [
170- (pillar, pillar_policy.type) for pillar_policy in pillar_policies]
171- required_policies = (
172- set(pillar_info_types).difference(existing_policy_types))
173- if len(required_policies) > 0:
174- pillar_policies.extend(policy_source.create(required_policies))
175
176 # We have the policies, we need to figure out which grants we need to
177 # create. We also need to revoke any grants which are not required.
178
179=== modified file 'lib/lp/registry/services/tests/test_sharingservice.py'
180--- lib/lp/registry/services/tests/test_sharingservice.py 2012-03-08 04:26:43 +0000
181+++ lib/lp/registry/services/tests/test_sharingservice.py 2012-03-12 06:35:22 +0000
182@@ -153,8 +153,8 @@
183 # Make existing grants to ensure sharePillarInformation handles those
184 # cases correctly.
185 # First, a grant that is in the add set - it wil be retained.
186- policy = self.factory.makeAccessPolicy(
187- pillar=pillar, type=InformationType.EMBARGOEDSECURITY)
188+ policy = getUtility(IAccessPolicySource).find(((
189+ pillar, InformationType.EMBARGOEDSECURITY),))[0]
190 self.factory.makeAccessPolicyGrant(
191 policy, grantee=sharee, grantor=grantor)
192 # Second, a grant that is not in the add set - it will be deleted.
193@@ -227,15 +227,9 @@
194 self._test_sharePillarInformationUnauthorized(product)
195
196 def _test_deletePillarSharee(self, pillar, types_to_delete=None):
197- # Make grants for some information types.
198- information_types = [
199- InformationType.EMBARGOEDSECURITY,
200- InformationType.USERDATA]
201- access_policies = []
202- for info_type in information_types:
203- access_policy = self.factory.makeAccessPolicy(
204- pillar=pillar, type=info_type)
205- access_policies.append(access_policy)
206+ access_policies = getUtility(IAccessPolicySource).findByPillar(
207+ (pillar,))
208+ information_types = [ap.type for ap in access_policies]
209 grantee = self.factory.makePerson()
210 # Make some access policy grants for our sharee.
211 for access_policy in access_policies:
212
213=== modified file 'lib/lp/registry/tests/test_accesspolicy.py'
214--- lib/lp/registry/tests/test_accesspolicy.py 2012-03-08 08:01:44 +0000
215+++ lib/lp/registry/tests/test_accesspolicy.py 2012-03-12 06:35:22 +0000
216@@ -46,7 +46,8 @@
217 def test_create(self):
218 wanted = [
219 (self.factory.makeProduct(), InformationType.PROPRIETARY),
220- (self.factory.makeDistribution(), InformationType.USERDATA),
221+ (self.factory.makeDistribution(),
222+ InformationType.UNEMBARGOEDSECURITY),
223 ]
224 policies = getUtility(IAccessPolicySource).create(wanted)
225 self.assertThat(
226@@ -64,17 +65,17 @@
227
228 wanted = [
229 (product, InformationType.PROPRIETARY),
230- (product, InformationType.USERDATA),
231+ (product, InformationType.UNEMBARGOEDSECURITY),
232 (distribution, InformationType.PROPRIETARY),
233- (distribution, InformationType.USERDATA),
234+ (distribution, InformationType.UNEMBARGOEDSECURITY),
235 (other_product, InformationType.PROPRIETARY),
236 ]
237 getUtility(IAccessPolicySource).create(wanted)
238
239 query = [
240 (product, InformationType.PROPRIETARY),
241- (product, InformationType.USERDATA),
242- (distribution, InformationType.USERDATA),
243+ (product, InformationType.UNEMBARGOEDSECURITY),
244+ (distribution, InformationType.UNEMBARGOEDSECURITY),
245 ]
246 self.assertContentEqual(
247 query,
248@@ -101,18 +102,24 @@
249 product = self.factory.makeProduct()
250 distribution = self.factory.makeProduct()
251 other_product = self.factory.makeProduct()
252- wanted = [
253- (pillar, type)
254- for type in InformationType.items
255- for pillar in (product, distribution, other_product)]
256- policies = getUtility(IAccessPolicySource).create(wanted)
257+ policies = (
258+ (product, InformationType.EMBARGOEDSECURITY),
259+ (product, InformationType.USERDATA),
260+ (distribution, InformationType.EMBARGOEDSECURITY),
261+ (distribution, InformationType.USERDATA),
262+ (other_product, InformationType.EMBARGOEDSECURITY),
263+ (other_product, InformationType.USERDATA),
264+ )
265 self.assertContentEqual(
266 policies,
267- getUtility(IAccessPolicySource).findByPillar(
268- [product, distribution, other_product]))
269+ [(ap.pillar, ap.type)
270+ for ap in getUtility(IAccessPolicySource).findByPillar(
271+ [product, distribution, other_product])])
272 self.assertContentEqual(
273- [policy for policy in policies if policy.pillar == product],
274- getUtility(IAccessPolicySource).findByPillar([product]))
275+ [policy for policy in policies if policy[0] == product],
276+ [(ap.pillar, ap.type)
277+ for ap in getUtility(IAccessPolicySource).findByPillar(
278+ [product])])
279
280
281 class TestAccessArtifact(TestCaseWithFactory):
282
283=== modified file 'lib/lp/registry/tests/test_distribution.py'
284--- lib/lp/registry/tests/test_distribution.py 2012-01-25 04:01:19 +0000
285+++ lib/lp/registry/tests/test_distribution.py 2012-03-12 06:35:22 +0000
286@@ -1,4 +1,4 @@
287-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
288+# Copyright 2009-2012 Canonical Ltd. This software is licensed under the
289 # GNU Affero General Public License version 3 (see the file LICENSE).
290
291 """Tests for Distribution."""
292@@ -25,10 +25,12 @@
293 from lp.app.enums import ServiceUsage
294 from lp.app.errors import NotFoundError
295 from lp.app.interfaces.launchpad import ILaunchpadCelebrities
296+from lp.registry.enums import InformationType
297 from lp.registry.errors import (
298 NoSuchDistroSeries,
299 OpenTeamLinkageError,
300 )
301+from lp.registry.interfaces.accesspolicy import IAccessPolicySource
302 from lp.registry.interfaces.distribution import (
303 IDistribution,
304 IDistributionSet,
305@@ -265,6 +267,14 @@
306 provides_all = MatchesAll(*map(Provides, expected_interfaces))
307 self.assertThat(distro, provides_all)
308
309+ def test_distribution_creation_creates_accesspolicies(self):
310+ # Creating a new distribution also creates AccessPolicies for it.
311+ distro = self.factory.makeDistribution()
312+ ap = getUtility(IAccessPolicySource).findByPillar((distro,))
313+ expected = [
314+ InformationType.USERDATA, InformationType.EMBARGOEDSECURITY]
315+ self.assertContentEqual(expected, [policy.type for policy in ap])
316+
317
318 class TestDistributionCurrentSourceReleases(
319 TestDistroSeriesCurrentSourceReleases):
320
321=== modified file 'lib/lp/registry/tests/test_product.py'
322--- lib/lp/registry/tests/test_product.py 2012-03-09 18:29:32 +0000
323+++ lib/lp/registry/tests/test_product.py 2012-03-12 06:35:22 +0000
324@@ -10,6 +10,7 @@
325 import pytz
326 from testtools.matchers import MatchesAll
327 import transaction
328+from zope.component import getUtility
329 from zope.security.interfaces import Unauthorized
330 from zope.security.proxy import removeSecurityProxy
331
332@@ -24,10 +25,12 @@
333 )
334 from lp.bugs.interfaces.bugsummary import IBugSummaryDimension
335 from lp.bugs.interfaces.bugsupervisor import IHasBugSupervisor
336+from lp.registry.enums import InformationType
337 from lp.registry.errors import (
338 CommercialSubscribersOnly,
339 OpenTeamLinkageError,
340 )
341+from lp.registry.interfaces.accesspolicy import IAccessPolicySource
342 from lp.registry.interfaces.oopsreferences import IHasOOPSReferences
343 from lp.registry.interfaces.person import (
344 CLOSED_TEAM_POLICY,
345@@ -343,6 +346,14 @@
346 product.setPrivateBugs(True, bug_supervisor)
347 self.assertTrue(product.private_bugs)
348
349+ def test_product_creation_creates_accesspolicies(self):
350+ # Creating a new product also creates AccessPolicies for it.
351+ product = self.factory.makeProduct()
352+ ap = getUtility(IAccessPolicySource).findByPillar((product,))
353+ expected = [
354+ InformationType.USERDATA, InformationType.EMBARGOEDSECURITY]
355+ self.assertContentEqual(expected, [policy.type for policy in ap])
356+
357
358 class TestProductFiles(TestCase):
359 """Tests for downloadable product files."""