66# See https://github.com/nexB/vulnerablecode for support or download.
77# See https://aboutcode.org for more information about nexB OSS projects.
88#
9- import dataclasses
10- import json
11- import pprint
9+
1210from typing import Iterable
1311from typing import List
1412from typing import Mapping
15- from typing import Set
1613from urllib .request import urlopen
1714
1815from packageurl import PackageURL
2219from vulnerabilities .importer import Importer
2320from vulnerabilities .importer import Reference
2421from vulnerabilities .importer import VulnerabilitySeverity
25-
26- # 9/28/2022 Wednesday 12:58:46 PM. Do we need the next import? It's used at the bottom!
27- from vulnerabilities .models import Advisory
28-
29- # 9/28/2022 Wednesday 1:04:27 PM. From /home/jmh/dev/nexb/vulnerablecode/vulnerabilities/importers/alpine_linux.py
30- # copy fetch_response function to vulnerabilities.utils then import here and use below
3122from vulnerabilities .utils import fetch_response
3223from vulnerabilities .utils import nearest_patched_package
3324
34- # Take a URL -> Grab the data from the URL -> Map it according to AdvisoryData
35-
3625
3726class ArchlinuxImporter (Importer ):
38- # def __enter__(self):
39- # self._api_response = self._fetch()
40-
41- # def updated_advisories(self) -> Set[AdvisoryData]:
42- # advisories = []
43-
44- # for record in self._api_response:
45- # advisories.extend(self._parse(record))
46-
47- # return self.batch_advisories(advisories)
48-
49- # def _fetch(self) -> Iterable[Mapping]:
50- # with urlopen(self.config.archlinux_tracker_url) as response:
51- # return json.load(response)
52-
5327 url = "https://security.archlinux.org/json"
5428 spdx_license_expression = "unknown"
5529
@@ -61,20 +35,21 @@ def advisory_data(self) -> Iterable[AdvisoryData]:
6135 for record in self .fetch ():
6236 yield self .parse_advisory (record )
6337
64- # def _parse(self, record) -> List[AdvisoryData]:
38+ # The JSON includes 'status' and 'type' fields do we want to incorporate them into the AdvisoryData objects?
39+ # Although not directly reflected in the JSON, the web page for at least some references include an additional reference,
40+ # see, e.g., https://security.archlinux.org/AVG-2781 (one of our test inputs, which lists this ref: https://github.com/jpadilla/pyjwt/security/advisories/GHSA-ffqj-6fqr-9h24)
41+ # Do we want to incorporate them into the AdvisoryData objects?
6542 def parse_advisory (self , record ) -> List [AdvisoryData ]:
6643 advisories = []
6744 aliases = record ["issues" ]
68- for cve_id in record ["issues" ]:
45+ for alias in record ["issues" ]:
6946 affected_packages = []
7047 for name in record ["packages" ]:
7148 impacted_purls , resolved_purls = [], []
7249 impacted_purls .append (
7350 PackageURL (
7451 name = name ,
75- # type="pacman",
76- # type="alpm",
77- type = "archlinux" ,
52+ type = "alpm" ,
7853 namespace = "archlinux" ,
7954 version = record ["affected" ],
8055 )
@@ -84,9 +59,7 @@ def parse_advisory(self, record) -> List[AdvisoryData]:
8459 resolved_purls .append (
8560 PackageURL (
8661 name = name ,
87- # type="pacman",
88- # type="alpm",
89- type = "archlinux" ,
62+ type = "alpm" ,
9063 namespace = "archlinux" ,
9164 version = record ["fixed" ],
9265 )
@@ -115,26 +88,41 @@ def parse_advisory(self, record) -> List[AdvisoryData]:
11588 )
11689
11790 advisories .append (
118- # Advisory(
11991 AdvisoryData (
120- # deprecated
121- # vulnerability_id=cve_id,
122- aliases = [cve_id ],
123- # summary="",
92+ # Do we want/need to keep this inside a list? "aliases" is plural but I understand we want to break out each alias individually.
93+ # However, it looks like alpine_linux.py and nginx.py, for example, return a list of aliases.
94+ aliases = [alias ],
95+ # aliases=alias,
96+ summary = "" ,
12497 affected_packages = affected_packages ,
12598 references = references ,
12699 )
127100 )
128101
129- print ("\r Hello World!\r " )
130-
131- print ("\r advisories = {}\r " .format (advisories ))
132-
133- for apple in advisories :
134- # pprint.pprint(apple.to_dict())
135- print (apple .affected_packages )
136- print (f"aliases: { apple .aliases } " )
137- print (f"summary: { apple .summary } " )
138- print (f"affected_packages: { apple .affected_packages } " )
102+ # The print statements below will print the structure of each test advisory when either of these tests is run:
103+ # pytest -vvs -k test_parse_advisory_single vulnerabilities/tests/test_archlinux.py
104+ # pytest -vvs -k test_parse_advisory_multi vulnerabilities/tests/test_archlinux.py
105+
106+ print ("\n \r =================================\n \r " )
107+
108+ for advisory in advisories :
109+ print (f"1. aliases: { advisory .aliases } \r " )
110+ print ("" )
111+ print (f"2. summary: { advisory .summary } \r " )
112+ print ("" )
113+ print (f"3. affected_packages: { advisory .affected_packages } \r " )
114+ for pkg in advisory .affected_packages :
115+ print ("" )
116+ print ("vulnerable_package: {}\r " .format (pkg .vulnerable_package ))
117+ print ("" )
118+ print ("patched_package: {}\r " .format (pkg .patched_package ))
119+ print ("" )
120+ print (f"4. references: { advisory .references } \r " )
121+ for ref in advisory .references :
122+ print ("" )
123+ print ("ref: {}\r " .format (ref ))
124+ print ("" )
125+ print (f"5. date_published: { advisory .date_published } \r " )
126+ print ("\n \r =================================\n \r " )
139127
140128 return advisories
0 commit comments