Skip to content

Commit 553dc44

Browse files
authored
Handle duplicate publishers IntegrityError (#18412)
* Handle integrityeror for duplicate publishers * Update translations
1 parent b1d0f63 commit 553dc44

File tree

3 files changed

+57
-9
lines changed

3 files changed

+57
-9
lines changed

tests/unit/accounts/test_views.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
HTTPTooManyRequests,
1717
HTTPUnauthorized,
1818
)
19-
from sqlalchemy.exc import NoResultFound
19+
from sqlalchemy.exc import IntegrityError, NoResultFound
2020
from webauthn.authentication.verify_authentication_response import (
2121
VerifiedAuthentication,
2222
)
@@ -4533,6 +4533,47 @@ def test_add_pending_oidc_publisher_already_exists(
45334533
)
45344534
]
45354535

4536+
def test_add_pending_oidc_publisher_integrityerror(self, monkeypatch, db_request):
4537+
db_request.user = UserFactory.create()
4538+
EmailFactory(user=db_request.user, verified=True, primary=True)
4539+
db_request.db.add = pretend.raiser(IntegrityError("foo", "bar", "baz"))
4540+
4541+
db_request.registry = pretend.stub(
4542+
settings={
4543+
"github.token": "fake-api-token",
4544+
}
4545+
)
4546+
db_request.flags = pretend.stub(
4547+
disallow_oidc=pretend.call_recorder(lambda f=None: False)
4548+
)
4549+
db_request.POST = MultiDict(
4550+
{
4551+
"owner": "some-owner",
4552+
"repository": "some-repository",
4553+
"workflow_filename": "some-workflow-filename.yml",
4554+
"environment": "some-environment",
4555+
"project_name": "some-project-name",
4556+
}
4557+
)
4558+
4559+
view = views.ManageAccountPublishingViews(db_request)
4560+
4561+
monkeypatch.setattr(
4562+
views.PendingGitHubPublisherForm,
4563+
"_lookup_owner",
4564+
lambda *a: {"login": "some-owner", "id": "some-owner-id"},
4565+
)
4566+
4567+
monkeypatch.setattr(
4568+
view, "_check_ratelimits", pretend.call_recorder(lambda: None)
4569+
)
4570+
monkeypatch.setattr(
4571+
view, "_hit_ratelimits", pretend.call_recorder(lambda: None)
4572+
)
4573+
4574+
resp = view.add_pending_github_oidc_publisher()
4575+
assert isinstance(resp, HTTPSeeOther)
4576+
45364577
@pytest.mark.parametrize(
45374578
("view_name", "publisher_name", "post_body", "publisher_class"),
45384579
[

warehouse/accounts/views.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from pyramid.security import forget, remember
2222
from pyramid.view import view_config, view_defaults
2323
from sqlalchemy import and_, func, select
24-
from sqlalchemy.exc import NoResultFound
24+
from sqlalchemy.exc import IntegrityError, NoResultFound
2525
from webauthn.helpers import bytes_to_base64url
2626
from webob.multidict import MultiDict
2727

@@ -1765,8 +1765,15 @@ def _add_pending_oidc_publisher(
17651765

17661766
pending_publisher = make_pending_publisher(self.request, form)
17671767

1768-
self.request.db.add(pending_publisher)
1769-
self.request.db.flush() # To get the new ID
1768+
try:
1769+
self.request.db.add(pending_publisher)
1770+
self.request.db.flush() # To get the new ID
1771+
except IntegrityError:
1772+
# The user has probably double-posted and a new publisher was
1773+
# created after our check for duplicates ran. The success message
1774+
# is probably already in the flash queue, so just redirect to the
1775+
# expected page on success if this is the response they are served.
1776+
return HTTPSeeOther(self.request.path)
17701777

17711778
self.request.user.record_event(
17721779
tag=EventTag.Account.PendingOIDCPublisherAdded,

warehouse/locale/messages.pot

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ msgstr ""
301301
msgid "Please review our updated <a href=\"${tos_url}\">Terms of Service</a>."
302302
msgstr ""
303303

304-
#: warehouse/accounts/views.py:1669 warehouse/accounts/views.py:1915
304+
#: warehouse/accounts/views.py:1669 warehouse/accounts/views.py:1922
305305
#: warehouse/manage/views/__init__.py:1409
306306
msgid ""
307307
"Trusted publishing is temporarily disabled. See https://pypi.org/help"
@@ -344,16 +344,16 @@ msgid ""
344344
" admins if this wasn't intentional."
345345
msgstr ""
346346

347-
#: warehouse/accounts/views.py:1786
347+
#: warehouse/accounts/views.py:1793
348348
msgid "Registered a new pending publisher to create "
349349
msgstr ""
350350

351-
#: warehouse/accounts/views.py:1928 warehouse/accounts/views.py:1941
352-
#: warehouse/accounts/views.py:1948
351+
#: warehouse/accounts/views.py:1935 warehouse/accounts/views.py:1948
352+
#: warehouse/accounts/views.py:1955
353353
msgid "Invalid publisher ID"
354354
msgstr ""
355355

356-
#: warehouse/accounts/views.py:1955
356+
#: warehouse/accounts/views.py:1962
357357
msgid "Removed trusted publisher for project "
358358
msgstr ""
359359

0 commit comments

Comments
 (0)