Skip to content

Commit 84851d2

Browse files
committed
publisher_name to method. Add more factories. Publisher agnostic token handler tests
1 parent 0ba3e9c commit 84851d2

File tree

4 files changed

+49
-42
lines changed

4 files changed

+49
-42
lines changed

tests/common/db/oidc.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,37 @@
1111
# limitations under the License.
1212

1313
import factory
14+
import pretend
1415

1516
from warehouse.oidc.models import (
1617
GitHubPublisher,
1718
GooglePublisher,
19+
OIDCPublisher,
1820
PendingGitHubPublisher,
1921
PendingGooglePublisher,
22+
PendingOIDCPublisher,
2023
)
2124

2225
from .accounts import UserFactory
2326
from .base import WarehouseFactory
2427

2528

29+
class PendingOIDCPublisherFactory(WarehouseFactory):
30+
class Meta:
31+
model = PendingOIDCPublisher
32+
33+
id = factory.Faker("uuid4", cast_to=None)
34+
project_name = "fake-nonexistent-project"
35+
added_by = factory.SubFactory(UserFactory)
36+
37+
38+
class OIDCPublisherFactory(WarehouseFactory):
39+
class Meta:
40+
model = OIDCPublisher
41+
42+
id = factory.Faker("uuid4", cast_to=None)
43+
44+
2645
class GitHubPublisherFactory(WarehouseFactory):
2746
class Meta:
2847
model = GitHubPublisher

tests/unit/oidc/test_views.py

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import pytest
1919

2020
from tests.common.db.accounts import UserFactory
21-
from tests.common.db.oidc import PendingGitHubPublisherFactory
21+
from tests.common.db.oidc import OIDCPublisherFactory, PendingOIDCPublisherFactory
2222
from tests.common.db.packaging import ProjectFactory
2323
from warehouse.events.tags import EventTag
2424
from warehouse.macaroons import caveats
@@ -111,7 +111,7 @@ def test_mint_token_from_github_oidc_not_enabled():
111111
{"token": {}},
112112
],
113113
)
114-
def test_mint_token_from_github_oidc_invalid_payload(body):
114+
def test_mint_token_oidc_invalid_payload(body):
115115
class Request:
116116
def __init__(self):
117117
self.response = pretend.stub(status=None)
@@ -202,7 +202,9 @@ def test_mint_token_from_trusted_publisher_lookup_fails():
202202

203203
def test_mint_token_from_oidc_pending_publisher_project_already_exists(db_request):
204204
project = ProjectFactory.create()
205-
pending_publisher = PendingGitHubPublisherFactory.create(project_name=project.name)
205+
pending_publisher = PendingOIDCPublisherFactory.create(
206+
project_name=project.name,
207+
)
206208

