← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~wgrant/launchpad/bug-1124352 into lp:launchpad

 

William Grant has proposed merging lp:~wgrant/launchpad/bug-1124352 into lp:launchpad.

Commit message:
Open up Archive:+admin to a new launchpad-ppa-self-admins team.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~wgrant/launchpad/bug-1124352/+merge/163270

This branch opens up Archive:+admin (mostly build virt/arch and privacy configuration) to PPA owners who are in a new celebrity team, ~launchpad-ppa-self-admins. This allows trusted users create non-virtual and private PPAs without also being able to see all private PPAs and projects.

I switched Archive's launchpad.Commercial to launchpad.Admin, a permission granted to people who hold launchpad.Edit and are members of a new ~launchpad-ppa-self-admins celebrity, as well as to commercial admins regardless of the archive.

I also dropped buildd_secret from Archive:+admin; it's sensitive and now automatically generated, so it's safer to just not have it there. It's not available on the API either, so only buildds and generate-ppa-htaccess get to see it.
-- 
https://code.launchpad.net/~wgrant/launchpad/bug-1124352/+merge/163270
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wgrant/launchpad/bug-1124352 into lp:launchpad.
=== modified file 'database/sampledata/current-dev.sql'
--- database/sampledata/current-dev.sql	2013-05-01 18:39:38 +0000
+++ database/sampledata/current-dev.sql	2013-05-10 07:07:29 +0000
@@ -1685,6 +1685,7 @@
 INSERT INTO person (id, displayname, teamowner, teamdescription, name, language, fti, defaultmembershipperiod, defaultrenewalperiod, subscriptionpolicy, merged, datecreated, homepage_content, icon, mugshot, hide_email_addresses, creation_rationale, creation_comment, registrant, logo, renewal_policy, personal_standing, personal_standing_reason, mail_resumption_date, mailing_list_auto_subscribe_policy, mailing_list_receive_duplicates, visibility, verbose_bugnotifications, account, description) VALUES (243631, 'Techboard Owner', NULL, NULL, 'techboard-owner', NULL, NULL, NULL, NULL, 1, NULL, '2009-08-04 10:50:39.370018', NULL, NULL, NULL, true, 1, NULL, NULL, NULL, 10, 0, NULL, NULL, 1, true, 1, true, 2436243, NULL);
 INSERT INTO person (id, displayname, teamowner, teamdescription, name, language, fti, defaultmembershipperiod, defaultrenewalperiod, subscriptionpolicy, merged, datecreated, homepage_content, icon, mugshot, hide_email_addresses, creation_rationale, creation_comment, registrant, logo, renewal_policy, personal_standing, personal_standing_reason, mail_resumption_date, mailing_list_auto_subscribe_policy, mailing_list_receive_duplicates, visibility, verbose_bugnotifications, account, description) VALUES (243632, 'Ubuntu Technical Board', 243631, NULL, 'techboard', NULL, NULL, NULL, NULL, 3, NULL, '2009-08-04 10:50:39.370018', NULL, NULL, NULL, false, NULL, NULL, NULL, NULL, 10, 0, NULL, NULL, 1, true, 1, true, NULL, NULL);
 INSERT INTO person (id, displayname, teamowner, teamdescription, name, language, fti, defaultmembershipperiod, defaultrenewalperiod, subscriptionpolicy, merged, datecreated, homepage_content, icon, mugshot, hide_email_addresses, creation_rationale, creation_comment, registrant, logo, renewal_policy, personal_standing, personal_standing_reason, mail_resumption_date, mailing_list_auto_subscribe_policy, mailing_list_receive_duplicates, visibility, verbose_bugnotifications, account, description) VALUES (243651, 'Software-center-agent', NULL, NULL, 'software-center-agent', NULL, NULL, NULL, NULL, 1, NULL, '2010-07-12 09:48:27.198885', NULL, NULL, NULL, false, 1, NULL, NULL, NULL, 10, 0, NULL, NULL, 1, true, 1, true, 243637, NULL);
+INSERT INTO person (id, displayname, teamowner, teamdescription, name, language, fti, defaultmembershipperiod, defaultrenewalperiod, subscriptionpolicy, merged, datecreated, homepage_content, icon, mugshot, hide_email_addresses, creation_rationale, creation_comment, registrant, logo, renewal_policy, personal_standing, personal_standing_reason, mail_resumption_date, mailing_list_auto_subscribe_policy, mailing_list_receive_duplicates, visibility, verbose_bugnotifications, account, description) VALUES (243652, 'Launchpad PPA Self Admins', 243621, NULL, 'launchpad-ppa-self-admins', NULL, NULL, NULL, NULL, 3, NULL, '2013-05-10 05:40:34.64279', NULL, NULL, NULL, false, NULL, NULL, NULL, NULL, 10, 0, NULL, NULL, 1, true, 1, true, NULL, NULL);
 
 
 ALTER TABLE person ENABLE TRIGGER ALL;
