launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #24523
[Merge] ~pappacena/launchpad:oci-project-admin into launchpad:master
Thiago F. Pappacena has proposed merging ~pappacena/launchpad:oci-project-admin into launchpad:master.
Commit message:
Adding the attribute and method to check if a given person has permission to manage OCI projects for a given Distribution.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~pappacena/launchpad/+git/launchpad/+merge/381321
This MP only adds the new Distribution.oci_project_admin attribute and Distribution.canAdministerOCIProjects, so we can unlock the development of UI and API for OCI project creation.
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~pappacena/launchpad:oci-project-admin into launchpad:master.
diff --git a/lib/lp/registry/interfaces/distribution.py b/lib/lp/registry/interfaces/distribution.py
index a7106f6..85e503d 100644
--- a/lib/lp/registry/interfaces/distribution.py
+++ b/lib/lp/registry/interfaces/distribution.py
@@ -249,6 +249,11 @@ class IDistributionPublic(
description=_("The person or team that has the rights to review and "
"mark this distribution's mirrors as official."),
required=True, vocabulary='ValidPersonOrTeam'))
+ oci_project_admin = exported(PublicPersonChoice(
+ title=_("OCI Project Administrator"),
+ description=_("The person or team that has the rights to manage OCI "
+ "Projects."),
+ required=False, vocabulary='ValidPersonOrTeam'))
archive_mirrors = exported(doNotSnapshot(
CollectionField(
description=_("All enabled and official ARCHIVE mirrors "
@@ -655,6 +660,10 @@ class IDistributionPublic(
def userCanEdit(user):
"""Can the user edit this distribution?"""
+ def canAdministerOCIProjects(person):
+ """Checks if the given person can administer OCI Projects of this
+ distro."""
+
class IDistribution(
IDistributionEditRestricted, IDistributionPublic, IHasBugSupervisor,
@@ -710,7 +719,8 @@ class IDistributionSet(Interface):
"""Return the IDistribution with the given name or None."""
def new(name, display_name, title, description, summary, domainname,
- members, owner, registrant, mugshot=None, logo=None, icon=None):
+ members, owner, registrant, mugshot=None, logo=None, icon=None,
+ oci_project_admin=None):
"""Create a new distribution."""
def getCurrentSourceReleases(distro_to_source_packagenames):
diff --git a/lib/lp/registry/model/distribution.py b/lib/lp/registry/model/distribution.py
index f78908b..ab0ad26 100644
--- a/lib/lp/registry/model/distribution.py
+++ b/lib/lp/registry/model/distribution.py
@@ -236,6 +236,9 @@ class Distribution(SQLBase, BugTargetBase, MakesAnnouncements,
mirror_admin = ForeignKey(
dbName='mirror_admin', foreignKey='Person',
storm_validator=validate_public_person, notNull=True)
+ oci_project_admin = ForeignKey(
+ dbName='oci_project_admin', foreignKey='Person',
+ storm_validator=validate_public_person, notNull=False)
translationgroup = ForeignKey(
dbName='translationgroup', foreignKey='TranslationGroup',
notNull=False, default=None)
@@ -1360,6 +1363,16 @@ class Distribution(SQLBase, BugTargetBase, MakesAnnouncements,
admins = getUtility(ILaunchpadCelebrities).admin
return user.inTeam(self.owner) or user.inTeam(admins)
+ def canAdministerOCIProjects(self, person):
+ """See `IDistribution`."""
+ if person is None or self.oci_project_admin is None:
+ return False
+ if person == self.oci_project_admin:
+ return True
+ if self.oci_project_admin.is_team:
+ return person in self.oci_project_admin.activemembers
+ return False
+
def newSeries(self, name, display_name, title, summary,
description, version, previous_series, registrant):
"""See `IDistribution`."""
@@ -1490,7 +1503,7 @@ class DistributionSet:
def new(self, name, display_name, title, description, summary, domainname,
members, owner, registrant, mugshot=None, logo=None, icon=None,
- vcs=None):
+ vcs=None, oci_project_admin=None):
"""See `IDistributionSet`."""
distro = Distribution(
name=name,
@@ -1506,7 +1519,8 @@ class DistributionSet:
mugshot=mugshot,
logo=logo,
icon=icon,
- vcs=vcs)
+ vcs=vcs,
+ oci_project_admin=oci_project_admin)
getUtility(IArchiveSet).new(distribution=distro,
owner=owner, purpose=ArchivePurpose.PRIMARY)
policies = itertools.product(
diff --git a/lib/lp/registry/tests/test_distribution.py b/lib/lp/registry/tests/test_distribution.py
index c7bf86f..b13d89b 100644
--- a/lib/lp/registry/tests/test_distribution.py
+++ b/lib/lp/registry/tests/test_distribution.py
@@ -1,4 +1,4 @@
-# Copyright 2009-2015 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2020 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Tests for Distribution."""
@@ -689,3 +689,43 @@ class TestWebService(WebServiceTestCase):
self.assertEqual(
[],
ws_distro.findReferencedOOPS(start_date=now - day, end_date=now))
+
+
+class DistributionOCIProjectAdminPermission(TestCaseWithFactory):
+ layer = DatabaseFunctionalLayer
+
+ def setUp(self):
+ super(DistributionOCIProjectAdminPermission, self).setUp()
+
+ def test_check_oci_project_admin_person(self):
+ person1 = self.factory.makePerson()
+ person2 = self.factory.makePerson()
+ distro = self.factory.makeDistribution(oci_project_admin=person1)
+
+ self.assertTrue(distro.canAdministerOCIProjects(person1))
+ self.assertFalse(distro.canAdministerOCIProjects(person2))
+ self.assertFalse(distro.canAdministerOCIProjects(None))
+
+ def test_check_oci_project_admin_team(self):
+ person1 = self.factory.makePerson()
+ person2 = self.factory.makePerson()
+ person3 = self.factory.makePerson()
+ team = self.factory.makeTeam(owner=person1)
+ distro = self.factory.makeDistribution(oci_project_admin=team)
+
+ admin = self.factory.makeAdministrator()
+ with person_logged_in(admin):
+ person2.join(team)
+
+ self.assertTrue(distro.canAdministerOCIProjects(team))
+ self.assertTrue(distro.canAdministerOCIProjects(person1))
+ self.assertTrue(distro.canAdministerOCIProjects(person2))
+ self.assertFalse(distro.canAdministerOCIProjects(person3))
+ self.assertFalse(distro.canAdministerOCIProjects(None))
+
+ def test_check_oci_project_admin_without_any_admin(self):
+ person1 = self.factory.makePerson()
+ distro = self.factory.makeDistribution(oci_project_admin=None)
+
+ self.assertFalse(distro.canAdministerOCIProjects(person1))
+ self.assertFalse(distro.canAdministerOCIProjects(None))
diff --git a/lib/lp/testing/factory.py b/lib/lp/testing/factory.py
index c65c941..b7d8faf 100644
--- a/lib/lp/testing/factory.py
+++ b/lib/lp/testing/factory.py
@@ -2660,7 +2660,8 @@ class BareLaunchpadObjectFactory(ObjectFactory):
aliases=None, bug_supervisor=None, driver=None,
publish_root_dir=None, publish_base_url=None,
publish_copy_base_url=None, no_pubconf=False,
- icon=None, summary=None, vcs=None):
+ icon=None, summary=None, vcs=None,
+ oci_project_admin=None):
"""Make a new distribution."""
if name is None:
name = self.getUniqueString(prefix="distribution")
@@ -2680,7 +2681,8 @@ class BareLaunchpadObjectFactory(ObjectFactory):
members = self.makeTeam(owner)
distro = getUtility(IDistributionSet).new(
name, displayname, title, description, summary, domainname,
- members, owner, registrant, icon=icon, vcs=vcs)
+ members, owner, registrant, icon=icon, vcs=vcs,
+ oci_project_admin=oci_project_admin)
naked_distro = removeSecurityProxy(distro)
if aliases is not None:
naked_distro.setAliases(aliases)