|
15 | 15 | GooglePublisherFactory, |
16 | 16 | PendingGitHubPublisherFactory, |
17 | 17 | ) |
| 18 | +from tests.common.db.organizations import OrganizationFactory |
18 | 19 | from tests.common.db.packaging import ProhibitedProjectFactory, ProjectFactory |
19 | 20 | from warehouse.events.tags import EventTag |
20 | 21 | from warehouse.macaroons import caveats |
|
27 | 28 | is_from_reusable_workflow, |
28 | 29 | should_send_environment_warning_email, |
29 | 30 | ) |
| 31 | +from warehouse.organizations.models import OrganizationProject |
30 | 32 | from warehouse.packaging import services |
31 | 33 | from warehouse.packaging.models import Project |
32 | 34 | from warehouse.rate_limiting.interfaces import IRateLimiter |
@@ -508,6 +510,74 @@ def test_mint_token_from_oidc_pending_publisher_ok(monkeypatch, db_request): |
508 | 510 | } |
509 | 511 |
|
510 | 512 |
|
| 513 | +def test_mint_token_from_oidc_pending_publisher_for_organization_ok( |
| 514 | + monkeypatch, db_request |
| 515 | +): |
| 516 | + """Test creating a project from an organization-owned pending publisher""" |
| 517 | + user = UserFactory.create() |
| 518 | + organization = OrganizationFactory.create() |
| 519 | + |
| 520 | + pending_publisher = PendingGitHubPublisherFactory.create( |
| 521 | + project_name="org-owned-project", |
| 522 | + added_by=user, |
| 523 | + repository_name="bar", |
| 524 | + repository_owner="foo", |
| 525 | + repository_owner_id="123", |
| 526 | + workflow_filename="example.yml", |
| 527 | + environment="fake", |
| 528 | + organization_id=organization.id, |
| 529 | + ) |
| 530 | + |
| 531 | + db_request.flags.disallow_oidc = lambda f=None: False |
| 532 | + db_request.body = json.dumps({"token": DUMMY_GITHUB_OIDC_JWT}) |
| 533 | + db_request.remote_addr = "0.0.0.0" |
| 534 | + |
| 535 | + ratelimiter = pretend.stub(clear=pretend.call_recorder(lambda id: None)) |
| 536 | + ratelimiters = { |
| 537 | + "user.oidc": ratelimiter, |
| 538 | + "ip.oidc": ratelimiter, |
| 539 | + } |
| 540 | + monkeypatch.setattr(views, "_ratelimiters", lambda r: ratelimiters) |
| 541 | + |
| 542 | + resp = views.mint_token_from_oidc(db_request) |
| 543 | + assert resp["success"] |
| 544 | + assert resp["token"].startswith("pypi-") |
| 545 | + |
| 546 | + # Verify project was created |
| 547 | + project = ( |
| 548 | + db_request.db.query(Project) |
| 549 | + .filter(Project.name == pending_publisher.project_name) |
| 550 | + .one() |
| 551 | + ) |
| 552 | + |
| 553 | + # Verify project is associated with organization |
| 554 | + org_project = ( |
| 555 | + db_request.db.query(OrganizationProject) |
| 556 | + .filter( |
| 557 | + OrganizationProject.organization_id == organization.id, |
| 558 | + OrganizationProject.project_id == project.id, |
| 559 | + ) |
| 560 | + .one() |
| 561 | + ) |
| 562 | + assert org_project.organization_id == organization.id |
| 563 | + assert org_project.project_id == project.id |
| 564 | + |
| 565 | + # Verify publisher was created |
| 566 | + publisher = db_request.db.query(GitHubPublisher).one() |
| 567 | + event = project.events.where( |
| 568 | + Project.Event.tag == EventTag.Project.OIDCPublisherAdded |
| 569 | + ).one() |
| 570 | + assert event.additional == { |
| 571 | + "publisher": publisher.publisher_name, |
| 572 | + "id": str(publisher.id), |
| 573 | + "specifier": str(publisher), |
| 574 | + "url": publisher.publisher_url(), |
| 575 | + "submitted_by": "OpenID created token", |
| 576 | + "reified_from_pending_publisher": True, |
| 577 | + "constrained_from_existing_publisher": False, |
| 578 | + } |
| 579 | + |
| 580 | + |
511 | 581 | def test_mint_token_from_pending_trusted_publisher_invalidates_others( |
512 | 582 | monkeypatch, db_request |
513 | 583 | ): |
|
0 commit comments