Skip to content

Commit 2326e31

Browse files
committed
Update ActiveState code to use actor
1 parent d01e191 commit 2326e31

File tree

8 files changed

+244
-256
lines changed

8 files changed

+244
-256
lines changed

tests/common/db/oidc.py

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -95,25 +95,22 @@ 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")
100-
organization_url_name = factory.Faker("pystr", max_chars=12)
101-
project_id = factory.Faker("uuid4")
102-
activestate_project_name = factory.Faker("pystr", max_chars=12)
103-
user_id = factory.Faker("uuid4")
104-
branch_id = factory.Faker("uuid4")
98+
organization = factory.Faker("pystr", max_chars=12)
99+
project = factory.Faker("pystr", max_chars=12)
100+
actor = factory.Faker("pystr", max_chars=12)
101+
actor_id = factory.Faker("uuid4")
102+
ingredient = factory.Faker("pystr", max_chars=12)
105103

106104

107105
class PendingActiveStatePublisherFactory(WarehouseFactory):
108106
class Meta:
109107
model = PendingActiveStatePublisher
110108

111109
id = factory.Faker("uuid4", cast_to=None)
112-
sub = factory.Faker("pystr", max_chars=12)
113110
project_name = factory.Faker("pystr", max_chars=12)
114-
organization_id = factory.Faker("uuid4")
115-
organization_url_name = factory.Faker("pystr", max_chars=12)
116-
project_id = factory.Faker("uuid4")
117-
activestate_project_name = factory.Faker("pystr", max_chars=12)
118-
user_id = factory.Faker("uuid4")
111+
organization = factory.Faker("pystr", max_chars=12)
112+
project = factory.Faker("pystr", max_chars=12)
113+
actor = factory.Faker("pystr", max_chars=12)
114+
actor_id = factory.Faker("uuid4")
119115
added_by = factory.SubFactory(UserFactory)
116+
ingredient = factory.Faker("pystr", max_chars=12)

tests/unit/oidc/models/test_activestate.py

Lines changed: 92 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,18 @@
2525
PendingActiveStatePublisher,
2626
)
2727

28-
ORG_ID = "00000000-0000-1000-8000-000000000000"
29-
PROJECT_ID = "00000000-0000-1000-8000-000000000001"
30-
USER_ID = "00000000-0000-1000-8000-000000000002"
31-
BRANCH_ID = "00000000-0000-1000-8000-000000000003"
28+
ORG_URL_NAME = "fakeorg"
29+
PROJECT_NAME = "fakeproject"
30+
ACTOR_ID = "00000000-0000-1000-8000-000000000002"
31+
ACTOR = "fakeuser"
32+
INGREDIENT = "fakeingredientname"
3233
# This follows the format of the subject that ActiveState sends us. We don't
3334
# validate the format when verifying the JWT. That should happen when the
3435
# Publisher is configured. We just need to make sure that the subject matches
3536
#
3637
# Technically, the branch should only be present if a branch was provided in the JWT
3738
# claims
38-
SUBJECT = "org:fake_org_id:project:fake_project_id:branch_id:fake_branch_id"
39+
SUBJECT = f"org:{ORG_URL_NAME}:project:{PROJECT_NAME}"
3940

4041

4142
def test_lookup_strategies():
@@ -48,27 +49,30 @@ def test_lookup_strategies():
4849

