Skip to content

Commit dd2febc

Browse files
committed
Fix ActiveState model tests, OIDC utils tests
1 parent 0cb873e commit dd2febc

File tree

6 files changed

+74
-69
lines changed

6 files changed

+74
-69
lines changed

tests/common/db/oidc.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,11 @@ class Meta:
9595
model = ActiveStatePublisher
9696

9797
id = factory.Faker("uuid4", cast_to=None)
98-
sub = factory.Faker("pystr", max_chars=12)
99-
organization_id = factory.Faker("uuid4")
10098
organization = factory.Faker("pystr", max_chars=12)
101-
project_id = factory.Faker("uuid4")
10299
project = factory.Faker("pystr", max_chars=12)
103100
actor = factory.Faker("pystr", max_chars=12)
104101
actor_id = factory.Faker("uuid4")
105-
branch_id = factory.Faker("uuid4")
102+
ingredient = factory.Faker("pystr", max_chars=12)
106103

107104

108105
class PendingActiveStatePublisherFactory(WarehouseFactory):
@@ -111,10 +108,9 @@ class Meta:
111108

112109
id = factory.Faker("uuid4", cast_to=None)
113110
project_name = factory.Faker("pystr", max_chars=12)
114-
organization_id = factory.Faker("uuid4")
115111
organization = factory.Faker("pystr", max_chars=12)
116-
project_id = factory.Faker("uuid4")
117112
project = factory.Faker("pystr", max_chars=12)
118113
actor = factory.Faker("pystr", max_chars=12)
119114
actor_id = factory.Faker("uuid4")
120115
added_by = factory.SubFactory(UserFactory)
116+
ingredient = factory.Faker("pystr", max_chars=12)

tests/unit/oidc/models/test_activestate.py

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@
2828
ORG_URL_NAME = "fakeorg"
2929
PROJECT_NAME = "fakeproject"
3030
ACTOR_ID = "00000000-0000-1000-8000-000000000002"
31+
ACTOR = "fakeuser"
32+
INGREDIENT = "fakeingredientname"
3133
# This follows the format of the subject that ActiveState sends us. We don't
3234
# validate the format when verifying the JWT. That should happen when the
3335
# Publisher is configured. We just need to make sure that the subject matches
3436
#
3537
# Technically, the branch should only be present if a branch was provided in the JWT
3638
# claims
37-
SUBJECT = "org:fake_org_id:project:fake_project_id"
39+
SUBJECT = f"org:{ORG_URL_NAME}:project:{PROJECT_NAME}"
3840

3941

4042
def test_lookup_strategies():
@@ -47,8 +49,9 @@ def test_lookup_strategies():
4749

4850
def new_signed_claims(
4951
sub: str = SUBJECT,
50-
actor: str = "fakeuser",
52+
actor: str = ACTOR,
5153
actor_id: str = ACTOR_ID,
54+
ingredient: str = INGREDIENT,
5255
organization: str = ORG_URL_NAME,
5356
org_id: str = "fakeorgid",
5457
project: str = PROJECT_NAME,
@@ -62,14 +65,14 @@ def new_signed_claims(
6265
"sub": sub,
6366
"actor": actor,
6467
"actor_id": actor_id,
68+
"ingredient": ingredient,
6569
"organization_id": org_id,
6670
"organization": organization,
6771
"project_visibility": project_visibility,
6872
"project_id": project_id,
6973
"project_path": project_path,
70-
"project_name": project,
71-
"builder": "fakebuilder",
72-
"ingredient": "fakeingredient",
74+
"project": project,
75+
"builder": "pypi-publisher",
7376
}
7477
)
7578
if branch_id:
@@ -109,6 +112,8 @@ def test_activestate_publisher_all_known_claims(self):
109112
"organization",
110113
"project",
111114
"actor_id",
115+
"actor",
116+
"builder",
112117
"sub",
113118
# optional verifiable claims
114119
"branch_id",
@@ -120,15 +125,14 @@ def test_activestate_publisher_all_known_claims(self):
120125
"aud",
121126
# unchecked claims
122127
"project_visibility",
123-
"project_name",
124128
"project_path",
125-
"organization",
129+
"ingredient",
130+
"organization_id",
131+
"project_id",
126132
}
127133

