launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #25228
[Merge] ~cjwatson/launchpad:oci-registry-credentials-not-owner into launchpad:master
Colin Watson has proposed merging ~cjwatson/launchpad:oci-registry-credentials-not-owner into launchpad:master.
Commit message:
Check owner permissions when creating OCI registry credentials
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/389914
It shouldn't be possible to create credentials owned by other people, or by teams of which the creating user isn't a member.
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:oci-registry-credentials-not-owner into launchpad:master.
diff --git a/lib/lp/oci/browser/ocirecipe.py b/lib/lp/oci/browser/ocirecipe.py
index c2dceb2..594b93d 100644
--- a/lib/lp/oci/browser/ocirecipe.py
+++ b/lib/lp/oci/browser/ocirecipe.py
@@ -543,7 +543,7 @@ class OCIRecipeEditPushRulesView(LaunchpadFormView):
credentials_set = getUtility(IOCIRegistryCredentialsSet)
try:
credentials = credentials_set.getOrCreate(
- owner=self.context.owner, url=url,
+ registrant=self.user, owner=self.context.owner, url=url,
credentials={'username': username, 'password': password})
except OCIRegistryCredentialsAlreadyExist:
self.setFieldError(
diff --git a/lib/lp/oci/browser/tests/test_ocirecipe.py b/lib/lp/oci/browser/tests/test_ocirecipe.py
index 8b17168..455ff57 100644
--- a/lib/lp/oci/browser/tests/test_ocirecipe.py
+++ b/lib/lp/oci/browser/tests/test_ocirecipe.py
@@ -911,8 +911,7 @@ class TestOCIRecipeEditPushRulesView(OCIConfigHelperMixin,
url = unicode(self.factory.getUniqueURL())
credentials = {'username': 'foo', 'password': 'bar'}
registry_credentials = getUtility(IOCIRegistryCredentialsSet).new(
- owner=self.person,
- url=url,
+ registrant=self.person, owner=self.person, url=url,
credentials=credentials)
image_name = self.factory.getUniqueUnicode()
push_rule = getUtility(IOCIPushRuleSet).new(
@@ -946,8 +945,7 @@ class TestOCIRecipeEditPushRulesView(OCIConfigHelperMixin,
url = unicode(self.factory.getUniqueURL())
credentials = {'username': 'foo', 'password': 'bar'}
registry_credentials = getUtility(IOCIRegistryCredentialsSet).new(
- owner=self.person,
- url=url,
+ registrant=self.person, owner=self.person, url=url,
credentials=credentials)
image_name = self.factory.getUniqueUnicode()
push_rule = getUtility(IOCIPushRuleSet).new(
@@ -1027,8 +1025,7 @@ class TestOCIRecipeEditPushRulesView(OCIConfigHelperMixin,
url = self.factory.getUniqueURL()
credentials = {'username': 'foo', 'password': 'bar'}
registry_credentials = getUtility(IOCIRegistryCredentialsSet).new(
- owner=self.person,
- url=url,
+ registrant=self.person, owner=self.person, url=url,
credentials=credentials)
image_name = self.factory.getUniqueUnicode()
push_rule = getUtility(IOCIPushRuleSet).new(
@@ -1092,8 +1089,7 @@ class TestOCIRecipeEditPushRulesView(OCIConfigHelperMixin,
url = self.factory.getUniqueURL()
credentials = {'username': 'foo', 'password': 'bar'}
registry_credentials = getUtility(IOCIRegistryCredentialsSet).new(
- owner=self.person,
- url=url,
+ registrant=self.person, owner=self.person, url=url,
credentials=credentials)
image_names = [self.factory.getUniqueUnicode() for _ in range(2)]
push_rules = [
@@ -1136,8 +1132,7 @@ class TestOCIRecipeEditPushRulesView(OCIConfigHelperMixin,
url = self.factory.getUniqueURL()
credentials = {'username': 'foo', 'password': 'bar'}
registry_credentials = getUtility(IOCIRegistryCredentialsSet).new(
- owner=self.person,
- url=url,
+ registrant=self.person, owner=self.person, url=url,
credentials=credentials)
image_name = self.factory.getUniqueUnicode()
push_rule = getUtility(IOCIPushRuleSet).new(
@@ -1242,7 +1237,7 @@ class TestOCIRecipeEditPushRulesView(OCIConfigHelperMixin,
existing_rule = self.factory.makeOCIPushRule(
recipe=self.recipe,
registry_credentials=self.factory.makeOCIRegistryCredentials(
- owner=self.recipe.owner))
+ registrant=self.recipe.owner, owner=self.recipe.owner))
existing_image_name = existing_rule.image_name
existing_registry_url = existing_rule.registry_url
existing_username = existing_rule.username
@@ -1267,7 +1262,8 @@ class TestOCIRecipeEditPushRulesView(OCIConfigHelperMixin,
existing_rule = self.factory.makeOCIPushRule(
recipe=self.recipe,
registry_credentials=self.factory.makeOCIRegistryCredentials(
- owner=self.recipe.owner, credentials={}))
+ registrant=self.recipe.owner, owner=self.recipe.owner,
+ credentials={}))
existing_registry_url = existing_rule.registry_url
browser = self.getViewBrowser(self.recipe, user=self.person)
browser.getLink("Edit push rules").click()
@@ -1367,8 +1363,7 @@ class TestOCIRecipeEditPushRulesView(OCIConfigHelperMixin,
credentials = {'username': 'foo', 'password': 'bar'}
image_name = self.factory.getUniqueUnicode()
registry_credentials = getUtility(IOCIRegistryCredentialsSet).new(
- owner=self.person,
- url=url,
+ registrant=self.person, owner=self.person, url=url,
credentials=credentials)
getUtility(IOCIPushRuleSet).new(
recipe=self.recipe,
diff --git a/lib/lp/oci/interfaces/ocirecipe.py b/lib/lp/oci/interfaces/ocirecipe.py
index c433825..9beb6af 100644
--- a/lib/lp/oci/interfaces/ocirecipe.py
+++ b/lib/lp/oci/interfaces/ocirecipe.py
@@ -300,6 +300,7 @@ class IOCIRecipeEdit(IWebhookTarget):
def destroySelf():
"""Delete this OCI recipe, provided that it has no builds."""
+ @call_with(registrant=REQUEST_USER)
@operation_parameters(
registry_url=TextLine(
title=_("Registry URL"),
@@ -321,7 +322,7 @@ class IOCIRecipeEdit(IWebhookTarget):
# Really IOCIPushRule, patched in lp.oci.interfaces.webservice.
@export_factory_operation(Interface, [])
@operation_for_version("devel")
- def newPushRule(registry_url, image_name, credentials,
+ def newPushRule(registrant, registry_url, image_name, credentials,
credentials_owner=None):
"""Add a new rule for pushing builds of this recipe to a registry."""
diff --git a/lib/lp/oci/interfaces/ociregistrycredentials.py b/lib/lp/oci/interfaces/ociregistrycredentials.py
index 08c1bdb..c6d2707 100644
--- a/lib/lp/oci/interfaces/ociregistrycredentials.py
+++ b/lib/lp/oci/interfaces/ociregistrycredentials.py
@@ -10,6 +10,7 @@ __all__ = [
'IOCIRegistryCredentials',
'IOCIRegistryCredentialsSet',
'OCIRegistryCredentialsAlreadyExist',
+ 'OCIRegistryCredentialsNotOwner',
'user_can_edit_credentials_for_owner',
]
@@ -20,6 +21,7 @@ from zope.schema import (
Int,
TextLine,
)
+from zope.security.interfaces import Unauthorized
from lp import _
from lp.registry.interfaces.role import (
@@ -43,6 +45,11 @@ class OCIRegistryCredentialsAlreadyExist(Exception):
"Credentials already exist with the same URL and username.")
+@error_status(http_client.UNAUTHORIZED)
+class OCIRegistryCredentialsNotOwner(Unauthorized):
+ """The registrant is not the owner or a member of its team."""
+
+
class IOCIRegistryCredentialsView(Interface):
id = Int(title=_("ID"), required=True, readonly=True)
@@ -97,10 +104,10 @@ class IOCIRegistryCredentials(IOCIRegistryCredentialsEdit,
class IOCIRegistryCredentialsSet(Interface):
"""A utility to create and access OCI Registry Credentials."""
- def new(owner, url, credentials):
+ def new(registrant, owner, url, credentials):
"""Create an `IOCIRegistryCredentials`."""
- def getOrCreate(owner, url, credentials):
+ def getOrCreate(registrant, owner, url, credentials):
"""Get an `IOCIRegistryCredentials` that match the url and username
or create a new object."""
diff --git a/lib/lp/oci/model/ocirecipe.py b/lib/lp/oci/model/ocirecipe.py
index 2a83ccc..c167b15 100644
--- a/lib/lp/oci/model/ocirecipe.py
+++ b/lib/lp/oci/model/ocirecipe.py
@@ -498,7 +498,7 @@ class OCIRecipe(Storm, WebhookTargetMixin):
def can_upload_to_registry(self):
return not self.push_rules.is_empty()
- def newPushRule(self, registry_url, image_name, credentials,
+ def newPushRule(self, registrant, registry_url, image_name, credentials,
credentials_owner=None):
"""See `IOCIRecipe`."""
if credentials_owner is None:
@@ -508,7 +508,7 @@ class OCIRecipe(Storm, WebhookTargetMixin):
# we give it a default.
credentials_owner = self.owner
oci_credentials = getUtility(IOCIRegistryCredentialsSet).getOrCreate(
- credentials_owner, registry_url, credentials)
+ registrant, credentials_owner, registry_url, credentials)
push_rule = getUtility(IOCIPushRuleSet).new(
self, oci_credentials, image_name)
Store.of(push_rule).flush()
diff --git a/lib/lp/oci/model/ociregistrycredentials.py b/lib/lp/oci/model/ociregistrycredentials.py
index d86b140..396124e 100644
--- a/lib/lp/oci/model/ociregistrycredentials.py
+++ b/lib/lp/oci/model/ociregistrycredentials.py
@@ -31,6 +31,7 @@ from lp.oci.interfaces.ociregistrycredentials import (
IOCIRegistryCredentials,
IOCIRegistryCredentialsSet,
OCIRegistryCredentialsAlreadyExist,
+ OCIRegistryCredentialsNotOwner,
)
from lp.services.config import config
from lp.services.crypto.interfaces import (
@@ -134,6 +135,17 @@ class OCIRegistryCredentials(Storm):
@implementer(IOCIRegistryCredentialsSet)
class OCIRegistryCredentialsSet:
+ def _checkOwner(self, registrant, owner):
+ if not registrant.inTeam(owner):
+ if owner.is_team:
+ raise OCIRegistryCredentialsNotOwner(
+ "%s is not a member of %s." %
+ (registrant.display_name, owner.display_name))
+ else:
+ raise OCIRegistryCredentialsNotOwner(
+ "%s cannot create credentials owned by %s." %
+ (registrant.display_name, owner.display_name))
+
def _checkForExisting(self, owner, url, credentials):
for existing in self.findByOwner(owner):
url_match = existing.url == url
@@ -142,18 +154,20 @@ class OCIRegistryCredentialsSet:
return existing
return None
- def new(self, owner, url, credentials):
+ def new(self, registrant, owner, url, credentials):
"""See `IOCIRegistryCredentialsSet`."""
+ self._checkOwner(registrant, owner)
if self._checkForExisting(owner, url, credentials):
raise OCIRegistryCredentialsAlreadyExist()
return OCIRegistryCredentials(owner, url, credentials)
- def getOrCreate(self, owner, url, credentials):
+ def getOrCreate(self, registrant, owner, url, credentials):
"""See `IOCIRegistryCredentialsSet`."""
+ self._checkOwner(registrant, owner)
existing = self._checkForExisting(owner, url, credentials)
if existing:
return existing
- return self.new(owner, url, credentials)
+ return self.new(registrant, owner, url, credentials)
def findByOwner(self, owner):
"""See `IOCIRegistryCredentialsSet`."""
diff --git a/lib/lp/oci/tests/test_ocirecipe.py b/lib/lp/oci/tests/test_ocirecipe.py
index ad67a7a..840d0a0 100644
--- a/lib/lp/oci/tests/test_ocirecipe.py
+++ b/lib/lp/oci/tests/test_ocirecipe.py
@@ -11,6 +11,7 @@ from fixtures import FakeLogger
from six import string_types
from storm.exceptions import LostObjectError
from storm.store import Store
+from testtools import ExpectedException
from testtools.matchers import (
ContainsDict,
Equals,
@@ -48,6 +49,9 @@ from lp.oci.interfaces.ocirecipe import (
)
from lp.oci.interfaces.ocirecipebuild import IOCIRecipeBuildSet
from lp.oci.interfaces.ocirecipejob import IOCIRecipeRequestBuildsJobSource
+from lp.oci.interfaces.ociregistrycredentials import (
+ OCIRegistryCredentialsNotOwner,
+ )
from lp.oci.tests.helpers import (
MatchesOCIRegistryCredentials,
OCIConfigHelperMixin,
@@ -459,7 +463,7 @@ class TestOCIRecipe(OCIConfigHelperMixin, TestCaseWithFactory):
with person_logged_in(recipe.registrant):
push_rule = recipe.newPushRule(
- url, image_name, credentials,
+ recipe.registrant, url, image_name, credentials,
credentials_owner=recipe.registrant)
self.assertThat(push_rule, MatchesStructure(
image_name=Equals(image_name),
@@ -480,7 +484,8 @@ class TestOCIRecipe(OCIConfigHelperMixin, TestCaseWithFactory):
"username": "test-username", "password": "test-password"}
with person_logged_in(recipe.registrant):
- push_rule = recipe.newPushRule(url, image_name, credentials)
+ push_rule = recipe.newPushRule(
+ recipe.registrant, url, image_name, credentials)
self.assertThat(push_rule, MatchesStructure(
image_name=Equals(image_name),
registry_credentials=MatchesOCIRegistryCredentials(
@@ -499,7 +504,8 @@ class TestOCIRecipe(OCIConfigHelperMixin, TestCaseWithFactory):
with person_logged_in(recipe.owner):
self.assertRaises(
ValidationError, recipe.newPushRule,
- url, image_name, credentials, credentials_owner=recipe.owner)
+ recipe.owner, url, image_name, credentials,
+ credentials_owner=recipe.owner)
# Avoid trying to flush the incomplete object on cleanUp.
Store.of(recipe).rollback()
@@ -513,11 +519,41 @@ class TestOCIRecipe(OCIConfigHelperMixin, TestCaseWithFactory):
with person_logged_in(recipe.owner):
recipe.newPushRule(
- url, image_name, credentials, credentials_owner=recipe.owner)
+ recipe.owner, url, image_name, credentials,
+ credentials_owner=recipe.owner)
self.assertRaises(
OCIPushRuleAlreadyExists,
recipe.newPushRule,
- url, image_name, credentials, credentials_owner=recipe.owner)
+ recipe.owner, url, image_name, credentials,
+ credentials_owner=recipe.owner)
+
+ def test_newPushRule_not_owner(self):
+ # If the registrant is not the owner or a member of the owner team,
+ # push rule creation fails.
+ self.setConfig()
+ recipe = self.factory.makeOCIRecipe()
+ url = self.factory.getUniqueURL()
+ image_name = self.factory.getUniqueUnicode()
+ credentials = {
+ "username": "test-username", "password": "test-password"}
+ other_person = self.factory.makePerson()
+ other_team = self.factory.makeTeam(owner=other_person)
+
+ with person_logged_in(recipe.registrant):
+ expected_message = "%s cannot create credentials owned by %s." % (
+ recipe.registrant.display_name, other_person.display_name)
+ with ExpectedException(
+ OCIRegistryCredentialsNotOwner, expected_message):
+ recipe.newPushRule(
+ recipe.registrant, url, image_name, credentials,
+ credentials_owner=other_person)
+ expected_message = "%s is not a member of %s." % (
+ recipe.registrant.display_name, other_team.display_name)
+ with ExpectedException(
+ OCIRegistryCredentialsNotOwner, expected_message):
+ recipe.newPushRule(
+ recipe.registrant, url, image_name, credentials,
+ credentials_owner=other_team)
def test_set_official_directly_is_forbidden(self):
recipe = self.factory.makeOCIRecipe()
diff --git a/lib/lp/oci/tests/test_ociregistrycredentials.py b/lib/lp/oci/tests/test_ociregistrycredentials.py
index 6e42b28..c0e9ba1 100644
--- a/lib/lp/oci/tests/test_ociregistrycredentials.py
+++ b/lib/lp/oci/tests/test_ociregistrycredentials.py
@@ -7,6 +7,7 @@ from __future__ import absolute_import, print_function, unicode_literals
import json
+from testtools import ExpectedException
from testtools.matchers import (
AfterPreprocessing,
Equals,
@@ -20,6 +21,7 @@ from lp.oci.interfaces.ociregistrycredentials import (
IOCIRegistryCredentials,
IOCIRegistryCredentialsSet,
OCIRegistryCredentialsAlreadyExist,
+ OCIRegistryCredentialsNotOwner,
)
from lp.oci.tests.helpers import OCIConfigHelperMixin
from lp.services.crypto.interfaces import IEncryptedContainer
@@ -39,9 +41,9 @@ class TestOCIRegistryCredentials(OCIConfigHelperMixin, TestCaseWithFactory):
self.setConfig()
def test_implements_interface(self):
+ owner = self.factory.makePerson()
oci_credentials = getUtility(IOCIRegistryCredentialsSet).new(
- owner=self.factory.makePerson(),
- url='http://example.org',
+ registrant=owner, owner=owner, url='http://example.org',
credentials={'username': 'foo', 'password': 'bar'})
self.assertProvides(oci_credentials, IOCIRegistryCredentials)
@@ -61,7 +63,7 @@ class TestOCIRegistryCredentials(OCIConfigHelperMixin, TestCaseWithFactory):
def test_credentials_set(self):
owner = self.factory.makePerson()
oci_credentials = self.factory.makeOCIRegistryCredentials(
- owner=owner,
+ registrant=owner, owner=owner,
url='http://example.org',
credentials={'username': 'foo', 'password': 'bar'})
@@ -73,7 +75,7 @@ class TestOCIRegistryCredentials(OCIConfigHelperMixin, TestCaseWithFactory):
def test_credentials_set_empty(self):
owner = self.factory.makePerson()
oci_credentials = self.factory.makeOCIRegistryCredentials(
- owner=owner,
+ registrant=owner, owner=owner,
url='http://example.org',
credentials={})
with person_logged_in(owner):
@@ -83,7 +85,7 @@ class TestOCIRegistryCredentials(OCIConfigHelperMixin, TestCaseWithFactory):
owner = self.factory.makePerson()
oci_credentials = removeSecurityProxy(
self.factory.makeOCIRegistryCredentials(
- owner=owner,
+ registrant=owner, owner=owner,
url='http://example.org',
credentials={"username": "test"}))
container = getUtility(IEncryptedContainer, "oci-registry-secrets")
@@ -99,7 +101,7 @@ class TestOCIRegistryCredentials(OCIConfigHelperMixin, TestCaseWithFactory):
owner = self.factory.makePerson()
oci_credentials = removeSecurityProxy(
self.factory.makeOCIRegistryCredentials(
- owner=owner,
+ registrant=owner, owner=owner,
url='http://example.org',
credentials={"password": "bar"}))
container = getUtility(IEncryptedContainer, "oci-registry-secrets")
@@ -113,7 +115,7 @@ class TestOCIRegistryCredentials(OCIConfigHelperMixin, TestCaseWithFactory):
owner = self.factory.makePerson()
oci_credentials = removeSecurityProxy(
self.factory.makeOCIRegistryCredentials(
- owner=owner,
+ registrant=owner, owner=owner,
url='http://example.org',
credentials={
"username": "foo", "password": "bar", "other": "baz"}))
@@ -143,9 +145,7 @@ class TestOCIRegistryCredentialsSet(OCIConfigHelperMixin, TestCaseWithFactory):
url = self.factory.getUniqueURL()
credentials = {'username': 'foo', 'password': 'bar'}
oci_credentials = getUtility(IOCIRegistryCredentialsSet).new(
- owner=owner,
- url=url,
- credentials=credentials)
+ registrant=owner, owner=owner, url=url, credentials=credentials)
self.assertEqual(oci_credentials.owner, owner)
self.assertEqual(oci_credentials.url, url)
self.assertEqual(oci_credentials.getCredentials(), credentials)
@@ -155,27 +155,46 @@ class TestOCIRegistryCredentialsSet(OCIConfigHelperMixin, TestCaseWithFactory):
url = self.factory.getUniqueURL()
credentials = {'username': 'foo', 'password': 'bar'}
getUtility(IOCIRegistryCredentialsSet).new(
- owner=owner,
- url=url,
- credentials=credentials)
+ registrant=owner, owner=owner, url=url, credentials=credentials)
self.assertRaises(
OCIRegistryCredentialsAlreadyExist,
getUtility(IOCIRegistryCredentialsSet).new,
- owner, url, credentials)
+ registrant=owner, owner=owner, url=url, credentials=credentials)
+
+ def test_new_not_owner(self):
+ registrant = self.factory.makePerson()
+ other_person = self.factory.makePerson()
+ other_team = self.factory.makeTeam(owner=other_person)
+ url = self.factory.getUniqueURL()
+ credentials = {'username': 'foo', 'password': 'bar'}
+ expected_message = "%s cannot create credentials owned by %s." % (
+ registrant.display_name, other_person.display_name)
+ with ExpectedException(
+ OCIRegistryCredentialsNotOwner, expected_message):
+ getUtility(IOCIRegistryCredentialsSet).new(
+ registrant=registrant,
+ owner=other_person,
+ url=url,
+ credentials=credentials)
+ expected_message = "%s is not a member of %s." % (
+ registrant.display_name, other_team.display_name)
+ with ExpectedException(
+ OCIRegistryCredentialsNotOwner, expected_message):
+ getUtility(IOCIRegistryCredentialsSet).new(
+ registrant=registrant,
+ owner=other_team,
+ url=url,
+ credentials=credentials)
def test_getOrCreate_existing(self):
owner = self.factory.makePerson()
url = self.factory.getUniqueURL()
credentials = {'username': 'foo', 'password': 'bar'}
new = getUtility(IOCIRegistryCredentialsSet).new(
- owner=owner,
- url=url,
- credentials=credentials)
+ registrant=owner, owner=owner, url=url, credentials=credentials)
existing = getUtility(IOCIRegistryCredentialsSet).getOrCreate(
- owner=owner,
- url=url,
- credentials=credentials)
+ registrant=owner, owner=owner, url=url, credentials=credentials)
self.assertEqual(new.id, existing.id)
@@ -184,18 +203,42 @@ class TestOCIRegistryCredentialsSet(OCIConfigHelperMixin, TestCaseWithFactory):
url = self.factory.getUniqueURL()
credentials = {'username': 'foo', 'password': 'bar'}
new = getUtility(IOCIRegistryCredentialsSet).getOrCreate(
- owner=owner,
- url=url,
- credentials=credentials)
+ registrant=owner, owner=owner, url=url, credentials=credentials)
self.assertEqual(new.owner, owner)
self.assertEqual(new.url, url)
self.assertEqual(new.getCredentials(), credentials)
+ def test_getOrCreate_not_owner(self):
+ registrant = self.factory.makePerson()
+ other_person = self.factory.makePerson()
+ other_team = self.factory.makeTeam(owner=other_person)
+ url = self.factory.getUniqueURL()
+ credentials = {'username': 'foo', 'password': 'bar'}
+ expected_message = "%s cannot create credentials owned by %s." % (
+ registrant.display_name, other_person.display_name)
+ with ExpectedException(
+ OCIRegistryCredentialsNotOwner, expected_message):
+ getUtility(IOCIRegistryCredentialsSet).getOrCreate(
+ registrant=registrant,
+ owner=other_person,
+ url=url,
+ credentials=credentials)
+ expected_message = "%s is not a member of %s." % (
+ registrant.display_name, other_team.display_name)
+ with ExpectedException(
+ OCIRegistryCredentialsNotOwner, expected_message):
+ getUtility(IOCIRegistryCredentialsSet).getOrCreate(
+ registrant=registrant,
+ owner=other_team,
+ url=url,
+ credentials=credentials)
+
def test_findByOwner(self):
owner = self.factory.makePerson()
for _ in range(3):
- self.factory.makeOCIRegistryCredentials(owner=owner)
+ self.factory.makeOCIRegistryCredentials(
+ registrant=owner, owner=owner)
# make some that have a different owner
for _ in range(5):
self.factory.makeOCIRegistryCredentials()
diff --git a/lib/lp/registry/browser/person.py b/lib/lp/registry/browser/person.py
index eed3ac1..facd4d2 100644
--- a/lib/lp/registry/browser/person.py
+++ b/lib/lp/registry/browser/person.py
@@ -3933,8 +3933,7 @@ class PersonEditOCIRegistryCredentialsView(LaunchpadFormView):
'password': password}
try:
getUtility(IOCIRegistryCredentialsSet).new(
- owner=owner,
- url=url,
+ registrant=self.user, owner=owner, url=url,
credentials=credentials)
except OCIRegistryCredentialsAlreadyExist:
self.setFieldError(
@@ -3946,8 +3945,7 @@ class PersonEditOCIRegistryCredentialsView(LaunchpadFormView):
credentials = {'username': username}
try:
getUtility(IOCIRegistryCredentialsSet).new(
- owner=owner,
- url=url,
+ registrant=self.user, owner=owner, url=url,
credentials=credentials)
except OCIRegistryCredentialsAlreadyExist:
self.setFieldError(
diff --git a/lib/lp/registry/browser/tests/test_person.py b/lib/lp/registry/browser/tests/test_person.py
index e3f74db..55ab037 100644
--- a/lib/lp/registry/browser/tests/test_person.py
+++ b/lib/lp/registry/browser/tests/test_person.py
@@ -1358,7 +1358,8 @@ class TestPersonOCIRegistryCredentialsView(
url = unicode(self.factory.getUniqueURL())
credentials = {'username': 'foo', 'password': 'bar'}
getUtility(IOCIRegistryCredentialsSet).new(
- owner=self.owner, url=url, credentials=credentials)
+ registrant=self.user, owner=self.owner, url=url,
+ credentials=credentials)
login_person(self.user)
view = create_initialized_view(
self.owner, '+oci-registry-credentials', principal=self.user)
@@ -1374,7 +1375,8 @@ class TestPersonOCIRegistryCredentialsView(
third_url = unicode(self.factory.getUniqueURL())
credentials = {'username': 'foo', 'password': 'bar'}
registry_credentials = getUtility(IOCIRegistryCredentialsSet).new(
- owner=self.owner, url=url, credentials=credentials)
+ registrant=self.user, owner=self.owner, url=url,
+ credentials=credentials)
browser = self.getViewBrowser(
self.owner, view_name='+oci-registry-credentials', user=self.user)
@@ -1453,7 +1455,8 @@ class TestPersonOCIRegistryCredentialsView(
credentials = {'username': 'foo', 'password': 'bar'}
image_name = self.factory.getUniqueUnicode()
registry_credentials = getUtility(IOCIRegistryCredentialsSet).new(
- owner=self.owner, url=url, credentials=credentials)
+ registrant=self.user, owner=self.owner, url=url,
+ credentials=credentials)
getUtility(IOCIPushRuleSet).new(
recipe=self.recipe,
registry_credentials=registry_credentials,
@@ -1502,7 +1505,8 @@ class TestPersonOCIRegistryCredentialsView(
url = unicode(self.factory.getUniqueURL())
credentials = {'username': 'foo', 'password': 'bar'}
registry_credentials = getUtility(IOCIRegistryCredentialsSet).new(
- owner=self.owner, url=url, credentials=credentials)
+ registrant=self.user, owner=self.owner, url=url,
+ credentials=credentials)
IStore(registry_credentials).flush()
registry_credentials_id = removeSecurityProxy(registry_credentials).id
image_name = self.factory.getUniqueUnicode()
diff --git a/lib/lp/testing/factory.py b/lib/lp/testing/factory.py
index efc5c57..e8fd8ed 100644
--- a/lib/lp/testing/factory.py
+++ b/lib/lp/testing/factory.py
@@ -5096,11 +5096,13 @@ class BareLaunchpadObjectFactory(ObjectFactory):
store.add(job)
return job
- def makeOCIRegistryCredentials(self, owner=None, url=None,
+ def makeOCIRegistryCredentials(self, registrant=None, owner=None, url=None,
credentials=None):
"""Make a new OCIRegistryCredentials."""
+ if registrant is None:
+ registrant = self.makePerson()
if owner is None:
- owner = self.makePerson()
+ owner = self.makeTeam(registrant)
if url is None:
url = self.getUniqueURL()
if credentials is None:
@@ -5108,8 +5110,7 @@ class BareLaunchpadObjectFactory(ObjectFactory):
'username': self.getUniqueUnicode(),
'password': self.getUniqueUnicode()}
return getUtility(IOCIRegistryCredentialsSet).new(
- owner=owner,
- url=url,
+ registrant=registrant, owner=owner, url=url,
credentials=credentials)
def makeOCIPushRule(self, recipe=None, registry_credentials=None,