4950
def new_signed_claims(
5051
sub: str = SUBJECT,
51-
organization_id: str = ORG_ID,
52-
org_url_name: str = "fakeorg",
53-
project_id: str = PROJECT_ID,
54-
project_name: str = "fakeproject",
52+
actor: str = ACTOR,
53+
actor_id: str = ACTOR_ID,
54+
ingredient: str = INGREDIENT,
55+
organization: str = ORG_URL_NAME,
56+
org_id: str = "fakeorgid",
57+
project: str = PROJECT_NAME,
58+
project_id: str = "fakeprojectid",
5559
project_path: str = "fakeorg/fakeproject",
56-
user_id: str = USER_ID,
5760
project_visibility: str = "public",
5861
branch_id: str | None = None,
5962
) -> SignedClaims:
60-
project_name = "fakeproject"
61-
org_url_name = "fakeorg"
6263
claims = SignedClaims(
6364
{
6465
"sub": sub,
65-
"organization_id": organization_id,
66-
"organization_url_name": org_url_name,
66+
"actor": actor,
67+
"actor_id": actor_id,
68+
"ingredient": ingredient,
69+
"organization_id": org_id,
70+
"organization": organization,
71+
"project_visibility": project_visibility,
6772
"project_id": project_id,
68-
"project_name": project_name,
6973
"project_path": project_path,
70-
"user_id": user_id,
71-
"project_visibility": project_visibility,
74+
"project": project,
75+
"builder": "pypi-publisher",
7276
}
7377
)
7478
if branch_id:
@@ -85,9 +89,7 @@ def test_publisher_name(self):
8589
def test_publisher_url(self):
8690
org_name = "fakeorg"
8791
project_name = "fakeproject"
88-
publisher = ActiveStatePublisher(
89-
organization_url_name=org_name, activestate_project_name=project_name
90-
)
92+
publisher = ActiveStatePublisher(organization=org_name, project=project_name)
9193

