diff --git a/vulnerabilities/pipes/advisory.py b/vulnerabilities/pipes/advisory.py index 96e1d4871..c812fdf86 100644 --- a/vulnerabilities/pipes/advisory.py +++ b/vulnerabilities/pipes/advisory.py @@ -291,7 +291,7 @@ def insert_advisory(advisory: AdvisoryData, pipeline_id: str, logger: Callable = def insert_advisory_v2( advisory: AdvisoryDataV2, pipeline_id: str, - logger: Callable = None, + logger: Callable, precedence: int = 0, ): from vulnerabilities.models import ImpactedPackage @@ -299,13 +299,8 @@ def insert_advisory_v2( from vulnerabilities.utils import compute_content_id_v2 advisory_obj = None - aliases = get_or_create_advisory_aliases(aliases=advisory.aliases) - references = get_or_create_advisory_references(references=advisory.references) - severities = get_or_create_advisory_severities(severities=advisory.severities) - patches = get_or_create_advisory_patches(patches=advisory.patches) - weaknesses = get_or_create_advisory_weaknesses(weaknesses=advisory.weaknesses) - content_id = compute_content_id_v2(advisory_data=advisory) created = False + content_id = compute_content_id_v2(advisory_data=advisory) try: default_data = { "datasource_id": pipeline_id, @@ -324,65 +319,73 @@ def insert_advisory_v2( unique_content_id=content_id, defaults=default_data, ) - related_fields = { - "aliases": aliases, - "references": references, - "severities": severities, - "weaknesses": weaknesses, - "patches": patches, - } - - for field_name, values in related_fields.items(): - if values: - getattr(advisory_obj, field_name).add(*values) - - except Advisory.MultipleObjectsReturned: + except AdvisoryV2.MultipleObjectsReturned: logger( f"Multiple Advisories returned: unique_content_id: {content_id}, url: {advisory.url}, advisory: {advisory!r}" ) raise except Exception as e: - if logger: - logger( - f"Error while processing {advisory!r} with aliases {advisory.aliases!r}: {e!r} \n {traceback_format_exc()}", - level=logging.ERROR, - ) + logger( + f"Error while processing {advisory!r} with aliases {advisory.aliases!r}: {e!r} \n {traceback_format_exc()}", + level=logging.ERROR, + ) + raise - if created: - for affected_pkg in advisory.affected_packages: - impact = ImpactedPackage.objects.create( - advisory=advisory_obj, - base_purl=str(affected_pkg.package), - affecting_vers=str(affected_pkg.affected_version_range) - if affected_pkg.affected_version_range - else None, - fixed_vers=str(affected_pkg.fixed_version_range) - if affected_pkg.fixed_version_range - else None, - ) - package_affected_purls, package_fixed_purls = get_exact_purls_v2( - affected_package=affected_pkg, - logger=logger, - ) + if not created: + return advisory_obj - affected_packages_v2 = PackageV2.objects.bulk_get_or_create_from_purls( - purls=package_affected_purls - ) - fixed_packages_v2 = PackageV2.objects.bulk_get_or_create_from_purls( - purls=package_fixed_purls - ) + aliases = get_or_create_advisory_aliases(aliases=advisory.aliases) + references = get_or_create_advisory_references(references=advisory.references) + severities = get_or_create_advisory_severities(severities=advisory.severities) + patches = get_or_create_advisory_patches(patches=advisory.patches) + weaknesses = get_or_create_advisory_weaknesses(weaknesses=advisory.weaknesses) - impact.affecting_packages.add(*affected_packages_v2) - impact.fixed_by_packages.add(*fixed_packages_v2) + related_fields = { + "aliases": aliases, + "references": references, + "severities": severities, + "weaknesses": weaknesses, + "patches": patches, + } + + for field_name, values in related_fields.items(): + if values: + getattr(advisory_obj, field_name).add(*values) + + for affected_pkg in advisory.affected_packages: + impact = ImpactedPackage.objects.create( + advisory=advisory_obj, + base_purl=str(affected_pkg.package), + affecting_vers=str(affected_pkg.affected_version_range) + if affected_pkg.affected_version_range + else None, + fixed_vers=str(affected_pkg.fixed_version_range) + if affected_pkg.fixed_version_range + else None, + ) + package_affected_purls, package_fixed_purls = get_exact_purls_v2( + affected_package=affected_pkg, + logger=logger, + ) - introduced_commit_v2 = get_or_create_advisory_package_commit_patches( - affected_pkg.introduced_by_commit_patches - ) - fixed_commit_v2 = get_or_create_advisory_package_commit_patches( - affected_pkg.fixed_by_commit_patches - ) - impact.introduced_by_package_commit_patches.add(*introduced_commit_v2) - impact.fixed_by_package_commit_patches.add(*fixed_commit_v2) + affected_packages_v2 = PackageV2.objects.bulk_get_or_create_from_purls( + purls=package_affected_purls + ) + fixed_packages_v2 = PackageV2.objects.bulk_get_or_create_from_purls( + purls=package_fixed_purls + ) + + impact.affecting_packages.add(*affected_packages_v2) + impact.fixed_by_packages.add(*fixed_packages_v2) + + introduced_commit_v2 = get_or_create_advisory_package_commit_patches( + affected_pkg.introduced_by_commit_patches + ) + fixed_commit_v2 = get_or_create_advisory_package_commit_patches( + affected_pkg.fixed_by_commit_patches + ) + impact.introduced_by_package_commit_patches.add(*introduced_commit_v2) + impact.fixed_by_package_commit_patches.add(*fixed_commit_v2) return advisory_obj diff --git a/vulnerabilities/tests/pipelines/exporters/test_federate_vulnerabilities.py b/vulnerabilities/tests/pipelines/exporters/test_federate_vulnerabilities.py index a0bbbb772..af36cc711 100644 --- a/vulnerabilities/tests/pipelines/exporters/test_federate_vulnerabilities.py +++ b/vulnerabilities/tests/pipelines/exporters/test_federate_vulnerabilities.py @@ -86,10 +86,12 @@ def setUp(self): insert_advisory_v2( advisory=advisory1, pipeline_id="test_pipeline_v2", + logger=self.logger.write, ) insert_advisory_v2( advisory=advisory2, pipeline_id="test_pipeline_v2", + logger=self.logger.write, ) @patch( diff --git a/vulnerabilities/tests/pipelines/v2_improvers/test_unfurl_version_range.py b/vulnerabilities/tests/pipelines/v2_improvers/test_unfurl_version_range.py index 2319f27d0..a1927a426 100644 --- a/vulnerabilities/tests/pipelines/v2_improvers/test_unfurl_version_range.py +++ b/vulnerabilities/tests/pipelines/v2_improvers/test_unfurl_version_range.py @@ -22,10 +22,12 @@ from vulnerabilities.models import PackageV2 from vulnerabilities.pipelines.v2_improvers.unfurl_version_range import UnfurlVersionRangePipeline from vulnerabilities.pipes.advisory import insert_advisory_v2 +from vulnerabilities.tests.pipelines import TestLogger class TestUnfurlVersionRangePipeline(TestCase): def setUp(self): + self.logger = TestLogger() advisory1 = AdvisoryDataV2( summary="Test advisory", aliases=["CVE-2025-0001"], @@ -49,6 +51,7 @@ def setUp(self): insert_advisory_v2( advisory=advisory1, pipeline_id="test_pipeline_v2", + logger=self.logger.write, ) @patch("vulnerabilities.pipelines.v2_improvers.unfurl_version_range.get_purl_versions") diff --git a/vulnerabilities/tests/test_models.py b/vulnerabilities/tests/test_models.py index 96dc9b0ff..69237b806 100644 --- a/vulnerabilities/tests/test_models.py +++ b/vulnerabilities/tests/test_models.py @@ -39,6 +39,7 @@ from vulnerabilities.severity_systems import CVSSV3 from vulnerabilities.severity_systems import CVSSV4 from vulnerabilities.severity_systems import ScoringSystem +from vulnerabilities.tests.pipelines import TestLogger from vulnerabilities.utils import compute_content_id @@ -747,6 +748,7 @@ def test_constraint_none(self): class TestAdvisoryV2Model(DjangoTestCase): def setUp(self): + self.logger = TestLogger() self.advisoryv2_data1 = AdvisoryDataV2( advisory_id="test_adv", aliases=[], @@ -770,7 +772,9 @@ def setUp(self): def test_advisoryv2_to_advisory_data_patch_seralization(self): from vulnerabilities.pipes.advisory import insert_advisory_v2 - insert_advisory_v2(advisory=self.advisoryv2_data1, pipeline_id="test_pipeline") + insert_advisory_v2( + advisory=self.advisoryv2_data1, pipeline_id="test_pipeline", logger=self.logger.write + ) result = models.AdvisoryV2.objects.first().to_advisory_data() self.assertEqual(result, self.advisoryv2_data1) @@ -778,6 +782,7 @@ def test_advisoryv2_to_advisory_data_patch_seralization(self): class TestAdvisoryV2ModelDuplication(DjangoTestCase): def setUp(self): + self.logger = TestLogger() self.advisoryv2_data1 = AdvisoryDataV2( advisory_id="CVE-2023-0401", aliases=[], @@ -813,8 +818,12 @@ def setUp(self): def test_advisoryv2_duplication_data(self): from vulnerabilities.pipes.advisory import insert_advisory_v2 - insert_advisory_v2(advisory=self.advisoryv2_data1, pipeline_id="test_pipeline") - insert_advisory_v2(advisory=self.advisoryv2_data2, pipeline_id="test_pipeline") + insert_advisory_v2( + advisory=self.advisoryv2_data1, pipeline_id="test_pipeline", logger=self.logger.write + ) + insert_advisory_v2( + advisory=self.advisoryv2_data2, pipeline_id="test_pipeline", logger=self.logger.write + ) result = models.AdvisoryV2.objects.count() self.assertEqual(result, 2) diff --git a/vulnerabilities/tests/test_utils.py b/vulnerabilities/tests/test_utils.py index 0460715be..a100cbd74 100644 --- a/vulnerabilities/tests/test_utils.py +++ b/vulnerabilities/tests/test_utils.py @@ -28,6 +28,7 @@ from vulnerabilities.pipelines import insert_advisory_v2 from vulnerabilities.references import XsaReferenceV2 from vulnerabilities.references import ZbxReferenceV2 +from vulnerabilities.tests.pipelines import TestLogger from vulnerabilities.utils import AffectedPackage from vulnerabilities.utils import get_item from vulnerabilities.utils import get_severity_range @@ -170,6 +171,7 @@ def test_get_severity_range(): class TestComputeContentIdV2(TestCase): def setUp(self): + self.logger = TestLogger() self.advisory1 = AdvisoryDataV2( summary="Test advisory", aliases=["CVE-2025-0001", "CVE-2024-0001"], @@ -239,6 +241,7 @@ def setUp(self): insert_advisory_v2( advisory=self.advisory1, pipeline_id="test_pipeline_v2", + logger=self.logger.write, ) def test_compute_content_id_v2(self):