Skip to content

Commit 9eb8098

Browse files
committed
Add model changes and support new advisory ingestion
Signed-off-by: Tushar Goel <tushar.goel.dav@gmail.com>
1 parent 9933581 commit 9eb8098

File tree

5 files changed

+89
-8
lines changed

5 files changed

+89
-8
lines changed

vulnerabilities/importer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ class AdvisoryDataV2:
413413
date_published must be aware datetime
414414
"""
415415

416+
advisory_id: str = ""
416417
aliases: List[str] = dataclasses.field(default_factory=list)
417418
summary: Optional[str] = ""
418419
affected_packages: List[AffectedPackage] = dataclasses.field(default_factory=list)

vulnerabilities/pipelines/__init__.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919
from aboutcode.pipeline import humanize_time
2020

2121
from vulnerabilities.importer import AdvisoryData
22+
from vulnerabilities.importer import AdvisoryDataV2
2223
from vulnerabilities.improver import MAX_CONFIDENCE
2324
from vulnerabilities.models import Advisory
2425
from vulnerabilities.pipes.advisory import import_advisory
2526
from vulnerabilities.pipes.advisory import insert_advisory
27+
from vulnerabilities.pipes.advisory import insert_advisory_v2
2628
from vulnerabilities.utils import classproperty
2729

2830
module_logger = logging.getLogger(__name__)
@@ -149,12 +151,20 @@ def collect_and_store_advisories(self):
149151

150152
progress = LoopProgress(total_iterations=estimated_advisory_count, logger=self.log)
151153
for advisory in progress.iter(self.collect_advisories()):
152-
if _obj := insert_advisory(
153-
advisory=advisory,
154-
pipeline_id=self.pipeline_id,
155-
logger=self.log,
156-
):
157-
collected_advisory_count += 1
154+
if isinstance(advisory, AdvisoryData):
155+
if _obj := insert_advisory(
156+
advisory=advisory,
157+
pipeline_id=self.pipeline_id,
158+
logger=self.log,
159+
):
160+
collected_advisory_count += 1
161+
if isinstance(advisory, AdvisoryDataV2):
162+
if _obj := insert_advisory_v2(
163+
advisory=advisory,
164+
pipeline_id=self.pipeline_id,
165+
logger=self.log,
166+
):
167+
collected_advisory_count += 1
158168

159169
self.log(f"Successfully collected {collected_advisory_count:,d} advisories")
160170

vulnerabilities/pipelines/alpine_linux_importer.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from univers.versions import AlpineLinuxVersion
2020

2121
from vulnerabilities.importer import AdvisoryData
22+
from vulnerabilities.importer import AdvisoryDataV2
2223
from vulnerabilities.importer import AffectedPackage
2324
from vulnerabilities.pipelines import VulnerableCodeBaseImporterPipeline
2425
from vulnerabilities.references import WireSharkReference
@@ -288,3 +289,26 @@ def load_advisories(
288289
aliases=aliases,
289290
url=url,
290291
)
292+
293+
if any(is_cve(alias) for alias in aliases):
294+
advisory_id = next((alias for alias in aliases if is_cve(alias)), None)
295+
aliases.remove(advisory_id)
296+
yield AdvisoryDataV2(
297+
references=references,
298+
affected_packages=affected_packages,
299+
url=url,
300+
advisory_id=advisory_id,
301+
aliases=aliases,
302+
)
303+
304+
else:
305+
aliases.sort()
306+
advisory_id = aliases[0]
307+
aliases = aliases[1:]
308+
yield AdvisoryDataV2(
309+
references=references,
310+
affected_packages=affected_packages,
311+
url=url,
312+
advisory_id=advisory_id,
313+
aliases=aliases,
314+
)

vulnerabilities/pipes/advisory.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@
1818
from django.db.models.query import QuerySet
1919

2020
from vulnerabilities.importer import AdvisoryData
21+
from vulnerabilities.importer import AdvisoryDataV2
2122
from vulnerabilities.improver import MAX_CONFIDENCE
2223
from vulnerabilities.models import Advisory
24+
from vulnerabilities.models import AdvisoryAlias
25+
from vulnerabilities.models import AdvisoryV2
2326
from vulnerabilities.models import AffectedByPackageRelatedVulnerability
2427
from vulnerabilities.models import Alias
2528
from vulnerabilities.models import FixingPackageRelatedVulnerability
@@ -36,6 +39,12 @@ def get_or_create_aliases(aliases: List) -> QuerySet:
3639
return Alias.objects.filter(alias__in=aliases)
3740

3841

42+
def get_or_create_aliases_v2(aliases: List) -> QuerySet:
43+
for alias in aliases:
44+
AdvisoryAlias.objects.get_or_create(alias=alias)
45+
return AdvisoryAlias.objects.filter(alias__in=aliases)
46+
47+
3948
def insert_advisory(advisory: AdvisoryData, pipeline_id: str, logger: Callable = None):
4049
from vulnerabilities.utils import compute_content_id
4150

@@ -74,6 +83,42 @@ def insert_advisory(advisory: AdvisoryData, pipeline_id: str, logger: Callable =
7483
return advisory_obj
7584

7685

86+
def insert_advisory_v2(advisory: AdvisoryDataV2, pipeline_id: str, logger: Callable = None):
87+
from vulnerabilities.utils import compute_content_id
88+
89+
advisory_obj = None
90+
aliases = get_or_create_aliases_v2(aliases=advisory.aliases)
91+
content_id = compute_content_id(advisory_data=advisory)
92+
try:
93+
default_data = {
94+
"summary": advisory.summary,
95+
"date_published": advisory.date_published,
96+
"created_by": pipeline_id,
97+
"date_collected": datetime.now(timezone.utc),
98+
"advisory_id": advisory.advisory_id,
99+
}
100+
101+
advisory_obj, _ = AdvisoryV2.objects.get_or_create(
102+
unique_content_id=content_id,
103+
url=advisory.url,
104+
defaults=default_data,
105+
)
106+
advisory_obj.aliases.add(*aliases)
107+
except Advisory.MultipleObjectsReturned:
108+
logger.error(
109+
f"Multiple Advisories returned: unique_content_id: {content_id}, url: {advisory.url}, advisory: {advisory!r}"
110+
)
111+
raise
112+
except Exception as e:
113+
if logger:
114+
logger(
115+
f"Error while processing {advisory!r} with aliases {advisory.aliases!r}: {e!r} \n {traceback_format_exc()}",
116+
level=logging.ERROR,
117+
)
118+
119+
return advisory_obj
120+
121+
77122
@transaction.atomic
78123
def import_advisory(
79124
advisory: Advisory,

vulnerabilities/utils.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
from univers.version_range import NginxVersionRange
4040
from univers.version_range import VersionRange
4141

42-
from aboutcode.hashid import build_vcid # NOQA
42+
from aboutcode.hashid import build_vcid
4343

4444
logger = logging.getLogger(__name__)
4545

@@ -595,6 +595,7 @@ def compute_content_id(advisory_data):
595595

596596
# Normalize fields
597597
from vulnerabilities.importer import AdvisoryData
598+
from vulnerabilities.importer import AdvisoryDataV2
598599
from vulnerabilities.models import Advisory
599600

600601
if isinstance(advisory_data, Advisory):
@@ -609,7 +610,7 @@ def compute_content_id(advisory_data):
609610
}
610611
normalized_data["url"] = advisory_data.url
611612

612-
elif isinstance(advisory_data, AdvisoryData):
613+
elif isinstance(advisory_data, AdvisoryData) or isinstance(advisory_data, AdvisoryDataV2):
613614
normalized_data = {
614615
"aliases": normalize_list(advisory_data.aliases),
615616
"summary": normalize_text(advisory_data.summary),

0 commit comments

Comments
 (0)