1515
1616from django .core .exceptions import ValidationError
1717from django .db import transaction
18+ from django .db .models .query import QuerySet
1819
1920from vulnerabilities .importer import AdvisoryData
2021from vulnerabilities .importer import Importer
@@ -96,12 +97,14 @@ def process_advisories(
9697 Insert advisories into the database
9798 Return the number of inserted advisories.
9899 """
100+ from vulnerabilities .pipes .advisory import get_or_create_aliases
101+
99102 count = 0
100103 advisories = []
101104 for data in advisory_datas :
102105 try :
106+ aliases = get_or_create_aliases (aliases = data .aliases )
103107 obj , created = Advisory .objects .get_or_create (
104- aliases = data .aliases ,
105108 summary = data .summary ,
106109 affected_packages = [pkg .to_dict () for pkg in data .affected_packages ],
107110 references = [ref .to_dict () for ref in data .references ],
@@ -113,6 +116,7 @@ def process_advisories(
113116 },
114117 url = data .url ,
115118 )
119+ obj .aliases .add (* aliases )
116120 if not obj .date_imported :
117121 advisories .append (obj )
118122 except Exception as e :
@@ -148,6 +152,8 @@ def process_inferences(inferences: List[Inference], advisory: Advisory, improver
148152 erroneous. Also, the atomic transaction for every advisory and its
149153 inferences makes sure that date_imported of advisory is consistent.
150154 """
155+ from vulnerabilities .pipes .advisory import get_or_create_aliases
156+
151157 inferences_processed_count = 0
152158
153159 if not inferences :
@@ -157,9 +163,10 @@ def process_inferences(inferences: List[Inference], advisory: Advisory, improver
157163 logger .info (f"Improving advisory id: { advisory .id } " )
158164
159165 for inference in inferences :
166+ aliases = get_or_create_aliases (inference .aliases )
160167 vulnerability = get_or_create_vulnerability_and_aliases (
161168 vulnerability_id = inference .vulnerability_id ,
162- aliases = inference . aliases ,
169+ aliases = aliases ,
163170 summary = inference .summary ,
164171 advisory = advisory ,
165172 )
@@ -265,14 +272,13 @@ def create_valid_vulnerability_reference(url, reference_id=None):
265272
266273
267274def get_or_create_vulnerability_and_aliases (
268- aliases : List [ str ] , vulnerability_id = None , summary = None , advisory = None
275+ aliases : QuerySet , vulnerability_id = None , summary = None , advisory = None
269276):
270277 """
271278 Get or create vulnerabilitiy and aliases such that all existing and new
272279 aliases point to the same vulnerability
273280 """
274- aliases = set (alias .strip () for alias in aliases if alias and alias .strip ())
275- new_alias_names , existing_vulns = get_vulns_for_aliases_and_get_new_aliases (aliases )
281+ new_aliases , existing_vulns = get_vulns_for_aliases_and_get_new_aliases (aliases )
276282
277283 # All aliases must point to the same vulnerability
278284 vulnerability = None
@@ -310,11 +316,11 @@ def get_or_create_vulnerability_and_aliases(
310316 # f"Inconsistent summary for {vulnerability.vulnerability_id}. "
311317 # f"Existing: {vulnerability.summary!r}, provided: {summary!r}"
312318 # )
313- associate_vulnerability_with_aliases (vulnerability = vulnerability , aliases = new_alias_names )
319+ associate_vulnerability_with_aliases (vulnerability = vulnerability , aliases = new_aliases )
314320 else :
315321 try :
316322 vulnerability = create_vulnerability_and_add_aliases (
317- aliases = new_alias_names , summary = summary
323+ aliases = new_aliases , summary = summary
318324 )
319325 importer_name = get_importer_name (advisory )
320326 VulnerabilityChangeLog .log_import (
@@ -324,24 +330,22 @@ def get_or_create_vulnerability_and_aliases(
324330 )
325331 except Exception as e :
326332 logger .error (
327- f"Cannot create vulnerability with summary { summary !r} and { new_alias_names !r} { e !r} .\n { traceback_format_exc ()} ."
333+ f"Cannot create vulnerability with summary { summary !r} and { new_aliases !r} { e !r} .\n { traceback_format_exc ()} ."
328334 )
329335 return
330336
331337 return vulnerability
332338
333339
334- def get_vulns_for_aliases_and_get_new_aliases (aliases ):
340+ def get_vulns_for_aliases_and_get_new_aliases (aliases : QuerySet ):
335341 """
336342 Return ``new_aliases`` that are not in the database and
337343 ``existing_vulns`` that point to the given ``aliases``.
338344 """
339- new_aliases = set (aliases )
340- existing_vulns = set ()
341- for alias in Alias .objects .filter (alias__in = aliases ):
342- existing_vulns .add (alias .vulnerability )
343- new_aliases .remove (alias .alias )
344- return new_aliases , existing_vulns
345+ new_aliases = aliases .filter (vulnerability__isnull = True )
346+ existing_vulns = [alias .vulnerability for alias in aliases .filter (vulnerability__isnull = False )]
347+
348+ return new_aliases , list (set (existing_vulns ))
345349
346350
347351@transaction .atomic
@@ -360,7 +364,5 @@ def create_vulnerability_and_add_aliases(aliases, summary):
360364
361365
362366def associate_vulnerability_with_aliases (aliases , vulnerability ):
363- for alias_name in aliases :
364- alias = Alias (alias = alias_name , vulnerability = vulnerability )
365- alias .save ()
366- logger .info (f"New alias for { vulnerability !r} : { alias_name } " )
367+ aliases .update (vulnerability = vulnerability )
368+ logger .info (f"New alias for { vulnerability !r} : { aliases } " )
0 commit comments