Skip to content

Commit 8bec93b

Browse files
woodruffwdi
andauthored
legacy: split attestation handling phases (#17067)
* legacy: split attestation handling phases Only persist attestations once the file is created. Signed-off-by: William Woodruff <william@trailofbits.com> * round out coverage Signed-off-by: William Woodruff <william@trailofbits.com> * cleanup, remove defunct test Signed-off-by: William Woodruff <william@trailofbits.com> --------- Signed-off-by: William Woodruff <william@trailofbits.com> Co-authored-by: Dustin Ingram <di@users.noreply.github.com>
1 parent 5845366 commit 8bec93b

File tree

2 files changed

+28
-21
lines changed

2 files changed

+28
-21
lines changed

tests/unit/forklift/test_legacy.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,7 @@ def storage_service_store(path, file_path, *, meta):
12321232
assert resp.status_code == 200
12331233
assert db_request.find_service.calls == [
12341234
pretend.call(IMetricsService, context=None),
1235+
pretend.call(IIntegrityService, context=None),
12351236
pretend.call(IFileStorage, name="archive"),
12361237
]
12371238
assert len(storage_service.store.calls) == 1
@@ -2796,6 +2797,7 @@ def storage_service_store(path, file_path, *, meta):
27962797
assert resp.status_code == 200
27972798
assert db_request.find_service.calls == [
27982799
pretend.call(IMetricsService, context=None),
2800+
pretend.call(IIntegrityService, context=None),
27992801
pretend.call(IFileStorage, name="archive"),
28002802
]
28012803
assert storage_service.store.calls == [
@@ -3159,6 +3161,7 @@ def storage_service_store(path, file_path, *, meta):
31593161
assert resp.status_code == 200
31603162
assert db_request.find_service.calls == [
31613163
pretend.call(IMetricsService, context=None),
3164+
pretend.call(IIntegrityService, context=None),
31623165
pretend.call(IFileStorage, name="archive"),
31633166
]
31643167
assert storage_service.store.calls == [

warehouse/forklift/legacy.py

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,6 @@ def file_upload(request):
10821082
# TODO: Remove sdist zip handling when #12245 is resolved
10831083
# (PEP 625 – Filename of a Source Distribution)
10841084
if form.filetype.data == "sdist" and filename.endswith(".zip"):
1085-
10861085
# PEP 625: Enforcement on filename extensions. Files ending with
10871086
# .zip will not be permitted.
10881087
send_pep625_extension_email(
@@ -1307,6 +1306,27 @@ def file_upload(request):
13071306
k: h.hexdigest().lower() for k, h in metadata_file_hashes.items()
13081307
}
13091308

1309+
# If the user provided attestations, verify them
1310+
# We persist these attestations subsequently, only after the
1311+
# release file is persisted.
1312+
integrity_service: IIntegrityService = request.find_service(
1313+
IIntegrityService, context=None
1314+
)
1315+
attestations: list[Attestation] = []
1316+
if "attestations" in request.POST and not request.flags.enabled(
1317+
AdminFlagValue.DISABLE_PEP740
1318+
):
1319+
try:
1320+
attestations = integrity_service.parse_attestations(
1321+
request,
1322+
Distribution(name=filename, digest=file_hashes["sha256"]),
1323+
)
1324+
except AttestationUploadError as e:
1325+
raise _exc_with_message(
1326+
HTTPBadRequest,
1327+
f"Invalid attestations supplied during upload: {e}",
1328+
)
1329+
13101330
# TODO: This should be handled by some sort of database trigger or a
13111331
# SQLAlchemy hook or the like instead of doing it inline in this
13121332
# view.
@@ -1375,28 +1395,12 @@ def file_upload(request):
13751395
)
13761396
)
13771397

1378-
# If the user provided attestations, verify and store them
1379-
if "attestations" in request.POST and not request.flags.enabled(
1380-
AdminFlagValue.DISABLE_PEP740
1381-
):
1382-
integrity_service: IIntegrityService = request.find_service(
1383-
IIntegrityService, context=None
1398+
# If we have attestations from above, persist them.
1399+
if attestations:
1400+
request.db.add(
1401+
integrity_service.build_provenance(request, file_, attestations)
13841402
)
13851403

1386-
try:
1387-
attestations: list[Attestation] = integrity_service.parse_attestations(
1388-
request,
1389-
Distribution(name=filename, digest=file_hashes["sha256"]),
1390-
)
1391-
request.db.add(
1392-
integrity_service.build_provenance(request, file_, attestations)
1393-
)
1394-
except AttestationUploadError as e:
1395-
raise _exc_with_message(
1396-
HTTPBadRequest,
1397-
f"Invalid attestations supplied during upload: {e}",
1398-
)
1399-
14001404
# Log successful attestation upload
14011405
metrics.increment("warehouse.upload.attestations.ok")
14021406

0 commit comments

Comments
 (0)