Skip to content

Commit

Permalink
Update ActiveState code to use actor
Browse files Browse the repository at this point in the history
  • Loading branch information
th3coop committed Aug 4, 2023
1 parent 2c61755 commit e7b3ef1
Show file tree
Hide file tree
Showing 8 changed files with 181 additions and 32 deletions.
4 changes: 2 additions & 2 deletions tests/common/db/oidc.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class Meta:
organization_url_name = factory.Faker("pystr", max_chars=12)
project_id = factory.Faker("uuid4")
activestate_project_name = factory.Faker("pystr", max_chars=12)
user_id = factory.Faker("uuid4")
actor_id = factory.Faker("uuid4")
branch_id = factory.Faker("uuid4")


Expand All @@ -115,5 +115,5 @@ class Meta:
organization_url_name = factory.Faker("pystr", max_chars=12)
project_id = factory.Faker("uuid4")
activestate_project_name = factory.Faker("pystr", max_chars=12)
user_id = factory.Faker("uuid4")
actor_id = factory.Faker("uuid4")
added_by = factory.SubFactory(UserFactory)
26 changes: 13 additions & 13 deletions tests/unit/oidc/models/test_activestate.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

ORG_ID = "00000000-0000-1000-8000-000000000000"
PROJECT_ID = "00000000-0000-1000-8000-000000000001"
USER_ID = "00000000-0000-1000-8000-000000000002"
ACTOR_ID = "00000000-0000-1000-8000-000000000002"
BRANCH_ID = "00000000-0000-1000-8000-000000000003"
# This follows the format of the subject that ActiveState sends us. We don't
# validate the format when verifying the JWT. That should happen when the
Expand All @@ -53,7 +53,7 @@ def new_signed_claims(
project_id: str = PROJECT_ID,
project_name: str = "fakeproject",
project_path: str = "fakeorg/fakeproject",
user_id: str = USER_ID,
actor_id: str = ACTOR_ID,
project_visibility: str = "public",
branch_id: str | None = None,
) -> SignedClaims:
Expand All @@ -67,7 +67,7 @@ def new_signed_claims(
"project_id": project_id,
"project_name": project_name,
"project_path": project_path,
"user_id": user_id,
"actor_id": actor_id,
"project_visibility": project_visibility,
}
)
Expand Down Expand Up @@ -111,7 +111,7 @@ def test_activestate_publisher_all_known_claims(self):
# verifiable claims
"organization_id",
"project_id",
"user_id",
"actor_id",
"sub",
# optional verifiable claims
"branch_id",
Expand Down Expand Up @@ -163,7 +163,7 @@ def test_activestate_publisher_unaccounted_claims(self, monkeypatch):
[
("organization_id", False),
("project_id", False),
("user_id", False),
("actor_id", False),
("branch_id", True),
("organization_url_name", True),
("project_visibility", True),
Expand All @@ -178,7 +178,7 @@ def test_activestate_publisher_missing_claims(
sub=SUBJECT,
organization_id=ORG_ID,
project_id=PROJECT_ID,
user_id=USER_ID,
actor_id=ACTOR_ID,
)

scope = pretend.stub()
Expand Down Expand Up @@ -222,7 +222,7 @@ def test_activestate_publisher_org_id_verified(
sub=SUBJECT,
organization_id=actual,
project_id=PROJECT_ID,
user_id=USER_ID,
actor_id=ACTOR_ID,
)

signed_claims = new_signed_claims(organization_id=expect)
Expand All @@ -248,7 +248,7 @@ def test_activestate_publisher_branch_id_verified(
sub=SUBJECT,
organization_id=ORG_ID,
project_id=PROJECT_ID,
user_id=USER_ID,
actor_id=ACTOR_ID,
branch_id=expect,
)

Expand All @@ -269,7 +269,7 @@ def test_activestate_publisher_project_id_verified(
sub=SUBJECT,
organization_id=ORG_ID,
project_id=actual,
user_id=USER_ID,
actor_id=ACTOR_ID,
)

signed_claims = new_signed_claims(project_id=expect)
Expand All @@ -278,8 +278,8 @@ def test_activestate_publisher_project_id_verified(
@pytest.mark.parametrize(
("expect", "actual", "valid"),
[
(USER_ID, USER_ID, True),
(USER_ID, ORG_ID, False),
(ACTOR_ID, ACTOR_ID, True),
(ACTOR_ID, ORG_ID, False),
],
)
def test_activestate_publisher_user_id_verified(
Expand All @@ -289,10 +289,10 @@ def test_activestate_publisher_user_id_verified(
sub=SUBJECT,
organization_id=ORG_ID,
project_id=PROJECT_ID,
user_id=actual,
actor_id=actual,
)

signed_claims = new_signed_claims(user_id=expect)
signed_claims = new_signed_claims(actor_id=expect)
assert publisher.verify_claims(signed_claims=signed_claims) is valid

@pytest.mark.parametrize(
Expand Down
12 changes: 6 additions & 6 deletions tests/unit/oidc/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def test_find_publisher_by_issuer_google(db_request, sub, expected_id):


@pytest.mark.parametrize(
"expected_id, sub, organization_id, project_id, user_id, branch_id",
"expected_id, sub, organization_id, project_id, actor_id, branch_id",
[
(
uuid.UUID("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"),
Expand Down Expand Up @@ -149,28 +149,28 @@ def test_find_publisher_by_issuer_activestate(
expected_id: str,
organization_id: str,
project_id: str,
user_id: str,
actor_id: str,
branch_id: str | None,
):
ActiveStatePublisherFactory(
id="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
organization_id="00000000-1000-8000-0000-000000000001",
project_id="00000000-1000-8000-0000-000000000002",
user_id="00000000-1000-8000-0000-000000000003",
actor_id="00000000-1000-8000-0000-000000000003",
sub="org:00000000-1000-8000-0000-000000000001:project:00000000-1000-8000-0000-000000000002", # noqa
)
ActiveStatePublisherFactory(
id="bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
organization_id="00000000-1000-8000-0000-000000000004",
project_id="00000000-1000-8000-0000-000000000005",
user_id="00000000-1000-8000-0000-000000000006",
actor_id="00000000-1000-8000-0000-000000000006",
sub="org:00000000-1000-8000-0000-000000000004:project:00000000-1000-8000-0000-000000000005", # noqa
)
ActiveStatePublisherFactory(
id="cccccccc-cccc-cccc-cccc-cccccccccccc",
organization_id="00000000-1000-8000-0000-000000000007",
project_id="00000000-1000-8000-0000-000000000008",
user_id="00000000-1000-8000-0000-000000000009",
actor_id="00000000-1000-8000-0000-000000000009",
branch_id="00000000-1000-8000-0000-000000000010",
sub="org:00000000-1000-8000-0000-000000000007:project:00000000-1000-8000-0000-000000000008:branch_id:00000000-1000-8000-0000-000000000010", # noqa
)
Expand All @@ -182,7 +182,7 @@ def test_find_publisher_by_issuer_activestate(
"project_id": project_id,
"project_name": "fakername1",
"project_path": "fakeOrg/fakername1",
"user_id": user_id,
"actor_id": actor_id,
"project_visibility": "public",
}

Expand Down
12 changes: 9 additions & 3 deletions tests/unit/oidc/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
import pytest

from tests.common.db.accounts import UserFactory
from tests.common.db.oidc import OIDCPublisherFactory, PendingOIDCPublisherFactory
from tests.common.db.oidc import (
OIDCPublisherFactory,
PendingGitHubPublisherFactory,
PendingOIDCPublisherFactory,
)
from tests.common.db.packaging import ProjectFactory
from warehouse.events.tags import EventTag
from warehouse.macaroons import caveats
Expand Down Expand Up @@ -285,7 +289,7 @@ def test_mint_token_from_pending_trusted_publisher_invalidates_others(
monkeypatch.setattr(views, "time", time)

user = UserFactory.create()
pending_publisher = PendingPublisherFactory.create(
pending_publisher = PendingGitHubPublisherFactory.create(
project_name="does-not-exist",
added_by=user,
)
Expand All @@ -296,7 +300,7 @@ def test_mint_token_from_pending_trusted_publisher_invalidates_others(
emailed_users = []
for project_name in ["does_not_exist", "does-not-exist", "dOeS-NoT-ExISt"]:
user = UserFactory.create()
PendingPublisherFactory.create(
PendingGitHubPublisherFactory.create(
project_name=project_name,
added_by=user,
)
Expand Down Expand Up @@ -340,6 +344,8 @@ def test_mint_token_from_pending_trusted_publisher_invalidates_others(

oidc_service = db_request.find_service(IOIDCPublisherService, name="github")

# This currently fails because it can't find the Publisher in the OIDC_SERVICE
# since there is no way to get a PendingPubliser by jwt fields.
resp = views.mint_token(oidc_service, db_request)
assert resp["success"]
assert resp["token"].startswith("pypi-")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Alter activestate publisher table to have actor_id
Revision ID: 6234fc5fa2ad
Revises: e8c7bb1b94c6
Create Date: 2023-08-01 21:09:17.643241
"""

import sqlalchemy as sa

from alembic import op

revision = "6234fc5fa2ad"
down_revision = "e8c7bb1b94c6"

# Note: It is VERY important to ensure that a migration does not lock for a
# long period of time and to ensure that each individual migration does
# not break compatibility with the *previous* version of the code base.
# This is because the migrations will be ran automatically as part of the
# deployment process, but while the previous version of the code is still
# up and running. Thus backwards incompatible changes must be broken up
# over multiple migrations inside of multiple pull requests in order to
# phase them in over multiple deploys.
#
# By default, migrations cannot wait more than 4s on acquiring a lock
# and each individual statement cannot take more than 5s. This helps
# prevent situations where a slow migration takes the entire site down.
#
# If you need to increase this timeout for a migration, you can do so
# by adding:
#
# op.execute("SET statement_timeout = 5000")
# op.execute("SET lock_timeout = 4000")
#
# To whatever values are reasonable for this migration as part of your
# migration.


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
"activestate_oidc_publishers",
sa.Column("actor_id", sa.VARCHAR(), nullable=False),
)
op.drop_constraint(
"_activestate_oidc_publisher_uc", "activestate_oidc_publishers", type_="unique"
)
op.create_unique_constraint(
"_activestate_oidc_publisher_uc",
"activestate_oidc_publishers",
[
"organization_id",
"organization_url_name",
"project_id",
"actor_id",
"branch_id",
],
)
op.drop_column("activestate_oidc_publishers", "user_id")
op.add_column(
"pending_activestate_oidc_publishers",
sa.Column("actor_id", sa.VARCHAR(), nullable=False),
)
op.drop_constraint(
"_pending_activestate_oidc_publisher_uc",
"pending_activestate_oidc_publishers",
type_="unique",
)
op.create_unique_constraint(
"_pending_activestate_oidc_publisher_uc",
"pending_activestate_oidc_publishers",
[
"organization_id",
"organization_url_name",
"project_id",
"actor_id",
"branch_id",
],
)
op.drop_column("pending_activestate_oidc_publishers", "user_id")
op.create_index(
"project_name_ultranormalized",
"projects",
[sa.text("ultranormalize_name(name)")],
unique=False,
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index("project_name_ultranormalized", table_name="projects")
op.add_column(
"pending_activestate_oidc_publishers",
sa.Column("user_id", sa.VARCHAR(), autoincrement=False, nullable=False),
)
op.drop_constraint(
"_pending_activestate_oidc_publisher_uc",
"pending_activestate_oidc_publishers",
type_="unique",
)
op.create_unique_constraint(
"_pending_activestate_oidc_publisher_uc",
"pending_activestate_oidc_publishers",
[
"organization_id",
"organization_url_name",
"project_id",
"user_id",
"branch_id",
],
)
op.drop_column("pending_activestate_oidc_publishers", "actor_id")
op.add_column(
"activestate_oidc_publishers",
sa.Column("user_id", sa.VARCHAR(), autoincrement=False, nullable=False),
)
op.drop_constraint(
"_activestate_oidc_publisher_uc", "activestate_oidc_publishers", type_="unique"
)
op.create_unique_constraint(
"_activestate_oidc_publisher_uc",
"activestate_oidc_publishers",
[
"organization_id",
"organization_url_name",
"project_id",
"user_id",
"branch_id",
],
)
op.drop_column("activestate_oidc_publishers", "actor_id")
# ### end Alembic commands ###
Loading

0 comments on commit e7b3ef1

Please sign in to comment.