Skip to content

Commit e3b29a2

Browse files
committed
feat: add support for component's evidences according to spec
Signed-off-by: Arun <[email protected]>
1 parent cb1a359 commit e3b29a2

15 files changed

+3921
-31
lines changed

cyclonedx/model/component.py

+686-31
Large diffs are not rendered by default.

tests/_data/models.py

+86
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,23 @@
4444
from cyclonedx.model.bom import Bom, BomMetaData
4545
from cyclonedx.model.bom_ref import BomRef
4646
from cyclonedx.model.component import (
47+
AnalysisTechnique,
48+
CallStack,
4749
Commit,
4850
Component,
4951
ComponentEvidence,
5052
ComponentScope,
5153
ComponentType,
5254
Diff,
55+
Identity,
56+
IdentityFieldType,
57+
Method,
58+
Occurrence,
5359
OmniborId,
5460
Patch,
5561
PatchClassification,
5662
Pedigree,
63+
StackFrame,
5764
Swhid,
5865
Swid,
5966
)
@@ -455,6 +462,10 @@ def get_bom_with_component_setuptools_complete() -> Bom:
455462
return _make_bom(components=[get_component_setuptools_complete()])
456463

457464

465+
def get_bom_with_component_evidence() -> Bom:
466+
return _make_bom(components=[get_component_with_evidence()])
467+
468+
458469
def get_bom_with_component_setuptools_with_vulnerability() -> Bom:
459470
bom = _make_bom()
460471
component = get_component_setuptools_simple()
@@ -737,6 +748,80 @@ def get_component_setuptools_complete(include_pedigree: bool = True) -> Componen
737748
return component
738749

739750

