Merge lp:~jml/launchpad/p3a-private-team into lp:launchpad

Proposed by Jonathan Lange
Status: Merged
Approved by: Curtis Hovey
Approved revision: no longer in the source branch.
Merged at revision: 15397
Proposed branch: lp:~jml/launchpad/p3a-private-team
Merge into: lp:launchpad
Prerequisite: lp:~jml/launchpad/validate-ppa-owner
Diff against target: 164 lines (+62/-14)
5 files modified
lib/lp/registry/model/person.py (+3/-0)
lib/lp/soyuz/browser/archive.py (+6/-13)
lib/lp/soyuz/model/archive.py (+3/-1)
lib/lp/soyuz/tests/test_archive.py (+32/-0)
lib/lp/soyuz/tests/test_person_createppa.py (+18/-0)
To merge this branch: bzr merge lp:~jml/launchpad/p3a-private-team
Reviewer Review Type Date Requested Status
Benji York (community) code Approve
Curtis Hovey (community) code Approve
Review via email: mp+109600@code.launchpad.net

Commit message

IPerson.createPPA allows creating private PPAs for private teams.

Description of the change

IPerson.createPPA allows creating PPAs via the API. At the moment, it's impossible to use it to create a private PPA for a private team, despite the fact that Launchpad's web UI allows you to do just that.

This branch brings createPPA up-to-date, and changes the browser code to go via createPPA.

To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote :

This is good to land, thank you.

review: Approve (code)
Revision history for this message
Benji York (benji) wrote :

