Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
97 changes: 96 additions & 1 deletion cyclonedx/model/bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

from collections.abc import Generator, Iterable
from datetime import datetime
from enum import Enum
from itertools import chain
from typing import TYPE_CHECKING, Optional, Union
from uuid import UUID, uuid4
Expand Down Expand Up @@ -56,6 +57,81 @@
from packageurl import PackageURL


@serializable.serializable_enum
class TlpClassification(str, Enum):
"""
Enum object that defines the Traffic Light Protocol (TLP) classification that controls the sharing and distribution
of the data that the BOM describes.

.. note::
Introduced in CycloneDX v1.7

.. note::
See the CycloneDX Schema definition: https://cyclonedx.org/docs/1.7/xml/#type_tlpClassificationType
"""

CLEAR = 'CLEAR'
GREEN = 'GREEN'
AMBER = 'AMBER'
AMBER_AND_STRICT = 'AMBER_AND_STRICT'
RED = 'RED'


@serializable.serializable_class(ignore_unknown_during_deserialization=True)
class DistributionConstraints:
"""
Our internal representation of the `distributionConstraints` complex type.
Conditions and constraints governing the sharing and distribution of the data or components described by this BOM.

.. note::
Introduced in CycloneDX v1.7

.. note::
See the CycloneDX Schema definition: https://cyclonedx.org/docs/1.7/xml/#type_metadata
"""

def __init__(
self, *,
tlp: Optional[TlpClassification] = None,
) -> None:
self.tlp = tlp or TlpClassification.CLEAR

@property
@serializable.xml_sequence(0)
def tlp(self) -> TlpClassification:
"""
The Traffic Light Protocol (TLP) classification that controls the sharing and distribution of the data that the
BOM describes.

Returns:
`TlpClassification` enum value
"""
return self._tlp

@tlp.setter
def tlp(self, tlp: TlpClassification) -> None:
self._tlp = tlp

def __comparable_tuple(self) -> _ComparableTuple:
return _ComparableTuple(self.tlp)

def __eq__(self, other: object) -> bool:
if isinstance(other, DistributionConstraints):
return self.__comparable_tuple() == other.__comparable_tuple()
return False

def __lt__(self, other: object) -> bool:
if isinstance(other, DistributionConstraints):
return self.__comparable_tuple() < other.__comparable_tuple()
return NotImplemented

def __hash__(self) -> int:
return hash(self.__comparable_tuple())

def __repr__(self) -> str:
return f'<DistributionConstraints tlp={self.tlp}>'


@serializable.serializable_class(ignore_unknown_during_deserialization=True)
class BomMetaData:
"""
Expand All @@ -76,6 +152,7 @@ def __init__(
timestamp: Optional[datetime] = None,
manufacturer: Optional[OrganizationalEntity] = None,
lifecycles: Optional[Iterable[Lifecycle]] = None,
distribution_constraints: Optional[DistributionConstraints] = None,
# Deprecated as of v1.6
manufacture: Optional[OrganizationalEntity] = None,
) -> None:
Expand All @@ -88,6 +165,7 @@ def __init__(
self.properties = properties or []
self.manufacturer = manufacturer
self.lifecycles = lifecycles or []
self.distribution_constraints = distribution_constraints
# deprecated properties below
self.manufacture = manufacture

Expand Down Expand Up @@ -301,10 +379,27 @@ def properties(self) -> 'SortedSet[Property]':
def properties(self, properties: Iterable[Property]) -> None:
self._properties = SortedSet(properties)

@property
@serializable.view(SchemaVersion1Dot7)
@serializable.xml_sequence(11)
def distribution_constraints(self) -> Optional[DistributionConstraints]:
"""
Conditions and constraints governing the sharing and distribution of the data or components described by this
BOM.

