Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 60 additions & 57 deletions vulnerabilities/pipes/advisory.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,21 +291,16 @@ 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
from vulnerabilities.models import PackageV2
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,
Expand All @@ -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


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
Expand All @@ -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")
Expand Down
15 changes: 12 additions & 3 deletions vulnerabilities/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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=[],
Expand All @@ -770,14 +772,17 @@ 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)


class TestAdvisoryV2ModelDuplication(DjangoTestCase):
def setUp(self):
self.logger = TestLogger()
self.advisoryv2_data1 = AdvisoryDataV2(
advisory_id="CVE-2023-0401",
aliases=[],
Expand Down Expand Up @@ -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)
3 changes: 3 additions & 0 deletions vulnerabilities/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"],
Expand Down Expand Up @@ -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):
Expand Down