Looks good.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/model/person.py'
2--- lib/lp/registry/model/person.py 2012-06-11 09:17:44 +0000
3+++ lib/lp/registry/model/person.py 2012-06-12 11:04:26 +0000
4@@ -2981,6 +2981,9 @@
5 errors = validate_ppa(self, name, private)
6 if errors:
7 raise PPACreationError(errors)
8+ # XXX cprov 2009-03-27 bug=188564: We currently only create PPAs
9+ # for Ubuntu distribution. PPA creation should be revisited when we
10+ # start supporting other distribution (debian, mainly).
11 ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
12 return getUtility(IArchiveSet).new(
13 owner=self, purpose=ArchivePurpose.PPA,
14
15=== modified file 'lib/lp/soyuz/browser/archive.py'
16--- lib/lp/soyuz/browser/archive.py 2012-06-11 09:17:44 +0000
17+++ lib/lp/soyuz/browser/archive.py 2012-06-12 11:04:26 +0000
18@@ -137,7 +137,6 @@
19 from lp.soyuz.browser.widgets.archive import PPANameWidget
20 from lp.soyuz.enums import (
21 ArchivePermissionType,
22- ArchivePurpose,
23 ArchiveStatus,
24 PackageCopyPolicy,
25 PackagePublishingStatus,
26@@ -1976,7 +1975,8 @@
27 'The default PPA is already activated. Please specify a '
28 'name for the new PPA and resubmit the form.')
29
30- errors = validate_ppa(self.context, proposed_name)
31+ errors = validate_ppa(
32+ self.context, proposed_name, private=self.is_private_team)
33 if errors is not None:
34 self.addError(errors)
35
36@@ -1988,21 +1988,14 @@
37 @action(_("Activate"), name="activate")
38 def save_action(self, action, data):
39 """Activate a PPA and moves to its page."""
40-
41 # 'name' field is omitted from the form data for default PPAs and
42 # it's dealt with by IArchive.new(), which will use the default
43 # PPA name.
44 name = data.get('name', None)
45-
46- # XXX: jml: I think this ought to call createPPA.
47- # XXX cprov 2009-03-27 bug=188564: We currently only create PPAs
48- # for Ubuntu distribution. PPA creation should be revisited when we
49- # start supporting other distribution (debian, mainly).
50- ppa = getUtility(IArchiveSet).new(
51- owner=self.context, purpose=ArchivePurpose.PPA,
52- distribution=self.ubuntu, name=name,
53- displayname=data['displayname'], description=data['description'])
54-
55+ displayname = data['displayname']
56+ description = data['description']
57+ ppa = self.context.createPPA(
58+ name, displayname, description, private=self.is_private_team)
59 self.next_url = canonical_url(ppa)
60
61 @property
62
63=== modified file 'lib/lp/soyuz/model/archive.py'
64--- lib/lp/soyuz/model/archive.py 2012-06-12 04:05:44 +0000
65+++ lib/lp/soyuz/model/archive.py 2012-06-12 11:04:26 +0000
66@@ -2103,8 +2103,10 @@
67 # which determines who is granted launchpad.Commercial
68 # permissions.
69 role = IPersonRoles(creator)
70- if not (role.in_admin or role.in_commercial_admin):
71+ if not (owner.private or role.in_admin or role.in_commercial_admin):
72 return '%s is not allowed to make private PPAs' % creator.name
73+ elif owner.private:
74+ return 'Private teams may not have public archives.'
75 if owner.is_team and (
76 owner.subscriptionpolicy in OPEN_TEAM_POLICY):
77 return "Open teams cannot have PPAs."
78
79=== modified file 'lib/lp/soyuz/tests/test_archive.py'
80--- lib/lp/soyuz/tests/test_archive.py 2012-06-12 04:05:44 +0000
81+++ lib/lp/soyuz/tests/test_archive.py 2012-06-12 11:04:26 +0000
82@@ -27,10 +27,12 @@
83 from lp.registry.interfaces.distribution import IDistributionSet
84 from lp.registry.interfaces.person import (
85 IPersonSet,
86+ PersonVisibility,
87 TeamSubscriptionPolicy,
88 )
89 from lp.registry.interfaces.pocket import PackagePublishingPocket
90 from lp.registry.interfaces.series import SeriesStatus
91+from lp.registry.interfaces.teammembership import TeamMembershipStatus
92 from lp.services.database.sqlbase import sqlvalues
93 from lp.services.features.testing import FeatureFixture
94 from lp.services.job.interfaces.job import JobStatus
95@@ -1802,6 +1804,36 @@
96 ppa_owner = self.factory.makePerson()
97 self.assertIsNone(validate_ppa(ppa_owner, None))
98
99+ def test_private_team_private_ppa(self):
100+ # Folk with launchpad.Edit on a private team can make private PPAs for
101+ # that team, regardless of whether they have super-powers.a
102+ team_owner = self.factory.makePerson()
103+ private_team = self.factory.makeTeam(
104+ owner=team_owner, visibility=PersonVisibility.PRIVATE,
105+ subscription_policy=TeamSubscriptionPolicy.RESTRICTED)
106+ team_admin = self.factory.makePerson()
107+ with person_logged_in(team_owner):
108+ private_team.addMember(
109+ team_admin, team_owner, status=TeamMembershipStatus.ADMIN)
110+ with person_logged_in(team_admin):
111+ result = validate_ppa(private_team, 'ppa', private=True)
112+ self.assertIsNone(result)
113+
114+ def test_private_team_public_ppa(self):
115+ # No one can make a public PPA for a private team.
116+ team_owner = self.factory.makePerson()
117+ private_team = self.factory.makeTeam(
118+ owner=team_owner, visibility=PersonVisibility.PRIVATE,
119+ subscription_policy=TeamSubscriptionPolicy.RESTRICTED)
120+ team_admin = self.factory.makePerson()
121+ with person_logged_in(team_owner):
122+ private_team.addMember(
123+ team_admin, team_owner, status=TeamMembershipStatus.ADMIN)
124+ with person_logged_in(team_admin):
125+ result = validate_ppa(private_team, 'ppa', private=False)
126+ self.assertEqual(
127+ 'Private teams may not have public archives.', result)
128+
129
130 class TestGetComponentsForSeries(TestCaseWithFactory):
131 """Tests for Archive.getComponentsForSeries."""
132
133=== modified file 'lib/lp/soyuz/tests/test_person_createppa.py'
134--- lib/lp/soyuz/tests/test_person_createppa.py 2012-06-10 09:06:08 +0000
135+++ lib/lp/soyuz/tests/test_person_createppa.py 2012-06-12 11:04:26 +0000
136@@ -7,6 +7,11 @@
137
138 from zope.security.interfaces import Unauthorized
139 from lp.registry.errors import PPACreationError
140+from lp.registry.interfaces.person import (
141+ PersonVisibility,
142+ TeamSubscriptionPolicy,
143+ )
144+from lp.registry.interfaces.teammembership import TeamMembershipStatus
145 from lp.testing import (
146 celebrity_logged_in,
147 person_logged_in,
148@@ -49,3 +54,16 @@
149 with person_logged_in(person):
150 ppa = person.createPPA(suppress_subscription_notifications=True)
151 self.assertEqual(True, ppa.suppress_subscription_notifications)
152+
153+ def test_private_team_private_ppa(self):
154+ team_owner = self.factory.makePerson()
155+ private_team = self.factory.makeTeam(
156+ owner=team_owner, visibility=PersonVisibility.PRIVATE,
157+ subscription_policy=TeamSubscriptionPolicy.RESTRICTED)
158+ team_admin = self.factory.makePerson()
159+ with person_logged_in(team_owner):
160+ private_team.addMember(
161+ team_admin, team_owner, status=TeamMembershipStatus.ADMIN)
162+ with person_logged_in(team_admin):
163+ ppa = private_team.createPPA(private=True)
164+ self.assertEqual(True, ppa.private)