Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 27 additions & 6 deletions cdxev/auxiliary/sbomFunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,21 +186,42 @@ def get_bom_refs_from_dependencies(dependencies: Sequence[dict]) -> list[str]:
return list_of_bom_refs


def get_ref_from_components(list_of_components: Sequence[dict]) -> list[str]:
def get_ref_from_components(
list_of_components: Sequence[dict], only_top_level: bool = True
) -> list[str]:
"""
Function that returns a list of bom-refs from a list of components
Function that returns a list of bom-refs from a list of components.
Per default only the references of top level components will be retrieved,
if the flag 'only_top_level' is set to false,
the references of nested components will also be retrieved.

Input:
list_of_components: list with dicts of components
only_top_level: bool describing if only top level components shall be considered

Output:
list_of_bom_refs: List of bom-refs from the components in the submitted list
"""
list_of_bom_refs = []
if only_top_level:
list_of_bom_refs = []
for component in list_of_components:
bom_ref = component.get("bom-ref", "")
list_of_bom_refs.append(bom_ref)
return list_of_bom_refs
else:
components = extract_components(list_of_components)
return get_ref_from_components(components)


def extract_components(list_of_components: Sequence[dict]) -> Sequence[dict]:
extracted_components = []
for component in list_of_components:
bom_ref = component.get("bom-ref", "")
list_of_bom_refs.append(bom_ref)
return list_of_bom_refs
if component.get("components", []) == []:
extracted_components.append(component)
else:
extracted_components.append(component)
extracted_components += extract_components(component.get("components", []))
return extracted_components


def compare_vulnerabilities(
Expand Down
10 changes: 7 additions & 3 deletions cdxev/build_public_bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,14 +154,18 @@ def build_public_bom(sbom: dict, path_to_schema: t.Union[Path, None]) -> dict:
) = remove_component_tagged_internal(components, path_to_schema)
for bom_ref in list_of_removed_components:
dependencies = merge_dependency_for_removed_component(bom_ref, dependencies)
new_compositions = get_ref_from_components(cleared_components)
kept_bom_refs = get_ref_from_components(cleared_components, only_top_level=False)
remove_internal_information_from_properties(
sbom.get("metadata", {}).get("component", {})
)
sbom["components"] = cleared_components
sbom["dependencies"] = dependencies
compositions = [{"aggregate": "incomplete", "assemblies": new_compositions}]
sbom["compositions"] = compositions
for composition in sbom.get("compositions", []):
new_assemblies = []
for bom_ref in composition.get("assemblies"):
if bom_ref in kept_bom_refs:
new_assemblies.append(bom_ref)
composition["assemblies"] = new_assemblies
return sbom


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,27 @@
"group": "org.acme",
"name": "web-framework",
"version": "1.0.0",
"purl": "pkg:maven/org.acme/web-framework@1.0.0"
"purl": "pkg:maven/org.acme/web-framework@1.0.0",
"components": [
{
"type": "library",
"bom-ref": "sub_comp1",
"supplier": {
"name": "Acme, Inc."
},
"licenses": [
{
"license": {
"id": "Apache-1.0"
}
}
],
"group": "org.acme",
"name": "sub_web-framework",
"version": "1.0.0",
"purl": "pkg:maven/org.acme/sub_web-framework@1.0.0"
}
]
},
{
"type": "library",
Expand Down Expand Up @@ -261,6 +281,7 @@
"aggregate": "incomplete",
"assemblies": [
"comp1",
"sub_comp1",
"comp2",
"comp3",
"comp4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,27 @@
"group": "org.acme",
"name": "web-framework",
"version": "1.0.0",
"purl": "pkg:maven/org.acme/web-framework@1.0.0"
"purl": "pkg:maven/org.acme/web-framework@1.0.0",
"components": [
{
"type": "library",
"bom-ref": "sub_comp1",
"supplier": {
"name": "Acme, Inc."
},
"licenses": [
{
"license": {
"id": "Apache-1.0"
}
}
],
"group": "org.acme",
"name": "sub_web-framework",
"version": "1.0.0",
"purl": "pkg:maven/org.acme/sub_web-framework@1.0.0"
}
]
},
{
"type": "library",
Expand Down Expand Up @@ -151,6 +171,7 @@
"aggregate": "incomplete",
"assemblies": [
"comp1",
"sub_comp1",
"comp2",
"comp3",
"comp4"
Expand Down
7 changes: 4 additions & 3 deletions tests/test_build_public_bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,6 @@ def test_build_public_no_schema(self) -> None:
sbom = get_test_sbom()
sbom = get_test_sbom()
public_sbom = get_test_sbom()

public_sbom["metadata"]["component"]["properties"].pop(1)
public_sbom["components"][1]["properties"].pop(1)
public_sbom["components"][1]["properties"].pop(2)
Expand All @@ -213,17 +212,19 @@ def test_build_public_no_schema(self) -> None:
public_sbom["components"][2]["properties"].pop(0)
public_sbom["components"][5]["properties"].pop(0)
external_bom = b_p_b.build_public_bom(sbom, None)

public_sbom["compositions"] = [
{
"aggregate": "incomplete",
"assemblies": [
"comp1",
"sub_comp1",
"comp2",
"internalcomp2",
"comp3",
"comp4",
"internalcomp3",
"internalcomp1",
"internalcomp2",
"internalcomp3",
],
}
]
Expand Down
82 changes: 82 additions & 0 deletions tests/test_sbom_functions.py
Comment thread
italvi marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import unittest
from typing import Sequence

from cdxev.auxiliary import sbomFunctions as sbF


class TestComponentFunctions(unittest.TestCase):
def test_extract_components(self) -> None:
example_list: Sequence[dict] = [
{
"bom-ref": "first_level_1",
"components": [
{
"bom-ref": "second_level_1",
},
{
"bom-ref": "second_level_2",
"components": [
{
"bom-ref": "third_level_1",
},
{
"bom-ref": "third_level_2",
},
],
},
],
},
{
"bom-ref": "first_level_2",
"components": [
{
"bom-ref": "second_level_3",
"components": [
{
"bom-ref": "third_level_3",
"components": [
{
"bom-ref": "fourth_level_1",
}
],
}
],
},
{
"bom-ref": "second_level_4",
},
],
},
{
"bom-ref": "first_level_3",
"components": [
{
"bom-ref": "second_level_5",
}
],
},
]
components = sbF.extract_components(example_list)
self.assertEqual(
set(sbF.get_ref_from_components(components)),
set(
[
"first_level_1",
"first_level_2",
"first_level_3",
"second_level_1",
"second_level_2",
"second_level_3",
"second_level_4",
"second_level_5",
"third_level_1",
"third_level_2",
"third_level_3",
"fourth_level_1",
]
),
)


if __name__ == "__main__":
unittest.main()