Code review comment for lp:~jcsackett/launchpad/private-bugs-without-supervision

Revision history for this message
j.c.sackett (jcsackett) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Here's a clean diff of just what's changed since the previously
approved MP.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJPjbI4AAoJEJvCBZ3E2NUPRvkH/iKGm03AAwiU4ftu2Crgb872
sBgMsDUKeDKcrvZqZC7U14OtMLeQew6Fuha6rUZghjHW+m+kQinyclKl6zdtZZAj
7zlcok4eNYQP2UMXp19OJIQkW1RUQPLqzA8x1og7Lz+KggiaSxtD9fG/QE4msGoE
vqGy59tJMZx3FwBmlsQzowNFHcQlFYNeUYGa80r7zx0ZfXJZoBnxc6RMjP5FGQwL
wk1aq20sRzfhKZxCz9aR/fP4JEAxjpqFN5/jaVgSM8TL8yU7UhHalofDwEyfm+iA
hvjjds4/gv+sjkfO/ckMQIx9hSkNqjekeKnzfLwQs4GCKPdrJ8jCuKwoAzl923k=
=RZ+X
-----END PGP SIGNATURE-----

1=== modified file 'lib/lp/bugs/doc/bugnotification-sending.txt'
2--- lib/lp/bugs/doc/bugnotification-sending.txt 2012-04-17 17:59:54 +0000
3+++ lib/lp/bugs/doc/bugnotification-sending.txt 2012-04-17 18:01:41 +0000
4@@ -756,9 +756,10 @@
5
6 >>> for message in trigger_and_get_email_messages(bug_three):
7 ... print message['To'], message.get_all('X-Launchpad-Bug-Private')
8+ foo.bar@canonical.com ['yes']
9+ mark@example.com ['yes']
10 test@canonical.com ['yes']
11
12-
13 The X-Launchpad-Bug-Security-Vulnerability header
14 -------------------------------------------------
15
16@@ -772,6 +773,8 @@
17 >>> for message in trigger_and_get_email_messages(bug_three):
18 ... print message['To'], (
19 ... message.get_all('X-Launchpad-Bug-Security-Vulnerability'))
20+ foo.bar@canonical.com ['no']
21+ mark@example.com ['no']
22 test@canonical.com ['no']
23
24 The presence of the security flag on a bug is, surprise, denoted by a
25@@ -786,6 +789,8 @@
26 >>> for message in trigger_and_get_email_messages(bug_three):
27 ... print message['To'], (
28 ... message.get_all('X-Launchpad-Bug-Security-Vulnerability'))
29+ foo.bar@canonical.com ['yes']
30+ mark@example.com ['yes']
31 test@canonical.com ['yes']
32
33
34
35=== modified file 'lib/lp/bugs/doc/bugsubscription.txt'
36--- lib/lp/bugs/doc/bugsubscription.txt 2012-04-17 17:58:37 +0000
37+++ lib/lp/bugs/doc/bugsubscription.txt 2012-04-17 18:01:41 +0000
38@@ -380,17 +380,7 @@
39 ()
40
41 When a bug is marked private, specific people like the bugtask bug supervisors
42-will be automatically subscribed, and only specifically allowed existing
43-direct subscribers (eg bugtask pillar maintainers) will remain subscribed.
44-
45-We currently use a feature flag to control who is subscribed when a bug is
46-made private.
47-
48- >>> from lp.services.features.testing import FeatureFixture
49- >>> feature_flag = {
50- ... 'disclosure.enhanced_private_bug_subscriptions.enabled': 'on'}
51- >>> flags = FeatureFixture(feature_flag)
52- >>> flags.setUp()
53+will be automatically subscribed.
54
55 >>> from zope.event import notify
56
57@@ -438,26 +428,20 @@
58 >>> print_displayname(linux_source_bug.getDirectSubscribers())
59 Foo Bar
60 Mark Shuttleworth
61+ Robert Collins
62+ Ubuntu Team
63
64 >>> print_displayname(linux_source_bug.getIndirectSubscribers())
65 Martin Pitt
66 No Privileges Person
67- Robert Collins
68 Sample Person
69 Scott James Remnant
70- Ubuntu Team
71
72 >>> print_displayname(linux_source_bug.getAlsoNotifiedSubscribers())
73 Martin Pitt
74 No Privileges Person
75- Robert Collins
76 Sample Person
77 Scott James Remnant
78- Ubuntu Team
79-
80-Clean up the feature flag.
81-
82- >>> flags.cleanUp()
83
84 To find out which email addresses should receive a notification email on
85 a bug, and why, IBug.getBugNotificationRecipients() assembles an
86@@ -472,8 +456,8 @@
87 [('foo.bar@canonical.com', 'Subscriber'),
88 ('mark@example.com', 'Subscriber'),
89 ('no-priv@canonical.com', u'Subscriber (linux-source-2.6.15 in Ubuntu)'),
90- ('robertc@robertcollins.net', u'Subscriber (Mozilla Firefox)'),
91- ('support@ubuntu.com', u'Subscriber (Ubuntu) @ubuntu-team'),
92+ ('robertc@robertcollins.net', 'Subscriber'),
93+ ('support@ubuntu.com', u'Subscriber @ubuntu-team'),
94 ('test@canonical.com', 'Assignee')]
95
96 If IBug.getBugNotificationRecipients() is passed a BugNotificationLevel
97@@ -486,8 +470,8 @@
98 >>> [(address, recipients.getReason(address)[1]) for address in addresses]
99 [('foo.bar@canonical.com', 'Subscriber'),
100 ('mark@example.com', 'Subscriber'),
101- ('robertc@robertcollins.net', u'Subscriber (Mozilla Firefox)'),
102- ('support@ubuntu.com', u'Subscriber (Ubuntu) @ubuntu-team'),
103+ ('robertc@robertcollins.net', 'Subscriber'),
104+ ('support@ubuntu.com', u'Subscriber @ubuntu-team'),
105 ('test@canonical.com', 'Assignee')]
106
107 When Sample Person is unsubscribed from linux_source_bug, he is no
108@@ -501,8 +485,8 @@
109 >>> [(address, recipients.getReason(address)[1]) for address in addresses]
110 [('foo.bar@canonical.com', 'Subscriber'),
111 ('mark@example.com', 'Subscriber'),
112- ('robertc@robertcollins.net', u'Subscriber (Mozilla Firefox)'),
113- ('support@ubuntu.com', u'Subscriber (Ubuntu) @ubuntu-team'),
114+ ('robertc@robertcollins.net', 'Subscriber'),
115+ ('support@ubuntu.com', u'Subscriber @ubuntu-team'),
116 ('test@canonical.com', 'Assignee')]
117
118 ...but remains included for the level LIFECYCLE.
119@@ -515,8 +499,8 @@
120 [('foo.bar@canonical.com', 'Subscriber'),
121 ('mark@example.com', 'Subscriber'),
122 ('no-priv@canonical.com', u'Subscriber (linux-source-2.6.15 in Ubuntu)'),
123- ('robertc@robertcollins.net', u'Subscriber (Mozilla Firefox)'),
124- ('support@ubuntu.com', u'Subscriber (Ubuntu) @ubuntu-team'),
125+ ('robertc@robertcollins.net', 'Subscriber'),
126+ ('support@ubuntu.com', u'Subscriber @ubuntu-team'),
127 ('test@canonical.com', 'Assignee')]
128
129 To find out if someone is already directly subscribed to a bug, call
130
131=== modified file 'lib/lp/bugs/doc/initial-bug-contacts.txt'
132--- lib/lp/bugs/doc/initial-bug-contacts.txt 2012-04-17 17:58:37 +0000
133+++ lib/lp/bugs/doc/initial-bug-contacts.txt 2012-04-17 18:01:41 +0000
134@@ -288,16 +288,6 @@
135 u'Sample Person', u'Steve Alexander', u'Ubuntu Gnome Team',
136 u'Ubuntu Team']
137
138-
139-We currently use a feature flag to control who is subscribed when a bug is
140-made private.
141-
142- >>> from lp.services.features.testing import FeatureFixture
143- >>> feature_flag = {
144- ... 'disclosure.enhanced_private_bug_subscriptions.enabled': 'on'}
145- >>> flags = FeatureFixture(feature_flag)
146- >>> flags.setUp()
147-
148 If a bug is private, no changes are made to the subscriber list when a
149 bug is reassigned to a different package.
150
151@@ -329,13 +319,9 @@
152 the unallowed subscribers are removed:
153
154 >>> subscriber_names(bug_one_in_ubuntu_firefox.bug)
155- [u'Foo Bar', u'Mark Shuttleworth', u'Sample Person',
156+ [u'Foo Bar', u'Sample Person',
157 u'Steve Alexander', u'Ubuntu Team']
158
159-Clean up the feature flag.
160-
161- >>> flags.cleanUp()
162-
163
164 Product Bug Supervisors and Bug Tasks
165 -------------------------------------
166
167=== modified file 'lib/lp/bugs/doc/security-teams.txt'
168--- lib/lp/bugs/doc/security-teams.txt 2012-04-17 17:58:37 +0000
169+++ lib/lp/bugs/doc/security-teams.txt 2012-04-17 18:01:41 +0000
170@@ -280,17 +280,7 @@
171
172
173 When a bug becomes security-related, the security contacts for the pillars it
174-affects are subscribed to it. This happens regardless of whether the feature
175-flag is set.
176-
177-We currently use a feature flag to control who is subscribed when a bug is
178-made security related.
179-
180- >>> from lp.services.features.testing import FeatureFixture
181- >>> feature_flag = {
182- ... 'disclosure.enhanced_private_bug_subscriptions.enabled': 'on'}
183- >>> security_flags = FeatureFixture(feature_flag)
184- >>> security_flags.setUp()
185+affects are subscribed to it.
186
187 >>> from zope.event import notify
188 >>> from lazr.lifecycle.event import ObjectModifiedEvent
189@@ -317,30 +307,3 @@
190 Bug Reporter
191 Distribution Security Contact
192 Product Security Contact
193-
194-Clean up the feature flag.
195-
196- >>> security_flags.cleanUp()
197-
198-And once more without the feature flag.
199-
200- >>> product = factory.makeProduct()
201- >>> product.security_contact = factory.makePerson(
202- ... displayname='Product Security Contact')
203- >>> distribution = factory.makeDistribution()
204- >>> distribution.security_contact = factory.makePerson(
205- ... displayname='Distribution Security Contact')
206- >>> reporter = factory.makePerson(displayname=u'Bug Reporter')
207- >>> bug = factory.makeBug(product=product, owner=reporter)
208- >>> bug.addTask(owner=reporter, target=distribution)
209- <BugTask ...>
210- >>> old_state = Snapshot(bug, providing=IBug)
211- >>> bug.setSecurityRelated(True, getUtility(ILaunchBag).user)
212- True
213- >>> notify(ObjectModifiedEvent(bug, old_state, ['security_related']))
214- >>> for subscriber_name in sorted(
215- ... s.displayname for s in bug.getDirectSubscribers()):
216- ... print subscriber_name
217- Bug Reporter
218- Distribution Security Contact
219- Product Security Contact
220
221=== modified file 'lib/lp/bugs/model/bug.py'
222--- lib/lp/bugs/model/bug.py 2012-04-17 18:00:24 +0000
223+++ lib/lp/bugs/model/bug.py 2012-04-17 18:01:41 +0000
224@@ -1740,9 +1740,11 @@
225 if information_type in PRIVATE_INFORMATION_TYPES:
226 self.who_made_private = who
227 self.date_made_private = UTC_NOW
228+ missing_subscribers = set([who, self.owner])
229 else:
230 self.who_made_private = None
231 self.date_made_private = None
232+ missing_subscribers = set()
233 # XXX: This should be a bulk update. RBC 20100827
234 # bug=https://bugs.launchpad.net/storm/+bug/625071
235 for attachment in self.attachments_unpopulated:
236@@ -1751,7 +1753,6 @@
237 self.updateHeat()
238
239 # There are several people we need to ensure are subscribed.
240- missing_subscribers = set([who, self.owner])
241 # If the information type is userdata, we need to check for bug
242 # supervisors who aren't subscribed and should be. If there is no
243 # bug supervisor, we need to subscribe the maintainer.
244@@ -1774,8 +1775,10 @@
245 missing_subscribers.add(pillar.owner)
246
247 for s in missing_subscribers:
248- subscriptions = get_structural_subscriptions_for_bug(self, s)
249- if subscriptions.is_empty():
250+ # Don't subscribe someone if they're already subscribed via a
251+ # team.
252+ already_subscribed_teams = self.getSubscribersForPerson(s)
253+ if already_subscribed_teams.is_empty():
254 self.subscribe(s, who)
255
256 self.information_type = information_type
257
258=== modified file 'lib/lp/bugs/model/tests/test_bug.py'
259--- lib/lp/bugs/model/tests/test_bug.py 2012-04-17 18:00:24 +0000
260+++ lib/lp/bugs/model/tests/test_bug.py 2012-04-17 18:01:41 +0000
261@@ -567,14 +567,6 @@
262
263 layer = DatabaseFunctionalLayer
264
265- def setUp(self):
266- super(TestBugPrivateAndSecurityRelatedUpdatesMixin, self).setUp()
267- f_flag_str = 'disclosure.enhanced_private_bug_subscriptions.enabled'
268- feature_flag = {f_flag_str: 'on'}
269- flags = FeatureFixture(feature_flag)
270- flags.setUp()
271- self.addCleanup(flags.cleanUp)
272-
273 def test_setPrivate_subscribes_person_who_makes_bug_private(self):
274 # When setPrivate(True) is called on a bug, the person who is
275 # marking the bug private is subscribed to the bug.
276@@ -589,8 +581,8 @@
277 # marking the bug private will not be subscribed if they're
278 # already a member of a team which is a direct subscriber.
279 bug = self.factory.makeBug()
280- team = self.factory.makeTeam()
281- person = team.teamowner
282+ person = self.factory.makePerson(name='teamowner')
283+ team = self.factory.makeTeam(owner=person, name='team')
284 with person_logged_in(person):
285 bug.subscribe(team, person)
286 bug.setPrivate(True, person)
287@@ -632,78 +624,71 @@
288 return (bug, bug_owner, naked_bugtask_a, naked_bugtask_b,
289 naked_default_bugtask)
290
291- def test_setPrivateTrueAndSecurityRelatedTrue(self):
292- # When a bug is marked as private=true and security_related=true, the
293- # direct subscribers should include:
294+ def test_transition_to_EMBARGOEDSECURITY_information_type(self):
295+ # When a bug is marked as EMBARGOEDSECURITY, the direct subscribers
296+ # should include:
297 # - the bug reporter
298 # - the bugtask pillar security contacts (if set)
299 # - the person changing the state
300 # - and bug/pillar owners, drivers if they are already subscribed
301- # If the bug is for a private project, then other direct subscribers
302- # should be unsubscribed.
303
304 (bug, bug_owner, bugtask_a, bugtask_b, default_bugtask) = (
305 self.createBugTasksAndSubscribers())
306 initial_subscribers = set((
307- self.factory.makePerson(), bugtask_a.owner, bug_owner,
308- bugtask_a.pillar.security_contact, bugtask_a.pillar.driver))
309+ self.factory.makePerson(name='subscriber'), bugtask_a.owner,
310+ bug_owner, bugtask_a.pillar.security_contact,
311+ bugtask_a.pillar.driver))
312+ initial_subscribers.update(bug.getDirectSubscribers())
313
314 with person_logged_in(bug_owner):
315 for subscriber in initial_subscribers:
316 bug.subscribe(subscriber, bug_owner)
317- who = self.factory.makePerson()
318+ who = self.factory.makePerson(name='who')
319 bug.transitionToInformationType(
320 InformationType.EMBARGOEDSECURITY, who=who)
321 subscribers = bug.getDirectSubscribers()
322+ initial_subscribers.update(bug.getDirectSubscribers())
323 expected_subscribers = set((
324 bugtask_a.owner,
325- default_bugtask.pillar.bug_supervisor,
326 default_bugtask.pillar.driver,
327 default_bugtask.pillar.security_contact,
328 bug_owner, who))
329- if not self.private_project:
330- expected_subscribers.update(initial_subscribers)
331+ expected_subscribers.update(initial_subscribers)
332 self.assertContentEqual(expected_subscribers, subscribers)
333
334- def test_setPrivateTrueAndSecurityRelatedFalse(self):
335- # When a bug is marked as private=true and security_related=false, the
336- # direct subscribers should include:
337+ def test_transition_to_USERDATA_information_type(self):
338+ # When a bug is marked as USERDATA, the direct subscribers should
339+ # include:
340 # - the bug reporter
341 # - the bugtask pillar bug supervisors (if set)
342 # - the person changing the state
343 # - and bug/pillar owners, drivers if they are already subscribed
344- # If the bug is for a private project, then other direct subscribers
345- # should be unsubscribed.
346
347 (bug, bug_owner, bugtask_a, bugtask_b, default_bugtask) = (
348 self.createBugTasksAndSubscribers(private_security_related=True))
349 initial_subscribers = set((
350- self.factory.makePerson(), bug_owner,
351+ self.factory.makePerson(name='subscriber'), bug_owner,
352 bugtask_a.pillar.security_contact, bugtask_a.pillar.driver))
353
354 with person_logged_in(bug_owner):
355 for subscriber in initial_subscribers:
356 bug.subscribe(subscriber, bug_owner)
357- who = self.factory.makePerson()
358+ who = self.factory.makePerson(name='who')
359 bug.transitionToInformationType(InformationType.USERDATA, who)
360 subscribers = bug.getDirectSubscribers()
361 expected_subscribers = set((
362 default_bugtask.pillar.bug_supervisor,
363 default_bugtask.pillar.driver,
364 bug_owner, who))
365- if not self.private_project:
366- expected_subscribers.update(initial_subscribers)
367- expected_subscribers.remove(bugtask_a.pillar.security_contact)
368+ expected_subscribers.update(initial_subscribers)
369 self.assertContentEqual(expected_subscribers, subscribers)
370
371- def test_setPrivateFalseAndSecurityRelatedTrue(self):
372- # When a bug is marked as private=false and security_related=true, the
373- # direct subscribers should include:
374+ def test_transition_to_UNEMBARGOEDSECURITY_information_type(self):
375+ # When a security bug is unembargoed, direct subscribers should
376+ # include:
377 # - the bug reporter
378 # - the bugtask pillar security contacts (if set)
379 # - and bug/pillar owners, drivers if they are already subscribed
380- # If the bug is for a private project, then other direct subscribers
381- # should be unsubscribed.
382
383 (bug, bug_owner, bugtask_a, bugtask_b, default_bugtask) = (
384 self.createBugTasksAndSubscribers(private_security_related=True))
385@@ -715,7 +700,7 @@
386 with person_logged_in(bug_owner):
387 for subscriber in initial_subscribers:
388 bug.subscribe(subscriber, bug_owner)
389- who = self.factory.makePerson()
390+ who = self.factory.makePerson(name='who')
391 bug.transitionToInformationType(
392 InformationType.UNEMBARGOEDSECURITY, who)
393 subscribers = bug.getDirectSubscribers()
394@@ -723,36 +708,33 @@
395 default_bugtask.pillar.driver,
396 default_bugtask.pillar.security_contact,
397 bug_owner))
398- if not self.private_project:
399- expected_subscribers.update(initial_subscribers)
400- expected_subscribers.remove(default_bugtask.pillar.bug_supervisor)
401+ expected_subscribers.update(initial_subscribers)
402 self.assertContentEqual(expected_subscribers, subscribers)
403
404- def test_setPrivateFalseAndSecurityRelatedFalse(self):
405- # When a bug is marked as private=false and security_related=false,
406- # any existing subscriptions are left alone.
407+ def test_transition_to_PUBLIC_information_type(self):
408+ # Subscriptions aren't altered when a bug is transitioned to the
409+ # PUBLIC information type.
410
411 (bug, bug_owner, bugtask_a, bugtask_b, default_bugtask) = (
412 self.createBugTasksAndSubscribers(private_security_related=True))
413 initial_subscribers = set((
414- self.factory.makePerson(), bug_owner,
415+ self.factory.makePerson(name='subscriber'), bug_owner,
416 bugtask_a.pillar.security_contact, bugtask_a.pillar.driver))
417
418 with person_logged_in(bug_owner):
419 for subscriber in initial_subscribers:
420 bug.subscribe(subscriber, bug_owner)
421- who = self.factory.makePerson()
422- expected_direct_subscribers = set(bug.getDirectSubscribers())
423+ who = self.factory.makePerson(name='who')
424+ subscribers_before_public = set(bug.getDirectSubscribers())
425 bug.transitionToInformationType(InformationType.PUBLIC, who)
426- subscribers = set(bug.getDirectSubscribers())
427- expected_direct_subscribers.difference_update(
428- (default_bugtask.pillar.security_contact,
429- default_bugtask.pillar.bug_supervisor,
430- bugtask_a.pillar.security_contact))
431- self.assertContentEqual(expected_direct_subscribers, subscribers)
432+ subscribers_after_public = set(bug.getDirectSubscribers())
433+ self.assertContentEqual(
434+ subscribers_before_public,
435+ subscribers_after_public)
436
437 def test_setPillarOwnerSubscribedIfNoBugSupervisor(self):
438- # The pillar owner is subscribed if the bug supervisor is not set.
439+ # The pillar owner is subscribed if the bug supervisor is not set and
440+ # the bug is marked as USERDATA.
441
442 bug_owner = self.factory.makePerson(name='bugowner')
443 bug = self.factory.makeBug(owner=bug_owner)
444@@ -766,18 +748,19 @@
445 subscribers)
446
447 def test_setPillarOwnerSubscribedIfNoSecurityContact(self):
448- # The pillar owner is subscribed if the security contact is not set.
449+ # The pillar owner is subscribed if the security contact is not set
450+ # and the bug is marked as EMBARGOEDSECURITY.
451
452 bug_owner = self.factory.makePerson(name='bugowner')
453 bug = self.factory.makeBug(owner=bug_owner)
454 with person_logged_in(bug_owner):
455- who = self.factory.makePerson()
456+ who = self.factory.makePerson(name='who')
457 bug.transitionToInformationType(
458- InformationType.UNEMBARGOEDSECURITY, who)
459+ InformationType.EMBARGOEDSECURITY, who)
460 subscribers = bug.getDirectSubscribers()
461 naked_bugtask = removeSecurityProxy(bug).default_bugtask
462 self.assertContentEqual(
463- set((naked_bugtask.pillar.owner, bug_owner)),
464+ set((naked_bugtask.pillar.owner, bug_owner, who)),
465 subscribers)
466
467 def _fetch_notifications(self, bug, reason_header):
468@@ -833,32 +816,6 @@
469 actual_recipients.append(recipient.person)
470 self.assertContentEqual(expected_recipients, actual_recipients)
471
472- def test_bugSupervisorUnsubscribedIfBugMadePublic(self):
473- # The bug supervisors are unsubscribed if a bug is made public and an
474- # email is sent telling them they have been unsubscribed.
475-
476- (bug, bug_owner, bugtask_a, bugtask_b, default_bugtask) = (
477- self.createBugTasksAndSubscribers(private_security_related=True))
478-
479- with person_logged_in(bug_owner):
480- bug.subscribe(default_bugtask.pillar.bug_supervisor, bug_owner)
481- who = self.factory.makePerson(name="who")
482- bug.transitionToInformationType(
483- InformationType.UNEMBARGOEDSECURITY, who)
484- subscribers = bug.getDirectSubscribers()
485- self.assertNotIn(
486- default_bugtask.pillar.bug_supervisor, subscribers)
487-
488- expected_recipients = [
489- default_bugtask.pillar.bug_supervisor,
490- ]
491- expected_body_text = '** This bug is no longer private'
492- expected_reason_body = ('You received this bug notification '
493- 'because you are a bug supervisor.')
494- self._check_notifications(
495- bug, expected_recipients, expected_body_text,
496- expected_reason_body, False, True, 'Bug Supervisor')
497-
498 def test_structural_bug_supervisor_becomes_direct_on_private(self):
499 # If a bug supervisor has a structural subscription to the bug, and
500 # the bug is marked as private, the supervisor should get a direct
501@@ -876,31 +833,6 @@
502 bug.transitionToInformationType(InformationType.USERDATA, who)
503 self.assertTrue(bug_supervisor in bug.getDirectSubscribers())
504
505- def test_securityContactUnsubscribedIfBugNotSecurityRelated(self):
506- # The security contacts are unsubscribed if a bug has security_related
507- # set to false and an email is sent telling them they have been
508- # unsubscribed.
509-
510- (bug, bug_owner, bugtask_a, bugtask_b, default_bugtask) = (
511- self.createBugTasksAndSubscribers(private_security_related=True))
512-
513- with person_logged_in(bug_owner):
514- bug.subscribe(bugtask_a.pillar.security_contact, bug_owner)
515- who = self.factory.makePerson(name="who")
516- bug.transitionToInformationType(InformationType.USERDATA, who)
517- subscribers = bug.getDirectSubscribers()
518- self.assertFalse(bugtask_a.pillar.security_contact in subscribers)
519-
520- expected_recipients = [
521- bugtask_a.pillar.security_contact,
522- ]
523- expected_body_text = '** This bug is no longer security related'
524- expected_reason_body = ('You received this bug notification '
525- 'because you are a security contact.')
526- self._check_notifications(
527- bug, expected_recipients, expected_body_text,
528- expected_reason_body, True, False, 'Security Contact')
529-
530
531 class TestBugPrivacy(TestCaseWithFactory):
532
533
534=== modified file 'lib/lp/bugs/tests/test_bug_mirror_access_triggers.py'
535--- lib/lp/bugs/tests/test_bug_mirror_access_triggers.py 2012-04-17 17:58:37 +0000
536+++ lib/lp/bugs/tests/test_bug_mirror_access_triggers.py 2012-04-17 18:01:41 +0000
537@@ -141,7 +141,9 @@
538 bug.setPrivate(True, bug.owner)
539 self.assertIsNot(
540 None, getUtility(IAccessArtifactSource).find([bug]).one())
541- self.assertEqual((1, 1), self.assertMirrored(bug))
542+ # There are two grants--one for the reporter, one for the product
543+ # owner or supervisor (if set). There is only one policy, USERDATA.
544+ self.assertEqual((2, 1), self.assertMirrored(bug))
545
546 def test_security_related(self):
547 # Setting the security_related flag uses EMBARGOEDSECURITY
548@@ -153,7 +155,9 @@
549 [InformationType.USERDATA],
550 self.getPolicyTypesForArtifact(artifact))
551 bug.setSecurityRelated(True, bug.owner)
552- self.assertEqual((1, 1), self.assertMirrored(bug))
553+ # Both the reporter and either the product owner or the product's
554+ # security contact have grants.
555+ self.assertEqual((2, 1), self.assertMirrored(bug))
556 self.assertContentEqual(
557 [InformationType.EMBARGOEDSECURITY],
558 self.getPolicyTypesForArtifact(artifact))
559
560=== modified file 'lib/lp/bugs/tests/test_bugvisibility.py'
561--- lib/lp/bugs/tests/test_bugvisibility.py 2012-04-17 17:59:54 +0000
562+++ lib/lp/bugs/tests/test_bugvisibility.py 2012-04-17 18:01:41 +0000
563@@ -88,72 +88,3 @@
564 def test_publicBugAnonUser(self):
565 # Since the bug is private, the anonymous user cannot see it.
566 self.assertFalse(self.bug.userCanView(None))
567-
568-
569-class TestPrivateBugVisibilityAfterTransition(TestCaseWithFactory):
570- """Test visibility for a public bug, set to private."""
571-
572- layer = DatabaseFunctionalLayer
573-
574- def setUp(self):
575- super(TestPrivateBugVisibilityAfterTransition, self).setUp()
576- self.product_owner = self.factory.makePerson(name="productowner")
577- self.maintainer = self.factory.makeTeam(
578- name="maintainer",
579- owner=self.product_owner,
580- subscription_policy=TeamSubscriptionPolicy.RESTRICTED)
581- self.maintainer_member = self.factory.makePerson(
582- name="maintainermember")
583- self.owner = self.factory.makePerson(name="bugowner")
584- self.product = self.factory.makeProduct(
585- name="regular-product", owner=self.maintainer)
586- self.bug = self.factory.makeBug(
587- owner=self.owner, product=self.product)
588-
589- self.bug_team_member = self.factory.makePerson(name="bugteammember")
590- self.bug_team = self.factory.makeTeam(
591- name="bugteam",
592- owner=self.product_owner)
593-
594- with celebrity_logged_in('admin'):
595- self.maintainer.addMember(
596- self.maintainer_member,
597- self.product_owner)
598- self.bug_team.addMember(self.bug_team_member, self.product_owner)
599-
600- def _makePrivate(self):
601- with celebrity_logged_in('admin'):
602- self.bug.setPrivate(private=True, who=self.product_owner)
603-
604- @contextmanager
605- def _setupSupervisor(self):
606- with celebrity_logged_in('admin'):
607- self.product.setBugSupervisor(
608- bug_supervisor=self.bug_team,
609- user=self.product_owner)
610- yield
611- with celebrity_logged_in('admin'):
612- self.product.setBugSupervisor(
613- bug_supervisor=None,
614- user=self.product_owner)
615-
616- def test_bug_supervisor_can_see_bug(self):
617- with self._setupSupervisor():
618- self._makePrivate()
619- self.assertTrue(self.bug.userCanView(self.bug_team_member))
620-
621- def test_reporter_can_see(self):
622- self._makePrivate()
623- self.assertTrue(self.bug.userCanView(self.owner))
624-
625- def test_maintainer_can_see_without_supervisor(self):
626- # If no bug supervisor is set, the maintainer is given access.
627- self._makePrivate()
628- self.assertTrue(self.bug.userCanView(self.maintainer_member))
629-
630- def test_assignee_can_see(self):
631- bug_assignee = self.factory.makePerson(name="bugassignee")
632- with celebrity_logged_in('admin'):
633- self.bug.default_bugtask.transitionToAssignee(bug_assignee)
634- self._makePrivate()
635- self.assertTrue(self.bug.userCanView(bug_assignee))

« Back to merge proposal