From 41ee3400f92ce1e78fdf82513407aca37c9cd30a Mon Sep 17 00:00:00 2001 From: Keshav Priyadarshi Date: Fri, 2 Oct 2026 18:51:58 +0530 Subject: [PATCH 1/2] feat: include datasource_id in advisory API response Signed-off-by: Keshav Priyadarshi --- vulnerabilities/api_v3.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/vulnerabilities/api_v3.py b/vulnerabilities/api_v3.py index 6c39e8617..3202968a0 100644 --- a/vulnerabilities/api_v3.py +++ b/vulnerabilities/api_v3.py @@ -171,6 +171,7 @@ class Meta: fields = [ "advisory_id", "advisory_uid", + "datasource_id", "url", "aliases", "summary", @@ -392,6 +393,7 @@ class Meta: fields = [ "advisory_id", "advisory_uid", + "datasource_id", "url", "aliases", "summary", @@ -713,6 +715,7 @@ def get_affected_advisories_bulk(packages, max_advisories, base_url, reachabilit "primary_advisory__avid", "primary_advisory__summary", "primary_advisory__advisory_id", + "primary_advisory__datasource_id", "primary_advisory__is_curation", ) ) @@ -842,6 +845,7 @@ def get_affected_advisories_bulk(packages, max_advisories, base_url, reachabilit { "advisory_id": identifier, "advisory_uid": primary.avid, + "datasource_id": primary.datasource_id, "aliases": aliases, "summary": primary.summary, "weighted_severity": weighted_severity, @@ -974,6 +978,7 @@ def get_affected_advisories_bulk(packages, max_advisories, base_url, reachabilit { "advisory_id": identifier, "advisory_uid": advisory.avid, + "datasource_id": advisory.datasource_id, "aliases": aliases, "summary": advisory.summary, "weighted_severity": advisory.weighted_severity, @@ -1026,6 +1031,7 @@ def get_fixing_advisories_bulk(packages, max_advisories, base_url): "id", "package_id", "primary_advisory__advisory_id", + "primary_advisory__datasource_id", ) ) @@ -1051,6 +1057,7 @@ def get_fixing_advisories_bulk(packages, max_advisories, base_url): "advisory_id": advisory.advisory_id.split("/")[-1], "resource_url": resource_url, "advisory_uid": advisory.avid, + "datasource_id": advisory.datasource_id, } ) @@ -1114,6 +1121,7 @@ def get_fixing_advisories_bulk(packages, max_advisories, base_url): "advisory_id": advisory.advisory_id.split("/")[-1], "resource_url": resource_url, "advisory_uid": advisory.avid, + "datasource_id": advisory.datasource_id, } ) result[package.id] = package_result From cd11232d812bd52faa847b943a4e26272d2749a7 Mon Sep 17 00:00:00 2001 From: Keshav Priyadarshi Date: Fri, 2 Oct 2026 18:52:40 +0530 Subject: [PATCH 2/2] test: add coverage for datasource in API response Signed-off-by: Keshav Priyadarshi --- vulnerabilities/tests/test_api_v3.py | 53 +++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/vulnerabilities/tests/test_api_v3.py b/vulnerabilities/tests/test_api_v3.py index 09579a8a3..c00c21354 100644 --- a/vulnerabilities/tests/test_api_v3.py +++ b/vulnerabilities/tests/test_api_v3.py @@ -52,11 +52,13 @@ def setUp(self): self.advisory.save() self.package = PackageV2.objects.from_purl(purl="pkg:pypi/sample@1.0.0") + self.package2 = PackageV2.objects.from_purl(purl="pkg:pypi/sample@2.0.0") self.impact = ImpactedPackage.objects.create( advisory=self.advisory, base_purl="pkg:pypi/sample", ) self.impact.affecting_packages.add(self.package) + self.impact.fixed_by_packages.add(self.package2) self.client = APIClient(enforce_csrf_checks=True) @@ -113,6 +115,31 @@ def test_packages_post_with_details(self): pkg = response.data["results"][0] self.assertEqual(pkg["purl"], "pkg:pypi/sample@1.0.0") + def test_packages_post_with_details_fixing_vulnerabilities(self): + url = reverse("package-v3-list") + GroupAdvisoriesForPackages().execute() + + with self.assertNumQueries(12): + response = self.client.post( + url, + data={ + "purls": ["pkg:pypi/sample@2.0.0"], + "details": True, + }, + format="json", + HTTP_USER_AGENT="VCIO_API_AGENT", + ) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + + pkg = response.data["results"][0] + fixing_vulnerability = pkg["fixing_vulnerabilities"][0] + + self.assertEqual(fixing_vulnerability["advisory_id"], "GHSA-1234") + self.assertEqual(fixing_vulnerability["advisory_uid"], "ghsa/GHSA-1234") + self.assertEqual(fixing_vulnerability["datasource_id"], "ghsa") + self.assertEqual(pkg["next_non_vulnerable_version"], "2.0.0") + def test_advisories_post(self): url = reverse("advisory-v3-list") @@ -129,6 +156,7 @@ def test_advisories_post(self): advisory = response.data["results"][0] self.assertEqual(advisory["advisory_id"], "GHSA-1234") self.assertEqual(advisory["advisory_uid"], "ghsa/GHSA-1234") + self.assertEqual(advisory["datasource_id"], "ghsa") def test_affected_by_advisories_list(self): url = reverse("affected-by-advisories-list") @@ -143,6 +171,7 @@ def test_affected_by_advisories_list(self): results = response.data["results"] self.assertEqual(len(results), 1) self.assertEqual(results[0]["advisory_id"], "GHSA-1234") + self.assertEqual(results[0]["datasource_id"], "ghsa") def test_fixing_advisories_list_empty(self): url = reverse("fixing-advisories-list") @@ -155,6 +184,21 @@ def test_fixing_advisories_list_empty(self): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data["results"]), 0) + def test_fixing_advisories_list(self): + url = reverse("fixing-advisories-list") + + with self.assertNumQueries(11): + response = self.client.get( + url, {"purl": "pkg:pypi/sample@2.0.0"}, HTTP_USER_AGENT="VCIO_API_AGENT" + ) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + + results = response.data["results"] + self.assertEqual(len(results), 1) + self.assertEqual(results[0]["advisory_id"], "GHSA-1234") + self.assertEqual(results[0]["datasource_id"], "ghsa") + def test_packages_pagination(self): url = reverse("package-v3-list") @@ -314,6 +358,7 @@ def test_get_all_vulnerable_purls(self): class PackageCommitPatchTests(APITestCase): def setUp(self): + self.logger = TestLogger() self.advisory = AdvisoryDataV2( advisory_id="AVID-123", aliases=[], @@ -352,7 +397,12 @@ def setUp(self): self.anon_patcher.start() self.addCleanup(self.anon_patcher.stop) - self.advisory = insert_advisory_v2(self.advisory, "importer_1", print, 100) + self.advisory = insert_advisory_v2( + advisory=self.advisory, + pipeline_id="importer_1", + logger=self.logger.write, + datasource_id="test_source", + ) self.advisory.is_latest = True self.advisory._all_impacts_unfurled_at = timezone.now() self.advisory.save() @@ -393,6 +443,7 @@ def test_packages_commit_patch(self): advisory_data = vulns[0] assert advisory_data["advisory_id"] == "AVID-123" + assert advisory_data["datasource_id"] == "test_source" assert advisory_data["introduced_in_patches"] == [ { "commit_hash": "06580c7f99c6fde7bcf18e30bdcc61f081430957",