128134
def test_activestate_publisher_unaccounted_claims(self, monkeypatch):
129-
publisher = ActiveStatePublisher(
130-
sub=SUBJECT,
131-
)
135+
publisher = ActiveStatePublisher()
132136

133137
scope = pretend.stub()
134138
sentry_sdk = pretend.stub(
@@ -161,21 +165,25 @@ def test_activestate_publisher_unaccounted_claims(self, monkeypatch):
161165
("organization", False),
162166
("project", False),
163167
("actor_id", False),
164-
("branch_id", True),
165-
("organization", True),
168+
("actor", False),
169+
("builder", False),
170+
("ingredient", True),
171+
("organization_id", True),
172+
("project_id", True),
166173
("project_visibility", True),
167-
("project_name", True),
168174
("project_path", True),
175+
("branch_id", True),
169176
],
170177
)
171178
def test_activestate_publisher_missing_claims(
172179
self, monkeypatch, claim_to_drop: str, valid: bool
173180
):
174181
publisher = ActiveStatePublisher(
175-
sub=SUBJECT,
176182
organization=ORG_URL_NAME,
177183
project=PROJECT_NAME,
178184
actor_id=ACTOR_ID,
185+
actor=ACTOR,
186+
ingredient=INGREDIENT,
179187
)
180188

181189
scope = pretend.stub()
@@ -216,10 +224,11 @@ def test_activestate_publisher_org_id_verified(
216224
self, expect: str, actual: str, valid: bool
217225
):
218226
publisher = ActiveStatePublisher(
219-
sub=SUBJECT,
220227
organization=actual,
221228
project=PROJECT_NAME,
222229
actor_id=ACTOR_ID,
230+
actor=ACTOR,
231+
ingredient=INGREDIENT,
223232
)
224233

225234
signed_claims = new_signed_claims(organization=expect)
@@ -236,10 +245,11 @@ def test_activestate_publisher_project_id_verified(
236245
self, expect: str, actual: str, valid: bool
237246
):
238247
publisher = ActiveStatePublisher(
239-
sub=SUBJECT,
240248
organization=ORG_URL_NAME,
241249
project=actual,
242250
actor_id=ACTOR_ID,
251+
actor=ACTOR,
252+
ingredient=INGREDIENT,
243253
)
244254

245255
signed_claims = new_signed_claims(project=expect)
@@ -256,10 +266,11 @@ def test_activestate_publisher_user_id_verified(
256266
self, expect: str, actual: str, valid: bool
257267
):
258268
publisher = ActiveStatePublisher(
259-
sub=SUBJECT,
260269
organization=ORG_URL_NAME,
261270
project=PROJECT_NAME,
262271
actor_id=actual,
272+
actor=ACTOR,
273+
ingredient=INGREDIENT,
263274
)
264275

265276
signed_claims = new_signed_claims(actor_id=expect)
@@ -296,7 +307,8 @@ def test_activestate_publisher_user_id_verified(
296307
)
297308
def test_activestate_publisher_sub(self, expected: str, actual: str, valid: bool):
298309
check = ActiveStatePublisher.__required_verifiable_claims__["sub"]
299-
assert check(expected, actual, pretend.stub()) is valid
310+
signed_claims = new_signed_claims(sub=actual)
311+
assert check(expected, actual, signed_claims) is valid
300312

301313

302314
class TestPendingActiveStatePublisher:

tests/unit/oidc/test_utils.py

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -115,80 +115,73 @@ def test_find_publisher_by_issuer_google(db_request, sub, expected_id):
115115

116116

