Source code for ossindex.model

#
# Copyright 2022-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.
#
from typing import Iterable, Optional, Set

# See https://github.com/package-url/packageurl-python/issues/65
from packageurl import PackageURL  # type: ignore


[docs]class Vulnerability: """ Model class that represents a Vulnerability as received back from OSS Index. """ def __init__(self, *, id_: str, display_name: str, title: str, description: str, cvss_score: Optional[float] = None, cvss_vector: Optional[str] = None, cve: Optional[str] = None, cwe: Optional[str] = None, version_ranges: Optional[Iterable[str]] = None, reference: str, external_references: Optional[Iterable[str]] = None): self.id = id_ self.display_name = display_name self.title = title self.description = description self.cvss_score = cvss_score self.cvss_vector = cvss_vector self.cve = cve self.cwe = cwe self.version_ranges = set(version_ranges or []) self.reference = reference self.external_references = set(external_references or []) @property
[docs] def id(self) -> str: """ OSS Index's unique UUID for this Vulnerability. Returns: `str` """ return self._id
@id.setter def id(self, id_: str) -> None: self._id = id_ @property
[docs] def display_name(self) -> str: """ displayName returned by OSS Index Returns: `str` """ return self._display_name
@display_name.setter def display_name(self, display_name: str) -> None: self._display_name = display_name @property
[docs] def title(self) -> str: """ title returned by OSS Index Returns: `str` """ return self._title
@title.setter def title(self, title: str) -> None: self._title = title @property
[docs] def description(self) -> str: """ description returned by OSS Index. Returns: `str` """ return self._description
@description.setter def description(self, description: str) -> None: self._description = description @property
[docs] def cvss_score(self) -> Optional[float]: """ CVSS Score returned from OSS Index. Returns: `float` if set else `None` """ return self._cvss_score
@cvss_score.setter def cvss_score(self, cvss_score: Optional[float]) -> None: self._cvss_score = cvss_score @property
[docs] def cvss_vector(self) -> Optional[str]: """ CVSS Vector returned from OSS Index Returns: `str` if set else `None` """ return self._cvss_vector
@cvss_vector.setter def cvss_vector(self, cvss_vector: Optional[str]) -> None: self._cvss_vector = cvss_vector @property
[docs] def cwe(self) -> Optional[str]: """ CWE returned from OSS Index. .. note: This is a string of the format CWE-nnn or an empty string Returns: `str` if set else `None` """ return self._cwe
@cwe.setter def cwe(self, cwe: Optional[str]) -> None: self._cwe = cwe @property
[docs] def cve(self) -> Optional[str]: """ CVE returned from OSS Index. Returns: `str` if set else `None` """ return self._cve
@cve.setter def cve(self, cve: Optional[str]) -> None: self._cve = cve @property
[docs] def reference(self) -> str: """ Reference URL to OSS Index for this Vulnerability. Returns: `str` """ return self._reference
@reference.setter def reference(self, reference: str) -> None: self._reference = reference @property
[docs] def version_ranges(self) -> Set[str]: """ Range of versions which are impacted by this Vulnerability. Returns: Set of `str` """ return self._version_ranges
@version_ranges.setter def version_ranges(self, version_ranges: Iterable[str]) -> None: self._version_ranges = set(version_ranges) @property
[docs] def external_references(self) -> Set[str]: """ List of external references that provide additional information about the vulnerability. Returns: Set of `str` """ return self._external_references
@external_references.setter def external_references(self, external_references: Iterable[str]) -> None: self._external_references = set(external_references)
[docs] def __eq__(self, other: object) -> bool: if isinstance(other, Vulnerability): return hash(other) == hash(self) return False
[docs] def __hash__(self) -> int: return hash(( self.id, self.display_name, self.title, self.description, self.cvss_score, self.cvss_vector, self.cve, self.cwe, tuple(self.version_ranges), self.reference, tuple(self.external_references) ))
[docs] def __repr__(self) -> str: return f'<Vulnerability id={self.id}, name={self.display_name}, cvss_score={self.cvss_score:.1f}>'
[docs]class OssIndexComponent: """ Model class that represents a Component Report as received back from OSS Index. """ def __init__(self, *, coordinates: str, description: Optional[str] = None, reference: str, vulnerabilities: Optional[Iterable[Vulnerability]] = None) -> None: self.coordinates = coordinates self.description = description self.reference = reference self.vulnerabilities = set(vulnerabilities or []) @property
[docs] def coordinates(self) -> str: """ PackageURL formatted coordinates of this Component. Returns: `str` """ return self._coordinates
@coordinates.setter def coordinates(self, coordinates: str) -> None: self._coordinates = coordinates @property
[docs] def description(self) -> Optional[str]: """ Description of the Component from OSS Index. Returns: `str` if set else `None` """ return self._description
@description.setter def description(self, description: Optional[str]) -> None: self._description = description @property
[docs] def reference(self) -> str: """ URL to this Component on OSS Index. Returns: `str` """ return self._reference
@reference.setter def reference(self, reference: str) -> None: self._reference = reference @property
[docs] def vulnerabilities(self) -> Set[Vulnerability]: """ Known vulnerabilities that relate to this Component. Returns: Set of `Vulnerability` """ return self._vulnerabilities
@vulnerabilities.setter def vulnerabilities(self, vulnerabilities: Iterable[Vulnerability]) -> None: self._vulnerabilities = set(vulnerabilities)
[docs] def __eq__(self, other: object) -> bool: if isinstance(other, OssIndexComponent): return hash(other) == hash(self) return False
[docs] def __hash__(self) -> int: return hash(( self.coordinates, self.description, self.reference, tuple(self.vulnerabilities) ))
[docs] def __repr__(self) -> str: return f'<OssIndexComponent coordinates={self.coordinates}>'
[docs] def get_package_url(self) -> PackageURL: """ Get a PURL representation of this components coordinates. Returns: `PackageURL` """ return PackageURL.from_string(purl=self.coordinates)
[docs] def get_max_cvss_score(self) -> float: """ Get the maximum CVSS Score across all Vulnerabilities known for this Component. Returns: `float` """ max_cvss_score = 0.0 if self.vulnerabilities: for v in self.vulnerabilities: max_cvss_score = OssIndexComponent._reduce_on_max_cvss_score(v=v, current_max=max_cvss_score) return max_cvss_score
@staticmethod
[docs] def _reduce_on_max_cvss_score(v: Vulnerability, current_max: float) -> float: if v.cvss_score: if v.cvss_score > current_max: return v.cvss_score return current_max