spdx_tools.spdx.validation.spdx_id_validators
1# SPDX-FileCopyrightText: 2022 spdx contributors 2# 3# SPDX-License-Identifier: Apache-2.0 4 5import re 6 7from beartype.typing import List 8 9from spdx_tools.spdx.document_utils import get_contained_spdx_element_ids 10from spdx_tools.spdx.model import Document, File 11 12 13def is_valid_internal_spdx_id(spdx_id: str) -> bool: 14 return bool(re.match(r"^SPDXRef-[\da-zA-Z.-]+$", spdx_id)) 15 16 17def is_valid_external_doc_ref_id(external_ref_id: str) -> bool: 18 return bool(re.match(r"^DocumentRef-[\da-zA-Z.+-]+$", external_ref_id)) 19 20 21def is_spdx_id_present_in_files(spdx_id: str, files: List[File]) -> bool: 22 return spdx_id in [file.spdx_id for file in files] 23 24 25def is_spdx_id_present_in_document(spdx_id: str, document: Document) -> bool: 26 all_spdx_ids_in_document: List[str] = get_list_of_all_spdx_ids(document) 27 28 return spdx_id in all_spdx_ids_in_document 29 30 31def get_list_of_all_spdx_ids(document: Document) -> List[str]: 32 all_spdx_ids_in_document: List[str] = [document.creation_info.spdx_id] 33 all_spdx_ids_in_document.extend(get_contained_spdx_element_ids(document)) 34 35 return all_spdx_ids_in_document 36 37 38def is_external_doc_ref_present_in_document(external_ref_id: str, document: Document) -> bool: 39 all_external_doc_ref_ids_in_document = [ 40 external_doc_ref.document_ref_id for external_doc_ref in document.creation_info.external_document_refs 41 ] 42 43 return external_ref_id in all_external_doc_ref_ids_in_document 44 45 46def validate_spdx_id( 47 spdx_id: str, document: Document, check_document: bool = False, check_files: bool = False 48) -> List[str]: 49 """Test that the given spdx_id (and a potential DocumentRef to an external document) is valid 50 and, if it is a reference, actually exists in the document. Optionally checks files or the whole document 51 for the existence of the spdx_id (i.e. if it is used as a reference). Returns a list of validation messages.""" 52 53 validation_messages: List[str] = [] 54 split_id: List[str] = spdx_id.split(":") 55 56 # # # invalid case # # # 57 if len(split_id) > 2: 58 return [ 59 f"spdx_id must not contain more than one colon in order to separate the external document reference id " 60 f"from the internal SPDX id, but is: {spdx_id}" 61 ] 62 63 # # # case with external document ref prefix # # # 64 if len(split_id) == 2: 65 if not is_valid_external_doc_ref_id(split_id[0]): 66 validation_messages.append( 67 f'the external document reference part of spdx_id must only contain letters, numbers, ".", "-" and ' 68 f'"+" and must begin with "DocumentRef-", but is: {split_id[0]}' 69 ) 70 if not is_valid_internal_spdx_id(split_id[1]): 71 validation_messages.append( 72 f'the internal SPDX id part of spdx_id must only contain letters, numbers, "." and "-" and must begin ' 73 f'with "SPDXRef-", but is: {split_id[1]}' 74 ) 75 if not is_external_doc_ref_present_in_document(split_id[0], document): 76 validation_messages.append( 77 f'did not find the external document reference "{split_id[0]}" in the SPDX document' 78 ) 79 80 return validation_messages 81 82 # # # "normal" case # # # 83 if not is_valid_internal_spdx_id(spdx_id): 84 validation_messages.append( 85 f'spdx_id must only contain letters, numbers, "." and "-" and must begin with "SPDXRef-", but is: ' 86 f"{spdx_id}" 87 ) 88 89 if check_document: 90 if not is_spdx_id_present_in_document(spdx_id, document): 91 validation_messages.append(f'did not find the referenced spdx_id "{spdx_id}" in the SPDX document') 92 93 if check_files: 94 if not is_spdx_id_present_in_files(spdx_id, document.files): 95 validation_messages.append( 96 f'did not find the referenced spdx_id "{spdx_id}" in the SPDX document\'s files' 97 ) 98 99 return validation_messages
def
is_valid_internal_spdx_id(spdx_id: str) -> bool:
def
is_valid_external_doc_ref_id(external_ref_id: str) -> bool:
def
is_spdx_id_present_in_files(spdx_id: str, files: list[spdx_tools.spdx.model.file.File]) -> bool:
def
is_spdx_id_present_in_document(spdx_id: str, document: spdx_tools.spdx.model.document.Document) -> bool:
def
is_external_doc_ref_present_in_document( external_ref_id: str, document: spdx_tools.spdx.model.document.Document) -> bool:
39def is_external_doc_ref_present_in_document(external_ref_id: str, document: Document) -> bool: 40 all_external_doc_ref_ids_in_document = [ 41 external_doc_ref.document_ref_id for external_doc_ref in document.creation_info.external_document_refs 42 ] 43 44 return external_ref_id in all_external_doc_ref_ids_in_document
def
validate_spdx_id( spdx_id: str, document: spdx_tools.spdx.model.document.Document, check_document: bool = False, check_files: bool = False) -> list[str]:
47def validate_spdx_id( 48 spdx_id: str, document: Document, check_document: bool = False, check_files: bool = False 49) -> List[str]: 50 """Test that the given spdx_id (and a potential DocumentRef to an external document) is valid 51 and, if it is a reference, actually exists in the document. Optionally checks files or the whole document 52 for the existence of the spdx_id (i.e. if it is used as a reference). Returns a list of validation messages.""" 53 54 validation_messages: List[str] = [] 55 split_id: List[str] = spdx_id.split(":") 56 57 # # # invalid case # # # 58 if len(split_id) > 2: 59 return [ 60 f"spdx_id must not contain more than one colon in order to separate the external document reference id " 61 f"from the internal SPDX id, but is: {spdx_id}" 62 ] 63 64 # # # case with external document ref prefix # # # 65 if len(split_id) == 2: 66 if not is_valid_external_doc_ref_id(split_id[0]): 67 validation_messages.append( 68 f'the external document reference part of spdx_id must only contain letters, numbers, ".", "-" and ' 69 f'"+" and must begin with "DocumentRef-", but is: {split_id[0]}' 70 ) 71 if not is_valid_internal_spdx_id(split_id[1]): 72 validation_messages.append( 73 f'the internal SPDX id part of spdx_id must only contain letters, numbers, "." and "-" and must begin ' 74 f'with "SPDXRef-", but is: {split_id[1]}' 75 ) 76 if not is_external_doc_ref_present_in_document(split_id[0], document): 77 validation_messages.append( 78 f'did not find the external document reference "{split_id[0]}" in the SPDX document' 79 ) 80 81 return validation_messages 82 83 # # # "normal" case # # # 84 if not is_valid_internal_spdx_id(spdx_id): 85 validation_messages.append( 86 f'spdx_id must only contain letters, numbers, "." and "-" and must begin with "SPDXRef-", but is: ' 87 f"{spdx_id}" 88 ) 89 90 if check_document: 91 if not is_spdx_id_present_in_document(spdx_id, document): 92 validation_messages.append(f'did not find the referenced spdx_id "{spdx_id}" in the SPDX document') 93 94 if check_files: 95 if not is_spdx_id_present_in_files(spdx_id, document.files): 96 validation_messages.append( 97 f'did not find the referenced spdx_id "{spdx_id}" in the SPDX document\'s files' 98 ) 99 100 return validation_messages
Test that the given spdx_id (and a potential DocumentRef to an external document) is valid and, if it is a reference, actually exists in the document. Optionally checks files or the whole document for the existence of the spdx_id (i.e. if it is used as a reference). Returns a list of validation messages.