Source code for ntia_conformance_checker.ntia_checker

# SPDX-FileCopyrightText: 2024 SPDX contributors
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: Apache-2.0

"""NTIA Minimum Elements checking functionality."""

from __future__ import annotations

import warnings

from .base_checker import BaseChecker


[docs] class NTIAChecker(BaseChecker): """ NTIA Minimum Elements check. See: https://www.ntia.gov/report/2021/minimum-elements-software-bill-materials-sbom """ def __init__( self, file: str, validate: bool = True, compliance: str = "ntia", sbom_spec: str = "spdx2", ): """ Initialize the NTIA Minimum Element Checker. Args: file (str): The name of the file to be checked. validate (bool): Whether to validate the file. compliance (str): The compliance standard to be used. sbom_spec (str): The SBOM specification to be used. """ super().__init__( file=file, validate=validate, compliance=compliance, sbom_spec=sbom_spec ) if compliance not in {"ntia"}: raise ValueError("Only NTIA Minimum Element compliance is supported.") if self.doc: self.compliant = self.check_compliance() # for backward compatibility self.ntia_minimum_elements_compliant = self.compliant
[docs] def check_compliance(self) -> bool: """Check overall compliance with NTIA minimum elements.""" return all( [ self.doc_author, self.doc_timestamp, self.dependency_relationships, not self.components_without_names, not self.components_without_versions, not self.components_without_identifiers, not self.components_without_suppliers, not self.validation_messages, ] )
[docs] def check_ntia_minimum_elements_compliance(self) -> bool: """Check overall compliance with NTIA minimum elements. This method is kept for backward compatibility. Please consider using check_compliance() instead.""" warnings.warn( "NTIAChecker.check_ntia_minimum_elements_compliance is deprecated; " "use check_compliance() instead.", DeprecationWarning, stacklevel=2, ) return self.check_compliance()
[docs] def print_components_missing_info(self, attributes=None) -> None: """Print detailed info about which components have missing info.""" super().print_components_missing_info( ["name", "version", "identifier", "supplier"] )
[docs] def print_table_output(self, verbose: bool = False, table_elements=None) -> None: """Print element-by-element result table.""" super().print_table_output( verbose=verbose, table_elements=[ ("All component names provided?", not self.components_without_names), ( "All component versions provided?", not self.components_without_versions, ), ( "All component identifiers provided?", not self.components_without_identifiers, ), ( "All component suppliers provided?", not self.components_without_suppliers, ), ("SBOM author name provided?", self.doc_author), ("SBOM creation timestamp provided?", self.doc_timestamp), ("Dependency relationships provided?", self.dependency_relationships), ], )
[docs] def output_html(self, table_elements=None) -> str: """Create a HTML of results.""" return super().output_html( table_elements=[ ("All component names provided", not self.components_without_names), ( "All component versions provided", not self.components_without_versions, ), ( "All component identifiers provided", not self.components_without_identifiers, ), ( "All component suppliers provided", not self.components_without_suppliers, ), ("SBOM author name provided", self.doc_author), ("SBOM creation timestamp provided", self.doc_timestamp), ("Dependency relationships provided", self.dependency_relationships), ], )