@@ -41,18 +41,16 @@ def datasource_advisory(self, purl) -> Iterable[VendorData]:
4141 VendorData instance containing the advisory information for the package.
4242 """
4343 package_slug = get_package_slug (purl )
44- location = download_subtree (package_slug , speculative_execution = True )
45- if not location :
46- clear_download (location )
44+ directory_files = fetch_directory_contents (package_slug )
45+ if not directory_files :
4746 path = self .supported_ecosystem ()[purl .type ]
4847 casesensitive_package_slug = get_casesensitive_slug (path , package_slug )
49- location = download_subtree (casesensitive_package_slug )
50- if location :
51- interesting_advisories = parse_interesting_advisories (
52- location , purl , delete_download = True
53- )
54- return interesting_advisories
55- clear_download (location )
48+ directory_files = fetch_directory_contents (casesensitive_package_slug )
49+
50+ yml_files = [file for file in directory_files if file ["name" ].endswith (".yml" )]
51+
52+ interesting_advisories = parse_interesting_advisories (yml_files , purl )
53+ return interesting_advisories
5654
5755 @classmethod
5856 def supported_ecosystem (cls ):
@@ -68,6 +66,21 @@ def supported_ecosystem(cls):
6866 }
6967
7068
69+ def fetch_directory_contents (package_slug ):
70+ url = f"https://gitlab.com/api/v4/projects/12006272/repository/tree?path={ package_slug } "
71+ response = requests .get (url )
72+ if response .status_code == 200 :
73+ return response .json ()
74+
75+
76+ def fetch_yaml (file_path ):
77+ response = requests .get (
78+ f"https://gitlab.com/gitlab-org/security-products/gemnasium-db/-/raw/master/{ file_path } "
79+ )
80+ if response .status_code == 200 :
81+ return response .text
82+
83+
7184def get_package_slug (purl ):
7285 """
7386 Constructs a package slug from a given purl.
@@ -92,43 +105,6 @@ def get_package_slug(purl):
92105 return f"{ ecosystem } /{ package_name } "
93106
94107
95- def download_subtree (package_slug : str , speculative_execution = False ):
96- """
97- Downloads and extracts a tar file from a given package slug.
98-
99- Parameters:
100- package_slug: A string representing the package slug to query.
101- speculative_execution: A boolean indicating whether to log errors or not.
102-
103- Returns:
104- A Path object representing the extracted location, or None if an error occurs.
105- """
106- url = f"https://gitlab.com/gitlab-org/security-products/gemnasium-db/-/archive/master/gemnasium-db-master.tar.gz?path={ package_slug } "
107- response = fetch (url )
108- if os .path .getsize (response .location ) > 0 :
109- extracted_location = Path (response .location ).parent .joinpath (
110- "temp_vulntotal_gitlab_datasource"
111- )
112- with tarfile .open (response .location , "r" ) as file_obj :
113- file_obj .extractall (extracted_location )
114- os .remove (response .location )
115- return extracted_location
116- if not speculative_execution :
117- logger .error (f"{ package_slug } doesn't exist" )
118- os .remove (response .location )
119-
120-
121- def clear_download (location ):
122- """
123- Deletes a directory and its contents.
124-
125- Parameters:
126- location: A Path object representing the directory to delete.
127- """
128- if location :
129- shutil .rmtree (location )
130-
131-
132108def get_casesensitive_slug (path , package_slug ):
133109 payload = [
134110 {
@@ -180,32 +156,28 @@ def get_casesensitive_slug(path, package_slug):
180156
181157 # If the namespace/subfolder contains multiple packages, then progressive transverse through folders tree
182158 if package_slug .lower ().startswith (slug_flatpath .lower ()):
183- return get_gitlab_style_slug (slug_flatpath , package_slug )
159+ return get_casesensitive_slug (slug_flatpath , package_slug )
184160
185161 payload [0 ]["variables" ]["nextPageCursor" ] = paginated_tree ["pageInfo" ]["endCursor" ]
186162 has_next = paginated_tree ["pageInfo" ]["hasNextPage" ]
187163
188164
189- def parse_interesting_advisories (location , purl , delete_download = False ) -> Iterable [VendorData ]:
165+ def parse_interesting_advisories (yml_files , purl ) -> Iterable [VendorData ]:
190166 """
191167 Parses advisories from YAML files in a given location that match a given version.
192168
193169 Parameters:
194- location: A Path object representing the location of the YAML files.
170+ yml_files: An array having the paths of yml files to parse .
195171 purl: PURL for the advisory.
196- version: A string representing the version to check against the affected range.
197- delete_download: A boolean indicating whether to delete the downloaded files after parsing.
198172
199173 Yields:
200174 VendorData instance containing the advisory information for the package.
201175 """
202176 version = purl .version
203- path = Path (location )
204- pattern = "**/*.yml"
205- files = [p for p in path .glob (pattern ) if p .is_file ()]
206- for file in sorted (files ):
207- with open (file ) as f :
208- gitlab_advisory = saneyaml .load (f )
177+
178+ for file in yml_files :
179+ yml_data = fetch_yaml (file ["path" ])
180+ gitlab_advisory = saneyaml .load (yml_data )
209181 affected_range = gitlab_advisory ["affected_range" ]
210182 if gitlab_constraints_satisfied (affected_range , version ):
211183 yield VendorData (
@@ -214,5 +186,3 @@ def parse_interesting_advisories(location, purl, delete_download=False) -> Itera
214186 affected_versions = [affected_range ],
215187 fixed_versions = gitlab_advisory ["fixed_versions" ],
216188 )
217- if delete_download :
218- clear_download (location )
0 commit comments