eric7/CycloneDXInterface/CycloneDXUtilities.py

branch
eric7
changeset 9119
5bcdef5207f6
parent 9117
c6afba2049cf
child 9122
ddf8ed8f7387
--- a/eric7/CycloneDXInterface/CycloneDXUtilities.py	Sat Jun 04 11:56:48 2022 +0200
+++ b/eric7/CycloneDXInterface/CycloneDXUtilities.py	Sat Jun 04 15:53:41 2022 +0200
@@ -20,6 +20,7 @@
 from cyclonedx.model import LicenseChoice
 from cyclonedx.model.bom import Bom
 from cyclonedx.model.component import Component
+from cyclonedx.model.vulnerability import Vulnerability, VulnerabilitySource
 from cyclonedx.output import (
     OutputFormat, SchemaVersion, get_instance as get_output_instance
 )
@@ -29,6 +30,10 @@
 from cyclonedx_py.parser.poetry import PoetryFileParser
 from cyclonedx_py.parser.requirements import RequirementsFileParser
 
+from PipInterface.PipVulnerabilityChecker import (
+    Package, VulnerabilityCheckError
+)
+
 
 class CycloneDXEnvironmentParser(BaseParser):
     """
@@ -76,10 +81,10 @@
     from .CycloneDXConfigDialog import CycloneDXConfigDialog
     dlg = CycloneDXConfigDialog(venvName)
     if dlg.exec() == QDialog.DialogCode.Accepted:
-        inputSource, inputFile, fileFormat, schemaVersion, sbomFile = (
-            dlg.getData()
-        )
+        (inputSource, inputFile, fileFormat, schemaVersion, sbomFile,
+         withVulnerabilities) = dlg.getData()
         
+        # check error conditions first
         if inputSource not in ("environment", "pipenv", "poetry",
                                "requirements"):
             raise RuntimeError("Unsupported input source given.")
@@ -110,6 +115,9 @@
             elif inputSource == "requirements":
                 parser = RequirementsFileParser(requirements_file=inputFile)
         
+        if withVulnerabilities:
+            addCycloneDXVulnerabilities(parser)
+        
         if fileFormat == "XML":
             outputFormat = OutputFormat.XML
         elif fileFormat == "JSON":
@@ -150,3 +158,52 @@
                 "<p>The SBOM data was written to file <b>{0}</b>.</p>"
             ).format(sbomFile)
         )
+
+
+def addCycloneDXVulnerabilities(parser):
+    """
+    Function to add vulnerability data to the list of created components.
+    
+    @param parser reference to the parser object containing the list of
+        components
+    @type BaseParser
+    """
+    components = parser.get_components()
+    
+    packages = [
+        Package(name=component.name, version=component.version)
+        for component in components
+    ]
+    
+    pip = ericApp().getObject("Pip")
+    error, vulnerabilities = pip.getVulnerabilityChecker().check(packages)
+    
+    if error == VulnerabilityCheckError.OK:
+        for package in vulnerabilities:
+            component = findCyccloneDXComponent(components, package)
+            if component:
+                for vuln in vulnerabilities[package]:
+                    component.add_vulnerability(Vulnerability(
+                        id=vuln.cve,
+                        description=vuln.advisory,
+                        recommendation="upgrade required",
+                        source=VulnerabilitySource(name="pyup.io")
+                    ))
+
+
+def findCyccloneDXComponent(components, name):
+    """
+    Function to find a component in a given list of components.
+    
+    @param components list of components to scan
+    @type list of Component
+    @param name name of the component to search for
+    @type str
+    @return reference to the found component or None
+    @rtype Component or None
+    """
+    for component in components:
+        if component.name == name:
+            return component
+    
+    return None

eric ide

mercurial