Merge lp:~stevenk/launchpad/bugs-use-information_type-redux into lp:launchpad
- bugs-use-information_type-redux
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Steve Kowalik |
Approved revision: | no longer in the source branch. |
Merged at revision: | 15009 |
Proposed branch: | lp:~stevenk/launchpad/bugs-use-information_type-redux |
Merge into: | lp:launchpad |
Diff against target: |
399 lines (+96/-44) 9 files modified
lib/lp/bugs/adapters/bug.py (+16/-1) lib/lp/bugs/browser/tests/test_bugsubscription_views.py (+1/-5) lib/lp/bugs/mail/tests/test_handler.py (+2/-2) lib/lp/bugs/model/bug.py (+32/-23) lib/lp/bugs/model/tests/test_bug.py (+19/-0) lib/lp/bugs/tests/test_bug_mirror_access_triggers.py (+3/-3) lib/lp/registry/enums.py (+11/-0) lib/lp/registry/model/person.py (+2/-2) lib/lp/services/feeds/stories/xx-security.txt (+10/-8) |
To merge this branch: | bzr merge lp:~stevenk/launchpad/bugs-use-information_type-redux |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
William Grant | code | Approve | |
Review via email: mp+99236@code.launchpad.net |
Commit message
Resurrect use of IBug.informatio
Description of the change
Resurrect the rollback of using IBug.informatio
Rename IBug.{private,
Fixed some tests that assumed that IBug.{private,
I cleaned up a small amount of lint.
Further to those changes, I have created a new method, convert_
Preview Diff
1 | === modified file 'lib/lp/bugs/adapters/bug.py' | |||
2 | --- lib/lp/bugs/adapters/bug.py 2010-08-20 20:31:18 +0000 | |||
3 | +++ lib/lp/bugs/adapters/bug.py 2012-03-26 00:18:19 +0000 | |||
4 | @@ -1,4 +1,4 @@ | |||
6 | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the | 1 | # Copyright 2009-2012 Canonical Ltd. This software is licensed under the |
7 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). |
8 | 3 | 3 | ||
9 | 4 | """Resources having to do with Launchpad bugs.""" | 4 | """Resources having to do with Launchpad bugs.""" |
10 | @@ -7,11 +7,14 @@ | |||
11 | 7 | __all__ = [ | 7 | __all__ = [ |
12 | 8 | 'bugcomment_to_entry', | 8 | 'bugcomment_to_entry', |
13 | 9 | 'bugtask_to_privacy', | 9 | 'bugtask_to_privacy', |
14 | 10 | 'convert_to_information_type', | ||
15 | 10 | ] | 11 | ] |
16 | 11 | 12 | ||
17 | 12 | from lazr.restful.interfaces import IEntry | 13 | from lazr.restful.interfaces import IEntry |
18 | 13 | from zope.component import getMultiAdapter | 14 | from zope.component import getMultiAdapter |
19 | 14 | 15 | ||
20 | 16 | from lp.registry.enums import InformationType | ||
21 | 17 | |||
22 | 15 | 18 | ||
23 | 16 | def bugcomment_to_entry(comment, version): | 19 | def bugcomment_to_entry(comment, version): |
24 | 17 | """Will adapt to the bugcomment to the real IMessage. | 20 | """Will adapt to the bugcomment to the real IMessage. |
25 | @@ -22,9 +25,21 @@ | |||
26 | 22 | return getMultiAdapter( | 25 | return getMultiAdapter( |
27 | 23 | (comment.bugtask.bug.messages[comment.index], version), IEntry) | 26 | (comment.bugtask.bug.messages[comment.index], version), IEntry) |
28 | 24 | 27 | ||
29 | 28 | |||
30 | 25 | def bugtask_to_privacy(bugtask): | 29 | def bugtask_to_privacy(bugtask): |
31 | 26 | """Adapt the bugtask to the underlying bug (which implements IPrivacy). | 30 | """Adapt the bugtask to the underlying bug (which implements IPrivacy). |
32 | 27 | 31 | ||
33 | 28 | Needed because IBugTask does not implement IPrivacy. | 32 | Needed because IBugTask does not implement IPrivacy. |
34 | 29 | """ | 33 | """ |
35 | 30 | return bugtask.bug | 34 | return bugtask.bug |
36 | 35 | |||
37 | 36 | |||
38 | 37 | def convert_to_information_type(private, security_related): | ||
39 | 38 | if private and security_related: | ||
40 | 39 | return InformationType.EMBARGOEDSECURITY | ||
41 | 40 | elif security_related: | ||
42 | 41 | return InformationType.UNEMBARGOEDSECURITY | ||
43 | 42 | elif private: | ||
44 | 43 | return InformationType.USERDATA | ||
45 | 44 | else: | ||
46 | 45 | return InformationType.PUBLIC | ||
47 | 31 | 46 | ||
48 | === modified file 'lib/lp/bugs/browser/tests/test_bugsubscription_views.py' | |||
49 | --- lib/lp/bugs/browser/tests/test_bugsubscription_views.py 2012-03-24 04:42:32 +0000 | |||
50 | +++ lib/lp/bugs/browser/tests/test_bugsubscription_views.py 2012-03-26 00:18:19 +0000 | |||
51 | @@ -40,10 +40,6 @@ | |||
52 | 40 | from lp.testing.views import create_initialized_view | 40 | from lp.testing.views import create_initialized_view |
53 | 41 | 41 | ||
54 | 42 | 42 | ||
55 | 43 | ON = 'on' | ||
56 | 44 | OFF = None | ||
57 | 45 | |||
58 | 46 | |||
59 | 47 | class BugsubscriptionPrivacyTests(TestCaseWithFactory): | 43 | class BugsubscriptionPrivacyTests(TestCaseWithFactory): |
60 | 48 | 44 | ||
61 | 49 | layer = LaunchpadFunctionalLayer | 45 | layer = LaunchpadFunctionalLayer |
62 | @@ -52,7 +48,7 @@ | |||
63 | 52 | super(BugsubscriptionPrivacyTests, self).setUp() | 48 | super(BugsubscriptionPrivacyTests, self).setUp() |
64 | 53 | self.user = self.factory.makePerson() | 49 | self.user = self.factory.makePerson() |
65 | 54 | self.bug = self.factory.makeBug(owner=self.user) | 50 | self.bug = self.factory.makeBug(owner=self.user) |
67 | 55 | removeSecurityProxy(self.bug).private = True | 51 | removeSecurityProxy(self.bug).setPrivate(True, self.user) |
68 | 56 | 52 | ||
69 | 57 | def _assert_subscription_fails(self, team): | 53 | def _assert_subscription_fails(self, team): |
70 | 58 | with person_logged_in(self.user): | 54 | with person_logged_in(self.user): |
71 | 59 | 55 | ||
72 | === modified file 'lib/lp/bugs/mail/tests/test_handler.py' | |||
73 | --- lib/lp/bugs/mail/tests/test_handler.py 2012-03-24 04:42:32 +0000 | |||
74 | +++ lib/lp/bugs/mail/tests/test_handler.py 2012-03-26 00:18:19 +0000 | |||
75 | @@ -287,7 +287,7 @@ | |||
76 | 287 | notification = self.getLatestBugNotification() | 287 | notification = self.getLatestBugNotification() |
77 | 288 | bug = notification.bug | 288 | bug = notification.bug |
78 | 289 | self.assertEqual('unsecure code', bug.title) | 289 | self.assertEqual('unsecure code', bug.title) |
80 | 290 | self.assertEqual(True, bug.security_related) | 290 | self.assertTrue(bug.security_related) |
81 | 291 | self.assertEqual(['ajax'], bug.tags) | 291 | self.assertEqual(['ajax'], bug.tags) |
82 | 292 | self.assertEqual(1, len(bug.bugtasks)) | 292 | self.assertEqual(1, len(bug.bugtasks)) |
83 | 293 | self.assertEqual(project, bug.bugtasks[0].target) | 293 | self.assertEqual(project, bug.bugtasks[0].target) |
84 | @@ -310,7 +310,7 @@ | |||
85 | 310 | notification = self.getLatestBugNotification() | 310 | notification = self.getLatestBugNotification() |
86 | 311 | bug = notification.bug | 311 | bug = notification.bug |
87 | 312 | self.assertEqual('security issue', bug.title) | 312 | self.assertEqual('security issue', bug.title) |
89 | 313 | self.assertEqual(True, bug.security_related) | 313 | self.assertTrue(bug.security_related) |
90 | 314 | self.assertEqual(1, len(bug.bugtasks)) | 314 | self.assertEqual(1, len(bug.bugtasks)) |
91 | 315 | self.assertEqual(project, bug.bugtasks[0].target) | 315 | self.assertEqual(project, bug.bugtasks[0].target) |
92 | 316 | recipients = set() | 316 | recipients = set() |
93 | 317 | 317 | ||
94 | === modified file 'lib/lp/bugs/model/bug.py' | |||
95 | --- lib/lp/bugs/model/bug.py 2012-03-24 04:42:32 +0000 | |||
96 | +++ lib/lp/bugs/model/bug.py 2012-03-26 00:18:19 +0000 | |||
97 | @@ -89,6 +89,7 @@ | |||
98 | 89 | ) | 89 | ) |
99 | 90 | from lp.app.interfaces.launchpad import ILaunchpadCelebrities | 90 | from lp.app.interfaces.launchpad import ILaunchpadCelebrities |
100 | 91 | from lp.app.validators import LaunchpadValidationError | 91 | from lp.app.validators import LaunchpadValidationError |
101 | 92 | from lp.bugs.adapters.bug import convert_to_information_type | ||
102 | 92 | from lp.bugs.adapters.bugchange import ( | 93 | from lp.bugs.adapters.bugchange import ( |
103 | 93 | BranchLinkedToBug, | 94 | BranchLinkedToBug, |
104 | 94 | BranchUnlinkedFromBug, | 95 | BranchUnlinkedFromBug, |
105 | @@ -157,7 +158,11 @@ | |||
106 | 157 | ) | 158 | ) |
107 | 158 | from lp.code.interfaces.branchcollection import IAllBranches | 159 | from lp.code.interfaces.branchcollection import IAllBranches |
108 | 159 | from lp.hardwaredb.interfaces.hwdb import IHWSubmissionBugSet | 160 | from lp.hardwaredb.interfaces.hwdb import IHWSubmissionBugSet |
110 | 160 | from lp.registry.enums import InformationType | 161 | from lp.registry.enums import ( |
111 | 162 | InformationType, | ||
112 | 163 | PRIVATE_INFORMATION_TYPES, | ||
113 | 164 | SECURITY_INFORMATION_TYPES, | ||
114 | 165 | ) | ||
115 | 161 | from lp.registry.interfaces.distribution import IDistribution | 166 | from lp.registry.interfaces.distribution import IDistribution |
116 | 162 | from lp.registry.interfaces.distroseries import IDistroSeries | 167 | from lp.registry.interfaces.distroseries import IDistroSeries |
117 | 163 | from lp.registry.interfaces.person import ( | 168 | from lp.registry.interfaces.person import ( |
118 | @@ -347,12 +352,13 @@ | |||
119 | 347 | dbName='duplicateof', foreignKey='Bug', default=None) | 352 | dbName='duplicateof', foreignKey='Bug', default=None) |
120 | 348 | datecreated = UtcDateTimeCol(notNull=True, default=UTC_NOW) | 353 | datecreated = UtcDateTimeCol(notNull=True, default=UTC_NOW) |
121 | 349 | date_last_updated = UtcDateTimeCol(notNull=True, default=UTC_NOW) | 354 | date_last_updated = UtcDateTimeCol(notNull=True, default=UTC_NOW) |
123 | 350 | private = BoolCol(notNull=True, default=False) | 355 | _private = BoolCol(dbName='private', notNull=True, default=False) |
124 | 351 | date_made_private = UtcDateTimeCol(notNull=False, default=None) | 356 | date_made_private = UtcDateTimeCol(notNull=False, default=None) |
125 | 352 | who_made_private = ForeignKey( | 357 | who_made_private = ForeignKey( |
126 | 353 | dbName='who_made_private', foreignKey='Person', | 358 | dbName='who_made_private', foreignKey='Person', |
127 | 354 | storm_validator=validate_public_person, default=None) | 359 | storm_validator=validate_public_person, default=None) |
129 | 355 | security_related = BoolCol(notNull=True, default=False) | 360 | _security_related = BoolCol( |
130 | 361 | dbName='security_related', notNull=True, default=False) | ||
131 | 356 | information_type = EnumCol( | 362 | information_type = EnumCol( |
132 | 357 | enum=InformationType, default=InformationType.PUBLIC) | 363 | enum=InformationType, default=InformationType.PUBLIC) |
133 | 358 | 364 | ||
134 | @@ -389,6 +395,20 @@ | |||
135 | 389 | heat_last_updated = UtcDateTimeCol(default=None) | 395 | heat_last_updated = UtcDateTimeCol(default=None) |
136 | 390 | latest_patch_uploaded = UtcDateTimeCol(default=None) | 396 | latest_patch_uploaded = UtcDateTimeCol(default=None) |
137 | 391 | 397 | ||
138 | 398 | @property | ||
139 | 399 | def private(self): | ||
140 | 400 | if self.information_type: | ||
141 | 401 | return self.information_type in PRIVATE_INFORMATION_TYPES | ||
142 | 402 | else: | ||
143 | 403 | return self._private | ||
144 | 404 | |||
145 | 405 | @property | ||
146 | 406 | def security_related(self): | ||
147 | 407 | if self.information_type: | ||
148 | 408 | return self.information_type in SECURITY_INFORMATION_TYPES | ||
149 | 409 | else: | ||
150 | 410 | return self._security_related | ||
151 | 411 | |||
152 | 392 | @cachedproperty | 412 | @cachedproperty |
153 | 393 | def _subscriber_cache(self): | 413 | def _subscriber_cache(self): |
154 | 394 | """Caches known subscribers.""" | 414 | """Caches known subscribers.""" |
155 | @@ -1697,16 +1717,6 @@ | |||
156 | 1697 | 1717 | ||
157 | 1698 | return bugtask | 1718 | return bugtask |
158 | 1699 | 1719 | ||
159 | 1700 | def _setInformationType(self): | ||
160 | 1701 | if self.private and self.security_related: | ||
161 | 1702 | self.information_type = InformationType.EMBARGOEDSECURITY | ||
162 | 1703 | elif self.private: | ||
163 | 1704 | self.information_type = InformationType.USERDATA | ||
164 | 1705 | elif self.security_related: | ||
165 | 1706 | self.information_type = InformationType.UNEMBARGOEDSECURITY | ||
166 | 1707 | else: | ||
167 | 1708 | self.information_type = InformationType.PUBLIC | ||
168 | 1709 | |||
169 | 1710 | def setPrivacyAndSecurityRelated(self, private, security_related, who): | 1720 | def setPrivacyAndSecurityRelated(self, private, security_related, who): |
170 | 1711 | """ See `IBug`.""" | 1721 | """ See `IBug`.""" |
171 | 1712 | private_changed = False | 1722 | private_changed = False |
172 | @@ -1734,7 +1744,7 @@ | |||
173 | 1734 | raise BugCannotBePrivate( | 1744 | raise BugCannotBePrivate( |
174 | 1735 | "Multi-pillar bugs cannot be private.") | 1745 | "Multi-pillar bugs cannot be private.") |
175 | 1736 | private_changed = True | 1746 | private_changed = True |
177 | 1737 | self.private = private | 1747 | self._private = private |
178 | 1738 | 1748 | ||
179 | 1739 | if private: | 1749 | if private: |
180 | 1740 | self.who_made_private = who | 1750 | self.who_made_private = who |
181 | @@ -1750,14 +1760,15 @@ | |||
182 | 1750 | 1760 | ||
183 | 1751 | if self.security_related != security_related: | 1761 | if self.security_related != security_related: |
184 | 1752 | security_related_changed = True | 1762 | security_related_changed = True |
186 | 1753 | self.security_related = security_related | 1763 | self._security_related = security_related |
187 | 1754 | 1764 | ||
188 | 1755 | if private_changed or security_related_changed: | 1765 | if private_changed or security_related_changed: |
189 | 1756 | # Correct the heat for the bug immediately, so that we don't have | 1766 | # Correct the heat for the bug immediately, so that we don't have |
190 | 1757 | # to wait for the next calculation job for the adjusted heat. | 1767 | # to wait for the next calculation job for the adjusted heat. |
191 | 1758 | self.updateHeat() | 1768 | self.updateHeat() |
192 | 1759 | 1769 | ||
194 | 1760 | self._setInformationType() | 1770 | self.information_type = convert_to_information_type( |
195 | 1771 | self._private, self._security_related) | ||
196 | 1761 | 1772 | ||
197 | 1762 | if private_changed or security_related_changed: | 1773 | if private_changed or security_related_changed: |
198 | 1763 | changed_fields = [] | 1774 | changed_fields = [] |
199 | @@ -2829,9 +2840,6 @@ | |||
200 | 2829 | bug.subscribe(params.product.bug_supervisor, params.owner) | 2840 | bug.subscribe(params.product.bug_supervisor, params.owner) |
201 | 2830 | else: | 2841 | else: |
202 | 2831 | bug.subscribe(params.product.owner, params.owner) | 2842 | bug.subscribe(params.product.owner, params.owner) |
203 | 2832 | else: | ||
204 | 2833 | # nothing to do | ||
205 | 2834 | pass | ||
206 | 2835 | 2843 | ||
207 | 2836 | # Create the task on a product if one was passed. | 2844 | # Create the task on a product if one was passed. |
208 | 2837 | if params.product: | 2845 | if params.product: |
209 | @@ -2858,8 +2866,6 @@ | |||
210 | 2858 | if notify_event: | 2866 | if notify_event: |
211 | 2859 | notify(event) | 2867 | notify(event) |
212 | 2860 | 2868 | ||
213 | 2861 | bug._setInformationType() | ||
214 | 2862 | |||
215 | 2863 | # Calculate the bug's initial heat. | 2869 | # Calculate the bug's initial heat. |
216 | 2864 | bug.updateHeat() | 2870 | bug.updateHeat() |
217 | 2865 | 2871 | ||
218 | @@ -2906,11 +2912,14 @@ | |||
219 | 2906 | date_made_private=params.datecreated, | 2912 | date_made_private=params.datecreated, |
220 | 2907 | who_made_private=params.owner) | 2913 | who_made_private=params.owner) |
221 | 2908 | 2914 | ||
222 | 2915 | information_type = convert_to_information_type( | ||
223 | 2916 | params.private, params.security_related) | ||
224 | 2909 | bug = Bug( | 2917 | bug = Bug( |
225 | 2910 | title=params.title, description=params.description, | 2918 | title=params.title, description=params.description, |
227 | 2911 | private=params.private, owner=params.owner, | 2919 | _private=params.private, owner=params.owner, |
228 | 2912 | datecreated=params.datecreated, | 2920 | datecreated=params.datecreated, |
230 | 2913 | security_related=params.security_related, | 2921 | _security_related=params.security_related, |
231 | 2922 | information_type=information_type, | ||
232 | 2914 | **extra_params) | 2923 | **extra_params) |
233 | 2915 | 2924 | ||
234 | 2916 | if params.subscribe_owner: | 2925 | if params.subscribe_owner: |
235 | 2917 | 2926 | ||
236 | === modified file 'lib/lp/bugs/model/tests/test_bug.py' | |||
237 | --- lib/lp/bugs/model/tests/test_bug.py 2012-03-14 12:39:42 +0000 | |||
238 | +++ lib/lp/bugs/model/tests/test_bug.py 2012-03-26 00:18:19 +0000 | |||
239 | @@ -9,6 +9,7 @@ | |||
240 | 9 | ) | 9 | ) |
241 | 10 | 10 | ||
242 | 11 | from pytz import UTC | 11 | from pytz import UTC |
243 | 12 | from storm.expr import Join | ||
244 | 12 | from storm.store import Store | 13 | from storm.store import Store |
245 | 13 | from testtools.testcase import ExpectedException | 14 | from testtools.testcase import ExpectedException |
246 | 14 | from zope.component import getUtility | 15 | from zope.component import getUtility |
247 | @@ -970,6 +971,24 @@ | |||
248 | 970 | bug.setPrivate(True, bug.owner) | 971 | bug.setPrivate(True, bug.owner) |
249 | 971 | self.assertEqual(InformationType.USERDATA, bug.information_type) | 972 | self.assertEqual(InformationType.USERDATA, bug.information_type) |
250 | 972 | 973 | ||
251 | 974 | def test_information_type_does_not_leak(self): | ||
252 | 975 | # Make sure that bug notifications for private bugs do not leak to | ||
253 | 976 | # people with a subscription on the product. | ||
254 | 977 | product = self.factory.makeProduct() | ||
255 | 978 | with person_logged_in(product.owner): | ||
256 | 979 | product.addSubscription(product.owner, product.owner) | ||
257 | 980 | reporter = self.factory.makePerson() | ||
258 | 981 | bug = self.factory.makeBug( | ||
259 | 982 | private=True, product=product, owner=reporter) | ||
260 | 983 | recipients = Store.of(bug).using( | ||
261 | 984 | BugNotificationRecipient, | ||
262 | 985 | Join(BugNotification, BugNotification.bugID == bug.id)).find( | ||
263 | 986 | BugNotificationRecipient, | ||
264 | 987 | BugNotificationRecipient.bug_notificationID == | ||
265 | 988 | BugNotification.id) | ||
266 | 989 | self.assertEqual( | ||
267 | 990 | [reporter], [recipient.person for recipient in recipients]) | ||
268 | 991 | |||
269 | 973 | 992 | ||
270 | 974 | class TestBugPrivateAndSecurityRelatedUpdatesPrivateProject( | 993 | class TestBugPrivateAndSecurityRelatedUpdatesPrivateProject( |
271 | 975 | TestBugPrivateAndSecurityRelatedUpdatesMixin, TestCaseWithFactory): | 994 | TestBugPrivateAndSecurityRelatedUpdatesMixin, TestCaseWithFactory): |
272 | 976 | 995 | ||
273 | === modified file 'lib/lp/bugs/tests/test_bug_mirror_access_triggers.py' | |||
274 | --- lib/lp/bugs/tests/test_bug_mirror_access_triggers.py 2012-03-24 04:42:32 +0000 | |||
275 | +++ lib/lp/bugs/tests/test_bug_mirror_access_triggers.py 2012-03-26 00:18:19 +0000 | |||
276 | @@ -136,7 +136,7 @@ | |||
277 | 136 | bug = self.makeBugAndPolicies(private=True) | 136 | bug = self.makeBugAndPolicies(private=True) |
278 | 137 | self.assertIsNot( | 137 | self.assertIsNot( |
279 | 138 | None, getUtility(IAccessArtifactSource).find([bug]).one()) | 138 | None, getUtility(IAccessArtifactSource).find([bug]).one()) |
281 | 139 | bug.private = False | 139 | bug.setPrivate(False, bug.owner) |
282 | 140 | self.assertIs( | 140 | self.assertIs( |
283 | 141 | None, getUtility(IAccessArtifactSource).find([bug]).one()) | 141 | None, getUtility(IAccessArtifactSource).find([bug]).one()) |
284 | 142 | 142 | ||
285 | @@ -144,7 +144,7 @@ | |||
286 | 144 | bug = self.makeBugAndPolicies(private=False) | 144 | bug = self.makeBugAndPolicies(private=False) |
287 | 145 | self.assertIs( | 145 | self.assertIs( |
288 | 146 | None, getUtility(IAccessArtifactSource).find([bug]).one()) | 146 | None, getUtility(IAccessArtifactSource).find([bug]).one()) |
290 | 147 | bug.private = True | 147 | bug.setPrivate(True, bug.owner) |
291 | 148 | self.assertIsNot( | 148 | self.assertIsNot( |
292 | 149 | None, getUtility(IAccessArtifactSource).find([bug]).one()) | 149 | None, getUtility(IAccessArtifactSource).find([bug]).one()) |
293 | 150 | self.assertEqual((1, 1), self.assertMirrored(bug)) | 150 | self.assertEqual((1, 1), self.assertMirrored(bug)) |
294 | @@ -158,7 +158,7 @@ | |||
295 | 158 | self.assertContentEqual( | 158 | self.assertContentEqual( |
296 | 159 | [InformationType.USERDATA], | 159 | [InformationType.USERDATA], |
297 | 160 | self.getPolicyTypesForArtifact(artifact)) | 160 | self.getPolicyTypesForArtifact(artifact)) |
299 | 161 | bug.security_related = True | 161 | bug.setSecurityRelated(True, bug.owner) |
300 | 162 | self.assertEqual((1, 1), self.assertMirrored(bug)) | 162 | self.assertEqual((1, 1), self.assertMirrored(bug)) |
301 | 163 | self.assertContentEqual( | 163 | self.assertContentEqual( |
302 | 164 | [InformationType.EMBARGOEDSECURITY], | 164 | [InformationType.EMBARGOEDSECURITY], |
303 | 165 | 165 | ||
304 | === modified file 'lib/lp/registry/enums.py' | |||
305 | --- lib/lp/registry/enums.py 2012-03-24 04:42:32 +0000 | |||
306 | +++ lib/lp/registry/enums.py 2012-03-26 00:18:19 +0000 | |||
307 | @@ -9,7 +9,9 @@ | |||
308 | 9 | 'DistroSeriesDifferenceType', | 9 | 'DistroSeriesDifferenceType', |
309 | 10 | 'InformationType', | 10 | 'InformationType', |
310 | 11 | 'PersonTransferJobType', | 11 | 'PersonTransferJobType', |
311 | 12 | 'PRIVATE_INFORMATION_TYPES', | ||
312 | 12 | 'ProductJobType', | 13 | 'ProductJobType', |
313 | 14 | 'SECURITY_INFORMATION_TYPES', | ||
314 | 13 | 'SharingPermission', | 15 | 'SharingPermission', |
315 | 14 | ] | 16 | ] |
316 | 15 | 17 | ||
317 | @@ -61,6 +63,15 @@ | |||
318 | 61 | """) | 63 | """) |
319 | 62 | 64 | ||
320 | 63 | 65 | ||
321 | 66 | PRIVATE_INFORMATION_TYPES = ( | ||
322 | 67 | InformationType.EMBARGOEDSECURITY, InformationType.USERDATA, | ||
323 | 68 | InformationType.PROPRIETARY) | ||
324 | 69 | |||
325 | 70 | |||
326 | 71 | SECURITY_INFORMATION_TYPES = ( | ||
327 | 72 | InformationType.UNEMBARGOEDSECURITY, InformationType.EMBARGOEDSECURITY) | ||
328 | 73 | |||
329 | 74 | |||
330 | 64 | class SharingPermission(DBEnumeratedType): | 75 | class SharingPermission(DBEnumeratedType): |
331 | 65 | """Sharing permission. | 76 | """Sharing permission. |
332 | 66 | 77 | ||
333 | 67 | 78 | ||
334 | === modified file 'lib/lp/registry/model/person.py' | |||
335 | --- lib/lp/registry/model/person.py 2012-03-24 04:42:32 +0000 | |||
336 | +++ lib/lp/registry/model/person.py 2012-03-26 00:18:19 +0000 | |||
337 | @@ -1744,14 +1744,14 @@ | |||
338 | 1744 | Bug, | 1744 | Bug, |
339 | 1745 | Join(BugSubscription, BugSubscription.bug_id == Bug.id)), | 1745 | Join(BugSubscription, BugSubscription.bug_id == Bug.id)), |
340 | 1746 | where=And( | 1746 | where=And( |
342 | 1747 | Bug.private == True, | 1747 | Bug._private == True, |
343 | 1748 | BugSubscription.person_id == self.id)), | 1748 | BugSubscription.person_id == self.id)), |
344 | 1749 | Select( | 1749 | Select( |
345 | 1750 | Bug.id, | 1750 | Bug.id, |
346 | 1751 | tables=( | 1751 | tables=( |
347 | 1752 | Bug, | 1752 | Bug, |
348 | 1753 | Join(BugTask, BugTask.bugID == Bug.id)), | 1753 | Join(BugTask, BugTask.bugID == Bug.id)), |
350 | 1754 | where=And(Bug.private == True, BugTask.assignee == self.id)), | 1754 | where=And(Bug._private == True, BugTask.assignee == self.id)), |
351 | 1755 | limit=1)) | 1755 | limit=1)) |
352 | 1756 | if private_bugs_involved.rowcount: | 1756 | if private_bugs_involved.rowcount: |
353 | 1757 | raise TeamSubscriptionPolicyError( | 1757 | raise TeamSubscriptionPolicyError( |
354 | 1758 | 1758 | ||
355 | === modified file 'lib/lp/services/feeds/stories/xx-security.txt' | |||
356 | --- lib/lp/services/feeds/stories/xx-security.txt 2012-03-24 04:42:32 +0000 | |||
357 | +++ lib/lp/services/feeds/stories/xx-security.txt 2012-03-26 00:18:19 +0000 | |||
358 | @@ -1,16 +1,16 @@ | |||
360 | 1 | == Feeds do not display private bugs == | 1 | Feeds do not display private bugs |
361 | 2 | ================================= | ||
362 | 2 | 3 | ||
363 | 3 | Feeds never contain private bugs, as we are serving feeds over HTTP. | 4 | Feeds never contain private bugs, as we are serving feeds over HTTP. |
364 | 4 | First, set all the bugs to private. | 5 | First, set all the bugs to private. |
365 | 5 | 6 | ||
366 | 6 | >>> from zope.security.interfaces import Unauthorized | 7 | >>> from zope.security.interfaces import Unauthorized |
367 | 7 | >>> from BeautifulSoup import BeautifulStoneSoup as BSS | 8 | >>> from BeautifulSoup import BeautifulStoneSoup as BSS |
368 | 9 | >>> from lp.services.database.lpstorm import IStore | ||
369 | 10 | >>> import transaction | ||
370 | 8 | >>> from lp.bugs.model.bug import Bug | 11 | >>> from lp.bugs.model.bug import Bug |
376 | 9 | >>> bugs = Bug.select() | 12 | >>> IStore(Bug).find(Bug).set(_private=True) |
377 | 10 | >>> for bug in bugs: | 13 | >>> transaction.commit() |
373 | 11 | ... bug.private = True | ||
374 | 12 | >>> from lp.services.database.sqlbase import flush_database_updates | ||
375 | 13 | >>> flush_database_updates() | ||
378 | 14 | 14 | ||
379 | 15 | There should be zero entries in these feeds, since all the bugs are private. | 15 | There should be zero entries in these feeds, since all the bugs are private. |
380 | 16 | 16 | ||
381 | @@ -26,7 +26,8 @@ | |||
382 | 26 | >>> BSS(browser.contents)('entry') | 26 | >>> BSS(browser.contents)('entry') |
383 | 27 | [] | 27 | [] |
384 | 28 | 28 | ||
386 | 29 | >>> browser.open('http://feeds.launchpad.dev/~simple-team/latest-bugs.atom') | 29 | >>> browser.open( |
387 | 30 | ... 'http://feeds.launchpad.dev/~simple-team/latest-bugs.atom') | ||
388 | 30 | >>> BSS(browser.contents)('entry') | 31 | >>> BSS(browser.contents)('entry') |
389 | 31 | [] | 32 | [] |
390 | 32 | 33 | ||
391 | @@ -66,7 +67,8 @@ | |||
392 | 66 | >>> print extract_text(BSS(browser.contents)('tr')[0]) | 67 | >>> print extract_text(BSS(browser.contents)('tr')[0]) |
393 | 67 | Bugs for Foo Bar | 68 | Bugs for Foo Bar |
394 | 68 | 69 | ||
396 | 69 | >>> browser.open('http://feeds.launchpad.dev/~simple-team/latest-bugs.html') | 70 | >>> browser.open( |
397 | 71 | ... 'http://feeds.launchpad.dev/~simple-team/latest-bugs.html') | ||
398 | 70 | >>> len(BSS(browser.contents)('tr')) | 72 | >>> len(BSS(browser.contents)('tr')) |
399 | 71 | 1 | 73 | 1 |
400 | 72 | 74 |
251 + def test_informatio n_type_ does_not_ leak(self) : makeProduct( )
252 + product = self.factory.
Not entirely descriptive :)
Also:
10:52:57 < wgrant> StevenK: I think I mentioned this in the last review, but from the diff it looks like bug.private writes were previously permitted by the security policy, but I don't see any ZCML changes in this brnach to prevent that. security_ related aren't in the ZCML, so I'm not sure how to tell it "forbid anyone setting these"
10:58:14 < StevenK> wgrant: wgrant: private/
11:00:04 < wgrant> StevenK: Indeed. I wonder if the removeSecurityProxy is really required, then