From 9031f65b4e39148c442f63aea9a8f0230035892e Mon Sep 17 00:00:00 2001 From: Ross Murphy Date: Wed, 3 Jul 2024 11:07:03 +0100 Subject: [PATCH 1/3] set license name instead of ID when using custom license Signed-off-by: Ross Murphy --- .../parser/cyclonedx/util/ModelConverter.java | 6 ++++- .../cyclonedx/CycloneDxValidatorTest.java | 26 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/dependencytrack/parser/cyclonedx/util/ModelConverter.java b/src/main/java/org/dependencytrack/parser/cyclonedx/util/ModelConverter.java index 83b6d04c94..9f275ec165 100644 --- a/src/main/java/org/dependencytrack/parser/cyclonedx/util/ModelConverter.java +++ b/src/main/java/org/dependencytrack/parser/cyclonedx/util/ModelConverter.java @@ -567,7 +567,11 @@ public static org.cyclonedx.model.Component convert(final QueryManager qm, final final LicenseChoice licenseChoice = new LicenseChoice(); if (component.getResolvedLicense() != null) { final org.cyclonedx.model.License license = new org.cyclonedx.model.License(); - license.setId(component.getResolvedLicense().getLicenseId()); + if(!component.getResolvedLicense().isCustomLicense()){ + license.setId(component.getResolvedLicense().getLicenseId()); + } else{ + license.setName(component.getResolvedLicense().getName()); + } license.setUrl(component.getLicenseUrl()); licenseChoice.addLicense(license); cycloneComponent.setLicenseChoice(licenseChoice); diff --git a/src/test/java/org/dependencytrack/parser/cyclonedx/CycloneDxValidatorTest.java b/src/test/java/org/dependencytrack/parser/cyclonedx/CycloneDxValidatorTest.java index 1e2e439163..2d295c1a91 100644 --- a/src/test/java/org/dependencytrack/parser/cyclonedx/CycloneDxValidatorTest.java +++ b/src/test/java/org/dependencytrack/parser/cyclonedx/CycloneDxValidatorTest.java @@ -278,4 +278,30 @@ public void testValidateXmlWithXxeProtection() { } } + @Test + public void testValidateJsonWithCustomLicense() { + assertThatExceptionOfType(InvalidBomException.class) + .isThrownBy(() -> validator.validate(""" + { + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "components": [ + { + "type": "library", + "name": "acme-library", + "version": "1.0.0", + "licenses" : [ + { + "license" : { + "id" : "CustomLicense" + } + } + ] + } + ] + } + """.getBytes())) + .withMessage("Schema validation failed"); + } + } \ No newline at end of file From aa8d844c47d728f2631c94ef7af00404b84d8fa7 Mon Sep 17 00:00:00 2001 From: Ross Murphy Date: Wed, 3 Jul 2024 11:36:27 +0100 Subject: [PATCH 2/3] remove unit test Signed-off-by: Ross Murphy --- .../cyclonedx/CycloneDxValidatorTest.java | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/src/test/java/org/dependencytrack/parser/cyclonedx/CycloneDxValidatorTest.java b/src/test/java/org/dependencytrack/parser/cyclonedx/CycloneDxValidatorTest.java index 2d295c1a91..1e2e439163 100644 --- a/src/test/java/org/dependencytrack/parser/cyclonedx/CycloneDxValidatorTest.java +++ b/src/test/java/org/dependencytrack/parser/cyclonedx/CycloneDxValidatorTest.java @@ -278,30 +278,4 @@ public void testValidateXmlWithXxeProtection() { } } - @Test - public void testValidateJsonWithCustomLicense() { - assertThatExceptionOfType(InvalidBomException.class) - .isThrownBy(() -> validator.validate(""" - { - "bomFormat": "CycloneDX", - "specVersion": "1.5", - "components": [ - { - "type": "library", - "name": "acme-library", - "version": "1.0.0", - "licenses" : [ - { - "license" : { - "id" : "CustomLicense" - } - } - ] - } - ] - } - """.getBytes())) - .withMessage("Schema validation failed"); - } - } \ No newline at end of file From 177d9b6af71e3952381a1f7b9b45526bd573478f Mon Sep 17 00:00:00 2001 From: Ross Murphy Date: Wed, 3 Jul 2024 14:40:15 +0100 Subject: [PATCH 3/3] add unit test to validate license Signed-off-by: Ross Murphy --- .../resources/v1/BomResourceTest.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/test/java/org/dependencytrack/resources/v1/BomResourceTest.java b/src/test/java/org/dependencytrack/resources/v1/BomResourceTest.java index c99eb4c63b..88b8711d68 100644 --- a/src/test/java/org/dependencytrack/resources/v1/BomResourceTest.java +++ b/src/test/java/org/dependencytrack/resources/v1/BomResourceTest.java @@ -315,6 +315,81 @@ public void exportProjectAsCycloneDxInventoryTest() { assertThat(componentWithVulnAndAnalysis.getDirectDependencies()).isNotNull(); } + @Test + public void exportProjectAsCycloneDxLicenseTest() { + Project project = qm.createProject("Acme Example", null, "1.0", null, null, null, true, false); + Component c = new Component(); + c.setProject(project); + c.setName("sample-component"); + c.setVersion("1.0"); + org.dependencytrack.model.License license = new org.dependencytrack.model.License(); + license.setId(1234); + license.setName("CustomName"); + license.setCustomLicense(true); + c.setResolvedLicense(license); + c.setDirectDependencies("[]"); + Component component = qm.createComponent(c, false); + qm.persist(project); + Response response = jersey.target(V1_BOM + "/cyclonedx/project/" + project.getUuid()).request() + .header(X_API_KEY, apiKey) + .get(Response.class); + + final String jsonResponse = getPlainTextBody(response); + assertThatNoException().isThrownBy(() -> CycloneDxValidator.getInstance().validate(jsonResponse.getBytes())); + assertThatJson(jsonResponse) + .withMatcher("component", equalTo(component.getUuid().toString())) + .withMatcher("projectUuid", equalTo(project.getUuid().toString())) + .isEqualTo(json(""" + { + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "serialNumber": "${json-unit.ignore}", + "version": 1, + "metadata": { + "timestamp": "${json-unit.any-string}", + "tools": [ + { + "vendor": "OWASP", + "name": "Dependency-Track", + "version": "${json-unit.any-string}" + } + ], + "component": { + "type": "library", + "bom-ref": "${json-unit.matches:projectUuid}", + "name": "Acme Example", + "version": "1.0" + } + }, + "components": [ + { + "type": "library", + "bom-ref": "${json-unit.matches:component}", + "name": "sample-component", + "version": "1.0", + "licenses": [ + { + "license": { + "name": "CustomName" + } + } + ] + } + ], + "dependencies": [ + { + "ref": "${json-unit.matches:projectUuid}", + "dependsOn": [] + }, + { + "ref": "${json-unit.matches:component}", + "dependsOn": [] + } + ] + } + """)); + } + @Test public void exportProjectAsCycloneDxInventoryWithVulnerabilitiesTest() { var vulnerability = new Vulnerability();