Skip to content

Commit

Permalink
feat: support bom.properties for CycloneDX v1.5+ (#585)
Browse files Browse the repository at this point in the history
Signed-off-by: Paul Horton <paul.horton@owasp.org>
  • Loading branch information
madpah committed Apr 10, 2024
1 parent d230e67 commit 1d1c45a
Show file tree
Hide file tree
Showing 151 changed files with 1,074 additions and 44 deletions.
53 changes: 33 additions & 20 deletions cyclonedx/model/bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,8 @@ def __init__(self, *, components: Optional[Iterable[Component]] = None,
serial_number: Optional[UUID] = None, version: int = 1,
metadata: Optional[BomMetaData] = None,
dependencies: Optional[Iterable[Dependency]] = None,
vulnerabilities: Optional[Iterable[Vulnerability]] = None) -> None:
vulnerabilities: Optional[Iterable[Vulnerability]] = None,
properties: Optional[Iterable[Property]] = None) -> None:
"""
Create a new Bom that you can manually/programmatically add data to later.
Expand All @@ -325,6 +326,7 @@ def __init__(self, *, components: Optional[Iterable[Component]] = None,
self.external_references = external_references or [] # type:ignore[assignment]
self.vulnerabilities = vulnerabilities or [] # type:ignore[assignment]
self.dependencies = dependencies or [] # type:ignore[assignment]
self.properties = properties or [] # type:ignore[assignment]

@property
@serializable.type_mapping(UrnUuidHelper)
Expand Down Expand Up @@ -364,7 +366,7 @@ def version(self, version: int) -> None:
@serializable.view(SchemaVersion1Dot4)
@serializable.view(SchemaVersion1Dot5)
@serializable.view(SchemaVersion1Dot6)
@serializable.xml_sequence(1)
@serializable.xml_sequence(10)
def metadata(self) -> BomMetaData:
"""
Get our internal metadata object for this Bom.
Expand All @@ -385,7 +387,7 @@ def metadata(self, metadata: BomMetaData) -> None:
@serializable.include_none(SchemaVersion1Dot0)
@serializable.include_none(SchemaVersion1Dot1)
@serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'component')
@serializable.xml_sequence(2)
@serializable.xml_sequence(20)
def components(self) -> 'SortedSet[Component]':
"""
Get all the Components currently in this Bom.
Expand All @@ -406,7 +408,7 @@ def components(self, components: Iterable[Component]) -> None:
@serializable.view(SchemaVersion1Dot5)
@serializable.view(SchemaVersion1Dot6)
@serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'service')
@serializable.xml_sequence(3)
@serializable.xml_sequence(30)
def services(self) -> 'SortedSet[Service]':
"""
Get all the Services currently in this Bom.
Expand All @@ -428,7 +430,7 @@ def services(self, services: Iterable[Service]) -> None:
@serializable.view(SchemaVersion1Dot5)
@serializable.view(SchemaVersion1Dot6)
@serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'reference')
@serializable.xml_sequence(4)
@serializable.xml_sequence(40)
def external_references(self) -> 'SortedSet[ExternalReference]':
"""
Provides the ability to document external references related to the BOM or to the project the BOM describes.
Expand All @@ -449,7 +451,7 @@ def external_references(self, external_references: Iterable[ExternalReference])
@serializable.view(SchemaVersion1Dot5)
@serializable.view(SchemaVersion1Dot6)
@serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'dependency')
@serializable.xml_sequence(5)
@serializable.xml_sequence(50)
def dependencies(self) -> 'SortedSet[Dependency]':
return self._dependencies

Expand All @@ -470,25 +472,35 @@ def dependencies(self, dependencies: Iterable[Dependency]) -> None:
# def compositions(self, ...) -> None:
# ... # TODO Since CDX 1.3

# @property
# ...
# @serializable.view(SchemaVersion1Dot3)
# @serializable.view(SchemaVersion1Dot4)
# @serializable.view(SchemaVersion1Dot5)
# @serializable.xml_sequence(7)
# def properties(self) -> ...:
# ... # TODO Since CDX 1.3
#
# @properties.setter
# def properties(self, ...) -> None:
# ... # TODO Since CDX 1.3
@property
# @serializable.view(SchemaVersion1Dot3) @todo: Update py-serializable to support view by OutputFormat filtering
# @serializable.view(SchemaVersion1Dot4) @todo: Update py-serializable to support view by OutputFormat filtering
@serializable.view(SchemaVersion1Dot5)
@serializable.view(SchemaVersion1Dot6)
@serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'property')
@serializable.xml_sequence(70)
def properties(self) -> 'SortedSet[Property]':
"""
Provides the ability to document properties in a name/value store. This provides flexibility to include data
not officially supported in the standard without having to use additional namespaces or create extensions.
Property names of interest to the general public are encouraged to be registered in the CycloneDX Property
Taxonomy - https://github.com/CycloneDX/cyclonedx-property-taxonomy. Formal registration is OPTIONAL.
Return:
Set of `Property`
"""
return self._properties

@properties.setter
def properties(self, properties: Iterable[Property]) -> None:
self._properties = SortedSet(properties)

@property
@serializable.view(SchemaVersion1Dot4)
@serializable.view(SchemaVersion1Dot5)
@serializable.view(SchemaVersion1Dot6)
@serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'vulnerability')
@serializable.xml_sequence(8)
@serializable.xml_sequence(80)
def vulnerabilities(self) -> 'SortedSet[Vulnerability]':
"""
Get all the Vulnerabilities in this BOM.
Expand Down Expand Up @@ -682,7 +694,8 @@ def __eq__(self, other: object) -> bool:
def __hash__(self) -> int:
return hash((
self.serial_number, self.version, self.metadata, tuple(self.components), tuple(self.services),
tuple(self.external_references), tuple(self.vulnerabilities), tuple(self.dependencies)
tuple(self.external_references), tuple(self.dependencies), tuple(self.properties),
tuple(self.vulnerabilities),
))

