Merge lp:~julian-edwards/launchpad/p3a-sub-private-teams-bug-597783 into lp:launchpad

Proposed by Julian Edwards
Status: Merged
Merged at revision: 11067
Proposed branch: lp:~julian-edwards/launchpad/p3a-sub-private-teams-bug-597783
Merge into: lp:launchpad
Diff against target: 93 lines (+70/-1)
2 files modified
lib/canonical/launchpad/security.py (+13/-1)
lib/lp/soyuz/tests/test_archive_subscriptions.py (+57/-0)
To merge this branch: bzr merge lp:~julian-edwards/launchpad/p3a-sub-private-teams-bug-597783
Reviewer Review Type Date Requested Status
Henning Eggers (community) code Approve
Māris Fogels (community) Approve
Curtis Hovey (community) code Approve
Review via email: mp+28621@code.launchpad.net

Description of the change

= Summary =
Subscribers of P3As owned by private teams should be able to see the team

== Proposed fix ==
https://bugs.edge.launchpad.net/soyuz/+bug/597783

Currently a subscriber to a private PPA owned by a private team will get a 403
when they visit their +archivesubscriptions page because the security adapter
still prevents access from seeing that team, but which is required to build a
URL to the repo location in the subscription token.

This branch changes the security adapter to take the subscriptions a user
might have, and allows launchpad.View to the team if it has a PPA and the user
has a subscription.

== Pre-implementation notes ==
Talked to Curtis, we both agreed there's not much else we can do here.

== Implementation details ==
As above.

== Tests ==
bin/test -cvv test_archive_subscriptions

== Demo and Q/A ==
QA Plan:

 * Create a private team
 * Give the team a private PPA
 * Confirm that Joe User can't see the team, but can see his
+archivesubscriptions
 * Subscribe Joe User to the PPA
 * Confirm that Joe User can see the subscription on his +archivesubscriptions
page

= Launchpad lint =

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  lib/lp/soyuz/tests/test_archive_subscriptions.py
  lib/canonical/launchpad/security.py

To post a comment you must log in.
Revision history for this message
Julian Edwards (julian-edwards) wrote :

/me grumbles at the stupid person picker

Maris, that's an r-c stamp I need from you please, you already gave me one on Friday for this but I'd like it if you can make it official.

Cheers.

Revision history for this message
Curtis Hovey (sinzui) wrote :

Hi Julian. Thanks for working on this. I have one trivial remark: There should be two blank lines before `def test_suite():`. I think we should consider this for an RC.

review: Approve (code)
Revision history for this message
Māris Fogels (mars) wrote :

Looks good to me, release-critical=mars

review: Approve
Revision history for this message
Henning Eggers (henninge) wrote :

Thanks for the fix and the improvement. Now just remove the unused import for IArchiveSet. ;)

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/canonical/launchpad/security.py'
--- lib/canonical/launchpad/security.py 2010-06-24 18:52:56 +0000
+++ lib/canonical/launchpad/security.py 2010-06-28 14:56:38 +0000
@@ -14,7 +14,6 @@
14from canonical.launchpad.interfaces.account import IAccount14from canonical.launchpad.interfaces.account import IAccount
15from canonical.launchpad.interfaces.emailaddress import IEmailAddress15from canonical.launchpad.interfaces.emailaddress import IEmailAddress
16from lp.registry.interfaces.announcement import IAnnouncement16from lp.registry.interfaces.announcement import IAnnouncement
17from lp.soyuz.interfaces.archive import IArchive
18from lp.soyuz.interfaces.archivepermission import (17from lp.soyuz.interfaces.archivepermission import (
19 IArchivePermissionSet)18 IArchivePermissionSet)
20from lp.soyuz.interfaces.archiveauthtoken import IArchiveAuthToken19from lp.soyuz.interfaces.archiveauthtoken import IArchiveAuthToken
@@ -735,6 +734,19 @@
735 if (invitee.is_team and734 if (invitee.is_team and
736 invitee in user.person.getAdministratedTeams()):735 invitee in user.person.getAdministratedTeams()):
737 return True736 return True
737
738 if (self.obj.is_team
739 and self.obj.visibility == PersonVisibility.PRIVATE):
740 # Grant visibility to people with subscriptions on a private
741 # team's private PPA.
742 subscriptions = getUtility(
743 IArchiveSubscriberSet).getBySubscriber(user.person)
744 subscriber_archive_ids = set(
745 sub.archive.id for sub in subscriptions)
746 team_ppa_ids = set(
747 ppa.id for ppa in self.obj.ppas if ppa.private)
748 if len(subscriber_archive_ids.intersection(team_ppa_ids)) > 0:
749 return True
738 return False750 return False
739751
740752
741753
=== added file 'lib/lp/soyuz/tests/test_archive_subscriptions.py'
--- lib/lp/soyuz/tests/test_archive_subscriptions.py 1970-01-01 00:00:00 +0000
+++ lib/lp/soyuz/tests/test_archive_subscriptions.py 2010-06-28 14:56:38 +0000
@@ -0,0 +1,57 @@
1# Copyright 2009 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4"""Test Archive features."""
5
6import unittest
7
8from zope.security.interfaces import Unauthorized
9
10from canonical.testing import DatabaseFunctionalLayer
11
12from lp.registry.interfaces.person import PersonVisibility
13from lp.testing import login_person, TestCaseWithFactory
14
15
16class TestArchiveSubscriptions(TestCaseWithFactory):
17 """Edge-case tests for private PPA subscribers.
18
19 See also lib/lp/soyuz/stories/ppa/xx-private-ppa-subscription-stories.txt
20 """
21
22 layer = DatabaseFunctionalLayer
23
24 def setUp(self):
25 """Create a test archive."""
26 super(TestArchiveSubscriptions, self).setUp()
27 self.private_team = self.factory.makeTeam(
28 visibility=PersonVisibility.PRIVATE, name="subscribertest")
29 login_person(self.private_team.teamowner)
30 self.archive = self.factory.makeArchive(
31 private=True, owner=self.private_team)
32 self.subscriber = self.factory.makePerson()
33
34 def test_subscriber_can_access_private_team_ppa(self):
35 # As per bug 597783, we need to make sure a subscriber can see
36 # a private team's PPA after they have been given a subscription.
37 # This is essentially allowing access for the subscriber to see
38 # the private team.
39
40 def get_name():
41 return self.archive.owner.name
42
43 # Before a subscription, accessing the team name will raise.
44 login_person(self.subscriber)
45 self.assertRaises(Unauthorized, get_name)
46
47 login_person(self.private_team.teamowner)
48 self.archive.newSubscription(
49 self.subscriber, registrant=self.archive.owner)
50
51 # When a subscription exists, it's fine.
52 login_person(self.subscriber)
53 self.assertEqual(self.archive.owner.name, "subscribertest")
54
55
56def test_suite():
57 return unittest.TestLoader().loadTestsFromName(__name__)