############################ Copyrights and license ############################ # # # Copyright 2023 Enrico Minack # # Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> # # Copyright 2023 Jonathan Leitschuh # # Copyright 2023 Joseph Henrich # # Copyright 2023 Trim21 # # Copyright 2024 Enrico Minack # # Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> # # Copyright 2025 Enrico Minack # # # # This file is part of PyGithub. # # http://pygithub.readthedocs.io/ # # # # PyGithub is free software: you can redistribute it and/or modify it under # # the terms of the GNU Lesser General Public License as published by the Free # # Software Foundation, either version 3 of the License, or (at your option) # # any later version. # # # # PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY # # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # # details. # # # # You should have received a copy of the GNU Lesser General Public License # # along with PyGithub. If not, see . # # # ################################################################################ from __future__ import annotations from typing import TYPE_CHECKING, Any, Union from typing_extensions import TypedDict import github.AdvisoryVulnerabilityPackage from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet if TYPE_CHECKING: from github.AdvisoryVulnerabilityPackage import AdvisoryVulnerabilityPackage class SimpleAdvisoryVulnerabilityPackage(TypedDict): """ A simple package in an advisory. """ ecosystem: str name: str | None class SimpleAdvisoryVulnerability(TypedDict): """ A simple vulnerability in a security advisory. """ package: SimpleAdvisoryVulnerabilityPackage patched_versions: str | None vulnerable_functions: list[str] | None vulnerable_version_range: str | None AdvisoryVulnerabilityInput = Union[SimpleAdvisoryVulnerability, "AdvisoryVulnerability"] class AdvisoryVulnerability(NonCompletableGithubObject): """ This class represents a package that is vulnerable to a parent SecurityAdvisory. The reference can be found here https://docs.github.com/en/rest/security-advisories/repository-advisories The OpenAPI schema can be found at - /components/schemas/repository-advisory-vulnerability - /components/schemas/vulnerability """ def _initAttributes(self) -> None: self._first_patched_version: Attribute[str] = NotSet self._package: Attribute[AdvisoryVulnerabilityPackage] = NotSet self._patched_versions: Attribute[str] = NotSet self._vulnerable_functions: Attribute[list[str]] = NotSet self._vulnerable_version_range: Attribute[str] = NotSet def __repr__(self) -> str: return self.get__repr__({"package": self.package}) @property def first_patched_version(self) -> str: return self._first_patched_version.value @property def package( self, ) -> AdvisoryVulnerabilityPackage: """ :type: :class:`github.AdvisoryVulnerability.AdvisoryVulnerability` """ return self._package.value @property def patched_versions(self) -> str: """ :type: string """ return self._patched_versions.value @property def vulnerable_functions(self) -> list[str] | None: """ :type: list of string """ return self._vulnerable_functions.value @property def vulnerable_version_range(self) -> str | None: """ :type: string """ return self._vulnerable_version_range.value @classmethod def _validate_vulnerability(cls, vulnerability: AdvisoryVulnerabilityInput) -> None: assert isinstance(vulnerability, (dict, cls)), vulnerability if isinstance(vulnerability, dict): assert "package" in vulnerability, vulnerability package: SimpleAdvisoryVulnerabilityPackage = vulnerability["package"] assert isinstance(package, dict), package assert "ecosystem" in package, package assert isinstance(package["ecosystem"], str), package assert "name" in package, package assert isinstance(package["name"], (str, type(None))), package assert "patched_versions" in vulnerability, vulnerability assert isinstance(vulnerability["patched_versions"], (str, type(None))), vulnerability assert "vulnerable_functions" in vulnerability, vulnerability assert isinstance(vulnerability["vulnerable_functions"], (list, type(None))), vulnerability assert "vulnerable_functions" in vulnerability, vulnerability assert ( all(isinstance(vf, str) for vf in vulnerability["vulnerable_functions"]) if vulnerability["vulnerable_functions"] is not None else True ), vulnerability assert "vulnerable_version_range" in vulnerability, vulnerability assert isinstance(vulnerability["vulnerable_version_range"], (str, type(None))), vulnerability else: assert ( vulnerability.package is github.AdvisoryVulnerabilityPackage.AdvisoryVulnerabilityPackage ), vulnerability @staticmethod def _to_github_dict( vulnerability: AdvisoryVulnerabilityInput, ) -> SimpleAdvisoryVulnerability: if isinstance(vulnerability, dict): vulnerability_package: SimpleAdvisoryVulnerabilityPackage = vulnerability["package"] return { "package": { "ecosystem": vulnerability_package["ecosystem"], "name": vulnerability_package["name"], }, "patched_versions": vulnerability["patched_versions"], "vulnerable_functions": vulnerability["vulnerable_functions"], "vulnerable_version_range": vulnerability["vulnerable_version_range"], } return { "package": { "ecosystem": vulnerability.package.ecosystem, "name": vulnerability.package.name, }, "patched_versions": vulnerability.patched_versions, "vulnerable_functions": vulnerability.vulnerable_functions, "vulnerable_version_range": vulnerability.vulnerable_version_range, } def _useAttributes(self, attributes: dict[str, Any]) -> None: if "first_patched_version" in attributes: # pragma no branch self._first_patched_version = self._makeStringAttribute(attributes["first_patched_version"]) if "package" in attributes: # pragma no branch self._package = self._makeClassAttribute( github.AdvisoryVulnerabilityPackage.AdvisoryVulnerabilityPackage, attributes["package"], ) if "patched_versions" in attributes: # pragma no branch self._patched_versions = self._makeStringAttribute(attributes["patched_versions"]) if "vulnerable_functions" in attributes: # pragma no branch self._vulnerable_functions = self._makeListOfStringsAttribute(attributes["vulnerable_functions"]) if "vulnerable_version_range" in attributes: # pragma no branch self._vulnerable_version_range = self._makeStringAttribute(attributes["vulnerable_version_range"])