From 67a7567143eb3373099f100bbe17143239cf5d4e Mon Sep 17 00:00:00 2001 From: nscuro Date: Tue, 27 Jun 2023 22:26:16 +0200 Subject: [PATCH] feat(spec1-5): add licensing, license properties, and license bom-ref Signed-off-by: nscuro --- convert.go | 11 ++++ cyclonedx.go | 48 +++++++++++++-- ...ripJSON-func1-valid-license-licensing.json | 59 +++++++++++++++++++ ...tRoundTripJSON-func1-valid-properties.json | 25 ++++++++ ...dTripXML-func1-valid-license-licensing.xml | 49 +++++++++++++++ ...estRoundTripXML-func1-valid-properties.xml | 11 ++++ testdata/valid-license-licensing.json | 55 +++++++++++++++++ testdata/valid-license-licensing.xml | 49 +++++++++++++++ testdata/valid-properties.json | 25 ++++++++ testdata/valid-properties.xml | 11 ++++ 10 files changed, 339 insertions(+), 4 deletions(-) create mode 100644 testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-license-licensing.json create mode 100644 testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-license-licensing.xml create mode 100644 testdata/valid-license-licensing.json create mode 100644 testdata/valid-license-licensing.xml diff --git a/convert.go b/convert.go index f0f861b..78a7329 100644 --- a/convert.go +++ b/convert.go @@ -196,6 +196,17 @@ func convertLicenses(licenses *Licenses, specVersion SpecVersion) { *licenses = converted } } + + if specVersion < SpecVersion1_5 { + for i := range *licenses { + choice := &(*licenses)[i] + if choice.License != nil { + choice.License.BOMRef = "" + choice.License.Licensing = nil + choice.License.Properties = nil + } + } + } } // serviceConverter modifies a Service such that it adheres to a given SpecVersion. diff --git a/cyclonedx.go b/cyclonedx.go index 19a3970..4ff3a9d 100644 --- a/cyclonedx.go +++ b/cyclonedx.go @@ -332,10 +332,13 @@ const ( ) type License struct { - ID string `json:"id,omitempty" xml:"id,omitempty"` - Name string `json:"name,omitempty" xml:"name,omitempty"` - Text *AttachedText `json:"text,omitempty" xml:"text,omitempty"` - URL string `json:"url,omitempty" xml:"url,omitempty"` + BOMRef string `json:"bom-ref,omitempty" xml:"bom-ref,attr,omitempty"` + ID string `json:"id,omitempty" xml:"id,omitempty"` + Name string `json:"name,omitempty" xml:"name,omitempty"` + Text *AttachedText `json:"text,omitempty" xml:"text,omitempty"` + URL string `json:"url,omitempty" xml:"url,omitempty"` + Licensing *Licensing `json:"licensing,omitempty" xml:"licensing,omitempty"` + Properties *[]Property `json:"properties,omitempty" xml:"properties>property,omitempty"` } type Licenses []LicenseChoice @@ -345,6 +348,38 @@ type LicenseChoice struct { Expression string `json:"expression,omitempty" xml:"-"` } +type LicenseType string + +const ( + LicenseTypeAcademic LicenseType = "academic" + LicenseTypeAppliance LicenseType = "appliance" + LicenseTypeClientAccess LicenseType = "client-access" + LicenseTypeConcurrentUser LicenseType = "concurrent-user" + LicenseTypeCorePoints LicenseType = "core-points" + LicenseTypeCustomMetric LicenseType = "custom-metric" + LicenseTypeDevice LicenseType = "device" + LicenseTypeEvaluation LicenseType = "evaluation" + LicenseTypeNamedUser LicenseType = "named-user" + LicenseTypeNodeLocked LicenseType = "node-locked" + LicenseTypeOEM LicenseType = "oem" + LicenseTypeOther LicenseType = "other" + LicenseTypePerpetual LicenseType = "perpetual" + LicenseTypeProcessorPoints LicenseType = "processor-points" + LicenseTypeSubscription LicenseType = "subscription" + LicenseTypeUser LicenseType = "user" +) + +type Licensing struct { + AltIDs *[]string `json:"altIds,omitempty" xml:"altIds>altId,omitempty"` + Licensor *OrganizationalEntityOrContact `json:"licensor,omitempty" xml:"licensor,omitempty"` + Licensee *OrganizationalEntityOrContact `json:"licensee,omitempty" xml:"licensee,omitempty"` + Purchaser *OrganizationalEntityOrContact `json:"purchaser,omitempty" xml:"purchaser,omitempty"` + PurchaseOrder string `json:"purchaseOrder,omitempty" xml:"purchaseOrder,omitempty"` + LicenseTypes *[]LicenseType `json:"licenseTypes,omitempty" xml:"licenseTypes>licenseType,omitempty"` + LastRenewal string `json:"lastRenewal,omitempty" xml:"lastRenewal,omitempty"` + Expiration string `json:"expiration,omitempty" xml:"expiration,omitempty"` +} + // MediaType defines the official media types for CycloneDX BOMs. // See https://cyclonedx.org/specification/overview/#registered-media-types type MediaType int @@ -391,6 +426,11 @@ type OrganizationalEntity struct { Contact *[]OrganizationalContact `json:"contact,omitempty" xml:"contact,omitempty"` } +type OrganizationalEntityOrContact struct { + Organization *OrganizationalEntity `json:"organization,omitempty" xml:"organization,omitempty"` + Individual *OrganizationalContact `json:"individual,omitempty" xml:"individual,omitempty"` +} + type Patch struct { Diff *Diff `json:"diff,omitempty" xml:"diff,omitempty"` Resolves *[]Issue `json:"resolves,omitempty" xml:"resolves>issue,omitempty"` diff --git a/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-license-licensing.json b/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-license-licensing.json new file mode 100644 index 0000000..b220db7 --- /dev/null +++ b/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-license-licensing.json @@ -0,0 +1,59 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "cryptographic-provider", + "version": "2.2.0", + "licenses": [ + { + "license": { + "bom-ref": "acme-license-1", + "name": "Acme Commercial License", + "licensing": { + "altIds": [ + "acme", + "acme-license" + ], + "licensor": { + "organization": { + "name": "Acme Inc", + "contact": [ + { + "name": "Acme Licensing Fulfillment", + "email": "licensing@example.com" + } + ] + } + }, + "licensee": { + "organization": { + "name": "Example Co." + } + }, + "purchaser": { + "individual": { + "name": "Samantha Wright", + "email": "samantha.wright@gmail.com", + "phone": "800-555-1212" + } + }, + "purchaseOrder": "PO-12345", + "licenseTypes": [ + "appliance" + ], + "lastRenewal": "2022-04-13T20:20:39+00:00", + "expiration": "2023-04-13T20:20:39+00:00" + } + } + } + ] + } + ] +} + diff --git a/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-properties.json b/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-properties.json index 7ac4f9f..5130bae 100644 --- a/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-properties.json +++ b/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-properties.json @@ -28,6 +28,31 @@ "type": "library", "name": "acme-library", "version": "1.0.0", + "licenses": [ + { + "license": { + "id": "Apache-2.0", + "properties": [ + { + "name": "Foo", + "value": "Bar" + }, + { + "name": "Foo", + "value": "You" + }, + { + "name": "Foo", + "value": "Two" + }, + { + "name": "Bar", + "value": "Foo" + } + ] + } + } + ], "properties": [ { "name": "Foo", diff --git a/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-license-licensing.xml b/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-license-licensing.xml new file mode 100644 index 0000000..681362b --- /dev/null +++ b/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-license-licensing.xml @@ -0,0 +1,49 @@ + + + + + Acme Inc + com.acme + cryptographic-provider + 2.2.0 + + + Acme Commercial License + + + acme + acme-license + + + + Acme Inc + + Acme Licensing Fulfillment + licensing@example.com + + + + + + Example Co. + + + + + Samantha Wright + samantha.wright@gmail.com + 800-555-1212 + + + PO-12345 + + appliance + + 2022-04-13T20:20:39+00:00 + 2023-04-13T20:20:39+00:00 + + + + + + diff --git a/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-properties.xml b/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-properties.xml index dfcd58f..e66d784 100644 --- a/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-properties.xml +++ b/testdata/snapshots/cyclonedx-go-TestRoundTripXML-func1-valid-properties.xml @@ -12,6 +12,17 @@ acme-library 1.0.0 + + + Apache-2.0 + + Bar + You + Two + Foo + + + Bar Foo diff --git a/testdata/valid-license-licensing.json b/testdata/valid-license-licensing.json new file mode 100644 index 0000000..84c4719 --- /dev/null +++ b/testdata/valid-license-licensing.json @@ -0,0 +1,55 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "components": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "cryptographic-provider", + "version": "2.2.0", + "licenses": [ + { + "license": { + "bom-ref": "acme-license-1", + "name": "Acme Commercial License", + "licensing": { + "altIds": [ + "acme", "acme-license" + ], + "licensor": { + "organization": { + "name": "Acme Inc", + "contact": [ + { + "name": "Acme Licensing Fulfillment", + "email": "licensing@example.com" + } + ] + } + }, + "licensee": { + "organization": { + "name": "Example Co." + } + }, + "purchaser": { + "individual": { + "name": "Samantha Wright", + "email": "samantha.wright@gmail.com", + "phone": "800-555-1212" + } + }, + "purchaseOrder": "PO-12345", + "licenseTypes": ["appliance"], + "lastRenewal": "2022-04-13T20:20:39+00:00", + "expiration": "2023-04-13T20:20:39+00:00" + } + } + } + ] + } + ] +} \ No newline at end of file diff --git a/testdata/valid-license-licensing.xml b/testdata/valid-license-licensing.xml new file mode 100644 index 0000000..75d070e --- /dev/null +++ b/testdata/valid-license-licensing.xml @@ -0,0 +1,49 @@ +?xml version="1.0"?> + + + + Acme Inc + com.acme + cryptographic-provider + 2.2.0 + + + Acme Commercial License + + + acme + acme-license + + + + Acme Inc + + Acme Licensing Fulfillment + licensing@example.com + + + + + + Example Co. + + + + + Samantha Wright + samantha.wright@gmail.com + 800-555-1212 + + + PO-12345 + + appliance + + 2022-04-13T20:20:39+00:00 + 2023-04-13T20:20:39+00:00 + + + + + + \ No newline at end of file diff --git a/testdata/valid-properties.json b/testdata/valid-properties.json index 3a33ccf..24ce5de 100644 --- a/testdata/valid-properties.json +++ b/testdata/valid-properties.json @@ -28,6 +28,31 @@ "type": "library", "name": "acme-library", "version": "1.0.0", + "licenses": [ + { + "license": { + "id": "Apache-2.0", + "properties": [ + { + "name": "Foo", + "value": "Bar" + }, + { + "name": "Foo", + "value": "You" + }, + { + "name": "Foo", + "value": "Two" + }, + { + "name": "Bar", + "value": "Foo" + } + ] + } + } + ], "properties": [ { "name": "Foo", diff --git a/testdata/valid-properties.xml b/testdata/valid-properties.xml index 85abf9e..91a1916 100644 --- a/testdata/valid-properties.xml +++ b/testdata/valid-properties.xml @@ -12,6 +12,17 @@ acme-library 1.0.0 + + + Apache-2.0 + + Bar + You + Two + Foo + + + Bar Foo