1313from typing import Iterable
1414from typing import List
1515from typing import Tuple
16+ from urllib .parse import urljoin
1617
1718import pytz
1819import saneyaml
@@ -55,15 +56,12 @@ def __init__(self, *args, purl=None, **kwargs):
5556 self .purl = purl
5657 # If a purl is provided, we are running in package-first mode
5758 if self .purl :
58- GitlabImporterPipeline .is_batch_run = False
59+ GitLabImporterPipeline .is_batch_run = False
5960
6061 @classmethod
6162 def steps (cls ):
6263 if not cls .is_batch_run :
63- return (
64- cls .collect_and_store_advisories ,
65- cls .clean_downloads ,
66- )
64+ return (cls .collect_and_store_advisories ,)
6765 return (
6866 cls .clone ,
6967 cls .collect_and_store_advisories ,
@@ -95,13 +93,13 @@ def advisories_count(self):
9593 return sum (1 for _ in root .rglob ("*.yml" ))
9694 else :
9795 return get_estimated_advisories_count (
98- self .purl , self .supported_ecosystem () , get_casesensitive_slug
96+ self .purl , self .purl_type_by_gitlab_scheme , get_casesensitive_slug
9997 )
10098
10199 def collect_advisories (self ) -> Iterable [AdvisoryData ]:
102100 if not self .is_batch_run :
103101 advisories = fetch_gitlab_advisories_for_purl (
104- self .purl , self .supported_ecosystem () , get_casesensitive_slug
102+ self .purl , self .purl_type_by_gitlab_scheme , get_casesensitive_slug
105103 )
106104
107105 input_version = self .purl .version
@@ -402,6 +400,12 @@ def advisory_dict_to_advisory_data(
402400 """
403401 aliases = advisory .get ("identifiers" , [])
404402 identifier = advisory .get ("identifier" , "" )
403+ package_slug = advisory .get ("package_slug" )
404+
405+ advisory_id = f"{ package_slug } /{ identifier } " if package_slug else identifier
406+ if advisory_id in aliases :
407+ aliases .remove (advisory_id )
408+
405409 summary = build_description (advisory .get ("title" ), advisory .get ("description" ))
406410 urls = advisory .get ("urls" , [])
407411 references = [ReferenceV2 .from_url (u ) for u in urls ]
@@ -412,8 +416,6 @@ def advisory_dict_to_advisory_data(
412416 date_published = dateparser .parse (advisory .get ("pubdate" ))
413417 date_published = date_published .replace (tzinfo = pytz .UTC )
414418
415- package_slug = advisory .get ("package_slug" )
416-
417419 # Determine purl if not provided
418420 if not purl :
419421 purl = get_purl (
@@ -428,6 +430,7 @@ def advisory_dict_to_advisory_data(
428430 level = logging .ERROR ,
429431 )
430432 return AdvisoryData (
433+ advisory_id = advisory_id ,
431434 aliases = aliases ,
432435 summary = summary ,
433436 references_v2 = references ,
@@ -466,12 +469,18 @@ def advisory_dict_to_advisory_data(
466469 level = logging .ERROR ,
467470 )
468471
472+ purl_without_version = get_purl (
473+ package_slug = package_slug ,
474+ purl_type_by_gitlab_scheme = purl_type_by_gitlab_scheme ,
475+ logger = logger ,
476+ )
477+
469478 if parsed_fixed_versions :
470479 affected_packages = list (
471480 extract_affected_packages (
472481 affected_version_range = affected_version_range ,
473482 fixed_versions = parsed_fixed_versions ,
474- purl = purl ,
483+ purl = purl_without_version ,
475484 )
476485 )
477486 else :
@@ -480,11 +489,19 @@ def advisory_dict_to_advisory_data(
480489 else :
481490 affected_packages = [
482491 AffectedPackage (
483- package = purl ,
492+ package = purl_without_version ,
484493 affected_version_range = affected_version_range ,
485494 )
486495 ]
496+
497+ if not advisory_url and package_slug and identifier :
498+ advisory_url = urljoin (
499+ "https://gitlab.com/gitlab-org/advisories-community/-/blob/main/" ,
500+ package_slug + "/" + identifier + ".yml" ,
501+ )
502+
487503 return AdvisoryData (
504+ advisory_id = advisory_id ,
488505 aliases = aliases ,
489506 summary = summary ,
490507 references_v2 = references ,
0 commit comments