4141from vulnerabilities .importers import oval_parser
4242
4343
44-
4544@dataclasses .dataclass
4645class UbuntuConfiguration (DataSourceConfiguration ):
4746 releases : list
4847
48+
4949class UbuntuDataSource (DataSource ):
5050
5151 CONFIG_CLASS = UbuntuConfiguration
52+
5253 def __init__ (self , * args , ** kwargs ):
5354 super ().__init__ (* args , ** kwargs )
54- #we could avoid setting translations, and have it
55- #set by default in the OvalParser, but we don't yet know
56- #whether all OVAL providers use the same format
57- self .translations = {'less than' :'<' }
55+ # we could avoid setting translations, and have it
56+ # set by default in the OvalParser, but we don't yet know
57+ # whether all OVAL providers use the same format
58+ self .translations = {'less than' : '<' }
5859 self ._versions = VersionAPI ()
5960
60- def _fetch (self ) :
61+ def _fetch (self ):
6162 base_url = 'https://people.canonical.com/~ubuntu-security/oval/'
6263 file_name = 'com.ubuntu.{}.cve.oval.xml.bz2'
63- releases = self .config .releases
64+ releases = self .config .releases
6465 for release in releases :
6566 resp = requests .get (base_url + file_name .format (release ))
6667 extracted = bz2 .decompress (resp .content )
6768 yield ET .ElementTree (ET .fromstring (extracted .decode ('utf-8' )))
6869
69- def added_advisories (self ) -> List [Advisory ] :
70+ def added_advisories (self ) -> List [Advisory ]:
7071 advisories = []
7172 for oval_file in self ._fetch ():
7273 advisories .extend (self .get_data_from_xml_doc (oval_file ))
73- return advisories
74+ return advisories
7475
75- @staticmethod
76- def _collect_pkgs (parsed_oval_data ) -> Set :
76+ @staticmethod
77+ def _collect_pkgs (parsed_oval_data ) -> Set :
7778 all_pkgs = set ()
78- for definition_data in parsed_oval_data :
79+ for definition_data in parsed_oval_data :
7980 for test_data in definition_data ['test_data' ]:
8081 for package in test_data ['package_list' ]:
8182 all_pkgs .add (package )
8283
8384 return all_pkgs
8485
85-
86- def get_data_from_xml_doc (self , xml_doc ) -> List [Advisory ] :
86+ def get_data_from_xml_doc (self , xml_doc ) -> List [Advisory ]:
8787 all_adv = []
8888 oval_doc = oval_parser .OvalParser (self .translations , xml_doc )
8989 raw_data = oval_doc .get_data ()
9090 all_pkgs = self ._collect_pkgs (raw_data )
9191
9292 asyncio .run (self ._versions .load_api (all_pkgs ))
9393
94- for definition_data in raw_data : # definition_data -> Advisory
94+ for definition_data in raw_data : # definition_data -> Advisory
9595 vuln_id = definition_data ['vuln_id' ]
9696 description = definition_data ['description' ]
9797 affected_purls = set ()
9898 safe_purls = set ()
9999 urls = definition_data ['reference_urls' ]
100- for test_data in definition_data ['test_data' ] :
100+ for test_data in definition_data ['test_data' ]:
101101 for package in test_data ['package_list' ]:
102102 pkg_name = package
103103 aff_ver_range = test_data ['version_ranges' ]
104104 all_versions = self ._versions .get (package )
105- #This filter is to filter out long versions.
106- #50 is limit because that's what db permits atm
107- all_versions = set (filter (lambda x : len (x )< 50 ,all_versions ))
105+ # This filter is to filter out long versions.
106+ # 50 is limit because that's what db permits atm
107+ all_versions = set (
108+ filter (
109+ lambda x : len (x ) < 50 ,
110+ all_versions ))
108111 if not all_versions :
109112 continue
110- affected_versions = set (filter (lambda x : x in aff_ver_range ,all_versions ))
113+ affected_versions = set (
114+ filter (
115+ lambda x : x in aff_ver_range ,
116+ all_versions ))
111117 safe_versions = all_versions - affected_versions
112118
113119 for version in affected_versions :
114- #should we add a qualifier like 'distro:ubuntu'?
115- pkg_url = PackageURL (name = pkg_name ,type = 'deb' ,version = version )
120+ # should we add a qualifier like 'distro:ubuntu'?
121+ pkg_url = PackageURL (
122+ name = pkg_name , type = 'deb' , version = version )
116123 affected_purls .add (pkg_url )
117124
118125 for version in safe_versions :
119- #should we add a qualifier like 'distro:ubuntu'?
120- pkg_url = PackageURL (name = pkg_name ,type = 'deb' ,version = version )
126+ # should we add a qualifier like 'distro:ubuntu'?
127+ pkg_url = PackageURL (
128+ name = pkg_name , type = 'deb' , version = version )
121129 safe_purls .add (pkg_url )
122130
123- all_adv .append (Advisory (summary = description ,impacted_package_urls = affected_purls ,
124- resolved_package_urls = safe_purls ,cve_id = vuln_id ,reference_urls = urls ))
131+ all_adv .append (
132+ Advisory (
133+ summary = description ,
134+ impacted_package_urls = affected_purls ,
135+ resolved_package_urls = safe_purls ,
136+ cve_id = vuln_id ,
137+ reference_urls = urls ))
125138 return all_adv
126139
127140
128-
129141class VersionAPI :
130142 def __init__ (self , cache : Mapping [str , Set [str ]] = None ):
131143 self .cache = cache or {}
@@ -135,27 +147,28 @@ def get(self, package_name: str) -> Set[str]:
135147
136148 async def load_api (self , pkg_set ):
137149 async with ClientSession () as session :
138- await asyncio .gather (* [self .set_api (pkg , session ) for pkg in pkg_set if pkg not in self .cache ])
150+ await asyncio .gather (* [self .set_api (pkg , session )
151+ for pkg in pkg_set if pkg not in self .cache ])
139152
140- async def set_api (self , pkg , session ):
153+ async def set_api (self , pkg , session ):
141154 url = ('https://api.launchpad.net/1.0/ubuntu/+archive/'
142- 'primary?ws.op=getPublishedSources&'
143- 'source_name={}&exact_match=true' .format (pkg ))
155+ 'primary?ws.op=getPublishedSources&'
156+ 'source_name={}&exact_match=true' .format (pkg ))
144157 try :
145158 all_versions = set ()
146159 while (True ):
147160 response = await session .request (method = 'GET' , url = url )
148161 response .raise_for_status ()
149162 resp_json = await response .json ()
150- if resp_json ['entries' ] == [] :
163+ if resp_json ['entries' ] == []:
151164 self .cache [pkg ] = {}
152165 break
153166 for release in resp_json ['entries' ]:
154167 all_versions .add (release ['source_package_version' ])
155- if resp_json .get ('next_collection_link' ) :
156- url = resp_json ['next_collection_link' ]
168+ if resp_json .get ('next_collection_link' ):
169+ url = resp_json ['next_collection_link' ]
157170 else :
158171 break
159172 self .cache [pkg ] = all_versions
160173 except ClientResponseError :
161- self .cache [pkg ] = {}
174+ self .cache [pkg ] = {}
0 commit comments