117117
@pytest.mark.parametrize(
118-
"expected_id, sub, organization_id, project_id, actor_id, branch_id",
118+
"expected_id, sub, organization, project, actor_id, actor",
119119
[
120120
(
121121
uuid.UUID("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"),
122-
"org:00000000-1000-8000-0000-000000000001:project:00000000-1000-8000-0000-000000000002", # noqa
123-
"00000000-1000-8000-0000-000000000001",
124-
"00000000-1000-8000-0000-000000000002",
122+
"org:fakeorg1:project:fakeproject1",
123+
"fakeorg1",
124+
"fakeproject1",
125125
"00000000-1000-8000-0000-000000000003",
126-
None,
126+
"fakeuser1",
127127
),
128128
(
129129
uuid.UUID("bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"),
130-
"org:00000000-1000-8000-0000-000000000004:project:00000000-1000-8000-0000-000000000005", # noqa
131-
"00000000-1000-8000-0000-000000000004",
132-
"00000000-1000-8000-0000-000000000005",
130+
"org:fakeorg2:project:fakeproject2",
131+
"fakeorg2",
132+
"fakeproject2",
133133
"00000000-1000-8000-0000-000000000006",
134-
None,
134+
"fakeuser2",
135135
),
136136
(
137137
uuid.UUID("cccccccc-cccc-cccc-cccc-cccccccccccc"),
138-
"org:00000000-1000-8000-0000-000000000007:project:00000000-1000-8000-0000-000000000008:branch_id:00000000-1000-8000-0000-000000000010", # noqa
139-
"00000000-1000-8000-0000-000000000007",
140-
"00000000-1000-8000-0000-000000000008",
138+
"org:fakeorg3:project:fakeproject3",
139+
"fakeorg3",
140+
"fakeproject3",
141141
"00000000-1000-8000-0000-000000000009",
142-
"00000000-1000-8000-0000-000000000010",
142+
"fakeuser3",
143143
),
144144
],
145145
)
146146
def test_find_publisher_by_issuer_activestate(
147147
db_request,
148148
sub: str,
149149
expected_id: str,
150-
organization_id: str,
151-
project_id: str,
150+
organization: str,
151+
project: str,
152152
actor_id: str,
153-
branch_id: str | None,
153+
actor: str,
154154
):
155155
ActiveStatePublisherFactory(
156156
id="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
157-
organization_id="00000000-1000-8000-0000-000000000001",
158-
project_id="00000000-1000-8000-0000-000000000002",
157+
organization="fakeorg1",
158+
project="fakeproject1",
159159
actor_id="00000000-1000-8000-0000-000000000003",
160-
sub="org:00000000-1000-8000-0000-000000000001:project:00000000-1000-8000-0000-000000000002", # noqa
160+
actor="fakeuser1",
161161
)
162162
ActiveStatePublisherFactory(
163163
id="bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
164-
organization_id="00000000-1000-8000-0000-000000000004",
165-
project_id="00000000-1000-8000-0000-000000000005",
164+
organization="fakeorg2",
165+
project="fakeproject2",
166166
actor_id="00000000-1000-8000-0000-000000000006",
167-
sub="org:00000000-1000-8000-0000-000000000004:project:00000000-1000-8000-0000-000000000005", # noqa
167+
actor="fakeuser2",
168168
)
169169
ActiveStatePublisherFactory(
170170
id="cccccccc-cccc-cccc-cccc-cccccccccccc",
171-
organization_id="00000000-1000-8000-0000-000000000007",
172-
project_id="00000000-1000-8000-0000-000000000008",
171+
organization="fakeorg3",
172+
project="fakeproject3",
173173
actor_id="00000000-1000-8000-0000-000000000009",
174-
branch_id="00000000-1000-8000-0000-000000000010",
175-
sub="org:00000000-1000-8000-0000-000000000007:project:00000000-1000-8000-0000-000000000008:branch_id:00000000-1000-8000-0000-000000000010", # noqa
174+
actor="fakeuser3",
176175
)
177176

178177
signed_claims = {
179178
"sub": sub,
180-
"organization_id": organization_id,
181-
"organization": "fakeOrg",
182-
"project_id": project_id,
183-
"project_name": "fakername1",
184-
"project_path": "fakeOrg/fakername1",
179+
"organization": organization,
180+
"project": project,
185181
"actor_id": actor_id,
186-
"project_visibility": "public",
182+
"actor": actor_id,
187183
}
188184

