Merge lp:~abentley/launchpad/milestone-spec-privacy into lp:launchpad

Proposed by Aaron Bentley on 2012-10-26
Status: Merged
Approved by: Aaron Bentley on 2012-10-26
Approved revision: no longer in the source branch.
Merged at revision: 16200
Proposed branch: lp:~abentley/launchpad/milestone-spec-privacy
Merge into: lp:launchpad
Diff against target: 100 lines (+39/-3)
3 files modified
lib/lp/registry/browser/tests/test_milestone.py (+17/-1)
lib/lp/registry/model/milestone.py (+6/-2)
lib/lp/registry/tests/test_milestone.py (+16/-0)
To merge this branch: bzr merge lp:~abentley/launchpad/milestone-spec-privacy
Reviewer Review Type Date Requested Status
Richard Harding (community) 2012-10-26 Approve on 2012-10-26
Review via email: mp+131560@code.launchpad.net

Commit Message

Milestone.getSpecifications respects spec privacy.

Description of the Change

= Summary =
Fix bug #1067531: private blueprints break milestone listings

== Proposed fix ==
Use get_specification_privacy_filter to filter out specifications not visible to the user.

== Pre-implementation notes ==
None

== LOC Rationale ==
Part of private projects

== Implementation details ==
None

== Tests ==
bin/test -t test_private_specifications -t test_getSpecifications_specification_privacy

== Demo and Q/A ==
Create a public project with a "Proprietary" specification sharing policy. Create a milestone. Create a blueprint targeted at that milestone. View the milestone index page. You should see it listed.

Log in as an unprivileged user. View the milestone index page. The specification should not be listed.

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/registry/tests/test_milestone.py
  lib/lp/registry/browser/tests/test_milestone.py
  lib/lp/registry/model/milestone.py

To post a comment you must log in.
Richard Harding (rharding) :
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/browser/tests/test_milestone.py'
2--- lib/lp/registry/browser/tests/test_milestone.py 2012-10-18 16:56:54 +0000
3+++ lib/lp/registry/browser/tests/test_milestone.py 2012-10-26 09:28:23 +0000
4@@ -8,12 +8,12 @@
5 import soupmatchers
6 from testtools.matchers import LessThan
7 from zope.component import getUtility
8-from zope.security.proxy import removeSecurityProxy
9
10 from lp.app.enums import InformationType
11 from lp.app.interfaces.launchpad import ILaunchpadCelebrities
12 from lp.bugs.interfaces.bugtask import IBugTaskSet
13 from lp.bugs.interfaces.bugtasksearch import BugTaskSearchParams
14+from lp.registry.enums import SpecificationSharingPolicy
15 from lp.registry.interfaces.accesspolicy import (
16 IAccessPolicyGrantSource,
17 IAccessPolicySource,
18@@ -101,6 +101,22 @@
19 browser.contents, soupmatchers.HTMLContains(
20 privacy_portlet_proprietary))
21
22+ def test_private_specifications(self):
23+ # Only specifications visible to the browser user are listed.
24+ owner = self.factory.makePerson()
25+ enum = SpecificationSharingPolicy
26+ product = self.factory.makeProduct(
27+ owner=owner, specification_sharing_policy=enum.PROPRIETARY)
28+ milestone = self.factory.makeMilestone(product=product)
29+ specification = self.factory.makeSpecification(
30+ information_type=InformationType.PROPRIETARY,
31+ milestone=milestone)
32+ with person_logged_in(None):
33+ browser = self.getViewBrowser(milestone, '+index', user=owner)
34+ self.assertIn(specification.name, browser.contents)
35+ with person_logged_in(None):
36+ browser = self.getViewBrowser(milestone, '+index')
37+
38
39 class TestAddMilestoneViews(TestCaseWithFactory):
40
41
42=== modified file 'lib/lp/registry/model/milestone.py'
43--- lib/lp/registry/model/milestone.py 2012-10-22 13:55:44 +0000
44+++ lib/lp/registry/model/milestone.py 2012-10-26 09:28:23 +0000
45@@ -38,7 +38,10 @@
46 from zope.interface import implements
47
48 from lp.app.errors import NotFoundError
49-from lp.blueprints.model.specification import Specification
50+from lp.blueprints.model.specification import (
51+ get_specification_privacy_filter,
52+ Specification,
53+ )
54 from lp.blueprints.model.specificationworkitem import SpecificationWorkItem
55 from lp.bugs.interfaces.bugsummary import IBugSummaryDimension
56 from lp.bugs.interfaces.bugtarget import IHasBugs
57@@ -172,7 +175,8 @@
58 SpecificationWorkItem.milestone_id.is_in(
59 milestones),
60 SpecificationWorkItem.deleted == False)),
61- all=True)))
62+ all=True)),
63+ get_specification_privacy_filter(user))
64 results.config(distinct=True)
65 ordered_results = results.order_by(Desc(Specification.priority),
66 Specification.definition_status,
67
68=== modified file 'lib/lp/registry/tests/test_milestone.py'
69--- lib/lp/registry/tests/test_milestone.py 2012-10-22 10:09:48 +0000
70+++ lib/lp/registry/tests/test_milestone.py 2012-10-26 09:28:23 +0000
71@@ -23,6 +23,7 @@
72 from lp.registry.enums import (
73 BugSharingPolicy,
74 SharingPermission,
75+ SpecificationSharingPolicy,
76 )
77 from lp.registry.interfaces.distribution import IDistributionSet
78 from lp.registry.interfaces.milestone import (
79@@ -504,6 +505,21 @@
80 self.assertContentEqual([spec],
81 milestone.getSpecifications(owner))
82
83+ def test_getSpecifications_specification_privacy(self):
84+ # Only specifications visible to the specified user are listed.
85+ owner = self.factory.makePerson()
86+ enum = SpecificationSharingPolicy
87+ product = self.factory.makeProduct(
88+ owner=owner, specification_sharing_policy=enum.PROPRIETARY)
89+ milestone = self.factory.makeMilestone(product=product)
90+ specification = self.factory.makeSpecification(
91+ information_type=InformationType.PROPRIETARY,
92+ milestone=milestone)
93+ self.assertIn(
94+ specification, list(milestone.getSpecifications(owner)))
95+ self.assertNotIn(
96+ specification, list(milestone.getSpecifications(None)))
97+
98 def test_bugtasks_milestone_privacy(self):
99 # Ensure bugtasks respects milestone privacy.
100 # This looks wrong, because the bugtask is actually public, and we