From d8941f57575ab2cb0d2e334ce546cf11af8ab63a Mon Sep 17 00:00:00 2001 From: Paul Horton Date: Thu, 16 Sep 2021 09:42:44 +0100 Subject: [PATCH] refactor: removing old Jake code superseded by cyclonedx-python-lib and ossindex-lib Signed-off-by: Paul Horton --- jake/audit/__init__.py | 0 jake/audit/audit.py | 187 ----------------------------------------- jake/parse/__init__.py | 0 jake/parse/parse.py | 82 ------------------ jake/pip/__init__.py | 0 jake/pip/pip.py | 59 ------------- 6 files changed, 328 deletions(-) delete mode 100644 jake/audit/__init__.py delete mode 100644 jake/audit/audit.py delete mode 100644 jake/parse/__init__.py delete mode 100644 jake/parse/parse.py delete mode 100644 jake/pip/__init__.py delete mode 100644 jake/pip/pip.py diff --git a/jake/audit/__init__.py b/jake/audit/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/jake/audit/audit.py b/jake/audit/audit.py deleted file mode 100644 index 8c2f857..0000000 --- a/jake/audit/audit.py +++ /dev/null @@ -1,187 +0,0 @@ -# -# Copyright 2019-Present Sonatype Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -""" audit.py for all your audit py needs """ -# pylint: disable=no-else-return -import json -import logging - -from typing import List -from textwrap import wrap -from colorama import Fore -from terminaltables import DoubleTable - -from ..types.coordinateresults import CoordinateResults -from ..types.vulnerabilities import Vulnerabilities - -class Audit: - """ Audit does the business, it prints results from OSS Index to the standard out """ - - def __init__(self, quiet=False): - self._log = logging.getLogger("jake") - self._quiet = quiet - - def audit_results(self, results: List[CoordinateResults], output_format='hr'): - """ - audit_results is the ingest point for the results from OSS Index, - and handles control flow - """ - self._log.debug("Results received, %s total results", len(results)) - - if output_format == 'json': - return self.print_results_json(results) - - total_vulns = 0 - pkg_num = 0 - good = [x for x in results if len(x.get_vulnerabilities()) == 0] - bad = [x for x in results if len(x.get_vulnerabilities()) > 0] - - if (len(good) != 0 and not self._quiet): - print() - print("Non-Vulnerable Dependencies") - print() - for coordinate in good: - pkg_num += 1 - total_vulns += self.print_result(coordinate, pkg_num, len(results)) - - if len(bad) != 0: - print() - print("Vulnerable Dependencies") - print() - - for coordinate in bad: - pkg_num += 1 - total_vulns += self.print_result(coordinate, pkg_num, len(results)) - - table_data = [ - ["Audited Dependencies", len(results)], - ["Vulnerablities Found", total_vulns], - ] - - table_instance = DoubleTable(table_data, "Summary") - - print() - - print(table_instance.table) - - return total_vulns - - @classmethod - def print_results_json(cls, results: List[CoordinateResults]): - """ - print_json takes a list of coordinate results, - and prints a json array of all vulnerabilities - """ - vulnerabilities = [] - for result in results: - for vulnerability in result.get_vulnerabilities(): - vulnerabilities.append({ - "package": result.get_coordinates()[4:], - "title": vulnerability.get_title(), - "cvss_score": vulnerability.get_cvss_score(), - "cve": vulnerability.get_cve(), - "description": vulnerability.get_description(), - }) - print(json.dumps(vulnerabilities)) - return sum(len(x.get_vulnerabilities()) for x in results) - - def print_result(self, coordinate: CoordinateResults, number, length): - """ - print_results takes a coordinate, the index of the coordinate in a list, - and the length, and handles printing it in different formats if a - vulnerability exists - """ - if len(coordinate.get_vulnerabilities()) == 0: - if not self._quiet: - self.do_print( - f"[{number}/{length}] - {coordinate.get_coordinates()}", - 0 - ) - return len(coordinate.get_vulnerabilities()) - self.do_print( - f"[{number}/{length}] - {coordinate.get_coordinates()} [VULNERABLE]", - coordinate.get_max_cvss_score(), - ) - self.do_print( - f"{len(coordinate.get_vulnerabilities())} known vulnerabilities for this version", - coordinate.get_max_cvss_score(), - ) - for vulnerability in coordinate.get_vulnerabilities(): - self.print_vulnerability(vulnerability) - return len(coordinate.get_vulnerabilities()) - - @classmethod - def print_vulnerability(cls, vulnerability: Vulnerabilities): - """ - print_vulnerability takes a vulnerability, and well, it prints it - """ - cvss_score = vulnerability.get_cvss_score() - table_data = [ - ["ID", vulnerability.get_id()], - ["Title", vulnerability.get_title()], - ["Description", '\n'.join(wrap(vulnerability.get_description(), 100))], - ["CVSS Score", f"{vulnerability.get_cvss_score()} - {cls.get_cvss_severity(cvss_score)}"], - ] - if vulnerability.get_cvss_vector(): - table_data.append( - ["CVSS Vector", vulnerability.get_cvss_vector()] - ) - - table_data.extend( - [ - ["CVE", vulnerability.get_cve()], - ["Reference", vulnerability.get_reference()] - ] - ) - table_instance = DoubleTable(table_data) - table_instance.inner_heading_row_border = False - table_instance.inner_row_border = True - cls.do_print(table_instance.table, cvss_score) - - print("----------------------------------------------------") - - @classmethod - def do_print(cls, text, cvss_score): - """ - do_print takes text, and a cvss_score and prints it in a different text depending on - the score - """ - if cvss_score == 0: - print(Fore.GREEN + text + Fore.RESET) - elif 0 < cvss_score < 4: - print(Fore.CYAN + text + Fore.RESET) - elif 4 <= cvss_score < 7: - print(Fore.LIGHTYELLOW_EX + text + Fore.RESET) - elif 7 <= cvss_score < 9: - print(Fore.YELLOW + text + Fore.RESET) - else: - print(Fore.RED + text + Fore.RESET) - - @classmethod - def get_cvss_severity(cls, cvss_score): - """ - get_cvss_severity takes a cvss_score and returns a human readable severity for it - """ - if cvss_score == 0: - return "None" - elif 0 < cvss_score < 4: - return "Low" - elif 4 <= cvss_score < 7: - return "Medium" - elif 7 <= cvss_score < 9: - return "High" - else: - return "Critical" diff --git a/jake/parse/__init__.py b/jake/parse/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/jake/parse/parse.py b/jake/parse/parse.py deleted file mode 100644 index bd9df30..0000000 --- a/jake/parse/parse.py +++ /dev/null @@ -1,82 +0,0 @@ -# -# Copyright 2019-Present Sonatype Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -"""parse.py parses dependencies and converts them to purls""" -import logging -from shutil import which - -from ..types.coordinates import Coordinates - -class Parse(): - """parse.py parses dependencies and converts them to purls""" - def __init__(self): - self._log = logging.getLogger('jake') - self._format = "conda" - - def get_dependencies(self, run_command_list): - """checks if conda exists and then gets a list of conda dependencies from stdout""" - if self.check_if_conda_exists(): - return self.really_get_conda_dependencies(run_command_list) - return None - - def get_deps_stdin(self, stdin): - """gets depdencies from stdin""" - return self.parse_conda_dependencies_into_purls(stdin) - - def check_if_conda_exists(self): - """checks to see if user installed conda""" - self._log.debug(which("python")) - conda_exists = which("conda") - - self._log.debug(conda_exists) - - if conda_exists is not None: - return True - - return False - - def really_get_conda_dependencies(self, run_command_list): - """gets a list of installed conda dependencies""" - results = self.run_conda_list_command(run_command_list) - - length = len(results) - - if results[length-1] == 0: - return self.parse_conda_dependencies_into_purls(results) - - return None - - @classmethod - def run_conda_list_command(cls, run_command_list): - """checks stdout to see if user installed conda""" - return run_command_list - - def parse_conda_dependencies_into_purls(self, stdin): - """converts list of dependencies from stdin into purl coordinates""" - coords = Coordinates() - self._log.debug("Starting to parse results") - for line in stdin: - if "#" in line: - self._log.debug("Skipping line") - else: - line_array = line.split() - if len(line_array) != 0: - coords.add_coordinate(line_array[0], line_array[1], self._format) - - if len(coords.get_coordinates()) == 0: - return None - - return coords diff --git a/jake/pip/__init__.py b/jake/pip/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/jake/pip/pip.py b/jake/pip/pip.py deleted file mode 100644 index 3eda0a7..0000000 --- a/jake/pip/pip.py +++ /dev/null @@ -1,59 +0,0 @@ -# -# Copyright 2019-Present Sonatype Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -"""pip.py gets installed pip dependencies""" -# pylint: disable=protected-access -import logging -import ast -import pkg_resources - -from ..types.coordinates import Coordinates - -class Pip(): - """pip.py gets installed pip dependencies""" - def __init__(self, targets=None, requirements_file_path=None): - self._log = logging.getLogger('jake') - self._format = "pypi" - self._working_set = pkg_resources.working_set - self.requirements_file_path = requirements_file_path - if targets: - self._working_set = pkg_resources.WorkingSet(ast.literal_eval(targets)) - self._coords = self.generate_dependencies() - - def generate_dependencies(self, coords=Coordinates()) -> (Coordinates): - """converts list of pkg_resource.working_set into purl coordinates""" - - if self.requirements_file_path: - with open(self.requirements_file_path, 'r') as requirements_file: - for line in requirements_file.readlines(): - name, version = line.strip().split('==') - coords.add_coordinate(name, version, self._format) - else: - for i in iter(self._working_set): - coords.add_coordinate(i.project_name, i._version, self._format) - - if len(coords.get_coordinates()) == 0: - return None - - self._coords = coords - return coords - - def get_dependencies(self) -> (Coordinates): - """ gets the list of dependencies generatated on init - Returns: - Coordinates object -- list of coordinates generated by pkg_resources - """ - return self._coords