189-
if branch_id:
190-
signed_claims["branch_id"] = branch_id
191-
192185
assert (
193186
utils.find_publisher_by_issuer(
194187
db_request.db,

warehouse/oidc/models/_core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,9 @@ def lookup_by_claims(cls, session, signed_claims: SignedClaims):
134134
# We might not build a query if we know the claim set can't
135135
# satisfy it. If that's the case, then we skip.
136136
continue
137-
138137
if publisher := query.with_session(session).one_or_none():
139138
return publisher
139+
140140
return None
141141

142142
@classmethod

warehouse/oidc/models/activestate.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ def _check_sub(
5050
if len(components) < 2:
5151
return False
5252

53-
return f"{components[0]}:{components[1]}" == ground_truth
53+
return (
54+
f"{components[0]}:{components[1]}:{components[2]}:{components[3]}"
55+
== ground_truth
56+
)
5457

5558

5659
class ActiveStatePublisherMixin:
@@ -72,25 +75,23 @@ class ActiveStatePublisherMixin:
7275
"project": oidccore.check_claim_binary(str.__eq__),
7376
"actor_id": oidccore.check_claim_binary(str.__eq__),
7477
"actor": oidccore.check_claim_binary(str.__eq__),
75-
"ingredient": oidccore.check_claim_binary(str.__eq__),
7678
# This is the name of the builder in the ActiveState Platform that
7779
# publishes things to PyPI.
7880
"builder": oidccore.check_claim_invariant("pypi-publisher"),
7981
}
8082

8183
__optional_verifiable_claims__: dict[str, CheckClaimCallable[Any]] = {
84+
# Should we check that the pypi projectname matches this ingredient
85+
# name?
8286
"ingredient": oidccore.check_claim_binary(str.__eq__),
8387
}
8488

8589
__unchecked_claims__ = {
8690
"organization_id",
87-
"project_visibility",
8891
"project_id",
92+
"project_visibility",
8993
"project_path",
9094
"branch_id",
91-
# Should we check that the pypi projectname matches this ingredient
92-
# name?
93-
"ingredient",
9495
}
9596

9697
@staticmethod
@@ -99,7 +100,6 @@ def __lookup_all__(klass, signed_claims: SignedClaims):
99100
organization=signed_claims["organization"],
100101
project=signed_claims["project"],
101102
actor_id=signed_claims["actor_id"],
102-
actor=signed_claims["actor"],
103103
)
104104

105105
__lookup_strategies__ = [
@@ -110,6 +110,10 @@ def __lookup_all__(klass, signed_claims: SignedClaims):
110110
def sub(self) -> str:
111111
return f"org:{self.organization}:project:{self.project}"
112112

113+
@property
114+
def builder(self) -> str:
115+
return "pypi-publisher"
116+
113117
@property
114118
def publisher_name(self) -> str:
115119
return "ActiveState"
@@ -168,15 +172,16 @@ def reify(self, session):
168172
ActiveStatePublisher.organization == self.organization,
169173
ActiveStatePublisher.project == self.project,
170174
ActiveStatePublisher.actor_id == self.actor_id,
175+
ActiveStatePublisher.actor == self.actor,
171176
)
172177
.one_or_none()
173178
)
174179

175180
publisher = maybe_publisher or ActiveStatePublisher(
176-
sub=self.sub,
177181
organization=self.organization,
178182
project=self.project,
179183
actor_id=self.actor_id,
184+
actor=self.actor,
180185
)
181186

182187
session.delete(self)

warehouse/oidc/utils.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ def find_publisher_by_issuer(session, issuer_url, signed_claims, *, pending=Fals
6666
# This indicates a logic error, since we shouldn't have verified
6767
# claims for an issuer that we don't recognize and support.
6868
return None
69-
7069
return publisher_cls.lookup_by_claims(session, signed_claims)
7170

7271

0 commit comments

Comments
 (0)