Skip to content

Commit

Permalink
Add support for supplier and manifacturer (#3090)
Browse files Browse the repository at this point in the history
* melbas changes with some error fixes

Signed-off-by: leec94 <[email protected]>

* adding manufacturer assertions

Signed-off-by: leec94 <[email protected]>

* fix varchar error

Signed-off-by: leec94 <[email protected]>

* fix format for contact

Signed-off-by: leec94 <[email protected]>

* passes test

Signed-off-by: leec94 <[email protected]>

* formatting

Signed-off-by: leec94 <[email protected]>

* account for no supplier

Signed-off-by: leec94 <[email protected]>

* account for no metadata

Signed-off-by: leec94 <[email protected]>

* allow new columns to be nullable

Signed-off-by: leec94 <[email protected]>

---------

Signed-off-by: leec94 <[email protected]>
  • Loading branch information
leec94 authored Nov 1, 2023
1 parent e9b216b commit c92336c
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 2 deletions.
31 changes: 30 additions & 1 deletion src/main/java/org/dependencytrack/model/Component.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import org.apache.commons.lang3.StringUtils;
import org.dependencytrack.model.validation.ValidSpdxExpression;
import org.dependencytrack.resources.v1.serializers.CustomPackageURLSerializer;

import javax.jdo.annotations.Column;
import javax.jdo.annotations.Element;
import javax.jdo.annotations.Extension;
Expand Down Expand Up @@ -116,6 +115,20 @@ public enum FetchGroup {
@Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The publisher may only contain printable characters")
private String publisher;

@Persistent /**Issue #2373, #2737 */
@Column(name = "MANUFACTURE", allowsNull = "true")
@Serialized
@Size(max = 255)
@Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The manufacture may only contain printable characters")
private OrganizationalEntity manufacture;

@Persistent /**Issue #2373, #2737 */
@Column(name = "SUPPLIER", allowsNull = "true")
@Serialized
@Size(max = 255)
@Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The supplier may only contain printable characters")
private OrganizationalEntity supplier;

@Persistent
@Column(name = "GROUP", jdbcType = "VARCHAR")
@Index(name = "COMPONENT_GROUP_IDX")
Expand Down Expand Up @@ -385,6 +398,22 @@ public void setPublisher(String publisher) {
this.publisher = publisher;
}

public OrganizationalEntity getSupplier() { /**Issue #2373, #2737 */
return supplier;
}

public void setSupplier(OrganizationalEntity supplier) {/**Issue #2373, #2737 */
this.supplier = supplier;
}

public OrganizationalEntity getManufacturer() { /**Issue #2373, #2737 */
return manufacture;
}

public void setManufacturer(OrganizationalEntity manufacture) {/**Issue #2373, #2737 */
this.manufacture = manufacture;
}

public String getGroup() {
return group;
}
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/org/dependencytrack/model/Project.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
@Persistent(name = "name"),
@Persistent(name = "author"),
@Persistent(name = "publisher"),
@Persistent(name = "supplier"),
@Persistent(name = "group"),
@Persistent(name = "name"),
@Persistent(name = "description"),
Expand Down Expand Up @@ -129,6 +130,18 @@ public enum FetchGroup {
@Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The publisher may only contain printable characters")
private String publisher;

@Persistent /**Issue #2373, #2737 */
@Column(name = "SUPPLIER", allowsNull = "true")
@Size(max = 255)
@Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The supplier may only contain printable characters")
private OrganizationalEntity supplier;

@Persistent /**Issue #2373, #2737 */
@Column(name = "MANUFACTURE", allowsNull = "true")
@Size(max = 255)
@Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The manufacturer may only contain printable characters")
private OrganizationalEntity manufacture;

@Persistent
@Column(name = "GROUP", jdbcType = "VARCHAR")
@Index(name = "PROJECT_GROUP_IDX")
Expand Down Expand Up @@ -285,6 +298,23 @@ public void setPublisher(String publisher) {
this.publisher = publisher;
}

public OrganizationalEntity getSupplier() {
return supplier;
}

public void setSupplier(OrganizationalEntity supplier) {
this.supplier = supplier;
}

public OrganizationalEntity getManufacturer() { /**Issue #2373, #2737 */
return manufacture;
}

public void setManufacturer(OrganizationalEntity manufacture) {/**Issue #2373, #2737 */
this.manufacture = manufacture;
}


public String getGroup() {
return group;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public static List<Component> convertComponents(final QueryManager qm, final Bom
return components;
}

/**Convert from CycloneDX to DT */
@SuppressWarnings("deprecation")
public static Component convert(final QueryManager qm, final org.cyclonedx.model.Component cycloneDxComponent, final Project project) {
Component component = qm.matchSingleIdentity(project, new ComponentIdentity(cycloneDxComponent));
Expand All @@ -108,6 +109,32 @@ public static Component convert(final QueryManager qm, final org.cyclonedx.model
component.setAuthor(StringUtils.trimToNull(cycloneDxComponent.getAuthor()));
component.setBomRef(StringUtils.trimToNull(cycloneDxComponent.getBomRef()));
component.setPublisher(StringUtils.trimToNull(cycloneDxComponent.getPublisher()));

/**Issue #2373, #2737 */
if (cycloneDxComponent.getSupplier() != null) {
OrganizationalEntity deptrackOrgEntity = new OrganizationalEntity();
deptrackOrgEntity.setName(cycloneDxComponent.getSupplier().getName());
deptrackOrgEntity.setUrls(cycloneDxComponent.getSupplier().getUrls().toArray(new String[0]));
// to do convert contacts
// deptrackOrgEntity.setContacts(cycloneDxComponent.getSupplier().getContacts());

if (cycloneDxComponent.getSupplier().getContacts() != null) {
List<OrganizationalContact> contacts = new ArrayList<>();
for (org.cyclonedx.model.OrganizationalContact organizationalContact: cycloneDxComponent.getSupplier().getContacts()) {
OrganizationalContact contact = new OrganizationalContact();
contact.setName(organizationalContact.getName());
contact.setEmail(organizationalContact.getEmail());
contact.setPhone(organizationalContact.getPhone());
contacts.add(contact);
}
deptrackOrgEntity.setContacts(contacts);
} else {
deptrackOrgEntity.setContacts(null);
}
component.setSupplier(deptrackOrgEntity);
} /**Issue #2373, #2737 */


component.setGroup(StringUtils.trimToNull(cycloneDxComponent.getGroup()));
component.setName(StringUtils.trimToNull(cycloneDxComponent.getName()));
component.setVersion(StringUtils.trimToNull(cycloneDxComponent.getVersion()));
Expand Down Expand Up @@ -242,7 +269,8 @@ else if (StringUtils.isNotBlank(cycloneLicense.getName()))
}
return component;
}


/**Convert from DT to CycloneDX */
@SuppressWarnings("deprecation")
public static org.cyclonedx.model.Component convert(final QueryManager qm, final Component component) {
final org.cyclonedx.model.Component cycloneComponent = new org.cyclonedx.model.Component();
Expand Down Expand Up @@ -395,6 +423,31 @@ public static org.cyclonedx.model.Metadata createMetadata(final Project project)
});
cycloneComponent.setExternalReferences(references);
}
/*Issue #2737: Adding Supplier contact functionality */
if (project.getSupplier() != null) {
org.cyclonedx.model.OrganizationalEntity supplier = new org.cyclonedx.model.OrganizationalEntity();
supplier.setName(project.getSupplier().getName());

if (project.getSupplier().getUrls() != null) {
supplier.setUrls(Arrays.asList(project.getSupplier().getUrls()));
} else {
supplier.setUrls(null);
}
if (project.getSupplier().getContacts() != null) {
List<org.cyclonedx.model.OrganizationalContact> contacts = new ArrayList<>();
for (OrganizationalContact organizationalContact: project.getSupplier().getContacts()) {
org.cyclonedx.model.OrganizationalContact contact = new org.cyclonedx.model.OrganizationalContact();
contact.setName(organizationalContact.getName());
contact.setEmail(organizationalContact.getEmail());
contact.setPhone(organizationalContact.getPhone());
contacts.add(contact);
}
supplier.setContacts(contacts);
}
cycloneComponent.setSupplier(supplier);
} else {
cycloneComponent.setSupplier(null);
}
metadata.setComponent(cycloneComponent);
}
return metadata;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
import org.dependencytrack.model.Classifier;
import org.dependencytrack.model.Component;
import org.dependencytrack.model.ConfigPropertyConstants;
import org.dependencytrack.model.OrganizationalEntity;
import org.dependencytrack.model.OrganizationalContact;
import org.dependencytrack.model.Project;
import org.dependencytrack.model.ServiceComponent;
import org.dependencytrack.notification.NotificationConstants;
Expand Down Expand Up @@ -120,6 +122,29 @@ public void inform(final Event e) {
serialNumnber = (cycloneDxBom.getSerialNumber() != null) ? cycloneDxBom.getSerialNumber().replaceFirst("urn:uuid:", "") : null;
components = ModelConverter.convertComponents(qm, cycloneDxBom, project);
services = ModelConverter.convertServices(qm, cycloneDxBom, project);
/**Issue #2373, #2737 */
if (cycloneDxBom.getMetadata() != null) {
if (cycloneDxBom.getMetadata().getManufacture() != null) {
OrganizationalEntity manufacturer = new OrganizationalEntity();
manufacturer.setName(cycloneDxBom.getMetadata().getManufacture().getName());
manufacturer.setUrls(cycloneDxBom.getMetadata().getManufacture().getUrls().toArray(new String[0]));
if (cycloneDxBom.getMetadata().getManufacture().getContacts() != null){
List<OrganizationalContact> contacts = new ArrayList<>();
for (org.cyclonedx.model.OrganizationalContact organizationalContact: cycloneDxBom.getMetadata().getManufacture().getContacts()) {
OrganizationalContact contact = new OrganizationalContact();
contact.setName(organizationalContact.getName());
contact.setEmail(organizationalContact.getEmail());
contact.setPhone(organizationalContact.getPhone());
contacts.add(contact);
}
manufacturer.setContacts(contacts);
} else {
manufacturer.setContacts(null);
}
project.setManufacturer(manufacturer);
}
} /**Issue #2373, #2737 */

} else {
LOGGER.warn("A CycloneDX BOM was uploaded but accepting CycloneDX BOMs is disabled. Aborting");
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,19 @@ public void informTest() throws Exception {
assertThat(components).hasSize(1);

final Component component = components.get(0);

assertThat(component.getSupplier().getName()).isEqualTo("Foo Incorporated"); /*Issue #2373, #2737 - Adding support for Supplier*/
assertThat(component.getSupplier().getUrls()[0]).isEqualTo("https://foo.bar.com");
assertThat(component.getSupplier().getContacts().get(0).getEmail()).isEqualTo("[email protected]");
assertThat(component.getSupplier().getContacts().get(0).getPhone()).isEqualTo("123-456-7890");

assertThat(project.getManufacturer().getName()).isEqualTo("Foo Incorporated");
assertThat(project.getManufacturer().getUrls()[0]).isEqualTo("https://foo.bar.com");
assertThat(project.getManufacturer().getContacts().get(0).getName()).isEqualTo("Foo Sr.");
assertThat(project.getManufacturer().getContacts().get(0).getEmail()).isEqualTo("[email protected]");
assertThat(project.getManufacturer().getContacts().get(0).getPhone()).isEqualTo("800-123-4567");


assertThat(component.getAuthor()).isEqualTo("Sometimes this field is long because it is composed of a list of authors......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................");
assertThat(component.getPublisher()).isEqualTo("Example Incorporated");
assertThat(component.getGroup()).isEqualTo("com.example");
Expand Down
36 changes: 36 additions & 0 deletions src/test/resources/bom-1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
<bom xmlns="http://cyclonedx.org/schema/bom/1.4" version="1">
<metadata>
<component type="application" bom-ref="acme">
<supplier>
<name>Foo Incorporated</name>
<url>https://foo.bar.com</url>
<contact>
<name>Foo Jr.</name>
<email>[email protected]</email>
<phone>123-456-7890</phone>
</contact>
</supplier>
<publisher>DependencyTrack</publisher>
<name>Acme example</name>
<externalReferences>
Expand All @@ -19,10 +28,37 @@
</reference>
</externalReferences>
</component>
<manufacture>
<name>Foo Incorporated</name>
<url>https://foo.bar.com</url>
<contact>
<name>Foo Sr.</name>
<email>[email protected]</email>
<phone>800-123-4567</phone>
</contact>
</manufacture>
<supplier>
<name>Foo Incorporated</name>
<url>https://foo.bar.com</url>
<contact>
<name>Foo Jr.</name>
<email>[email protected]</email>
<phone>123-456-7890</phone>
</contact>
</supplier>
</metadata>
<components>
<component type="application">
<author>Sometimes this field is long because it is composed of a list of authors......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................</author>
<supplier>
<name>Foo Incorporated</name>
<url>https://foo.bar.com</url>
<contact>
<name>Foo Jr.</name>
<email>[email protected]</email>
<phone>123-456-7890</phone>
</contact>
</supplier>
<publisher>Example Incorporated</publisher>
<group>com.example</group>
<name>xmlutil</name>
Expand Down

0 comments on commit c92336c

Please sign in to comment.