207209
db_request.flags.disallow_oidc = lambda f=None: False
208210
db_request.body = json.dumps({"token": "faketoken"})
@@ -237,14 +239,9 @@ def test_mint_token_from_oidc_pending_publisher_ok(
237239
db_request,
238240
):
239241
user = UserFactory.create()
240-
pending_publisher = PendingGitHubPublisherFactory.create(
242+
pending_publisher = PendingOIDCPublisherFactory.create(
241243
project_name="does-not-exist",
242244
added_by=user,
243-
repository_name="bar",
244-
repository_owner="foo",
245-
repository_owner_id="123",
246-
workflow_filename="example.yml",
247-
environment="",
248245
)
249246

250247
db_request.flags.disallow_oidc = lambda f=None: False
@@ -293,14 +290,9 @@ def test_mint_token_from_pending_trusted_publisher_invalidates_others(
293290
monkeypatch.setattr(views, "time", time)
294291

295292
user = UserFactory.create()
296-
pending_publisher = PendingGitHubPublisherFactory.create(
293+
pending_publisher = PendingPublisherFactory.create(
297294
project_name="does-not-exist",
298295
added_by=user,
299-
repository_name="bar",
300-
repository_owner="foo",
301-
repository_owner_id="123",
302-
workflow_filename="example.yml",
303-
environment="",
304296
)
305297

306298
# Create some other pending publishers for the same nonexistent project,
@@ -309,7 +301,7 @@ def test_mint_token_from_pending_trusted_publisher_invalidates_others(
309301
emailed_users = []
310302
for project_name in ["does_not_exist", "does-not-exist", "dOeS-NoT-ExISt"]:
311303
user = UserFactory.create()
312-
PendingGitHubPublisherFactory.create(
304+
PendingPublisherFactory.create(
313305
project_name=project_name,
314306
added_by=user,
315307
)
@@ -342,6 +334,7 @@ def test_mint_token_from_pending_trusted_publisher_invalidates_others(
342334
)
343335
db_request.body = json.dumps({"token": token})
344336
db_request.remote_addr = "0.0.0.0"
337+
db_request.db = pretend.stub(delete=pretend.call_recorder(lambda _S: None))
345338

346339
ratelimiter = pretend.stub(clear=pretend.call_recorder(lambda id: None))
347340
ratelimiters = {
@@ -369,6 +362,10 @@ def test_mint_token_from_pending_trusted_publisher_invalidates_others(
369362
pretend.call(db_request.remote_addr),
370363
]
371364

365+
assert db_request.db.delete.calls == [
366+
pretend.call(pending_publisher),
367+
]
368+
372369

373370
@pytest.mark.parametrize(
374371
("claims_in_token", "claims_input"),
@@ -379,7 +376,7 @@ def test_mint_token_from_pending_trusted_publisher_invalidates_others(
379376
],
380377
)
381378
def test_mint_token_from_oidc_no_pending_publisher_ok(
382-
monkeypatch, claims_in_token, claims_input
379+
monkeypatch, db_request, claims_in_token, claims_input
383380
):
384381
time = pretend.stub(time=pretend.call_recorder(lambda: 0))
385382
monkeypatch.setattr(views, "time", time)
@@ -389,14 +386,10 @@ def test_mint_token_from_oidc_no_pending_publisher_ok(
389386
project, "record_event", pretend.call_recorder(lambda **kw: None)
390387
)
391388

392-
publisher = github.GitHubPublisher(
393-
repository_name="fakerepo",
394-
repository_owner="fakeowner",
395-
repository_owner_id="fakeid",
396-
workflow_filename="fakeworkflow.yml",
397-
environment="fakeenv",
398-
)
389+
publisher = OIDCPublisherFactory.create()
399390
publisher.projects = [project]
391+
publisher.publisher_name = pretend.call_recorder(lambda **kw: "FakePublisher")
392+
publisher.publisher_url = pretend.call_recorder(lambda **kw: "FakePubURL")
400393
# NOTE: Can't set __str__ using pretend.stub()
401394
monkeypatch.setattr(publisher, "id", "fakepublisherid")
402395

@@ -425,16 +418,14 @@ def find_service(iface, **kw):
425418
return macaroon_service
426419
assert False, iface
427420

428-
request = pretend.stub(
429-
response=pretend.stub(status=None),
430-
body=json.dumps({"token": "faketoken"}),
431-
find_service=find_service,
432-
domain="fakedomain",
433-
remote_addr="0.0.0.0",
434-
flags=pretend.stub(disallow_oidc=lambda *a: False),
435-
)
421+
db_request.response = pretend.stub(status=None)
422+
db_request.body = json.dumps({"token": "faketoken"})
423+
db_request.find_service = find_service
424+
db_request.domain = "fakedomain"
425+
db_request.remote_addr = "0.0.0.0"
426+
db_request.flags = pretend.stub(disallow_oidc=lambda *a: False)
436427

437-
response = views.mint_token(oidc_service, request)
428+
response = views.mint_token(oidc_service, db_request)
438429
assert response == {
439430
"success": True,
440431
"token": "raw-macaroon",
@@ -448,7 +439,7 @@ def find_service(iface, **kw):
448439
assert macaroon_service.create_macaroon.calls == [
449440
pretend.call(
450441
"fakedomain",
451-
f"OpenID token: fakeworkflow.yml ({datetime.fromtimestamp(0).isoformat()})",
442+
f"OpenID token: OIDCPublisher(discriminator='oidc_publishers', id='fakepublisherid') ({datetime.fromtimestamp(0).isoformat()})",
452443
[
453444
caveats.OIDCPublisher(
454445
oidc_publisher_id="fakepublisherid",
@@ -463,11 +454,11 @@ def find_service(iface, **kw):
463454
assert project.record_event.calls == [
464455
pretend.call(
465456
tag=EventTag.Project.ShortLivedAPITokenAdded,
466-
request=request,
457+
request=db_request,
467458
additional={
468459
"expires": 900,
469-
"publisher_name": "GitHub",
470-
"publisher_url": f"https://github.com/{publisher.repository_owner}/{publisher.repository_name}", # noqa
460+
"publisher_name": "FakePublisher",
461+
"publisher_url": "FakePubURL",
471462
},
472463
)
473464
]

warehouse/oidc/models/_core.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,14 +225,11 @@ def verify_claims(self, signed_claims: SignedClaims):
225225

226226
return True
227227

228-
@property
229228
def publisher_name(self) -> str: # pragma: no cover
230229
# Only concrete subclasses are constructed.
231230
raise NotImplementedError
232231

233-
def publisher_url(
234-
self, claims: SignedClaims | None = None
235-
) -> str: # pragma: no cover
232+
def publisher_url(self, claims: SignedClaims | None = None) -> str | None:
236233
"""
237234
NOTE: This is **NOT** a `@property` because we pass `claims` to it.
238235
When calling, make sure to use `publisher_url()`

warehouse/oidc/views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ def mint_token(oidc_service: OIDCPublisherService, request: Request) -> JsonResp
250250
request=request,
251251
additional={
252252
"expires": expires_at,
253-
"publisher_name": publisher.publisher_name,
253+
"publisher_name": publisher.publisher_name(),
254254
"publisher_url": publisher.publisher_url(),
255255
},
256256
)

0 commit comments

Comments
 (0)