def __repr__(self) -> str:
Expand Down
28 changes: 4 additions & 24 deletions docs/schema-support.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,16 @@ The following sub-sections aim to explain what support this library provides and
by calling out support for data as defined in the latest CycloneDX standard specification, regardless of whether it is
supported in prior versions of the CycloneDX schema.

Root Level Schema Support
-------------------------

+----------------------------+---------------+---------------------------------------------------------------------------------------------------+
| Data Path | Supported? | Notes |
+============================+===============+===================================================================================================+
| ``bom[@version]`` | Yes | |
+----------------------------+---------------+---------------------------------------------------------------------------------------------------+
| ``bom[@serialNumber]`` | Yes | |
+----------------------------+---------------+---------------------------------------------------------------------------------------------------+
| ``bom.metadata`` | Yes | Not supported: ``lifecycles`` |
| ``bom.metadata`` | Yes | |
+----------------------------+---------------+---------------------------------------------------------------------------------------------------+
| ``bom.components`` | Yes | Not supported: ``modified`` (as it is deprecated), ``modelCard``, ``data``, ``signature``. |
| ``bom.components`` | Yes | Not supported: ``modified`` (as it is deprecated), ``signature``. |
+----------------------------+---------------+---------------------------------------------------------------------------------------------------+
| ``bom.services`` | Yes | Not supported: ``signature``. |
+----------------------------+---------------+---------------------------------------------------------------------------------------------------+
Expand All @@ -43,6 +40,8 @@ Root Level Schema Support
+----------------------------+---------------+---------------------------------------------------------------------------------------------------+
| ``bom.compositions`` | No | |
+----------------------------+---------------+---------------------------------------------------------------------------------------------------+
| ``bom.properties`` | Yes | Supported when outputting to Schema Version >= 1.5. See `schema specification bug 130`_ |
+----------------------------+---------------+---------------------------------------------------------------------------------------------------+
| ``bom.vulnerabilities`` | Yes | Note: Prior to CycloneDX 1.4, these were present under ``bom.components`` via a schema extension. |
| | | Note: As of ``cyclonedx-python-lib`` ``>3.0.0``, Vulnerability are modelled differently |
+----------------------------+---------------+---------------------------------------------------------------------------------------------------+
Expand All @@ -54,27 +53,8 @@ Root Level Schema Support
+----------------------------+---------------+---------------------------------------------------------------------------------------------------+
| ``bom.definitions`` | No | |
+----------------------------+---------------+---------------------------------------------------------------------------------------------------+
| ``bom.properties`` | No | See `schema specification bug 130`_ |
+----------------------------+---------------+---------------------------------------------------------------------------------------------------+
| ``bom.signature`` | No | |
+----------------------------+---------------+---------------------------------------------------------------------------------------------------+

Internal Model Schema Support
-----------------------------

+----------------------------+---------------+----------------------------------------------------------------------------------------------+
| Internal Model | Supported? | Notes |
+============================+===============+==============================================================================================+
| ``ComponentEvidence`` |Yes | Not currently supported: ``callstack``, ``identity``, ``occurrences``. |
+----------------------------+---------------+----------------------------------------------------------------------------------------------+
| ``DisjunctiveLicense`` |Yes | Not currently supported: ``@bom-ref``, ``licensing``, ``properties``. |
+----------------------------+---------------+----------------------------------------------------------------------------------------------+
| ``LicenseExpression`` |Yes | Not currently supported: ``@bom-ref`` |
+----------------------------+---------------+----------------------------------------------------------------------------------------------+
| ``OrganizationalContact`` |Yes | Not currently supported: ``@bom-ref`` |
+----------------------------+---------------+----------------------------------------------------------------------------------------------+
| ``OrganizationalEntity`` |Yes | Not currently supported: ``@bom-ref`` |
+----------------------------+---------------+----------------------------------------------------------------------------------------------+

