eric7/CycloneDXInterface/CycloneDXUtilities.py

branch
eric7
changeset 9119
5bcdef5207f6
parent 9117
c6afba2049cf
child 9122
ddf8ed8f7387
equal deleted inserted replaced
9118:9858a6c957f5 9119:5bcdef5207f6
18 from packageurl import PackageURL 18 from packageurl import PackageURL
19 19
20 from cyclonedx.model import LicenseChoice 20 from cyclonedx.model import LicenseChoice
21 from cyclonedx.model.bom import Bom 21 from cyclonedx.model.bom import Bom
22 from cyclonedx.model.component import Component 22 from cyclonedx.model.component import Component
23 from cyclonedx.model.vulnerability import Vulnerability, VulnerabilitySource
23 from cyclonedx.output import ( 24 from cyclonedx.output import (
24 OutputFormat, SchemaVersion, get_instance as get_output_instance 25 OutputFormat, SchemaVersion, get_instance as get_output_instance
25 ) 26 )
26 from cyclonedx.parser import BaseParser 27 from cyclonedx.parser import BaseParser
27 28
28 from cyclonedx_py.parser.pipenv import PipEnvFileParser 29 from cyclonedx_py.parser.pipenv import PipEnvFileParser
29 from cyclonedx_py.parser.poetry import PoetryFileParser 30 from cyclonedx_py.parser.poetry import PoetryFileParser
30 from cyclonedx_py.parser.requirements import RequirementsFileParser 31 from cyclonedx_py.parser.requirements import RequirementsFileParser
32
33 from PipInterface.PipVulnerabilityChecker import (
34 Package, VulnerabilityCheckError
35 )
31 36
32 37
33 class CycloneDXEnvironmentParser(BaseParser): 38 class CycloneDXEnvironmentParser(BaseParser):
34 """ 39 """
35 Class implementing a parser to get package data for a named environment. 40 Class implementing a parser to get package data for a named environment.
74 @exception RuntimeError raised to indicate illegal creation parameters 79 @exception RuntimeError raised to indicate illegal creation parameters
75 """ 80 """
76 from .CycloneDXConfigDialog import CycloneDXConfigDialog 81 from .CycloneDXConfigDialog import CycloneDXConfigDialog
77 dlg = CycloneDXConfigDialog(venvName) 82 dlg = CycloneDXConfigDialog(venvName)
78 if dlg.exec() == QDialog.DialogCode.Accepted: 83 if dlg.exec() == QDialog.DialogCode.Accepted:
79 inputSource, inputFile, fileFormat, schemaVersion, sbomFile = ( 84 (inputSource, inputFile, fileFormat, schemaVersion, sbomFile,
80 dlg.getData() 85 withVulnerabilities) = dlg.getData()
81 ) 86
82 87 # check error conditions first
83 if inputSource not in ("environment", "pipenv", "poetry", 88 if inputSource not in ("environment", "pipenv", "poetry",
84 "requirements"): 89 "requirements"):
85 raise RuntimeError("Unsupported input source given.") 90 raise RuntimeError("Unsupported input source given.")
86 if fileFormat not in ("XML", "JSON"): 91 if fileFormat not in ("XML", "JSON"):
87 raise RuntimeError("Unsupported SBOM file format given.") 92 raise RuntimeError("Unsupported SBOM file format given.")
108 elif inputSource == "poetry": 113 elif inputSource == "poetry":
109 parser = PoetryFileParser(poetry_lock_filename=inputFile) 114 parser = PoetryFileParser(poetry_lock_filename=inputFile)
110 elif inputSource == "requirements": 115 elif inputSource == "requirements":
111 parser = RequirementsFileParser(requirements_file=inputFile) 116 parser = RequirementsFileParser(requirements_file=inputFile)
112 117
118 if withVulnerabilities:
119 addCycloneDXVulnerabilities(parser)
120
113 if fileFormat == "XML": 121 if fileFormat == "XML":
114 outputFormat = OutputFormat.XML 122 outputFormat = OutputFormat.XML
115 elif fileFormat == "JSON": 123 elif fileFormat == "JSON":
116 outputFormat = OutputFormat.JSON 124 outputFormat = OutputFormat.JSON
117 125
148 QCoreApplication.translate( 156 QCoreApplication.translate(
149 "CycloneDX", 157 "CycloneDX",
150 "<p>The SBOM data was written to file <b>{0}</b>.</p>" 158 "<p>The SBOM data was written to file <b>{0}</b>.</p>"
151 ).format(sbomFile) 159 ).format(sbomFile)
152 ) 160 )
161
162
163 def addCycloneDXVulnerabilities(parser):
164 """
165 Function to add vulnerability data to the list of created components.
166
167 @param parser reference to the parser object containing the list of
168 components
169 @type BaseParser
170 """
171 components = parser.get_components()
172
173 packages = [
174 Package(name=component.name, version=component.version)
175 for component in components
176 ]
177
178 pip = ericApp().getObject("Pip")
179 error, vulnerabilities = pip.getVulnerabilityChecker().check(packages)
180
181 if error == VulnerabilityCheckError.OK:
182 for package in vulnerabilities:
183 component = findCyccloneDXComponent(components, package)
184 if component:
185 for vuln in vulnerabilities[package]:
186 component.add_vulnerability(Vulnerability(
187 id=vuln.cve,
188 description=vuln.advisory,
189 recommendation="upgrade required",
190 source=VulnerabilitySource(name="pyup.io")
191 ))
192
193
194 def findCyccloneDXComponent(components, name):
195 """
196 Function to find a component in a given list of components.
197
198 @param components list of components to scan
199 @type list of Component
200 @param name name of the component to search for
201 @type str
202 @return reference to the found component or None
203 @rtype Component or None
204 """
205 for component in components:
206 if component.name == name:
207 return component
208
209 return None

eric ide

mercurial