From 963fd8241b4264d21d3a0a768c797ea58c8a97cb Mon Sep 17 00:00:00 2001 From: Mike Reiche Date: Fri, 24 Oct 2025 13:47:38 +0200 Subject: [PATCH 1/3] Add support for multiple patch levels --- .github/workflows/test.yml | 2 +- README.md | 2 +- owasp_dt/models/api_key.py | 18 ++++++------- patch.json => patch-full.json | 0 patch-minimal.json | 51 +++++++++++++++++++++++++++++++++++ regenerate-api-client.sh | 5 +++- schema.json | 6 ++--- test/test_projects.py | 4 +-- 8 files changed, 71 insertions(+), 17 deletions(-) rename patch.json => patch-full.json (100%) create mode 100644 patch-minimal.json diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dcb04ac..79e1e77 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Test and build +name: Test env: REGISTRY: ghcr.io diff --git a/README.md b/README.md index 5320897..4d24443 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ This library is part of a wider OWASP Dependency Track tool chain: 1. Install the requirements: `pip install -r requirements.txt` 2. Start a OWASP DT instance locally (like via. Docker-Compose): https://docs.dependencytrack.org/getting-started/deploy-docker/ -3. Run `regenerate-api-client.sh` +3. Run `regenerate-api-client.sh [patch-full.json|patch-minimal.json]` 4. Check if bug https://github.com/openapi-generators/openapi-python-client/issues/1256 is still in effect 5. Publish this library with the API version tag diff --git a/owasp_dt/models/api_key.py b/owasp_dt/models/api_key.py index 853669c..f38f72e 100644 --- a/owasp_dt/models/api_key.py +++ b/owasp_dt/models/api_key.py @@ -22,8 +22,8 @@ class ApiKey: last_used (Union[Unset, int]): UNIX epoch timestamp in milliseconds public_id (Union[Unset, str]): key (Union[Unset, str]): - legacy (Union[Unset, bool]): masked_key (Union[Unset, str]): + legacy (Union[Unset, bool]): """ comment: Union[Unset, str] = UNSET @@ -31,8 +31,8 @@ class ApiKey: last_used: Union[Unset, int] = UNSET public_id: Union[Unset, str] = UNSET key: Union[Unset, str] = UNSET - legacy: Union[Unset, bool] = UNSET masked_key: Union[Unset, str] = UNSET + legacy: Union[Unset, bool] = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -46,10 +46,10 @@ def to_dict(self) -> dict[str, Any]: key = self.key - legacy = self.legacy - masked_key = self.masked_key + legacy = self.legacy + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update({}) @@ -63,10 +63,10 @@ def to_dict(self) -> dict[str, Any]: field_dict["publicId"] = public_id if key is not UNSET: field_dict["key"] = key - if legacy is not UNSET: - field_dict["legacy"] = legacy if masked_key is not UNSET: field_dict["maskedKey"] = masked_key + if legacy is not UNSET: + field_dict["legacy"] = legacy return field_dict @@ -83,18 +83,18 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: key = d.pop("key", UNSET) - legacy = d.pop("legacy", UNSET) - masked_key = d.pop("maskedKey", UNSET) + legacy = d.pop("legacy", UNSET) + api_key = cls( comment=comment, created=created, last_used=last_used, public_id=public_id, key=key, - legacy=legacy, masked_key=masked_key, + legacy=legacy, ) api_key.additional_properties = d diff --git a/patch.json b/patch-full.json similarity index 100% rename from patch.json rename to patch-full.json diff --git a/patch-minimal.json b/patch-minimal.json new file mode 100644 index 0000000..5512994 --- /dev/null +++ b/patch-minimal.json @@ -0,0 +1,51 @@ +{ + "components": { + "schemas": { + "Vulnerability": { + "properties": { + "findingAttribution": { + "$ref": "#/components/schemas/FindingAttrib" + } + } + }, + "FindingAttrib": { + "type": "object", + "properties": { + "attributedOn": { + "type": "integer", + "description": "UNIX epoch timestamp in milliseconds", + "format": "int64" + }, + "analyzerIdentity": { + "type": "string", + "enum": [ + "INTERNAL_ANALYZER", + "OSSINDEX_ANALYZER", + "NPM_AUDIT_ANALYZER", + "VULNDB_ANALYZER", + "SNYK_ANALYZER", + "TRIVY_ANALYZER", + "NONE" + ] + }, + "component": { + "$ref": "#/components/schemas/Component" + }, + "vulnerability": { + "$ref": "#/components/schemas/Vulnerability" + }, + "alternateIdentifier": { + "type": "string" + }, + "referenceUrl": { + "type": "string" + }, + "uuid": { + "type": "string", + "format": "uuid" + } + } + } + } + } +} diff --git a/regenerate-api-client.sh b/regenerate-api-client.sh index 1e3f574..0e9d5c1 100755 --- a/regenerate-api-client.sh +++ b/regenerate-api-client.sh @@ -1,8 +1,11 @@ #!/usr/bin/env bash +PATCH_FILE="$1" +USE_PATCH_FILE="${PATCH_FILE:-patch-full.json}" + curl -lo openapi.json http://localhost:8081/api/openapi.json #jq -s 'reduce .[] as $item ({}; . * $item)' openapi.json patch.json > schema.json -jq -s '.[0] * .[1]' openapi.json patch.json > schema.json +jq -s '.[0] * .[1]' openapi.json "${USE_PATCH_FILE}" > schema.json jq 'del(.components.schemas.FindingAttribution)' schema.json > tmp.json mv tmp.json schema.json openapi-python-client generate --overwrite --path ./schema.json --meta none --config generator-config.yml diff --git a/schema.json b/schema.json index 1224d9d..e1127bf 100644 --- a/schema.json +++ b/schema.json @@ -13355,11 +13355,11 @@ "key": { "type": "string" }, - "legacy": { - "type": "boolean" - }, "maskedKey": { "type": "string" + }, + "legacy": { + "type": "boolean" } } }, diff --git a/test/test_projects.py b/test/test_projects.py index cdaff66..d6fe7c4 100644 --- a/test/test_projects.py +++ b/test/test_projects.py @@ -6,7 +6,7 @@ from owasp_dt.api.project import get_projects -@pytest.mark.depends(on=['test/test_upload.py::test_upload_sbom']) +#@pytest.mark.depends(on=['test/test_upload.py::test_upload_sbom']) def test_search_project_by_name(client: owasp_dt.Client): resp = get_projects.sync_detailed(client=client, name=test.project_name) projects = resp.parsed @@ -14,7 +14,7 @@ def test_search_project_by_name(client: owasp_dt.Client): assert projects[0].uuid is not None test.project_uuid = projects[0].uuid -@pytest.mark.depends(on=['test/test_upload.py::test_get_scan_status', 'test_search_project_by_name']) +#@pytest.mark.depends(on=['test/test_upload.py::test_get_scan_status', 'test_search_project_by_name']) def test_get_project_metrics(client: owasp_dt.Client): resp = get_project_current_metrics.sync_detailed(client=client, uuid=test.project_uuid) metrics = resp.parsed From 5d3c2435c3d66ac28afb2fdeeb833a1d00f86b19 Mon Sep 17 00:00:00 2001 From: Mike Reiche Date: Fri, 24 Oct 2025 13:58:33 +0200 Subject: [PATCH 2/3] Fix test depends --- test/test_projects.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_projects.py b/test/test_projects.py index d6fe7c4..cdaff66 100644 --- a/test/test_projects.py +++ b/test/test_projects.py @@ -6,7 +6,7 @@ from owasp_dt.api.project import get_projects -#@pytest.mark.depends(on=['test/test_upload.py::test_upload_sbom']) +@pytest.mark.depends(on=['test/test_upload.py::test_upload_sbom']) def test_search_project_by_name(client: owasp_dt.Client): resp = get_projects.sync_detailed(client=client, name=test.project_name) projects = resp.parsed @@ -14,7 +14,7 @@ def test_search_project_by_name(client: owasp_dt.Client): assert projects[0].uuid is not None test.project_uuid = projects[0].uuid -#@pytest.mark.depends(on=['test/test_upload.py::test_get_scan_status', 'test_search_project_by_name']) +@pytest.mark.depends(on=['test/test_upload.py::test_get_scan_status', 'test_search_project_by_name']) def test_get_project_metrics(client: owasp_dt.Client): resp = get_project_current_metrics.sync_detailed(client=client, uuid=test.project_uuid) metrics = resp.parsed From 4cc5af5cea1863de98cf5546f1a1c45537b05f12 Mon Sep 17 00:00:00 2001 From: Mike Reiche Date: Fri, 24 Oct 2025 14:00:03 +0200 Subject: [PATCH 3/3] Cleanups --- test/test_upload.py | 2 +- test/test_violations.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/test/test_upload.py b/test/test_upload.py index 461b826..7e32e00 100644 --- a/test/test_upload.py +++ b/test/test_upload.py @@ -1,4 +1,3 @@ -from pathlib import Path from time import sleep import pytest @@ -9,6 +8,7 @@ from owasp_dt.api.event import is_token_being_processed_1 from owasp_dt.models import UploadBomBody, IsTokenBeingProcessedResponse + def test_upload_sbom(client: owasp_dt.Client): with open(test.base_dir / "files/test.sbom.xml") as sbom_file: resp = upload_bom.sync_detailed(client=client, body=UploadBomBody( diff --git a/test/test_violations.py b/test/test_violations.py index 8065350..f2ca211 100644 --- a/test/test_violations.py +++ b/test/test_violations.py @@ -1,5 +1,4 @@ import pytest -from is_empty import empty import owasp_dt import test