.. _schema specification bug 130: https://github.com/CycloneDX/specification/issues/130

1 change: 1 addition & 0 deletions tests/_data/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ def _make_bom(**kwargs: Any) -> Bom:
bom = Bom(**kwargs)
bom.serial_number = BOM_SERIAL_NUMBER
bom.metadata.timestamp = BOM_TIMESTAMP
bom.properties = get_properties_1()
return bom


Expand Down
10 changes: 10 additions & 0 deletions tests/_data/snapshots/enum_ComponentScope-1.5.json.bin
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@
}
]
},
"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",
Expand Down
4 changes: 4 additions & 0 deletions tests/_data/snapshots/enum_ComponentScope-1.5.xml.bin
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,8 @@
<dependency ref="scoped-OPTIONAL"/>
<dependency ref="scoped-REQUIRED"/>
</dependencies>
<properties>
<property name="key1">val1</property>
<property name="key2">val2</property>
</properties>
</bom>
10 changes: 10 additions & 0 deletions tests/_data/snapshots/enum_ComponentScope-1.6.json.bin
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@
}
]
},
"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",
Expand Down
4 changes: 4 additions & 0 deletions tests/_data/snapshots/enum_ComponentScope-1.6.xml.bin
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,8 @@
<dependency ref="scoped-OPTIONAL"/>
<dependency ref="scoped-REQUIRED"/>
</dependencies>
<properties>
<property name="key1">val1</property>
<property name="key2">val2</property>
</properties>
</bom>
10 changes: 10 additions & 0 deletions tests/_data/snapshots/enum_ComponentType-1.5.json.bin
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,16 @@
}
]
},
"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",
Expand Down
4 changes: 4 additions & 0 deletions tests/_data/snapshots/enum_ComponentType-1.5.xml.bin
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,8 @@
<dependency ref="typed-OPERATING_SYSTEM"/>
<dependency ref="typed-PLATFORM"/>
</dependencies>
<properties>
<property name="key1">val1</property>
<property name="key2">val2</property>
</properties>
</bom>
10 changes: 10 additions & 0 deletions tests/_data/snapshots/enum_ComponentType-1.6.json.bin
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,16 @@
}
]
},
"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",
Expand Down
4 changes: 4 additions & 0 deletions tests/_data/snapshots/enum_ComponentType-1.6.xml.bin
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,8 @@
<dependency ref="typed-OPERATING_SYSTEM"/>
<dependency ref="typed-PLATFORM"/>
</dependencies>
<properties>
<property name="key1">val1</property>
<property name="key2">val2</property>
</properties>
</bom>
10 changes: 10 additions & 0 deletions tests/_data/snapshots/enum_DataFlow-1.5.json.bin
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@
}
]
},
"properties": [
{
"name": "key1",
"value": "val1"
},
{
"name": "key2",
"value": "val2"
}
],
"serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac",
"services": [
{
Expand Down
4 changes: 4 additions & 0 deletions tests/_data/snapshots/enum_DataFlow-1.5.xml.bin
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,8 @@
<dependencies>
<dependency ref="dummy"/>
</dependencies>
<properties>
<property name="key1">val1</property>
<property name="key2">val2</property>
</properties>
</bom>
10 changes: 10 additions & 0 deletions tests/_data/snapshots/enum_DataFlow-1.6.json.bin
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@
}
]
},
"properties": [
{
"name": "key1",
"value": "val1"
},
{
"name": "key2",
"value": "val2"
}
],
"serialNumber": "urn:uuid:1441d33a-e0fc-45b5-af3b-61ee52a88bac",
"services": [
{
Expand Down
4 changes: 4 additions & 0 deletions tests/_data/snapshots/enum_DataFlow-1.6.xml.bin
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,8 @@
<dependencies>
<dependency ref="dummy"/>
</dependencies>
<properties>
<property name="key1">val1</property>
<property name="key2">val2</property>
</properties>
</bom>
10 changes: 10 additions & 0 deletions tests/_data/snapshots/enum_Encoding-1.5.json.bin
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@
}
]
},
"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",
Expand Down
4 changes: 4 additions & 0 deletions tests/_data/snapshots/enum_Encoding-1.5.xml.bin
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,8 @@
<dependencies>
<dependency ref="dummy"/>
</dependencies>
<properties>
<property name="key1">val1</property>
<property name="key2">val2</property>
</properties>
</bom>
10 changes: 10 additions & 0 deletions tests/_data/snapshots/enum_Encoding-1.6.json.bin
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@
}
]
},
"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",
Expand Down
4 changes: 4 additions & 0 deletions tests/_data/snapshots/enum_Encoding-1.6.xml.bin
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,8 @@
<dependencies>
<dependency ref="dummy"/>
</dependencies>
<properties>
<property name="key1">val1</property>
<property name="key2">val2</property>
</properties>
</bom>
Loading

0 comments on commit 1d1c45a

Please sign in to comment.