From 02d2ba86dae04938e00bd0abb41b71fe1709b551 Mon Sep 17 00:00:00 2001 From: Paul Horton Date: Wed, 16 Feb 2022 10:53:43 +0000 Subject: [PATCH] feat: completed work on #155 fix: resolved #169 (part of #155) feat: as part of solving #155, #147 has been implemented Signed-off-by: Paul Horton --- cyclonedx/output/json.py | 77 ++++++++---- cyclonedx/output/schema.py | 33 ++++++ cyclonedx/output/xml.py | 46 +++++++ tests/data.py | 14 ++- .../json/1.2/bom_external_references.json | 1 - .../json/1.2/bom_services_complex.json | 1 - .../json/1.2/bom_services_nested.json | 2 - .../json/1.2/bom_services_simple.json | 1 - .../json/1.2/bom_setuptools_complete.json | 66 +++++------ tests/fixtures/json/1.2/bom_toml_1.json | 8 +- .../json/1.2/bom_with_full_metadata.json | 3 +- .../json/1.3/bom_external_references.json | 1 - .../json/1.3/bom_services_complex.json | 1 - .../json/1.3/bom_services_nested.json | 2 - .../json/1.3/bom_services_simple.json | 1 - .../json/1.3/bom_setuptools_complete.json | 48 +++++++- .../json/1.3/bom_with_full_metadata.json | 3 +- .../json/1.4/bom_external_references.json | 1 - .../json/1.4/bom_services_complex.json | 1 - .../json/1.4/bom_services_nested.json | 2 - .../json/1.4/bom_services_simple.json | 1 - .../json/1.4/bom_setuptools_complete.json | 109 ++++++++++++++++- .../json/1.4/bom_with_full_metadata.json | 3 +- .../xml/1.0/bom_setuptools_complete.xml | 21 ++++ .../xml/1.1/bom_setuptools_complete.xml | 40 ++++++- .../xml/1.2/bom_setuptools_complete.xml | 56 ++++++++- .../xml/1.3/bom_setuptools_complete.xml | 72 ++++++++++- .../xml/1.4/bom_setuptools_complete.xml | 112 +++++++++++++++++- 28 files changed, 623 insertions(+), 103 deletions(-) diff --git a/cyclonedx/output/json.py b/cyclonedx/output/json.py index 235be936..0c646891 100644 --- a/cyclonedx/output/json.py +++ b/cyclonedx/output/json.py @@ -93,22 +93,7 @@ def _specialise_output_for_schema_version(self, bom_json: Dict[Any, Any]) -> str del bom_json['metadata']['properties'] # Iterate Components - if 'components' in bom_json.keys(): - for i in range(len(bom_json['components'])): - if self.component_version_optional() and bom_json['components'][i]['version'] == "": - del bom_json['components'][i]['version'] - - if not self.component_supports_author() and 'author' in bom_json['components'][i].keys(): - del bom_json['components'][i]['author'] - - if not self.component_supports_mime_type_attribute() \ - and 'mime-type' in bom_json['components'][i].keys(): - del bom_json['components'][i]['mime-type'] - - if not self.component_supports_release_notes() and 'releaseNotes' in bom_json['components'][i].keys(): - del bom_json['components'][i]['releaseNotes'] - else: - bom_json['components'] = [] + bom_json = self._recurse_specialise_component(bom_json=bom_json) # Iterate Services if 'services' in bom_json.keys(): @@ -126,11 +111,6 @@ def _specialise_output_for_schema_version(self, bom_json: Dict[Any, Any]) -> str and 'hashes' in bom_json['externalReferences'][i].keys(): del bom_json['externalReferences'][i]['hashes'] - # Iterate Vulnerabilities - if 'vulnerabilities' in bom_json.keys(): - for i in range(len(bom_json['vulnerabilities'])): - print("Checking " + str(bom_json['vulnerabilities'][i])) - return json.dumps(bom_json) def output_as_string(self) -> str: @@ -151,6 +131,61 @@ def _create_bom_element(self) -> Dict[str, Union[str, int]]: def _get_schema_uri(self) -> Optional[str]: pass + def _recurse_specialise_component(self, bom_json: Dict[Any, Any], base_key: str = 'components') -> Dict[Any, Any]: + if base_key in bom_json.keys(): + for i in range(len(bom_json[base_key])): + if not self.component_supports_mime_type_attribute() \ + and 'mime-type' in bom_json[base_key][i].keys(): + del bom_json[base_key][i]['mime-type'] + + if not self.component_supports_supplier() and 'supplier' in bom_json[base_key][i].keys(): + del bom_json[base_key][i]['supplier'] + + if not self.component_supports_author() and 'author' in bom_json[base_key][i].keys(): + del bom_json[base_key][i]['author'] + + if self.component_version_optional() and bom_json[base_key][i]['version'] == "": + del bom_json[base_key][i]['version'] + + if not self.component_supports_pedigree() and 'pedigree' in bom_json[base_key][i].keys(): + del bom_json[base_key][i]['pedigree'] + elif 'pedigree' in bom_json[base_key][i].keys(): + if 'ancestors' in bom_json[base_key][i]['pedigree'].keys(): + # recurse into ancestors + bom_json[base_key][i]['pedigree'] = self._recurse_specialise_component( + bom_json=bom_json[base_key][i]['pedigree'], base_key='ancestors' + ) + if 'descendants' in bom_json[base_key][i]['pedigree'].keys(): + # recurse into descendants + bom_json[base_key][i]['pedigree'] = self._recurse_specialise_component( + bom_json=bom_json[base_key][i]['pedigree'], base_key='descendants' + ) + if 'variants' in bom_json[base_key][i]['pedigree'].keys(): + # recurse into variants + bom_json[base_key][i]['pedigree'] = self._recurse_specialise_component( + bom_json=bom_json[base_key][i]['pedigree'], base_key='variants' + ) + + if not self.external_references_supports_hashes() and 'externalReferences' \ + in bom_json[base_key][i].keys(): + for j in range(len(bom_json[base_key][i]['externalReferences'])): + del bom_json[base_key][i]['externalReferences'][j]['hashes'] + + if not self.component_supports_properties() and 'properties' in bom_json[base_key][i].keys(): + del bom_json[base_key][i]['properties'] + + # recurse + if 'components' in bom_json[base_key][i].keys(): + bom_json[base_key][i] = self._recurse_specialise_component(bom_json=bom_json[base_key][i]) + + if not self.component_supports_evidence() and 'evidence' in bom_json[base_key][i].keys(): + del bom_json[base_key][i]['evidence'] + + if not self.component_supports_release_notes() and 'releaseNotes' in bom_json[base_key][i].keys(): + del bom_json[base_key][i]['releaseNotes'] + + return bom_json + class JsonV1Dot0(Json, SchemaVersion1Dot0): diff --git a/cyclonedx/output/schema.py b/cyclonedx/output/schema.py index 369ec1a7..781762df 100644 --- a/cyclonedx/output/schema.py +++ b/cyclonedx/output/schema.py @@ -65,6 +65,9 @@ def bom_supports_vulnerabilities_via_extension(self) -> bool: def bom_requires_modified(self) -> bool: return False + def component_supports_supplier(self) -> bool: + return True + def component_supports_author(self) -> bool: return True @@ -92,6 +95,12 @@ def pedigree_supports_patches(self) -> bool: def component_supports_external_references(self) -> bool: return True + def component_supports_properties(self) -> bool: + return True + + def component_supports_evidence(self) -> bool: + return True + def component_supports_release_notes(self) -> bool: return True @@ -174,6 +183,12 @@ def bom_supports_vulnerabilities_via_extension(self) -> bool: def component_supports_mime_type_attribute(self) -> bool: return False + def component_supports_properties(self) -> bool: + return False + + def component_supports_evidence(self) -> bool: + return False + def component_supports_release_notes(self) -> bool: return False @@ -220,12 +235,21 @@ def bom_supports_metadata(self) -> bool: def component_supports_mime_type_attribute(self) -> bool: return False + def component_supports_supplier(self) -> bool: + return False + def component_supports_author(self) -> bool: return False def component_supports_swid(self) -> bool: return False + def component_supports_properties(self) -> bool: + return False + + def component_supports_evidence(self) -> bool: + return False + def component_supports_release_notes(self) -> bool: return False @@ -281,6 +305,9 @@ def license_supports_expression(self) -> bool: def component_supports_mime_type_attribute(self) -> bool: return False + def component_supports_supplier(self) -> bool: + return False + def component_supports_swid(self) -> bool: return False @@ -290,6 +317,12 @@ def component_supports_pedigree(self) -> bool: def component_supports_external_references(self) -> bool: return False + def component_supports_properties(self) -> bool: + return False + + def component_supports_evidence(self) -> bool: + return False + def component_supports_release_notes(self) -> bool: return False diff --git a/cyclonedx/output/xml.py b/cyclonedx/output/xml.py index bd6230a3..acc5a5fb 100644 --- a/cyclonedx/output/xml.py +++ b/cyclonedx/output/xml.py @@ -180,9 +180,20 @@ def _add_component_element(self, component: Component) -> ElementTree.Element: component_element = ElementTree.Element('component', element_attributes) + # supplier + if self.component_supports_supplier() and component.supplier: + self._add_organizational_entity( + parent_element=component_element, organization=component.supplier, tag_name='supplier' + ) + + # author if self.component_supports_author() and component.author is not None: ElementTree.SubElement(component_element, 'author').text = component.author + # publisher + if component.publisher: + ElementTree.SubElement(component_element, 'publisher').text = component.publisher + # group if component.group: ElementTree.SubElement(component_element, 'group').text = component.group @@ -201,6 +212,14 @@ def _add_component_element(self, component: Component) -> ElementTree.Element: else: ElementTree.SubElement(component_element, 'version').text = component.version + # description + if component.description: + ElementTree.SubElement(component_element, 'description').text = component.description + + # scope + if component.scope: + ElementTree.SubElement(component_element, 'scope').text = component.scope.value + # hashes if component.hashes: Xml._add_hashes_to_element(hashes=component.hashes, element=component_element) @@ -212,6 +231,10 @@ def _add_component_element(self, component: Component) -> ElementTree.Element: if not license_output: component_element.remove(licenses_e) + # copyright + if component.copyright: + ElementTree.SubElement(component_element, 'copyright').text = component.copyright + # cpe if component.cpe: ElementTree.SubElement(component_element, 'cpe').text = component.cpe @@ -286,6 +309,29 @@ def _add_component_element(self, component: Component) -> ElementTree.Element: if self.component_supports_external_references() and len(component.external_references) > 0: self._add_external_references_to_element(ext_refs=component.external_references, element=component_element) + # properties + if self.component_supports_properties() and component.properties: + Xml._add_properties_element(properties=component.properties, parent_element=component_element) + + # components + if component.components: + components_element = ElementTree.SubElement(component_element, 'components') + for nested_component in component.components: + components_element.append(self._add_component_element(component=nested_component)) + + # evidence + if self.component_supports_evidence() and component.evidence: + evidence_element = ElementTree.SubElement(component_element, 'evidence') + if component.evidence.licenses: + evidence_licenses_element = ElementTree.SubElement(evidence_element, 'licenses') + self._add_licenses_to_element( + licenses=component.evidence.licenses, parent_element=evidence_licenses_element + ) + if component.evidence.copyright: + evidence_copyrights_element = ElementTree.SubElement(evidence_element, 'copyright') + for evidence_copyright in component.evidence.copyright: + ElementTree.SubElement(evidence_copyrights_element, 'text').text = evidence_copyright.text + # releaseNotes if self.component_supports_release_notes() and component.release_notes: Xml._add_release_notes_element(release_notes=component.release_notes, parent_element=component_element) diff --git a/tests/data.py b/tests/data.py index 2177567a..cd0571fc 100644 --- a/tests/data.py +++ b/tests/data.py @@ -28,7 +28,7 @@ Property, Tool, XsUri from cyclonedx.model.bom import Bom from cyclonedx.model.component import Commit, Component, ComponentEvidence, ComponentType, Copyright, Patch, \ - PatchClassification, Pedigree, Swid + PatchClassification, Pedigree, Swid, ComponentScope from cyclonedx.model.issue import IssueClassification, IssueType, IssueTypeSource from cyclonedx.model.release_note import ReleaseNotes from cyclonedx.model.service import Service @@ -67,15 +67,25 @@ def get_bom_with_component_setuptools_with_release_notes() -> Bom: def get_bom_with_component_setuptools_complete() -> Bom: - component = get_component_setuptools_simple() + component = get_component_setuptools_simple(bom_ref=MOCK_UUID_6) + component.supplier = get_org_entity_1() + component.publisher = 'CycloneDX' + component.description = 'This component is awesome' + component.scope = ComponentScope.REQUIRED + component.copyright = 'Apache 2.0 baby!' component.cpe = 'cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*' component.swid = get_swid_1() component.pedigree = get_pedigree_1() + component.external_references.add( + get_external_reference_1() + ) + component.properties = get_properties_1() component.components.update([ get_component_setuptools_simple(), get_component_toml_with_hashes_with_references() ]) component.evidence = ComponentEvidence(copyright_=[Copyright(text='Commercial'), Copyright(text='Commercial 2')]) + component.release_notes = get_release_notes() return Bom(components=[component]) diff --git a/tests/fixtures/json/1.2/bom_external_references.json b/tests/fixtures/json/1.2/bom_external_references.json index 5043c2f3..78e0db56 100644 --- a/tests/fixtures/json/1.2/bom_external_references.json +++ b/tests/fixtures/json/1.2/bom_external_references.json @@ -14,7 +14,6 @@ } ] }, - "components": [], "externalReferences": [ { "url": "https://cyclonedx.org", diff --git a/tests/fixtures/json/1.2/bom_services_complex.json b/tests/fixtures/json/1.2/bom_services_complex.json index 693cf3dc..cbf93031 100644 --- a/tests/fixtures/json/1.2/bom_services_complex.json +++ b/tests/fixtures/json/1.2/bom_services_complex.json @@ -20,7 +20,6 @@ "version": "1.0.0" } }, - "components": [], "services": [ { "bom-ref": "my-specific-bom-ref-for-my-first-service", diff --git a/tests/fixtures/json/1.2/bom_services_nested.json b/tests/fixtures/json/1.2/bom_services_nested.json index 22032681..b1a8a0d2 100644 --- a/tests/fixtures/json/1.2/bom_services_nested.json +++ b/tests/fixtures/json/1.2/bom_services_nested.json @@ -1,8 +1,6 @@ { "$schema": "http://cyclonedx.org/schema/bom-1.2a.schema.json", "bomFormat": "CycloneDX", - "components": [ - ], "metadata": { "component": { "bom-ref": "bb5911d6-1a1d-41c9-b6e0-46e848d16655", diff --git a/tests/fixtures/json/1.2/bom_services_simple.json b/tests/fixtures/json/1.2/bom_services_simple.json index 4695a368..696cafe4 100644 --- a/tests/fixtures/json/1.2/bom_services_simple.json +++ b/tests/fixtures/json/1.2/bom_services_simple.json @@ -20,7 +20,6 @@ "version": "1.0.0" } }, - "components": [], "services": [ { "bom-ref": "bb5911d6-1a1d-41c9-b6e0-46e848d16655", diff --git a/tests/fixtures/json/1.2/bom_setuptools_complete.json b/tests/fixtures/json/1.2/bom_setuptools_complete.json index c0039feb..42288aa2 100644 --- a/tests/fixtures/json/1.2/bom_setuptools_complete.json +++ b/tests/fixtures/json/1.2/bom_setuptools_complete.json @@ -17,15 +17,36 @@ "components": [ { "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "bom-ref": "df70b5f1-8f53-47a4-be48-669ae78795e6", + "supplier": { + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" + ], + "contact": [ + { + "name": "Paul Horton", + "email": "paul.horton@owasp.org" + }, + { + "name": "A N Other", + "email": "someone@somewhere.tld", + "phone": "+44 (0)1234 567890" + } + ] + }, "author": "Test Author", + "publisher": "CycloneDX", "name": "setuptools", "version": "50.3.2", + "description": "This component is awesome", + "scope": "required", "licenses": [ { "expression": "MIT License" } ], + "copyright": "Apache 2.0 baby!", "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "swid": { @@ -97,13 +118,7 @@ { "type": "distribution", "url": "https://cyclonedx.org", - "comment": "No comment", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ] + "comment": "No comment" } ] } @@ -125,13 +140,7 @@ { "type": "distribution", "url": "https://cyclonedx.org", - "comment": "No comment", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ] + "comment": "No comment" } ] }, @@ -162,6 +171,13 @@ ], "notes": "Some notes here please" }, + "externalReferences": [ + { + "type": "distribution", + "url": "https://cyclonedx.org", + "comment": "No comment" + } + ], "components": [ { "type": "library", @@ -192,27 +208,11 @@ { "type": "distribution", "url": "https://cyclonedx.org", - "comment": "No comment", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ] + "comment": "No comment" } ] } - ], - "evidence": { - "copyright": [ - { - "text": "Commercial" - }, - { - "text": "Commercial 2" - } - ] - } + ] } ] } \ No newline at end of file diff --git a/tests/fixtures/json/1.2/bom_toml_1.json b/tests/fixtures/json/1.2/bom_toml_1.json index 9cd6ac54..0e07e956 100644 --- a/tests/fixtures/json/1.2/bom_toml_1.json +++ b/tests/fixtures/json/1.2/bom_toml_1.json @@ -31,13 +31,7 @@ { "type": "distribution", "url": "https://cyclonedx.org", - "comment": "No comment", - "hashes": [ - { - "alg": "SHA-256", - "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" - } - ] + "comment": "No comment" } ] } diff --git a/tests/fixtures/json/1.2/bom_with_full_metadata.json b/tests/fixtures/json/1.2/bom_with_full_metadata.json index 76b1dd11..d479798b 100644 --- a/tests/fixtures/json/1.2/bom_with_full_metadata.json +++ b/tests/fixtures/json/1.2/bom_with_full_metadata.json @@ -60,6 +60,5 @@ } ] } - }, - "components": [] + } } \ No newline at end of file diff --git a/tests/fixtures/json/1.3/bom_external_references.json b/tests/fixtures/json/1.3/bom_external_references.json index 5e9246e7..9ce40c64 100644 --- a/tests/fixtures/json/1.3/bom_external_references.json +++ b/tests/fixtures/json/1.3/bom_external_references.json @@ -14,7 +14,6 @@ } ] }, - "components": [], "externalReferences": [ { "url": "https://cyclonedx.org", diff --git a/tests/fixtures/json/1.3/bom_services_complex.json b/tests/fixtures/json/1.3/bom_services_complex.json index ad262fdf..24d0ca06 100644 --- a/tests/fixtures/json/1.3/bom_services_complex.json +++ b/tests/fixtures/json/1.3/bom_services_complex.json @@ -20,7 +20,6 @@ "version": "1.0.0" } }, - "components": [], "services": [ { "bom-ref": "my-specific-bom-ref-for-my-first-service", diff --git a/tests/fixtures/json/1.3/bom_services_nested.json b/tests/fixtures/json/1.3/bom_services_nested.json index 106b5255..23c0bd1d 100644 --- a/tests/fixtures/json/1.3/bom_services_nested.json +++ b/tests/fixtures/json/1.3/bom_services_nested.json @@ -1,8 +1,6 @@ { "$schema": "http://cyclonedx.org/schema/bom-1.3.schema.json", "bomFormat": "CycloneDX", - "components": [ - ], "metadata": { "component": { "bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857", diff --git a/tests/fixtures/json/1.3/bom_services_simple.json b/tests/fixtures/json/1.3/bom_services_simple.json index 4e26ad37..a16b1ed9 100644 --- a/tests/fixtures/json/1.3/bom_services_simple.json +++ b/tests/fixtures/json/1.3/bom_services_simple.json @@ -20,7 +20,6 @@ "version": "1.0.0" } }, - "components": [], "services": [ { "bom-ref": "cd3e9c95-9d41-49e7-9924-8cf0465ae789", diff --git a/tests/fixtures/json/1.3/bom_setuptools_complete.json b/tests/fixtures/json/1.3/bom_setuptools_complete.json index b82097ae..813cd334 100644 --- a/tests/fixtures/json/1.3/bom_setuptools_complete.json +++ b/tests/fixtures/json/1.3/bom_setuptools_complete.json @@ -17,15 +17,36 @@ "components": [ { "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "bom-ref": "df70b5f1-8f53-47a4-be48-669ae78795e6", + "supplier": { + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" + ], + "contact": [ + { + "name": "Paul Horton", + "email": "paul.horton@owasp.org" + }, + { + "name": "A N Other", + "email": "someone@somewhere.tld", + "phone": "+44 (0)1234 567890" + } + ] + }, "author": "Test Author", + "publisher": "CycloneDX", "name": "setuptools", "version": "50.3.2", + "description": "This component is awesome", + "scope": "required", "licenses": [ { "expression": "MIT License" } ], + "copyright": "Apache 2.0 baby!", "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "swid": { @@ -162,6 +183,19 @@ ], "notes": "Some notes here please" }, + "externalReferences": [ + { + "type": "distribution", + "url": "https://cyclonedx.org", + "comment": "No comment", + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ] + } + ], "components": [ { "type": "library", @@ -212,7 +246,17 @@ "text": "Commercial 2" } ] - } + }, + "properties": [ + { + "name": "key1", + "value": "val1" + }, + { + "name": "key2", + "value": "val2" + } + ] } ] } \ No newline at end of file diff --git a/tests/fixtures/json/1.3/bom_with_full_metadata.json b/tests/fixtures/json/1.3/bom_with_full_metadata.json index ec87032e..21baef21 100644 --- a/tests/fixtures/json/1.3/bom_with_full_metadata.json +++ b/tests/fixtures/json/1.3/bom_with_full_metadata.json @@ -75,6 +75,5 @@ "value": "val2" } ] - }, - "components": [] + } } \ No newline at end of file diff --git a/tests/fixtures/json/1.4/bom_external_references.json b/tests/fixtures/json/1.4/bom_external_references.json index a054cd86..84d69448 100644 --- a/tests/fixtures/json/1.4/bom_external_references.json +++ b/tests/fixtures/json/1.4/bom_external_references.json @@ -48,7 +48,6 @@ } ] }, - "components": [], "externalReferences": [ { "url": "https://cyclonedx.org", diff --git a/tests/fixtures/json/1.4/bom_services_complex.json b/tests/fixtures/json/1.4/bom_services_complex.json index c6747a6d..78784f48 100644 --- a/tests/fixtures/json/1.4/bom_services_complex.json +++ b/tests/fixtures/json/1.4/bom_services_complex.json @@ -54,7 +54,6 @@ "version": "1.0.0" } }, - "components": [], "services": [ { "bom-ref": "my-specific-bom-ref-for-my-first-service", diff --git a/tests/fixtures/json/1.4/bom_services_nested.json b/tests/fixtures/json/1.4/bom_services_nested.json index 20c7ee12..93705699 100644 --- a/tests/fixtures/json/1.4/bom_services_nested.json +++ b/tests/fixtures/json/1.4/bom_services_nested.json @@ -1,8 +1,6 @@ { "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", "bomFormat": "CycloneDX", - "components": [ - ], "metadata": { "component": { "bom-ref": "be2c6502-7e9a-47db-9a66-e34f729810a3", diff --git a/tests/fixtures/json/1.4/bom_services_simple.json b/tests/fixtures/json/1.4/bom_services_simple.json index 37ce9475..ba87360d 100644 --- a/tests/fixtures/json/1.4/bom_services_simple.json +++ b/tests/fixtures/json/1.4/bom_services_simple.json @@ -54,7 +54,6 @@ "version": "1.0.0" } }, - "components": [], "services": [ { "bom-ref": "0b049d09-64c0-4490-a0f5-c84d9aacf857", diff --git a/tests/fixtures/json/1.4/bom_setuptools_complete.json b/tests/fixtures/json/1.4/bom_setuptools_complete.json index ae228504..b224cee0 100644 --- a/tests/fixtures/json/1.4/bom_setuptools_complete.json +++ b/tests/fixtures/json/1.4/bom_setuptools_complete.json @@ -51,15 +51,36 @@ "components": [ { "type": "library", - "bom-ref": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", + "bom-ref": "df70b5f1-8f53-47a4-be48-669ae78795e6", + "supplier": { + "name": "CycloneDX", + "url": [ + "https://cyclonedx.org" + ], + "contact": [ + { + "name": "Paul Horton", + "email": "paul.horton@owasp.org" + }, + { + "name": "A N Other", + "email": "someone@somewhere.tld", + "phone": "+44 (0)1234 567890" + } + ] + }, "author": "Test Author", + "publisher": "CycloneDX", "name": "setuptools", "version": "50.3.2", + "description": "This component is awesome", + "scope": "required", "licenses": [ { "expression": "MIT License" } ], + "copyright": "Apache 2.0 baby!", "cpe": "cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*", "purl": "pkg:pypi/setuptools@50.3.2?extension=tar.gz", "swid": { @@ -92,7 +113,6 @@ "bom-ref": "8a3893b3-9923-4adb-a1d3-47456636ba0a", "author": "Test Author", "name": "setuptools", - "version": "", "licenses": [ { "expression": "MIT License" @@ -107,7 +127,6 @@ "bom-ref": "28b2d8ce-def0-446f-a221-58dee0b44acc", "author": "Test Author", "name": "setuptools", - "version": "", "licenses": [ { "expression": "MIT License" @@ -196,6 +215,19 @@ ], "notes": "Some notes here please" }, + "externalReferences": [ + { + "type": "distribution", + "url": "https://cyclonedx.org", + "comment": "No comment", + "hashes": [ + { + "alg": "SHA-256", + "content": "806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b" + } + ] + } + ], "components": [ { "type": "library", @@ -246,7 +278,76 @@ "text": "Commercial 2" } ] - } + }, + "releaseNotes": { + "type": "major", + "title": "Release Notes Title", + "featuredImage": "https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png", + "socialImage": "https://cyclonedx.org/cyclonedx-icon.png", + "description": "This release is a test release", + "timestamp": "2021-12-31T10:00:00+00:00", + "aliases": [ + "First Test Release" + ], + "tags": [ + "test", + "alpha" + ], + "resolves": [ + { + "type": "security", + "id": "CVE-2021-44228", + "name": "Apache Log3Shell", + "description": "Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features...", + "source": { + "name": "NVD", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-44228" + }, + "references": [ + "https://logging.apache.org/log4j/2.x/security.html", + "https://central.sonatype.org/news/20211213_log4shell_help" + ] + } + ], + "notes": [ + { + "locale": "en-GB", + "text": { + "contentType": "text/plain; charset=UTF-8", + "encoding": "base64", + "content": "U29tZSBzaW1wbGUgcGxhaW4gdGV4dA==" + } + }, + { + "locale": "en-US", + "text": { + "contentType": "text/plain; charset=UTF-8", + "encoding": "base64", + "content": "U29tZSBzaW1wbGUgcGxhaW4gdGV4dA==" + } + } + ], + "properties": [ + { + "name": "key1", + "value": "val1" + }, + { + "name": "key2", + "value": "val2" + } + ] + }, + "properties": [ + { + "name": "key1", + "value": "val1" + }, + { + "name": "key2", + "value": "val2" + } + ] } ] } \ No newline at end of file diff --git a/tests/fixtures/json/1.4/bom_with_full_metadata.json b/tests/fixtures/json/1.4/bom_with_full_metadata.json index 8588cd52..230f4f26 100644 --- a/tests/fixtures/json/1.4/bom_with_full_metadata.json +++ b/tests/fixtures/json/1.4/bom_with_full_metadata.json @@ -109,6 +109,5 @@ "value": "val2" } ] - }, - "components": [] + } } \ No newline at end of file diff --git a/tests/fixtures/xml/1.0/bom_setuptools_complete.xml b/tests/fixtures/xml/1.0/bom_setuptools_complete.xml index 3c617136..32a3dafb 100644 --- a/tests/fixtures/xml/1.0/bom_setuptools_complete.xml +++ b/tests/fixtures/xml/1.0/bom_setuptools_complete.xml @@ -2,11 +2,32 @@ + CycloneDX setuptools 50.3.2 + This component is awesome + required + Apache 2.0 baby! cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* pkg:pypi/setuptools@50.3.2?extension=tar.gz false + + + setuptools + 50.3.2 + pkg:pypi/setuptools@50.3.2?extension=tar.gz + false + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + false + + \ No newline at end of file diff --git a/tests/fixtures/xml/1.1/bom_setuptools_complete.xml b/tests/fixtures/xml/1.1/bom_setuptools_complete.xml index a7aee096..0a116a29 100644 --- a/tests/fixtures/xml/1.1/bom_setuptools_complete.xml +++ b/tests/fixtures/xml/1.1/bom_setuptools_complete.xml @@ -1,12 +1,16 @@ - + + CycloneDX setuptools 50.3.2 + This component is awesome + required MIT License + Apache 2.0 baby! cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* pkg:pypi/setuptools@50.3.2?extension=tar.gz @@ -21,7 +25,7 @@ setuptools - + MIT License @@ -31,7 +35,7 @@ setuptools - + MIT License @@ -84,6 +88,36 @@ Some notes here please + + + https://cyclonedx.org + No comment + + + + + setuptools + 50.3.2 + + MIT License + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + \ No newline at end of file diff --git a/tests/fixtures/xml/1.2/bom_setuptools_complete.xml b/tests/fixtures/xml/1.2/bom_setuptools_complete.xml index 4cb2b93e..195ffd0f 100644 --- a/tests/fixtures/xml/1.2/bom_setuptools_complete.xml +++ b/tests/fixtures/xml/1.2/bom_setuptools_complete.xml @@ -11,13 +11,30 @@ - + + + CycloneDX + https://cyclonedx.org + + Paul Horton + paul.horton@owasp.org + + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + Test Author + CycloneDX setuptools 50.3.2 + This component is awesome + required MIT License + Apache 2.0 baby! cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* pkg:pypi/setuptools@50.3.2?extension=tar.gz @@ -37,7 +54,7 @@ Test Author setuptools - + MIT License @@ -48,7 +65,7 @@ Test Author setuptools - + MIT License @@ -101,10 +118,41 @@ - + Some notes here please + + + https://cyclonedx.org + No comment + + + + + Test Author + setuptools + 50.3.2 + + MIT License + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + + + \ No newline at end of file diff --git a/tests/fixtures/xml/1.3/bom_setuptools_complete.xml b/tests/fixtures/xml/1.3/bom_setuptools_complete.xml index 675ddf93..0a2a149c 100644 --- a/tests/fixtures/xml/1.3/bom_setuptools_complete.xml +++ b/tests/fixtures/xml/1.3/bom_setuptools_complete.xml @@ -11,13 +11,30 @@ - + + + CycloneDX + https://cyclonedx.org + + Paul Horton + paul.horton@owasp.org + + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + Test Author + CycloneDX setuptools 50.3.2 + This component is awesome + required MIT License + Apache 2.0 baby! cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* pkg:pypi/setuptools@50.3.2?extension=tar.gz @@ -37,7 +54,7 @@ Test Author setuptools - + MIT License @@ -48,7 +65,7 @@ Test Author setuptools - + MIT License @@ -107,10 +124,57 @@ - + Some notes here please + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + val1 + val2 + + + + Test Author + setuptools + 50.3.2 + + MIT License + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + Commercial + Commercial 2 + + \ No newline at end of file diff --git a/tests/fixtures/xml/1.4/bom_setuptools_complete.xml b/tests/fixtures/xml/1.4/bom_setuptools_complete.xml index 4136bbf1..39968cf8 100644 --- a/tests/fixtures/xml/1.4/bom_setuptools_complete.xml +++ b/tests/fixtures/xml/1.4/bom_setuptools_complete.xml @@ -37,13 +37,30 @@ - + + + CycloneDX + https://cyclonedx.org + + Paul Horton + paul.horton@owasp.org + + + A N Other + someone@somewhere.tld + +44 (0)1234 567890 + + Test Author + CycloneDX setuptools 50.3.2 + This component is awesome + required MIT License + Apache 2.0 baby! cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:* pkg:pypi/setuptools@50.3.2?extension=tar.gz @@ -131,10 +148,101 @@ - + Some notes here please + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + val1 + val2 + + + + Test Author + setuptools + 50.3.2 + + MIT License + + pkg:pypi/setuptools@50.3.2?extension=tar.gz + + + toml + 0.10.2 + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + pkg:pypi/toml@0.10.2?extension=tar.gz + + + https://cyclonedx.org + No comment + + 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b + + + + + + + + Commercial + Commercial 2 + + + + major + Release Notes Title + https://cyclonedx.org/theme/assets/images/CycloneDX-Twitter-Card.png + https://cyclonedx.org/cyclonedx-icon.png + This release is a test release + 2021-12-31T10:00:00+00:00 + + First Test Release + + + test + alpha + + + + CVE-2021-44228 + Apache Log3Shell + Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features... + + NVD + https://nvd.nist.gov/vuln/detail/CVE-2021-44228 + + + https://logging.apache.org/log4j/2.x/security.html + https://central.sonatype.org/news/20211213_log4shell_help + + + + + + en-GB + U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== + + + en-US + U29tZSBzaW1wbGUgcGxhaW4gdGV4dA== + + + + val1 + val2 + + \ No newline at end of file