1515from traceback import format_exc as traceback_format_exc
1616from typing import Iterable
1717from typing import List
18- from typing import Optional
1918
2019from aboutcode .pipeline import LoopProgress
2120from aboutcode .pipeline import PipelineDefinition
2221from aboutcode .pipeline import humanize_time
23- from fetchcode import package_versions
24- from packageurl import PackageURL
2522
2623from vulnerabilities .importer import AdvisoryData
27- from vulnerabilities .importer import AffectedPackage
28- from vulnerabilities .importer import UnMergeablePackageError
2924from vulnerabilities .improver import MAX_CONFIDENCE
3025from vulnerabilities .models import Advisory
31- from vulnerabilities .models import PackageV2
3226from vulnerabilities .models import PipelineRun
3327from vulnerabilities .pipes .advisory import import_advisory
3428from vulnerabilities .pipes .advisory import insert_advisory
3529from vulnerabilities .pipes .advisory import insert_advisory_v2
36- from vulnerabilities .utils import AffectedPackage as LegacyAffectedPackage
37- from vulnerabilities .utils import classproperty
38- from vulnerabilities .utils import get_affected_packages_by_patched_package
39- from vulnerabilities .utils import nearest_patched_package
40- from vulnerabilities .utils import resolve_version_range
4130
4231module_logger = logging .getLogger (__name__ )
4332
@@ -271,13 +260,15 @@ class VulnerableCodeBaseImporterPipelineV2(VulnerableCodePipeline):
271260 license_url = None
272261 spdx_license_expression = None
273262 repo_url = None
274- advisory_confidence = MAX_CONFIDENCE
275263 ignorable_versions = []
276- unfurl_version_ranges = False
277264
278265 @classmethod
279266 def steps (cls ):
280- return (cls .collect_and_store_advisories ,)
267+ return (
268+ # Add step for downloading/cloning resource as required.
269+ cls .collect_and_store_advisories ,
270+ # Add step for removing downloaded/cloned resource as required.
271+ )
281272
282273 def collect_advisories (self ) -> Iterable [AdvisoryData ]:
283274 """
@@ -311,7 +302,6 @@ def collect_and_store_advisories(self):
311302 if _obj := insert_advisory_v2 (
312303 advisory = advisory ,
313304 pipeline_id = self .pipeline_id ,
314- get_advisory_packages = self .get_advisory_packages ,
315305 logger = self .log ,
316306 ):
317307 collected_advisory_count += 1
@@ -323,203 +313,3 @@ def collect_and_store_advisories(self):
323313 continue
324314
325315 self .log (f"Successfully collected { collected_advisory_count :,d} advisories" )
326-
327- def get_advisory_packages (self , advisory_data : AdvisoryData ) -> list :
328- """
329- Return the list of packages for the given advisory.
330-
331- Used by ``import_advisory`` to get the list of packages for the advisory.
332- """
333- from vulnerabilities .improvers import default
334-
335- affected_purls = []
336- fixed_purls = []
337- for affected_package in advisory_data .affected_packages :
338- package_affected_purls , package_fixed_purls = default .get_exact_purls (
339- affected_package = affected_package
340- )
341- affected_purls .extend (package_affected_purls )
342- fixed_purls .extend (package_fixed_purls )
343-
344- if self .unfurl_version_ranges :
345- vulnerable_pvs , fixed_pvs = self .get_impacted_packages (
346- affected_packages = advisory_data .affected_packages ,
347- advisory_date_published = advisory_data .date_published ,
348- )
349- affected_purls .extend (vulnerable_pvs )
350- fixed_purls .extend (fixed_pvs )
351-
352- vulnerable_packages = []
353- fixed_packages = []
354-
355- for affected_purl in affected_purls :
356- vulnerable_package , _ = PackageV2 .objects .get_or_create_from_purl (purl = affected_purl )
357- vulnerable_packages .append (vulnerable_package )
358-
359- for fixed_purl in fixed_purls :
360- fixed_package , _ = PackageV2 .objects .get_or_create_from_purl (purl = fixed_purl )
361- fixed_packages .append (fixed_package )
362-
363- return vulnerable_packages , fixed_packages
364-
365- def get_published_package_versions (
366- self , package_url : PackageURL , until : Optional [datetime ] = None
367- ) -> List [str ]:
368- """
369- Return a list of versions published before `until` for the `package_url`
370- """
371- versions_before_until = []
372- try :
373- versions = package_versions .versions (str (package_url ))
374- for version in versions or []:
375- if (
376- version .release_date
377- and version .release_date .tzinfo
378- and until
379- and until .tzinfo is None
380- ):
381- until = until .replace (tzinfo = timezone .utc )
382- if until and version .release_date and version .release_date > until :
383- continue
384- versions_before_until .append (version .value )
385-
386- return versions_before_until
387- except Exception as e :
388- self .log (
389- f"Failed to fetch versions for package { str (package_url )} { e !r} " ,
390- level = logging .ERROR ,
391- )
392- return []
393-
394- def get_impacted_packages (self , affected_packages , advisory_date_published ):
395- """
396- Return a tuple of lists of affected and fixed PackageURLs
397- """
398- if not affected_packages :
399- return [], []
400-
401- mergable = True
402-
403- # TODO: We should never had the exception in first place
404- try :
405- purl , affected_version_ranges , fixed_versions = AffectedPackage .merge (affected_packages )
406- except UnMergeablePackageError :
407- self .log (f"Cannot merge with different purls { affected_packages !r} " , logging .ERROR )
408- mergable = False
409-
410- if not mergable :
411- vulnerable_packages = []
412- fixed_packages = []
413- for affected_package in affected_packages :
414- purl = affected_package .package
415- affected_version_range = affected_package .affected_version_range
416- fixed_version = affected_package .fixed_version
417- pkg_type = purl .type
418- pkg_namespace = purl .namespace
419- pkg_name = purl .name
420- if not affected_version_range and fixed_version :
421- fixed_packages .append (
422- PackageURL (
423- type = pkg_type ,
424- namespace = pkg_namespace ,
425- name = pkg_name ,
426- version = str (fixed_version ),
427- )
428- )
429- else :
430- valid_versions = self .get_published_package_versions (
431- package_url = purl , until = advisory_date_published
432- )
433- affected_pvs , fixed_pvs = self .resolve_package_versions (
434- affected_version_range = affected_version_range ,
435- pkg_type = pkg_type ,
436- pkg_namespace = pkg_namespace ,
437- pkg_name = pkg_name ,
438- valid_versions = valid_versions ,
439- )
440- vulnerable_packages .extend (affected_pvs )
441- fixed_packages .extend (fixed_pvs )
442- return vulnerable_packages , fixed_packages
443- else :
444- pkg_type = purl .type
445- pkg_namespace = purl .namespace
446- pkg_name = purl .name
447- pkg_qualifiers = purl .qualifiers
448- fixed_purls = [
449- PackageURL (
450- type = pkg_type ,
451- namespace = pkg_namespace ,
452- name = pkg_name ,
453- version = str (version ),
454- qualifiers = pkg_qualifiers ,
455- )
456- for version in fixed_versions
457- ]
458- if not affected_version_ranges :
459- return [], fixed_purls
460- else :
461- valid_versions = self .get_published_package_versions (
462- package_url = purl , until = advisory_date_published
463- )
464- vulnerable_packages = []
465- fixed_packages = []
466- for affected_version_range in affected_version_ranges :
467- vulnerable_pvs , fixed_pvs = self .resolve_package_versions (
468- affected_version_range = affected_version_range ,
469- pkg_type = pkg_type ,
470- pkg_namespace = pkg_namespace ,
471- pkg_name = pkg_name ,
472- valid_versions = valid_versions ,
473- )
474- vulnerable_packages .extend (vulnerable_pvs )
475- fixed_packages .extend (fixed_pvs )
476- return vulnerable_packages , fixed_packages
477-
478- def resolve_package_versions (
479- self ,
480- affected_version_range ,
481- pkg_type ,
482- pkg_namespace ,
483- pkg_name ,
484- valid_versions ,
485- ):
486- """
487- Return a tuple of lists of ``affected_packages`` and ``fixed_packages`` PackageURL for the given `affected_version_range` and `valid_versions`.
488-
489- ``valid_versions`` are the valid version listed on the package registry for that package
490-
491- """
492- aff_vers , unaff_vers = resolve_version_range (
493- affected_version_range = affected_version_range ,
494- ignorable_versions = self .ignorable_versions ,
495- package_versions = valid_versions ,
496- )
497-
498- affected_purls = list (
499- self .expand_verion_range_to_purls (pkg_type , pkg_namespace , pkg_name , aff_vers )
500- )
501-
502- unaffected_purls = list (
503- self .expand_verion_range_to_purls (pkg_type , pkg_namespace , pkg_name , unaff_vers )
504- )
505-
506- fixed_packages = []
507- affected_packages = []
508-
509- patched_packages = nearest_patched_package (
510- vulnerable_packages = affected_purls , resolved_packages = unaffected_purls
511- )
512-
513- for (
514- fixed_package ,
515- affected_purls ,
516- ) in get_affected_packages_by_patched_package (patched_packages ).items ():
517- if fixed_package :
518- fixed_packages .append (fixed_package )
519- affected_packages .extend (affected_purls )
520-
521- return affected_packages , fixed_packages
522-
523- def expand_verion_range_to_purls (self , pkg_type , pkg_namespace , pkg_name , versions ):
524- for version in versions :
525- yield PackageURL (type = pkg_type , namespace = pkg_namespace , name = pkg_name , version = version )
0 commit comments