@@ -5223,6 +5224,7 @@
 INSERT INTO lp_person (id, displayname, teamowner, teamdescription, name, language, fti, defaultmembershipperiod, defaultrenewalperiod, subscriptionpolicy, merged, datecreated, addressline1, addressline2, organization, city, province, country, postcode, phone, homepage_content, icon, mugshot, hide_email_addresses, creation_rationale, creation_comment, registrant, logo, renewal_policy, personal_standing, personal_standing_reason, mail_resumption_date, mailing_list_auto_subscribe_policy, mailing_list_receive_duplicates, visibility, verbose_bugnotifications, account) VALUES (243631, 'Techboard Owner', NULL, NULL, 'techboard-owner', NULL, NULL, NULL, NULL, 1, NULL, '2009-08-04 10:50:39.370018', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, true, 1, NULL, NULL, NULL, 10, 0, NULL, NULL, 1, true, 1, true, 2436243);
 INSERT INTO lp_person (id, displayname, teamowner, teamdescription, name, language, fti, defaultmembershipperiod, defaultrenewalperiod, subscriptionpolicy, merged, datecreated, addressline1, addressline2, organization, city, province, country, postcode, phone, homepage_content, icon, mugshot, hide_email_addresses, creation_rationale, creation_comment, registrant, logo, renewal_policy, personal_standing, personal_standing_reason, mail_resumption_date, mailing_list_auto_subscribe_policy, mailing_list_receive_duplicates, visibility, verbose_bugnotifications, account) VALUES (243632, 'Ubuntu Technical Board', 243631, NULL, 'techboard', NULL, NULL, NULL, NULL, 3, NULL, '2009-08-04 10:50:39.370018', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, NULL, NULL, NULL, NULL, 10, 0, NULL, NULL, 1, true, 1, true, NULL);
 INSERT INTO lp_person (id, displayname, teamowner, teamdescription, name, language, fti, defaultmembershipperiod, defaultrenewalperiod, subscriptionpolicy, merged, datecreated, addressline1, addressline2, organization, city, province, country, postcode, phone, homepage_content, icon, mugshot, hide_email_addresses, creation_rationale, creation_comment, registrant, logo, renewal_policy, personal_standing, personal_standing_reason, mail_resumption_date, mailing_list_auto_subscribe_policy, mailing_list_receive_duplicates, visibility, verbose_bugnotifications, account) VALUES (243651, 'Software-center-agent', NULL, NULL, 'software-center-agent', NULL, NULL, NULL, NULL, 1, NULL, '2010-07-12 09:48:27.198885', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, 1, NULL, NULL, NULL, 10, 0, NULL, NULL, 1, true, 1, true, 243637);
+INSERT INTO lp_person (id, displayname, teamowner, teamdescription, name, language, fti, defaultmembershipperiod, defaultrenewalperiod, subscriptionpolicy, merged, datecreated, addressline1, addressline2, organization, city, province, country, postcode, phone, homepage_content, icon, mugshot, hide_email_addresses, creation_rationale, creation_comment, registrant, logo, renewal_policy, personal_standing, personal_standing_reason, mail_resumption_date, mailing_list_auto_subscribe_policy, mailing_list_receive_duplicates, visibility, verbose_bugnotifications, account) VALUES (243652, 'Launchpad PPA Self Admins', 243621, NULL, 'launchpad-ppa-self-admins', NULL, NULL, NULL, NULL, 3, NULL, '2013-05-10 05:40:34.64279', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, NULL, NULL, NULL, NULL, 10, 0, NULL, NULL, 1, true, 1, true, NULL);
 
 
 ALTER TABLE lp_person ENABLE TRIGGER ALL;
@@ -5440,6 +5442,9 @@
 INSERT INTO lp_teamparticipation (id, team, person) VALUES (221, 243632, 243632);
 INSERT INTO lp_teamparticipation (id, team, person) VALUES (222, 243632, 243631);
 INSERT INTO lp_teamparticipation (id, team, person) VALUES (253, 243651, 243651);
+INSERT INTO lp_teamparticipation (id, team, person) VALUES (254, 243652, 243652);
+INSERT INTO lp_teamparticipation (id, team, person) VALUES (256, 243652, 243621);
+INSERT INTO lp_teamparticipation (id, team, person) VALUES (257, 243652, 243622);
 
 
 ALTER TABLE lp_teamparticipation ENABLE TRIGGER ALL;