9294
assert (
9395
publisher.publisher_url()
@@ -97,9 +99,7 @@ def test_publisher_url(self):
9799
def test_stringifies_as_project_url(self):
98100
org_name = "fakeorg"
99101
project_name = "fakeproject"
100-
publisher = ActiveStatePublisher(
101-
organization_url_name=org_name, activestate_project_name=project_name
102-
)
102+
publisher = ActiveStatePublisher(organization=org_name, project=project_name)
103103

104104
assert (
105105
str(publisher)
@@ -109,9 +109,11 @@ def test_stringifies_as_project_url(self):
109109
def test_activestate_publisher_all_known_claims(self):
110110
assert ActiveStatePublisher.all_known_claims() == {
111111
# verifiable claims
112-
"organization_id",
113-
"project_id",
114-
"user_id",
112+
"organization",
113+
"project",
114+
"actor_id",
115+
"actor",
116+
"builder",
115117
"sub",
116118
# optional verifiable claims
117119
"branch_id",
@@ -123,15 +125,14 @@ def test_activestate_publisher_all_known_claims(self):
123125
"aud",
124126
# unchecked claims
125127
"project_visibility",
126-
"project_name",
127128
"project_path",
128-
"organization_url_name",
129+
"ingredient",
130+
"organization_id",
131+
"project_id",
129132
}
130133

131134
def test_activestate_publisher_unaccounted_claims(self, monkeypatch):
132-
publisher = ActiveStatePublisher(
133-
sub=SUBJECT,
134-
)
135+
publisher = ActiveStatePublisher()
135136

136137
scope = pretend.stub()
137138
sentry_sdk = pretend.stub(
@@ -161,24 +162,28 @@ def test_activestate_publisher_unaccounted_claims(self, monkeypatch):
161162
@pytest.mark.parametrize(
162163
("claim_to_drop", "valid"),
163164
[
164-
("organization_id", False),
165-
("project_id", False),
166-
("user_id", False),
167-
("branch_id", True),
168-
("organization_url_name", True),
165+
("organization", False),
166+
("project", False),
167+
("actor_id", False),
168+
("actor", False),
169+
("builder", False),
170+
("ingredient", True),
171+
("organization_id", True),
172+
("project_id", True),
169173
("project_visibility", True),
170-
("project_name", True),
171174
("project_path", True),
175+
("branch_id", True),
172176
],
173177
)
174178
def test_activestate_publisher_missing_claims(
175179
self, monkeypatch, claim_to_drop: str, valid: bool
176180
):
177181
publisher = ActiveStatePublisher(
178-
sub=SUBJECT,
179-
organization_id=ORG_ID,
180-
project_id=PROJECT_ID,
181-
user_id=USER_ID,
182+
organization=ORG_URL_NAME,
183+
project=PROJECT_NAME,
184+
actor_id=ACTOR_ID,
185+
actor=ACTOR,
186+
ingredient=INGREDIENT,
182187
)
183188

184189
scope = pretend.stub()
@@ -211,128 +216,99 @@ def test_activestate_publisher_missing_claims(
211216
@pytest.mark.parametrize(
212217
("expect", "actual", "valid"),
213218
[
214-
(ORG_ID, ORG_ID, True),
215-
(ORG_ID, PROJECT_ID, False),
219+
(ORG_URL_NAME, ORG_URL_NAME, True),
220+
(ORG_URL_NAME, PROJECT_NAME, False),
216221
],
217222
)
218223
def test_activestate_publisher_org_id_verified(
219224
self, expect: str, actual: str, valid: bool
220225
):
221226
publisher = ActiveStatePublisher(
222-
sub=SUBJECT,
223-
organization_id=actual,
224-
project_id=PROJECT_ID,
225-
user_id=USER_ID,
227+
organization=actual,
228+
project=PROJECT_NAME,
229+
actor_id=ACTOR_ID,
230+
actor=ACTOR,
231+
ingredient=INGREDIENT,
226232
)
227233

228-
signed_claims = new_signed_claims(organization_id=expect)
234+
signed_claims = new_signed_claims(organization=expect)
229235
assert publisher.verify_claims(signed_claims=signed_claims) is valid
230236

231237
@pytest.mark.parametrize(
232238
("expect", "actual", "valid"),
233239
[
234-
(BRANCH_ID, BRANCH_ID, True),
235-
(BRANCH_ID, PROJECT_ID, False),
236-
# If it's configured in the publisher, it must be present in the claim
237-
(BRANCH_ID, None, False),
238-
# If it's not configured in the publisher, we don't care what it is
239-
# in the claim
240-
(None, None, True),
241-
(None, PROJECT_ID, True),
242-
],
243-
)
244-
def test_activestate_publisher_branch_id_verified(
245-
self, expect: str, actual: str, valid: bool
246-
):
247-
publisher = ActiveStatePublisher(
248-
sub=SUBJECT,
249-
organization_id=ORG_ID,
250-
project_id=PROJECT_ID,
251-
user_id=USER_ID,
252-
branch_id=expect,
253-
)
254-
255-
signed_claims = new_signed_claims(branch_id=actual)
256-
assert publisher.verify_claims(signed_claims=signed_claims) is valid
257-
258-
@pytest.mark.parametrize(
259-
("expect", "actual", "valid"),
260-
[
261-
(PROJECT_ID, PROJECT_ID, True),
262-
(PROJECT_ID, ORG_ID, False),
240+
(PROJECT_NAME, PROJECT_NAME, True),
241+
(PROJECT_NAME, ORG_URL_NAME, False),
263242
],
264243
)
265244
def test_activestate_publisher_project_id_verified(
266245
self, expect: str, actual: str, valid: bool
267246
):
268247
publisher = ActiveStatePublisher(
269-
sub=SUBJECT,
270-
organization_id=ORG_ID,
271-
project_id=actual,
272-
user_id=USER_ID,
248+
organization=ORG_URL_NAME,
249+
project=actual,
250+
actor_id=ACTOR_ID,
251+
actor=ACTOR,
252+
ingredient=INGREDIENT,
273253
)
274254

275-
signed_claims = new_signed_claims(project_id=expect)
255+
signed_claims = new_signed_claims(project=expect)
276256
assert publisher.verify_claims(signed_claims=signed_claims) is valid
277257

278258
@pytest.mark.parametrize(
279259
("expect", "actual", "valid"),
280260
[
281-
(USER_ID, USER_ID, True),
282-
(USER_ID, ORG_ID, False),
261+
(ACTOR_ID, ACTOR_ID, True),
262+
(ACTOR_ID, ORG_URL_NAME, False),
283263
],
284264
)
285265
def test_activestate_publisher_user_id_verified(
286266
self, expect: str, actual: str, valid: bool
287267
):
288268
publisher = ActiveStatePublisher(
289-
sub=SUBJECT,
290-
organization_id=ORG_ID,
291-
project_id=PROJECT_ID,
292-
user_id=actual,
269+
organization=ORG_URL_NAME,
270+
project=PROJECT_NAME,
271+
actor_id=actual,
272+
actor=ACTOR,
273+
ingredient=INGREDIENT,
293274
)
294275

295-
signed_claims = new_signed_claims(user_id=expect)
276+
signed_claims = new_signed_claims(actor_id=expect)
296277
assert publisher.verify_claims(signed_claims=signed_claims) is valid
297278

298279
@pytest.mark.parametrize(
299280
("expected", "actual", "valid"),
300281
[
301282
# Both present: must match.
302283
(
303-
f"org:{ORG_ID}:project:{PROJECT_ID}",
304-
f"org:{ORG_ID}:project:{PROJECT_ID}",
305-
True,
306-
),
307-
# Both present, with branch id: must match.
308-
(
309-
f"org:{ORG_ID}:project:{PROJECT_ID}:branch_id:{BRANCH_ID}",
310-
f"org:{ORG_ID}:project:{PROJECT_ID}:branch_id:{BRANCH_ID}",
284+
f"org:{ORG_URL_NAME}:project:{PROJECT_NAME}",
285+
f"org:{ORG_URL_NAME}:project:{PROJECT_NAME}",
311286
True,
312287
),
313-
# sub configured without branch id, claim has branch id: must fail.
288+
# Wrong value, project, must fail.
314289
(
315-
f"org:{ORG_ID}:project:{PROJECT_ID}",
316-
f"org:{ORG_ID}:project:{PROJECT_ID}:branch_id:{BRANCH_ID}",
290+
f"org:{ORG_URL_NAME}:project:{PROJECT_NAME}",
291+
f"org:{ORG_URL_NAME}:project:{ORG_URL_NAME}",
317292
False,
318293
),
319-
# sub configured with branch id, claim missing branch id: must fail.
294+
# Wrong value, org_id, must fail.
320295
(
321-
f"org:{ORG_ID}:project:{PROJECT_ID}:branch_id:{BRANCH_ID}",
322-
f"org:{ORG_ID}:project:{PROJECT_ID}",
296+
f"org:{ORG_URL_NAME}:project:{PROJECT_NAME}",
297+
f"org:{PROJECT_NAME}:project:{PROJECT_NAME}",
323298
False,
324299
),
325-
# Wrong format for sub to expect from ActiveState: must fail.
300+
# Just nonsenes, must fail.
326301
(
327-
f"org:{ORG_ID}:project:{PROJECT_ID}",
328-
f"org:{ORG_ID}:project:{ORG_ID}",
302+
f"org:{ORG_URL_NAME}:project:{PROJECT_NAME}",
303+
"Nonsense",
329304
False,
330305
),
331306
],
332307
)
333308
def test_activestate_publisher_sub(self, expected: str, actual: str, valid: bool):
334309
check = ActiveStatePublisher.__required_verifiable_claims__["sub"]
335-
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
336312

337313

338314
class TestPendingActiveStatePublisher:
@@ -343,8 +319,10 @@ def test_reify_does_not_exist_yet(self, db_request):
343319
assert (
344320
db_request.db.query(ActiveStatePublisher)
345321
.filter_by(
346-
organization_id=pending_publisher.organization_id,
347-
sub=pending_publisher.sub,
322+
organization=pending_publisher.organization,
323+
project=pending_publisher.project,
324+
actor_id=pending_publisher.actor_id,
325+
actor=pending_publisher.actor,
348326
)
349327
.one_or_none()
350328
is None
@@ -353,16 +331,16 @@ def test_reify_does_not_exist_yet(self, db_request):
353331

354332
assert isinstance(publisher, ActiveStatePublisher)
355333
assert pending_publisher in db_request.db.deleted
356-
assert publisher.organization_id == pending_publisher.organization_id
334+
assert publisher.organization == pending_publisher.organization
357335
assert publisher.sub == pending_publisher.sub
358336

359337
def test_reify_already_exists(self, db_request):
360338
existing_publisher: ActiveStatePublisher = ActiveStatePublisherFactory.create()
361339
pending_publisher = PendingActiveStatePublisherFactory.create(
362-
organization_id=existing_publisher.organization_id,
363-
project_id=existing_publisher.project_id,
364-
branch_id=existing_publisher.branch_id,
365-
sub=existing_publisher.sub,
340+
organization=existing_publisher.organization,
341+
project=existing_publisher.project,
342+
actor_id=existing_publisher.actor_id,
343+
actor=existing_publisher.actor,
366344
)
367345
publisher = pending_publisher.reify(db_request.db)
368346

0 commit comments

Comments
 (0)