Returns:
`DistributionConstraints` or `None`
"""
return self._distribution_constraints

@distribution_constraints.setter
def distribution_constraints(self, distribution_constraints: Optional[DistributionConstraints]) -> None:
self._distribution_constraints = distribution_constraints

def __comparable_tuple(self) -> _ComparableTuple:
return _ComparableTuple((
_ComparableTuple(self.authors), self.component, _ComparableTuple(self.licenses), self.manufacture,
_ComparableTuple(self.properties),
_ComparableTuple(self.properties), self.distribution_constraints,
_ComparableTuple(self.lifecycles), self.supplier, self.timestamp, self.tools, self.manufacturer
))

Expand Down
15 changes: 14 additions & 1 deletion tests/_data/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
Property,
XsUri,
)
from cyclonedx.model.bom import Bom, BomMetaData
from cyclonedx.model.bom import Bom, BomMetaData, DistributionConstraints, TlpClassification
from cyclonedx.model.bom_ref import BomRef
from cyclonedx.model.component import (
Commit,
Expand Down Expand Up @@ -582,6 +582,7 @@ def get_bom_just_complete_metadata() -> Bom:
)]
bom.metadata.lifecycles = [PredefinedLifecycle(LifecyclePhase.BUILD)]
bom.metadata.properties = get_properties_1()
bom.metadata.distribution_constraints = DistributionConstraints(tlp=TlpClassification.GREEN)
return bom


Expand Down Expand Up @@ -1403,6 +1404,17 @@ def get_bom_with_lifecycles() -> Bom:
)


def get_bom_with_distribution_constraints() -> Bom:
return _make_bom(
metadata=BomMetaData(
distribution_constraints=DistributionConstraints(
tlp=TlpClassification.AMBER_AND_STRICT
),
component=Component(name='app', type=ComponentType.APPLICATION, bom_ref='my-app'),
)
)


def get_bom_with_definitions_standards() -> Bom:
"""
Returns a BOM with definitions and standards only.
Expand Down Expand Up @@ -1584,6 +1596,7 @@ def get_bom_for_issue540_duplicate_components() -> Bom:
get_bom_with_component_setuptools_with_v16_fields,
get_bom_for_issue_630_empty_property,
get_bom_with_lifecycles,
get_bom_with_distribution_constraints,
get_bom_with_definitions_standards,
get_bom_with_definitions_and_detailed_standards,
}
4 changes: 4 additions & 0 deletions tests/_data/snapshots/enum_TlpClassification-1.0.xml.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" ?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.0" version="1">
<components/>
</bom>
4 changes: 4 additions & 0 deletions tests/_data/snapshots/enum_TlpClassification-1.1.xml.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" ?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.1" serialNumber="urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac" version="1">
<components/>
</bom>
10 changes: 10 additions & 0 deletions tests/_data/snapshots/enum_TlpClassification-1.2.json.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"metadata": {
"timestamp": "2023-01-07T13:44:32.312678+00:00"
},
"serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac",
"version": 1,
"$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.2"
}
6 changes: 6 additions & 0 deletions tests/_data/snapshots/enum_TlpClassification-1.2.xml.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" ?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.2" serialNumber="urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac" version="1">
<metadata>
<timestamp>2023-01-07T13:44:32.312678+00:00</timestamp>
</metadata>
</bom>
10 changes: 10 additions & 0 deletions tests/_data/snapshots/enum_TlpClassification-1.3.json.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"metadata": {
"timestamp": "2023-01-07T13:44:32.312678+00:00"
},
"serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac",
"version": 1,
"$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.3"
}
6 changes: 6 additions & 0 deletions tests/_data/snapshots/enum_TlpClassification-1.3.xml.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" ?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.3" serialNumber="urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac" version="1">
<metadata>
<timestamp>2023-01-07T13:44:32.312678+00:00</timestamp>
</metadata>
</bom>
10 changes: 10 additions & 0 deletions tests/_data/snapshots/enum_TlpClassification-1.4.json.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"metadata": {
"timestamp": "2023-01-07T13:44:32.312678+00:00"
},
"serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac",
"version": 1,
"$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.4"
}
6 changes: 6 additions & 0 deletions tests/_data/snapshots/enum_TlpClassification-1.4.xml.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" ?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.4" serialNumber="urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac" version="1">
<metadata>
<timestamp>2023-01-07T13:44:32.312678+00:00</timestamp>
</metadata>
</bom>
20 changes: 20 additions & 0 deletions tests/_data/snapshots/enum_TlpClassification-1.5.json.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"metadata": {
"timestamp": "2023-01-07T13:44:32.312678+00:00"
},
"properties": [
{
"name": "key1",
"value": "val1"
},
{
"name": "key2",
"value": "val2"
}
],
"serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac",
"version": 1,
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.5"
}
10 changes: 10 additions & 0 deletions tests/_data/snapshots/enum_TlpClassification-1.5.xml.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" ?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.5" serialNumber="urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac" version="1">
<metadata>
<timestamp>2023-01-07T13:44:32.312678+00:00</timestamp>
</metadata>
<properties>
<property name="key1">val1</property>
<property name="key2">val2</property>
</properties>
</bom>
20 changes: 20 additions & 0 deletions tests/_data/snapshots/enum_TlpClassification-1.6.json.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"metadata": {
"timestamp": "2023-01-07T13:44:32.312678+00:00"
},
"properties": [
{
"name": "key1",
"value": "val1"
},
{
"name": "key2",
"value": "val2"
}
],
"serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac",
"version": 1,
"$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.6"
}
10 changes: 10 additions & 0 deletions tests/_data/snapshots/enum_TlpClassification-1.6.xml.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" ?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.6" serialNumber="urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac" version="1">
<metadata>
<timestamp>2023-01-07T13:44:32.312678+00:00</timestamp>
</metadata>
<properties>
<property name="key1">val1</property>
<property name="key2">val2</property>
</properties>
</bom>
23 changes: 23 additions & 0 deletions tests/_data/snapshots/enum_TlpClassification-1.7.json.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"metadata": {
"distributionConstraints": {
"tlp": "CLEAR"
},
"timestamp": "2023-01-07T13:44:32.312678+00:00"
},
"properties": [
{
"name": "key1",
"value": "val1"
},
{
"name": "key2",
"value": "val2"
}
],
"serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac",
"version": 1,
"$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.7"
}
13 changes: 13 additions & 0 deletions tests/_data/snapshots/enum_TlpClassification-1.7.xml.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" ?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.7" serialNumber="urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac" version="1">
<metadata>
<timestamp>2023-01-07T13:44:32.312678+00:00</timestamp>
<distributionConstraints>
<tlp>CLEAR</tlp>
</distributionConstraints>
</metadata>
<properties>
<property name="key1">val1</property>
<property name="key2">val2</property>
</properties>
</bom>
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,9 @@
"type": "library",
"version": "50.3.2"
},
"distributionConstraints": {
"tlp": "GREEN"
},
"licenses": [
{
"license": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,9 @@
<property name="key1">val1</property>
<property name="key2">val2</property>
</properties>
<distributionConstraints>
<tlp>GREEN</tlp>
</distributionConstraints>
</metadata>
<dependencies>
<dependency ref="my-specific-bom-ref-for-dings"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" ?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.0" version="1">
<components/>
</bom>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" ?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.1" serialNumber="urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac" version="1">
<components/>
</bom>
Loading
Loading