Skip to content

Commit

Permalink
Added 'serialNumber' to SBOMs (JSON and XML).
Browse files Browse the repository at this point in the history
  • Loading branch information
madpah committed Sep 1, 2021
1 parent bb41dc6 commit 50e3c75
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 6 deletions.
7 changes: 7 additions & 0 deletions cyclonedx/model/bom.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import datetime
from typing import List
from uuid import uuid4

from .cyclonedx import Component
from ..parser import BaseParser

Expand Down Expand Up @@ -28,6 +30,7 @@ class Bom:
to the requested schema version.
"""

_uuid: str
_metadata: BomMetaData = None
_components: List[Component] = []

Expand All @@ -38,6 +41,7 @@ def from_parser(parser: BaseParser):
return bom

def __init__(self):
self._uuid = uuid4()
self._metadata = BomMetaData()
self._components.clear()

Expand All @@ -56,5 +60,8 @@ def get_components(self) -> List[Component]:
def get_metadata(self) -> BomMetaData:
return self._metadata

def get_urn_uuid(self) -> str:
return 'urn:uuid:{}'.format(self._uuid)

def has_component(self, component: Component) -> bool:
return component in self._components
2 changes: 1 addition & 1 deletion cyclonedx/output/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def _get_json(self) -> dict:
return {
"bomFormat": "CycloneDX",
"specVersion": str(self._get_schema_version()),
"serialNumber": "",
"serialNumber": self.get_bom().get_urn_uuid(),
"version": 1,
"metadata": self._get_metadata_as_dict(),
"components": components
Expand Down
5 changes: 2 additions & 3 deletions cyclonedx/output/xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ def get_target_namespace(self) -> str:
return 'http://cyclonedx.org/schema/bom/{}'.format(self._get_schema_version())

def output_as_string(self) -> str:
bom = ElementTree.Element('bom', {'xmlns': self.get_target_namespace(), 'version': '1'})
bom = ElementTree.Element('bom', {'xmlns': self.get_target_namespace(), 'version': '1',
'serialNumber': self.get_bom().get_urn_uuid()})
bom = self._add_metadata(bom=bom)
components = ElementTree.SubElement(bom, 'components')
for component in self.get_bom().get_components():
Expand Down Expand Up @@ -97,8 +98,6 @@ def _get_schema_version(self) -> str:
pass




class XmlV1Dot2(Xml):

def _get_schema_version(self) -> str:
Expand Down
12 changes: 10 additions & 2 deletions tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@

import json
from datetime import datetime, timezone
from uuid import uuid4
from xml.dom import minidom

single_uuid: str = 'urn:uuid:{}'.format(uuid4())


class BaseJsonTestCase(TestCase):

Expand All @@ -21,8 +24,8 @@ def assertEqualJsonBom(self, a: str, b: str):
ab, bb = json.loads(a), json.loads(b)

# Null serialNumbers
ab['serialNumber'] = ''
bb['serialNumber'] = ''
ab['serialNumber'] = single_uuid
bb['serialNumber'] = single_uuid

# Unify timestamps to ensure they will compare
now = datetime.now(tz=timezone.utc)
Expand All @@ -45,6 +48,11 @@ def assertEqualXmlBom(self, a: str, b: str, namespace: str):
"""
ba, bb = xml.etree.ElementTree.fromstring(a), xml.etree.ElementTree.fromstring(b)

# Align serialNumbers
ba.set('serialNumber', single_uuid)
bb.set('serialNumber', single_uuid)

# Align timestamps in metadata
now = datetime.now(tz=timezone.utc)
metadata_ts_a = ba.find('./{{{}}}metadata/{{{}}}timestamp'.format(namespace, namespace))
if metadata_ts_a is not None:
Expand Down

0 comments on commit 50e3c75

Please sign in to comment.