751+
def get_component_with_evidence(include_pedigree: bool = True) -> Component:
752+
component = get_component_setuptools_simple(bom_ref='my-specific-bom-ref-for-dings')
753+
component.supplier = get_org_entity_1()
754+
component.publisher = 'CycloneDX'
755+
component.description = 'This component is awesome'
756+
component.scope = ComponentScope.REQUIRED
757+
component.copyright = 'Apache 2.0 baby!'
758+
component.cpe = 'cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*'
759+
component.swid = get_swid_1()
760+
if include_pedigree:
761+
component.pedigree = get_pedigree_1()
762+
component.external_references.add(
763+
get_external_reference_1()
764+
)
765+
component.properties = get_properties_1()
766+
component.components.update([
767+
get_component_setuptools_simple(),
768+
get_component_toml_with_hashes_with_references()
769+
])
770+
component.evidence = get_component_evidence_basic()
771+
component.release_notes = get_release_notes()
772+
return component
773+
774+
775+
def get_component_evidence_basic() -> ComponentEvidence:
776+
"""
777+
Returns a basic ComponentEvidence object for testing.
778+
"""
779+
return ComponentEvidence(
780+
identity=[
781+
Identity(
782+
field=IdentityFieldType.NAME,
783+
confidence=Decimal('0.9'),
784+
concluded_value='example-component',
785+
methods=[
786+
Method(technique=AnalysisTechnique.SOURCE_CODE_ANALYSIS,
787+
confidence=Decimal('0.8'), value='analysis-tool')
788+
],
789+
tools=[
790+
BomRef('ref0'), # BomRef reference
791+
BomRef('ref1') # BomRef reference
792+
]
793+
)
794+
],
795+
occurrences=[
796+
Occurrence(
797+
location='path/to/file',
798+
line=42,
799+
offset=16,
800+
symbol='exampleSymbol',
801+
additional_context='Found in source code',
802+
bom_ref='BomRef.2392456298152259.7035102660516194',
803+
)
804+
],
805+
callstack=CallStack(
806+
frames=[
807+
StackFrame(
808+
package='example.package',
809+
module='example.module',
810+
function='example_function',
811+
parameters=['param1', 'param2'],
812+
line=10,
813+
column=5,
814+
full_filename='path/to/file',
815+
)
816+
]
817+
),
818+
licenses=[DisjunctiveLicense(id='MIT')],
819+
copyright=[
820+
Copyright(text='Commercial'), Copyright(text='Commercial 2')
821+
]
822+
)
823+
824+
740825
def get_component_setuptools_simple(
741826
bom_ref: Optional[str] = 'pkg:pypi/[email protected]?extension=tar.gz'
742827
) -> Component:
@@ -1485,4 +1570,5 @@ def get_bom_for_issue540_duplicate_components() -> Bom:
14851570
get_bom_with_lifecycles,
14861571
get_bom_with_definitions_standards,
14871572
get_bom_with_definitions_and_detailed_standards,
1573+
get_bom_with_component_evidence,
14881574
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" ?>
2+
<bom xmlns="http://cyclonedx.org/schema/bom/1.0" version="1">
3+
<components>
4+
<component type="library">
5+
<publisher>CycloneDX</publisher>
6+
<name>setuptools</name>
7+
<version>50.3.2</version>
8+
<description>This component is awesome</description>
9+
<scope>required</scope>
10+
<copyright>Apache 2.0 baby!</copyright>
11+
<cpe>cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*</cpe>
12+
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
13+
<modified>false</modified>
14+
<components>
15+
<component type="library">
16+
<name>setuptools</name>
17+
<version>50.3.2</version>
18+
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
19+
<modified>false</modified>
20+
</component>
21+
<component type="library">
22+
<name>toml</name>
23+
<version>0.10.2</version>
24+
<hashes>
25+
<hash alg="SHA-256">806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b</hash>
26+
</hashes>
27+
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
28+
<modified>false</modified>
29+
</component>
30+
</components>
31+
</component>
32+
</components>
33+
</bom>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
<?xml version="1.0" ?>
2+
<bom xmlns="http://cyclonedx.org/schema/bom/1.1" serialNumber="urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac" version="1">
3+
<components>
4+
<component type="library" bom-ref="my-specific-bom-ref-for-dings">
5+
<publisher>CycloneDX</publisher>
6+
<name>setuptools</name>
7+
<version>50.3.2</version>
8+
<description>This component is awesome</description>
9+
<scope>required</scope>
10+
<licenses>
11+
<license>
12+
<id>MIT</id>
13+
</license>
14+
</licenses>
15+
<copyright>Apache 2.0 baby!</copyright>
16+
<cpe>cpe:2.3:a:python:setuptools:50.3.2:*:*:*:*:*:*:*</cpe>
17+
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
18+
<pedigree>
19+
<ancestors>
20+
<component type="library" bom-ref="ccc8d7ee-4b9c-4750-aee0-a72585152291">
21+
<name>setuptools</name>
22+
<version>50.3.2</version>
23+
<licenses>
24+
<license>
25+
<id>MIT</id>
26+
</license>
27+
</licenses>
28+
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
29+
</component>
30+
<component type="library" bom-ref="8a3893b3-9923-4adb-a1d3-47456636ba0a">
31+
<name>setuptools</name>
32+
<version/>
33+
<licenses>
34+
<license>
35+
<id>MIT</id>
36+
</license>
37+
</licenses>
38+
<purl>pkg:pypi/setuptools?extension=tar.gz</purl>
39+
</component>
40+
</ancestors>
41+
<descendants>
42+
<component type="library" bom-ref="28b2d8ce-def0-446f-a221-58dee0b44acc">
43+
<name>setuptools</name>
44+
<version/>
45+
<licenses>
46+
<license>
47+
<id>MIT</id>
48+
</license>
49+
</licenses>
50+
<purl>pkg:pypi/setuptools?extension=tar.gz</purl>
51+
</component>
52+
<component type="library" bom-ref="555ca729-93c6-48f3-956e-bdaa4a2f0bfa">
53+
<name>toml</name>
54+
<version>0.10.2</version>
55+
<hashes>
56+
<hash alg="SHA-256">806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b</hash>
57+
</hashes>
58+
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
59+
<externalReferences>
60+
<reference type="distribution">
61+
<url>https://cyclonedx.org</url>
62+
<comment>No comment</comment>
63+
</reference>
64+
</externalReferences>
65+
</component>
66+
</descendants>
67+
<variants>
68+
<component type="library" bom-ref="ded1d73e-1fca-4302-b520-f1bc53979958">
69+
<name>setuptools</name>
70+
<version>50.3.2</version>
71+
<licenses>
72+
<license>
73+
<id>MIT</id>
74+
</license>
75+
</licenses>
76+
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
77+
</component>
78+
<component type="library" bom-ref="e7abdcca-5ba2-4f29-b2cf-b1e1ef788e66">
79+
<name>toml</name>
80+
<version>0.10.2</version>
81+
<hashes>
82+
<hash alg="SHA-256">806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b</hash>
83+
</hashes>
84+
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
85+
<externalReferences>
86+
<reference type="distribution">
87+
<url>https://cyclonedx.org</url>
88+
<comment>No comment</comment>
89+
</reference>
90+
</externalReferences>
91+
</component>
92+
</variants>
93+
<commits>
94+
<commit>
95+
<uid>a-random-uid</uid>
96+
<message>A commit message</message>
97+
</commit>
98+
</commits>
99+
<notes>Some notes here please</notes>
100+
</pedigree>
101+
<externalReferences>
102+
<reference type="distribution">
103+
<url>https://cyclonedx.org</url>
104+
<comment>No comment</comment>
105+
</reference>
106+
</externalReferences>
107+
<components>
108+
<component type="library" bom-ref="pkg:pypi/[email protected]?extension=tar.gz">
109+
<name>setuptools</name>
110+
<version>50.3.2</version>
111+
<licenses>
112+
<license>
113+
<id>MIT</id>
114+
</license>
115+
</licenses>
116+
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
117+
</component>
118+
<component type="library" bom-ref="pkg:pypi/[email protected]?extension=tar.gz">
119+
<name>toml</name>
120+
<version>0.10.2</version>
121+
<hashes>
122+
<hash alg="SHA-256">806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b</hash>
123+
</hashes>
124+
<purl>pkg:pypi/[email protected]?extension=tar.gz</purl>
125+
<externalReferences>
126+
<reference type="distribution">
127+
<url>https://cyclonedx.org</url>
128+
<comment>No comment</comment>
129+
</reference>
130+
</externalReferences>
131+
</component>
132+
</components>
133+
</component>
134+
</components>
135+
</bom>

0 commit comments

Comments
 (0)