@@ -10153,6 +10158,7 @@
 INSERT INTO teammembership (id, person, team, status, date_joined, date_expires, last_changed_by, last_change_comment, proposed_by, acknowledged_by, reviewed_by, date_proposed, date_last_changed, date_acknowledged, date_reviewed, proponent_comment, acknowledger_comment, reviewer_comment, date_created) VALUES (103, 243622, 243630, 2, '2009-07-09 11:58:38.122886', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2009-07-09 11:58:38.122886');
 INSERT INTO teammembership (id, person, team, status, date_joined, date_expires, last_changed_by, last_change_comment, proposed_by, acknowledged_by, reviewed_by, date_proposed, date_last_changed, date_acknowledged, date_reviewed, proponent_comment, acknowledger_comment, reviewer_comment, date_created) VALUES (104, 243623, 243630, 2, '2009-07-09 11:58:38.122886', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2009-07-09 11:58:38.122886');
 INSERT INTO teammembership (id, person, team, status, date_joined, date_expires, last_changed_by, last_change_comment, proposed_by, acknowledged_by, reviewed_by, date_proposed, date_last_changed, date_acknowledged, date_reviewed, proponent_comment, acknowledger_comment, reviewer_comment, date_created) VALUES (105, 243631, 243632, 3, '2009-08-04 10:50:47.920683', NULL, NULL, NULL, 243631, NULL, 243631, '2009-08-04 10:50:47.920683', NULL, NULL, '2009-08-04 10:50:47.920683', NULL, NULL, NULL, '2009-08-04 10:50:39.370018');
+INSERT INTO teammembership (id, person, team, status, date_joined, date_expires, last_changed_by, last_change_comment, proposed_by, acknowledged_by, reviewed_by, date_proposed, date_last_changed, date_acknowledged, date_reviewed, proponent_comment, acknowledger_comment, reviewer_comment, date_created) VALUES (107, 243621, 243652, 3, '2013-05-10 05:44:12.01517', NULL, NULL, NULL, 16, NULL, 16, '2013-05-10 05:44:12.01517', NULL, NULL, '2013-05-10 05:44:12.01517', NULL, NULL, NULL, '2013-05-10 05:44:11.87651');
 
 
 ALTER TABLE teammembership ENABLE TRIGGER ALL;
@@ -10357,6 +10363,9 @@
 INSERT INTO teamparticipation (id, team, person) VALUES (221, 243632, 243632);
 INSERT INTO teamparticipation (id, team, person) VALUES (222, 243632, 243631);
 INSERT INTO teamparticipation (id, team, person) VALUES (253, 243651, 243651);
+INSERT INTO teamparticipation (id, team, person) VALUES (254, 243652, 243652);
+INSERT INTO teamparticipation (id, team, person) VALUES (256, 243652, 243621);
+INSERT INTO teamparticipation (id, team, person) VALUES (257, 243652, 243622);
 
 
 ALTER TABLE teamparticipation ENABLE TRIGGER ALL;

=== modified file 'database/sampledata/current.sql'
--- database/sampledata/current.sql	2013-05-01 18:39:38 +0000
+++ database/sampledata/current.sql	2013-05-10 07:07:29 +0000
@@ -1685,6 +1685,7 @@
 INSERT INTO person (id, displayname, teamowner, teamdescription, name, language, fti, defaultmembershipperiod, defaultrenewalperiod, subscriptionpolicy, merged, datecreated, homepage_content, icon, mugshot, hide_email_addresses, creation_rationale, creation_comment, registrant, logo, renewal_policy, personal_standing, personal_standing_reason, mail_resumption_date, mailing_list_auto_subscribe_policy, mailing_list_receive_duplicates, visibility, verbose_bugnotifications, account, description) VALUES (243631, 'Techboard Owner', NULL, NULL, 'techboard-owner', NULL, NULL, NULL, NULL, 1, NULL, '2009-08-04 10:50:39.370018', NULL, NULL, NULL, true, 1, NULL, NULL, NULL, 10, 0, NULL, NULL, 1, true, 1, true, 2436243, NULL);
 INSERT INTO person (id, displayname, teamowner, teamdescription, name, language, fti, defaultmembershipperiod, defaultrenewalperiod, subscriptionpolicy, merged, datecreated, homepage_content, icon, mugshot, hide_email_addresses, creation_rationale, creation_comment, registrant, logo, renewal_policy, personal_standing, personal_standing_reason, mail_resumption_date, mailing_list_auto_subscribe_policy, mailing_list_receive_duplicates, visibility, verbose_bugnotifications, account, description) VALUES (243632, 'Ubuntu Technical Board', 243631, NULL, 'techboard', NULL, NULL, NULL, NULL, 3, NULL, '2009-08-04 10:50:39.370018', NULL, NULL, NULL, false, NULL, NULL, NULL, NULL, 10, 0, NULL, NULL, 1, true, 1, true, NULL, NULL);
 INSERT INTO person (id, displayname, teamowner, teamdescription, name, language, fti, defaultmembershipperiod, defaultrenewalperiod, subscriptionpolicy, merged, datecreated, homepage_content, icon, mugshot, hide_email_addresses, creation_rationale, creation_comment, registrant, logo, renewal_policy, personal_standing, personal_standing_reason, mail_resumption_date, mailing_list_auto_subscribe_policy, mailing_list_receive_duplicates, visibility, verbose_bugnotifications, account, description) VALUES (243651, 'Software-center-agent', NULL, NULL, 'software-center-agent', NULL, NULL, NULL, NULL, 1, NULL, '2010-07-12 09:48:27.198885', NULL, NULL, NULL, false, 1, NULL, NULL, NULL, 10, 0, NULL, NULL, 1, true, 1, true, 243637, NULL);
+INSERT INTO person (id, displayname, teamowner, teamdescription, name, language, fti, defaultmembershipperiod, defaultrenewalperiod, subscriptionpolicy, merged, datecreated, homepage_content, icon, mugshot, hide_email_addresses, creation_rationale, creation_comment, registrant, logo, renewal_policy, personal_standing, personal_standing_reason, mail_resumption_date, mailing_list_auto_subscribe_policy, mailing_list_receive_duplicates, visibility, verbose_bugnotifications, account, description) VALUES (243652, 'Launchpad PPA Self Admins', 243621, NULL, 'launchpad-ppa-self-admins', NULL, NULL, NULL, NULL, 3, NULL, '2013-05-10 05:43:04.018122', NULL, NULL, NULL, false, NULL, NULL, NULL, NULL, 10, 0, NULL, NULL, 1, true, 1, true, NULL, NULL);
 
 
 ALTER TABLE person ENABLE TRIGGER ALL;
@@ -5140,6 +5141,7 @@
 INSERT INTO lp_person (id, displayname, teamowner, teamdescription, name, language, fti, defaultmembershipperiod, defaultrenewalperiod, subscriptionpolicy, merged, datecreated, addressline1, addressline2, organization, city, province, country, postcode, phone, homepage_content, icon, mugshot, hide_email_addresses, creation_rationale, creation_comment, registrant, logo, renewal_policy, personal_standing, personal_standing_reason, mail_resumption_date, mailing_list_auto_subscribe_policy, mailing_list_receive_duplicates, visibility, verbose_bugnotifications, account) VALUES (243631, 'Techboard Owner', NULL, NULL, 'techboard-owner', NULL, NULL, NULL, NULL, 1, NULL, '2009-08-04 10:50:39.370018', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, true, 1, NULL, NULL, NULL, 10, 0, NULL, NULL, 1, true, 1, true, 2436243);
 INSERT INTO lp_person (id, displayname, teamowner, teamdescription, name, language, fti, defaultmembershipperiod, defaultrenewalperiod, subscriptionpolicy, merged, datecreated, addressline1, addressline2, organization, city, province, country, postcode, phone, homepage_content, icon, mugshot, hide_email_addresses, creation_rationale, creation_comment, registrant, logo, renewal_policy, personal_standing, personal_standing_reason, mail_resumption_date, mailing_list_auto_subscribe_policy, mailing_list_receive_duplicates, visibility, verbose_bugnotifications, account) VALUES (243632, 'Ubuntu Technical Board', 243631, NULL, 'techboard', NULL, NULL, NULL, NULL, 3, NULL, '2009-08-04 10:50:39.370018', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, NULL, NULL, NULL, NULL, 10, 0, NULL, NULL, 1, true, 1, true, NULL);
 INSERT INTO lp_person (id, displayname, teamowner, teamdescription, name, language, fti, defaultmembershipperiod, defaultrenewalperiod, subscriptionpolicy, merged, datecreated, addressline1, addressline2, organization, city, province, country, postcode, phone, homepage_content, icon, mugshot, hide_email_addresses, creation_rationale, creation_comment, registrant, logo, renewal_policy, personal_standing, personal_standing_reason, mail_resumption_date, mailing_list_auto_subscribe_policy, mailing_list_receive_duplicates, visibility, verbose_bugnotifications, account) VALUES (243651, 'Software-center-agent', NULL, NULL, 'software-center-agent', NULL, NULL, NULL, NULL, 1, NULL, '2010-07-12 09:48:27.198885', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, 1, NULL, NULL, NULL, 10, 0, NULL, NULL, 1, true, 1, true, 243637);
+INSERT INTO lp_person (id, displayname, teamowner, teamdescription, name, language, fti, defaultmembershipperiod, defaultrenewalperiod, subscriptionpolicy, merged, datecreated, addressline1, addressline2, organization, city, province, country, postcode, phone, homepage_content, icon, mugshot, hide_email_addresses, creation_rationale, creation_comment, registrant, logo, renewal_policy, personal_standing, personal_standing_reason, mail_resumption_date, mailing_list_auto_subscribe_policy, mailing_list_receive_duplicates, visibility, verbose_bugnotifications, account) VALUES (243652, 'Launchpad PPA Self Admins', 243621, NULL, 'launchpad-ppa-self-admins', NULL, NULL, NULL, NULL, 3, NULL, '2013-05-10 05:43:04.018122', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, NULL, NULL, NULL, NULL, 10, 0, NULL, NULL, 1, true, 1, true, NULL);
 
 
 ALTER TABLE lp_person ENABLE TRIGGER ALL;
@@ -5357,6 +5359,9 @@
 INSERT INTO lp_teamparticipation (id, team, person) VALUES (221, 243632, 243632);
 INSERT INTO lp_teamparticipation (id, team, person) VALUES (222, 243632, 243631);
 INSERT INTO lp_teamparticipation (id, team, person) VALUES (253, 243651, 243651);
+INSERT INTO lp_teamparticipation (id, team, person) VALUES (254, 243652, 243652);
+INSERT INTO lp_teamparticipation (id, team, person) VALUES (256, 243652, 243621);
+INSERT INTO lp_teamparticipation (id, team, person) VALUES (257, 243652, 243622);
 
 
 ALTER TABLE lp_teamparticipation ENABLE TRIGGER ALL;
@@ -10070,6 +10075,7 @@
 INSERT INTO teammembership (id, person, team, status, date_joined, date_expires, last_changed_by, last_change_comment, proposed_by, acknowledged_by, reviewed_by, date_proposed, date_last_changed, date_acknowledged, date_reviewed, proponent_comment, acknowledger_comment, reviewer_comment, date_created) VALUES (103, 243622, 243630, 2, '2009-07-09 11:58:38.122886', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2009-07-09 11:58:38.122886');
 INSERT INTO teammembership (id, person, team, status, date_joined, date_expires, last_changed_by, last_change_comment, proposed_by, acknowledged_by, reviewed_by, date_proposed, date_last_changed, date_acknowledged, date_reviewed, proponent_comment, acknowledger_comment, reviewer_comment, date_created) VALUES (104, 243623, 243630, 2, '2009-07-09 11:58:38.122886', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2009-07-09 11:58:38.122886');
 INSERT INTO teammembership (id, person, team, status, date_joined, date_expires, last_changed_by, last_change_comment, proposed_by, acknowledged_by, reviewed_by, date_proposed, date_last_changed, date_acknowledged, date_reviewed, proponent_comment, acknowledger_comment, reviewer_comment, date_created) VALUES (105, 243631, 243632, 3, '2009-08-04 10:50:47.920683', NULL, NULL, NULL, 243631, NULL, 243631, '2009-08-04 10:50:47.920683', NULL, NULL, '2009-08-04 10:50:47.920683', NULL, NULL, NULL, '2009-08-04 10:50:39.370018');
+INSERT INTO teammembership (id, person, team, status, date_joined, date_expires, last_changed_by, last_change_comment, proposed_by, acknowledged_by, reviewed_by, date_proposed, date_last_changed, date_acknowledged, date_reviewed, proponent_comment, acknowledger_comment, reviewer_comment, date_created) VALUES (107, 243621, 243652, 3, '2013-05-10 05:43:32.395783', NULL, NULL, NULL, 16, NULL, 16, '2013-05-10 05:43:32.395783', NULL, NULL, '2013-05-10 05:43:32.395783', NULL, NULL, NULL, '2013-05-10 05:43:32.221684');
 
 
 ALTER TABLE teammembership ENABLE TRIGGER ALL;
@@ -10274,6 +10280,9 @@
 INSERT INTO teamparticipation (id, team, person) VALUES (221, 243632, 243632);
 INSERT INTO teamparticipation (id, team, person) VALUES (222, 243632, 243631);
 INSERT INTO teamparticipation (id, team, person) VALUES (253, 243651, 243651);
+INSERT INTO teamparticipation (id, team, person) VALUES (254, 243652, 243652);
+INSERT INTO teamparticipation (id, team, person) VALUES (256, 243652, 243621);
+INSERT INTO teamparticipation (id, team, person) VALUES (257, 243652, 243622);
 
 
 ALTER TABLE teamparticipation ENABLE TRIGGER ALL;

=== modified file 'lib/lp/app/interfaces/launchpad.py'
--- lib/lp/app/interfaces/launchpad.py	2012-08-16 13:35:52 +0000
+++ lib/lp/app/interfaces/launchpad.py	2013-05-10 07:07:29 +0000
@@ -56,6 +56,7 @@
     launchpad_developers = Attribute("The Launchpad development team.")
     obsolete_junk = Attribute("The Obsolete Junk project.")
     ppa_key_guard = Attribute("The PPA signing keys owner.")
+    ppa_self_admins = Attribute("The Launchpad PPA Self Admins team.")
     registry_experts = Attribute("The Registry Administrators team.")
     rosetta_experts = Attribute("The Rosetta Experts team.")
     savannah_tracker = Attribute("The GNU Savannah Bug Tracker.")

=== modified file 'lib/lp/app/utilities/celebrities.py'
--- lib/lp/app/utilities/celebrities.py	2012-08-16 13:35:52 +0000
+++ lib/lp/app/utilities/celebrities.py	2013-05-10 07:07:29 +0000
@@ -145,6 +145,7 @@
     launchpad_developers = PersonCelebrityDescriptor('launchpad')
     obsolete_junk = CelebrityDescriptor(IProductSet, 'obsolete-junk')
     ppa_key_guard = PersonCelebrityDescriptor('ppa-key-guard')
+    ppa_self_admins = PersonCelebrityDescriptor('launchpad-ppa-self-admins')
     registry_experts = PersonCelebrityDescriptor('registry')
     rosetta_experts = PersonCelebrityDescriptor('rosetta-admins')
     savannah_tracker = CelebrityDescriptor(IBugTrackerSet, 'savannah')

=== modified file 'lib/lp/registry/browser/tests/private-team-creation-views.txt'
--- lib/lp/registry/browser/tests/private-team-creation-views.txt	2012-12-10 13:43:47 +0000
+++ lib/lp/registry/browser/tests/private-team-creation-views.txt	2013-05-10 07:07:29 +0000
@@ -297,7 +297,6 @@
     ...         owner=team, purpose=ArchivePurpose.PPA,
     ...         distribution=ubuntu, name=team.name+'-archive',
     ...         require_virtualized=False)
-    ...     private_archive.buildd_secret = 'my secret'
     ...     private_archive.private = True
     ...     # A private PPA subscription.
     ...     login('foo.bar@xxxxxxxxxxxxx')

=== modified file 'lib/lp/registry/interfaces/role.py'
--- lib/lp/registry/interfaces/role.py	2012-08-21 04:28:11 +0000
+++ lib/lp/registry/interfaces/role.py	2013-05-10 07:07:29 +0000
@@ -100,6 +100,9 @@
     in_ppa_key_guard = Bool(
         title=_("True if this person is the ppa key guard."),
         required=True, readonly=True)
+    in_ppa_self_admins = Bool(
+        title=_("True if this person is a PPA self admin."),
+        required=True, readonly=True)
     in_registry_experts = Bool(
         title=_("True if this person is a registry expert."),
         required=True, readonly=True)

=== modified file 'lib/lp/security.py'
--- lib/lp/security.py	2013-05-02 00:40:14 +0000
+++ lib/lp/security.py	2013-05-10 07:07:29 +0000
@@ -2520,6 +2520,24 @@
                 user.in_admin)
 
 
+class AdminArchive(AuthorizationBase):
+    """Restrict changing privacy and build settings on archives.
+
+    The security of the non-virtualised build farm depends on these
+    settings, so they can only be changed by commercial admins, or by
+    PPA self admins on PPAs that they can already edit.
+    """
+    permission = 'launchpad.Admin'
+    usedfor = IArchive
+
+    def checkAuthenticated(self, user):
+        if user.in_commercial_admin or user.in_admin:
+            return True
+        return (
+            user.in_ppa_self_admins
+            and EditArchive(self.obj).checkAuthenticated(user))
+
+
 class ViewArchiveAuthToken(AuthorizationBase):
     """Restrict viewing of archive tokens.
 

=== modified file 'lib/lp/soyuz/browser/archive.py'
--- lib/lp/soyuz/browser/archive.py	2013-05-03 16:43:19 +0000
+++ lib/lp/soyuz/browser/archive.py	2013-05-10 07:07:29 +0000
@@ -437,7 +437,7 @@
         text = 'View PPA'
         return Link(canonical_url(self.context), text, icon='info')
 
-    @enabled_with_permission('launchpad.Commercial')
+    @enabled_with_permission('launchpad.Admin')
     def admin(self):
         text = 'Administer archive'
         return Link('+admin', text, icon='edit')
@@ -2033,7 +2033,6 @@
         'suppress_subscription_notifications',
         'require_virtualized',
         'build_debug_symbols',
-        'buildd_secret',
         'authorized_size',
         'relative_build_score',
         'external_dependencies',
@@ -2046,25 +2045,8 @@
     def label(self):
         return 'Administer %s' % self.context.displayname
 
-    def updateContextFromData(self, data):
-        """Update context from form data.
-
-        If the user did not specify a buildd secret but marked the
-        archive as private, generate a secret for them.
-        """
-        if data['private'] and data['buildd_secret'] is None:
-            # The buildd secret is auto-generated and set when 'private'
-            # is set to True
-            del(data['buildd_secret'])
-        super(ArchiveAdminView, self).updateContextFromData(data)
-
     def validate_save(self, action, data):
-        """Validate the save action on ArchiveAdminView.
-
-        buildd_secret can only, and must, be set for private archives.
-        If the archive is private and the buildd secret is not set it will be
-        generated.
-        """
+        """Validate the save action on ArchiveAdminView."""
         super(ArchiveAdminView, self).validate_save(action, data)
 
         if data.get('private') != self.context.private:
@@ -2079,10 +2061,6 @@
             self.setFieldError(
                 'private',
                 'Private teams may not have public archives.')
-        elif data.get('buildd_secret') is not None and not data['private']:
-            self.setFieldError(
-                'buildd_secret',
-                'Do not specify for non-private archives')
 
         # Check the external_dependencies field.
         ext_deps = data.get('external_dependencies')

=== modified file 'lib/lp/soyuz/browser/configure.zcml'
--- lib/lp/soyuz/browser/configure.zcml	2013-02-18 03:47:21 +0000
+++ lib/lp/soyuz/browser/configure.zcml	2013-05-10 07:07:29 +0000
@@ -298,7 +298,7 @@
         name="+admin"
         for="lp.soyuz.interfaces.archive.IArchive"
         class="lp.soyuz.browser.archive.ArchiveAdminView"
-        permission="launchpad.Commercial"
+        permission="launchpad.Admin"
         template="../../app/templates/generic-edit.pt"/>
     <browser:pages
         for="lp.soyuz.interfaces.archive.IArchive"

=== modified file 'lib/lp/soyuz/browser/tests/test_archive_admin_view.py'
--- lib/lp/soyuz/browser/tests/test_archive_admin_view.py	2012-09-21 06:52:06 +0000
+++ lib/lp/soyuz/browser/tests/test_archive_admin_view.py	2013-05-10 07:07:29 +0000
@@ -25,7 +25,7 @@
         # object.
         login('admin@xxxxxxxxxxxxx')
 
-    def initialize_admin_view(self, private=True, buildd_secret=''):
+    def initialize_admin_view(self, private=True):
         """Initialize the admin view to set the privacy.."""
         method = 'POST'
         form = {
@@ -33,7 +33,6 @@
             'field.actions.save': 'Save',
             }
 
-        form['field.buildd_secret'] = buildd_secret
         if private is True:
             form['field.private'] = 'on'
         else:
@@ -44,11 +43,6 @@
         view.initialize()
         return view
 
-    def make_ppa_private(self, ppa):
-        """Helper method to privatise a ppa."""
-        ppa.private = True
-        ppa.buildd_secret = "secret"
-
     def publish_to_ppa(self, ppa):
         """Helper method to publish a package in a PPA."""
         publisher = SoyuzTestPublisher()
@@ -57,33 +51,25 @@
 
     def test_set_private_without_packages(self):
         # If a ppa does not have packages published, it is possible to
-        # update the private attribute.
-        view = self.initialize_admin_view(private=True, buildd_secret="test")
+        # update the private attribute. Marking the PPA private also
+        # generates a buildd secret.
+        view = self.initialize_admin_view(private=True)
         self.assertEqual(0, len(view.errors))
         self.assertTrue(view.context.private)
+        self.assertTrue(len(view.context.buildd_secret) > 4)
 
     def test_set_public_without_packages(self):
         # If a ppa does not have packages published, it is possible to
         # update the private attribute.
-        self.make_ppa_private(self.ppa)
-        self.assertTrue(self.ppa.private)
-
-        view = self.initialize_admin_view(private=False, buildd_secret='')
+        self.ppa.private = True
+        view = self.initialize_admin_view(private=False)
         self.assertEqual(0, len(view.errors))
         self.assertFalse(view.context.private)
 
-    def test_set_private_without_buildd_secret(self):
-        """If a PPA is marked private but no buildd secret is specified,
-        one will be generated."""
-        view = self.initialize_admin_view(private=True, buildd_secret='')
-        self.assertEqual(0, len(view.errors))
-        self.assertTrue(view.context.private)
-        self.assertTrue(len(view.context.buildd_secret) > 4)
-
     def test_set_private_with_packages(self):
         # A PPA that does have packages cannot be privatised.
         self.publish_to_ppa(self.ppa)
-        view = self.initialize_admin_view(private=True, buildd_secret="test")
+        view = self.initialize_admin_view(private=True)
         self.assertEqual(1, len(view.errors))
         self.assertEqual(
             'This archive already has published sources. '
@@ -93,11 +79,10 @@
     def test_set_public_with_packages(self):
         # A PPA that does have (or had) packages published is presented
         # with a disabled 'private' field.
-        self.make_ppa_private(self.ppa)
-        self.assertTrue(self.ppa.private)
+        self.ppa.private = True
         self.publish_to_ppa(self.ppa)
 
-        view = self.initialize_admin_view(private=False, buildd_secret='')
+        view = self.initialize_admin_view(private=False)
         self.assertEqual(1, len(view.errors))
         self.assertEqual(
             'This archive already has published sources. '

=== modified file 'lib/lp/soyuz/browser/tests/test_archive_packages.py'
--- lib/lp/soyuz/browser/tests/test_archive_packages.py	2013-03-11 03:58:16 +0000
+++ lib/lp/soyuz/browser/tests/test_archive_packages.py	2013-05-10 07:07:29 +0000
@@ -57,7 +57,6 @@
         super(TestP3APackages, self).setUp()
         self.private_ppa = self.factory.makeArchive(description='Foo')
         login('admin@xxxxxxxxxxxxx')
-        self.private_ppa.buildd_secret = 'blah'
         self.private_ppa.private = True
         self.joe = self.factory.makePerson(name='joe')
         self.fred = self.factory.makePerson(name='fred')

=== modified file 'lib/lp/soyuz/browser/tests/test_archive_webservice.py'
--- lib/lp/soyuz/browser/tests/test_archive_webservice.py	2012-08-17 09:31:57 +0000
+++ lib/lp/soyuz/browser/tests/test_archive_webservice.py	2013-05-10 07:07:29 +0000
@@ -307,7 +307,7 @@
         ws_archive = self.wsObject(archive, user=archive.owner)
         self.assertContentEqual([], ws_archive.enabled_restricted_families)
         expected_re = (
-            "(.|\n)*'launchpad\.Commercial'(.|\n)*")
+            "(.|\n)*'launchpad\.Admin'(.|\n)*")
         with ExpectedException(LRUnauthorized, expected_re):
             ws_archive.enableRestrictedFamily(family=ws_arm)
 
@@ -324,7 +324,7 @@
         ws_archive = self.wsObject(archive, user=just_some_guy)
         self.assertContentEqual([], ws_archive.enabled_restricted_families)
         expected_re = (
-            "(.|\n)*'launchpad\.Commercial'(.|\n)*")
+            "(.|\n)*'launchpad\.Admin'(.|\n)*")
         with ExpectedException(LRUnauthorized, expected_re):
             ws_archive.enableRestrictedFamily(family=ws_arm)
 

=== modified file 'lib/lp/soyuz/browser/tests/test_breadcrumbs.py'
--- lib/lp/soyuz/browser/tests/test_breadcrumbs.py	2012-01-01 02:58:52 +0000
+++ lib/lp/soyuz/browser/tests/test_breadcrumbs.py	2013-05-10 07:07:29 +0000
@@ -54,7 +54,6 @@
         self.ppa = self.factory.makeArchive()
         login('foo.bar@xxxxxxxxxxxxx')
         self.ppa.private = True
-        self.ppa.buildd_secret = 'secret'
 
         owner = self.ppa.owner
         login_person(owner)

=== modified file 'lib/lp/soyuz/configure.zcml'
--- lib/lp/soyuz/configure.zcml	2013-05-09 08:52:48 +0000
+++ lib/lp/soyuz/configure.zcml	2013-05-10 07:07:29 +0000
@@ -419,24 +419,21 @@
                             suppress_subscription_notifications"/>
         <!--
            NOTE: The 'private' permission controls who can turn a public
-           archive into a private one, and vice versa. The logic that says this
-           requires launchpad.Commercial permissions is duplicated in
-           validate_ppa.
+           archive into a private one, and vice versa. The logic that
+           says this requires launchpad.Admin permissions is duplicated
+           in validate_ppa.
           -->
         <require
-            permission="launchpad.Commercial"
-            interface="lp.soyuz.interfaces.archive.IArchiveCommercial"
-            set_attributes="authorized_size build_debug_symbols buildd_secret
-                            enabled_restricted_families
+            permission="launchpad.Admin"
+            interface="lp.soyuz.interfaces.archive.IArchiveAdmin"
+            set_attributes="name authorized_size build_debug_symbols
+                            buildd_secret enabled_restricted_families
                             external_dependencies private
                             require_virtualized"/>
         <require
             permission="launchpad.Moderate"
             set_schema="lp.soyuz.interfaces.archive.IArchiveRestricted"/>
         <require
-            permission="launchpad.Admin"
-            set_attributes="name" />
-        <require
             permission="launchpad.InternalScriptsOnly"
             set_attributes="distribution signing_key"/>
     </class>

=== modified file 'lib/lp/soyuz/doc/archive.txt'
--- lib/lp/soyuz/doc/archive.txt	2013-05-09 08:53:01 +0000
+++ lib/lp/soyuz/doc/archive.txt	2013-05-10 07:07:29 +0000
@@ -88,7 +88,7 @@
     >>> cprov_archive.external_dependencies = "test"
     Traceback (most recent call last):
     ...
-    Unauthorized: (..., 'external_dependencies', 'launchpad.Commercial')
+    Unauthorized: (..., 'external_dependencies', 'launchpad.Admin')
 
 As a Launchpad admin, setting this property will work.
 
@@ -1757,6 +1757,27 @@
     >>> login('foo.bar@xxxxxxxxxxxxx')
     >>> cprov_archive.enable()
 
+Commercial admins can manage the privacy and build settings of any PPA.
+Additionally, a member of launchpad-ppa-self-admins can manage those
+settings on PPAs that they can otherwise edit.
+
+    >>> login('celso.providelo@xxxxxxxxxxxxx')
+    >>> check_permission('launchpad.Admin', cprov_archive)
+    False
+
+    >>> login('commercial-member@xxxxxxxxxxxxx')
+    >>> check_permission('launchpad.Admin', cprov_archive)
+    True
+    >>> celeb = getUtility(IPersonSet).getByName('launchpad-ppa-self-admins')
+    >>> celeb.addMember(person=cprov, reviewer=celeb.teamowner)
+    (True, ...)
+
+    >>> login('celso.providelo@xxxxxxxxxxxxx')
+    >>> check_permission('launchpad.Admin', cprov_archive)
+    True
+    >>> check_permission('launchpad.Admin', joes_ppa)
+    False
+
 
 Rebuild archives
 ----------------

=== modified file 'lib/lp/soyuz/interfaces/archive.py'
--- lib/lp/soyuz/interfaces/archive.py	2013-05-01 18:39:38 +0000
+++ lib/lp/soyuz/interfaces/archive.py	2013-05-10 07:07:29 +0000
@@ -19,8 +19,8 @@
     'CannotUploadToPocket',
     'FULL_COMPONENT_SUPPORT',
     'IArchive',
+    'IArchiveAdmin',
     'IArchiveAppend',
-    'IArchiveCommercial',
     'IArchiveEdit',
     'IArchiveEditDependenciesForm',
     'IArchiveSubscriberView',
@@ -1906,7 +1906,7 @@
         """
 
 
-class IArchiveCommercial(Interface):
+class IArchiveAdmin(Interface):
     """Archive interface for operations restricted by commercial."""
 
     @operation_parameters(
@@ -1933,7 +1933,7 @@
 
 
 class IArchive(IArchivePublic, IArchiveAppend, IArchiveEdit,
-               IArchiveSubscriberView, IArchiveView, IArchiveCommercial,
+               IArchiveSubscriberView, IArchiveView, IArchiveAdmin,
                IArchiveRestricted):
     """Main Archive interface."""
     export_as_webservice_entry()

=== modified file 'lib/lp/soyuz/model/archive.py'
--- lib/lp/soyuz/model/archive.py	2013-05-02 00:40:14 +0000
+++ lib/lp/soyuz/model/archive.py	2013-05-10 07:07:29 +0000
@@ -2015,12 +2015,12 @@
     creator = getUtility(ILaunchBag).user
     ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
     if private:
-        # NOTE: This duplicates the policy in lp/soyuz/configure.zcml which
-        # says that one needs 'launchpad.Commercial' permission to set
-        # 'private', and the logic in `AdminByCommercialTeamOrAdmins` which
-        # determines who is granted launchpad.Commercial permissions. The
-        # difference is that here we grant ability to set 'private' to people
-        # with a commercial subscription.
+        # NOTE: This duplicates the policy in lp/soyuz/configure.zcml
+        # which says that one needs 'launchpad.Admin' permission to set
+        # 'private', and the logic in `AdminArchive` which determines
+        # who is granted launchpad.Admin permissions. The difference is
+        # that here we grant ability to set 'private' to people with a
+        # commercial subscription.
         if not (owner.private or creator.checkAllowVisibility()):
             return '%s is not allowed to make private PPAs' % creator.name
     elif owner.private:

=== modified file 'lib/lp/soyuz/scripts/tests/test_expire_archive_files.py'
--- lib/lp/soyuz/scripts/tests/test_expire_archive_files.py	2013-01-11 09:38:09 +0000
+++ lib/lp/soyuz/scripts/tests/test_expire_archive_files.py	2013-05-10 07:07:29 +0000
@@ -257,7 +257,6 @@
     def testPrivatePPAsNotExpired(self):
         """Test that private PPAs are not expired."""
         self.archive.private = True
-        self.archive.buildd_secret = "foo"
         source, binary = self._setUpExpirablePublications()
         self.runScript()
         self.assertSourceNotExpired(source)

=== modified file 'lib/lp/soyuz/stories/ppa/xx-ppa-workflow.txt'
--- lib/lp/soyuz/stories/ppa/xx-ppa-workflow.txt	2013-02-21 01:10:08 +0000
+++ lib/lp/soyuz/stories/ppa/xx-ppa-workflow.txt	2013-05-10 07:07:29 +0000
@@ -376,7 +376,6 @@
     >>> admin_browser.getControl(name="field.private").value = True
     >>> admin_browser.getControl(
     ...     name="field.suppress_subscription_notifications").value = True
-    >>> admin_browser.getControl(name="field.buildd_secret").value = "secret"
     >>> admin_browser.getControl(
     ...     name="field.require_virtualized").value = True
     >>> admin_browser.getControl(name="field.authorized_size").value = '1'
@@ -419,20 +418,6 @@
     &#x27;deb not_a_url&#x27; is not a complete and valid sources.list entry
 
 
-Setting the buildd secret for non-private archives also generates an error:
-
-    >>> admin_browser.getControl(
-    ...     name="field.external_dependencies").value = ""
-    >>> admin_browser.getControl(name="field.private").value = False
-    >>> admin_browser.getControl(name="field.buildd_secret").value = "secret"
-    >>> admin_browser.getControl("Save").click()
-
-    >>> for error in get_feedback_messages(admin_browser.contents):
-    ...     print error
-    There is 1 error.
-    Do not specify for non-private archives
-
-
 There is a maximum value allowed for `IArchive.authorized_size`, it is
 currently 2147483647 and the unit used in code is MiB, so in practice
 the size limit is 2 PiB.

=== modified file 'lib/lp/soyuz/stories/ppa/xx-private-ppas.txt'
--- lib/lp/soyuz/stories/ppa/xx-private-ppas.txt	2012-01-15 11:06:57 +0000
+++ lib/lp/soyuz/stories/ppa/xx-private-ppas.txt	2013-05-10 07:07:29 +0000
@@ -67,7 +67,6 @@
 
     >>> admin_browser.getLink("Administer archive").click()
     >>> admin_browser.getControl(name="field.private").value = True
-    >>> admin_browser.getControl(name="field.buildd_secret").value = "secret"
     >>> admin_browser.getControl("Save").click()
 
 A member of a private team PPA will see his team's PPA in the listing.

=== modified file 'lib/lp/soyuz/stories/soyuz/xx-distribution-archives.txt'
--- lib/lp/soyuz/stories/soyuz/xx-distribution-archives.txt	2013-02-18 12:42:17 +0000
+++ lib/lp/soyuz/stories/soyuz/xx-distribution-archives.txt	2013-05-10 07:07:29 +0000
@@ -126,7 +126,6 @@
     >>> naked_copy_location = remove_security_proxy_and_shout_at_engineer(
     ...     copy_location)
     >>> copy_archive = naked_copy_location.archive
-    >>> copy_archive.buildd_secret = 'really secret'
     >>> copy_archive.private = True
     >>> copy_archive.owner.displayname = "Harry Potter"
     >>> package_copy_request = ubuntu.main_archive.requestPackageCopy(

=== modified file 'lib/lp/soyuz/stories/webservice/xx-archive.txt'
--- lib/lp/soyuz/stories/webservice/xx-archive.txt	2013-05-09 08:53:01 +0000
+++ lib/lp/soyuz/stories/webservice/xx-archive.txt	2013-05-10 07:07:29 +0000
@@ -1151,7 +1151,7 @@
     >>> print modify_archive(user_webservice, mark_archive)
     HTTP/1.1 401 Unauthorized
     ...
-    (<Archive at ...>, 'authorized_size', 'launchpad.Commercial')
+    (<Archive at ...>, 'authorized_size', 'launchpad.Admin')
 
 Private archives
 ~~~~~~~~~~~~~~~~
@@ -1327,7 +1327,7 @@
     >>> print modify_archive(user_webservice, mark_archive)
     HTTP/1.1 401 Unauthorized
     ...
-    (<Archive at ...>, 'private', 'launchpad.Commercial')
+    (<Archive at ...>, 'private', 'launchpad.Admin')
 
 
 Copying private file to public archives

=== modified file 'lib/lp/soyuz/tests/test_archive.py'
--- lib/lp/soyuz/tests/test_archive.py	2013-05-09 08:53:01 +0000
+++ lib/lp/soyuz/tests/test_archive.py	2013-05-10 07:07:29 +0000
@@ -1052,7 +1052,7 @@
         login(ANONYMOUS)
         e = self.assertRaises(
             Unauthorized, setattr, self.archive, "buildd_secret", "boing")
-        self.assertEqual("launchpad.Commercial", e.args[2])
+        self.assertEqual("launchpad.Admin", e.args[2])
 
     def test_commercial_admin_can_set_buildd_secret(self):
         with celebrity_logged_in("commercial_admin"):

=== modified file 'lib/lp/soyuz/tests/test_archive_privacy.py'
--- lib/lp/soyuz/tests/test_archive_privacy.py	2012-06-11 10:18:41 +0000
+++ lib/lp/soyuz/tests/test_archive_privacy.py	2013-05-10 07:07:29 +0000
@@ -49,7 +49,7 @@
         with person_logged_in(ppa.owner):
             # XXX: jml 2012-06-11: We actually want this to be allowed, but I
             # can't think of any way to grant this without also granting other
-            # attributes that have launchpad.Commercial.
+            # attributes that have launchpad.Admin.
             self.assertRaises(Unauthorized, setattr, ppa, 'private', True)
 
     def test_admin_changing_privacy(self):