Skip to content

Commit

Permalink
Merge pull request #588 from DependencyTrack/issue-1058
Browse files Browse the repository at this point in the history
Ingest `metadata.tools` and make it available in CEL policies
  • Loading branch information
nscuro authored Feb 29, 2024
2 parents 26ad987 + beb34ed commit 101b84b
Show file tree
Hide file tree
Showing 30 changed files with 998 additions and 109 deletions.
24 changes: 24 additions & 0 deletions src/main/java/org/dependencytrack/model/Component.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.github.packageurl.MalformedPackageURLException;
Expand Down Expand Up @@ -114,24 +115,28 @@ public enum FetchGroup {
@Persistent
@Column(name = "AUTHOR", jdbcType = "CLOB")
@Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The author may only contain printable characters")
@JsonView(JsonViews.MetadataTools.class)
private String author;

@Persistent
@Column(name = "PUBLISHER", jdbcType = "VARCHAR")
@Size(max = 255)
@Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The publisher may only contain printable characters")
@JsonView(JsonViews.MetadataTools.class)
private String publisher;

@Persistent(defaultFetchGroup = "true")
@Convert(OrganizationalEntityJsonConverter.class)
@Column(name = "SUPPLIER", jdbcType = "CLOB", allowsNull = "true")
@JsonView(JsonViews.MetadataTools.class)
private OrganizationalEntity supplier;

@Persistent
@Column(name = "GROUP", jdbcType = "VARCHAR")
@Index(name = "COMPONENT_GROUP_IDX")
@Size(max = 255)
@Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The group may only contain printable characters")
@JsonView(JsonViews.MetadataTools.class)
private String group;

@Persistent
Expand All @@ -141,19 +146,22 @@ public enum FetchGroup {
@Size(min = 1, max = 255)
@JsonDeserialize(using = TrimmedStringDeserializer.class)
@Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The name may only contain printable characters")
@JsonView(JsonViews.MetadataTools.class)
private String name;

@Persistent
@Column(name = "VERSION", jdbcType = "VARCHAR")
@Size(max = 255)
@JsonDeserialize(using = TrimmedStringDeserializer.class)
@Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The version may only contain printable characters")
@JsonView(JsonViews.MetadataTools.class)
private String version;

@Persistent
@Column(name = "CLASSIFIER", jdbcType = "VARCHAR")
@Index(name = "COMPONENT_CLASSIFIER_IDX")
@Extension(vendorName = "datanucleus", key = "enum-check-constraint", value = "true")
@JsonView(JsonViews.MetadataTools.class)
private Classifier classifier;

@Persistent
Expand All @@ -174,72 +182,84 @@ public enum FetchGroup {
@Index(name = "COMPONENT_MD5_IDX")
@Column(name = "MD5", jdbcType = "VARCHAR", length = 32)
@Pattern(regexp = "^[0-9a-fA-F]{32}$", message = "The MD5 hash must be a valid 32 character HEX number")
@JsonView(JsonViews.MetadataTools.class)
private String md5;

@Persistent
@Index(name = "COMPONENT_SHA1_IDX")
@Column(name = "SHA1", jdbcType = "VARCHAR", length = 40)
@Pattern(regexp = "^[0-9a-fA-F]{40}$", message = "The SHA1 hash must be a valid 40 character HEX number")
@JsonView(JsonViews.MetadataTools.class)
private String sha1;

@Persistent
@Index(name = "COMPONENT_SHA256_IDX")
@Column(name = "SHA_256", jdbcType = "VARCHAR", length = 64)
@Pattern(regexp = "^[0-9a-fA-F]{64}$", message = "The SHA-256 hash must be a valid 64 character HEX number")
@JsonView(JsonViews.MetadataTools.class)
private String sha256;

@Persistent
@Index(name = "COMPONENT_SHA384_IDX")
@Column(name = "SHA_384", jdbcType = "VARCHAR", length = 96)
@Pattern(regexp = "^[0-9a-fA-F]{96}$", message = "The SHA-384 hash must be a valid 96 character HEX number")
@JsonView(JsonViews.MetadataTools.class)
private String sha384;

@Persistent
@Index(name = "COMPONENT_SHA512_IDX")
@Column(name = "SHA_512", jdbcType = "VARCHAR", length = 128)
@Pattern(regexp = "^[0-9a-fA-F]{128}$", message = "The SHA-512 hash must be a valid 128 character HEX number")
@JsonView(JsonViews.MetadataTools.class)
private String sha512;

@Persistent
@Index(name = "COMPONENT_SHA3_256_IDX")
@Column(name = "SHA3_256", jdbcType = "VARCHAR", length = 64)
@Pattern(regexp = "^[0-9a-fA-F]{64}$", message = "The SHA3-256 hash must be a valid 64 character HEX number")
@JsonView(JsonViews.MetadataTools.class)
private String sha3_256;

@Persistent
@Index(name = "COMPONENT_SHA3_384_IDX")
@Column(name = "SHA3_384", jdbcType = "VARCHAR", length = 96)
@Pattern(regexp = "^[0-9a-fA-F]{96}$", message = "The SHA3-384 hash must be a valid 96 character HEX number")
@JsonView(JsonViews.MetadataTools.class)
private String sha3_384;

@Persistent
@Index(name = "COMPONENT_SHA3_512_IDX")
@Column(name = "SHA3_512", jdbcType = "VARCHAR", length = 128)
@Pattern(regexp = "^[0-9a-fA-F]{128}$", message = "The SHA3-512 hash must be a valid 128 character HEX number")
@JsonView(JsonViews.MetadataTools.class)
private String sha3_512;

@Persistent
@Index(name = "COMPONENT_BLAKE2B_256_IDX")
@Column(name = "BLAKE2B_256", jdbcType = "VARCHAR", length = 64)
@Pattern(regexp = RegexSequence.Definition.HASH_SHA256, message = "The BLAKE2b hash must be a valid 64 character HEX number")
@JsonView(JsonViews.MetadataTools.class)
private String blake2b_256;

@Persistent
@Index(name = "COMPONENT_BLAKE2B_384_IDX")
@Column(name = "BLAKE2B_384", jdbcType = "VARCHAR", length = 96)
@Pattern(regexp = RegexSequence.Definition.HASH_SHA384, message = "The BLAKE2b hash must be a valid 96 character HEX number")
@JsonView(JsonViews.MetadataTools.class)
private String blake2b_384;

@Persistent
@Index(name = "COMPONENT_BLAKE2B_512_IDX")
@Column(name = "BLAKE2B_512", jdbcType = "VARCHAR", length = 128)
@Pattern(regexp = RegexSequence.Definition.HASH_SHA512, message = "The BLAKE2b hash must be a valid 128 character HEX number")
@JsonView(JsonViews.MetadataTools.class)
private String blake2b_512;

@Persistent
@Index(name = "COMPONENT_BLAKE3_IDX")
@Column(name = "BLAKE3", jdbcType = "VARCHAR", length = 255)
@Pattern(regexp = RegexSequence.Definition.HEXADECIMAL, message = "The BLAKE3 hash must be a valid HEX number")
@JsonView(JsonViews.MetadataTools.class)
private String blake3;

@Persistent
Expand All @@ -248,6 +268,7 @@ public enum FetchGroup {
@Size(max = 255)
//Patterns obtained from https://csrc.nist.gov/schema/cpe/2.3/cpe-naming_2.3.xsd
@Pattern(regexp = "(cpe:2\\.3:[aho\\*\\-](:(((\\?*|\\*?)([a-zA-Z0-9\\-\\._]|(\\\\[\\\\\\*\\?!\"#$$%&'\\(\\)\\+,/:;<=>@\\[\\]\\^`\\{\\|}~]))+(\\?*|\\*?))|[\\*\\-])){5}(:(([a-zA-Z]{2,3}(-([a-zA-Z]{2}|[0-9]{3}))?)|[\\*\\-]))(:(((\\?*|\\*?)([a-zA-Z0-9\\-\\._]|(\\\\[\\\\\\*\\?!\"#$$%&'\\(\\)\\+,/:;<=>@\\[\\]\\^`\\{\\|}~]))+(\\?*|\\*?))|[\\*\\-])){4})|([c][pP][eE]:/[AHOaho]?(:[A-Za-z0-9\\._\\-~%]*){0,6})", message = "The CPE must conform to the CPE v2.2 or v2.3 specification defined by NIST")
@JsonView(JsonViews.MetadataTools.class)
private String cpe;

@Persistent(defaultFetchGroup = "true")
Expand All @@ -256,6 +277,7 @@ public enum FetchGroup {
@Size(max = 1024)
@com.github.packageurl.validator.PackageURL
@JsonDeserialize(using = TrimmedStringDeserializer.class)
@JsonView(JsonViews.MetadataTools.class)
private String purl;

@Persistent(defaultFetchGroup = "true")
Expand All @@ -270,6 +292,7 @@ public enum FetchGroup {
@Index(name = "COMPONENT_SWID_TAGID_IDX")
@Size(max = 255)
@Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The SWID tagId may only contain printable characters")
@JsonView(JsonViews.MetadataTools.class)
private String swidTagId;

@Persistent
Expand Down Expand Up @@ -323,6 +346,7 @@ public enum FetchGroup {
@Persistent(defaultFetchGroup = "true")
@Column(name = "EXTERNAL_REFERENCES")
@Serialized
@JsonView(JsonViews.MetadataTools.class)
private List<ExternalReference> externalReferences;

@Persistent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.dependencytrack.model;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonView;

import java.io.Serializable;

Expand Down Expand Up @@ -50,7 +51,10 @@ private Direction(String name) {
}
}

@JsonView(JsonViews.MetadataTools.class)
private Direction direction;

@JsonView(JsonViews.MetadataTools.class)
private String name;

public Direction getDirection() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import alpine.common.validation.RegexSequence;
import alpine.server.json.TrimmedStringDeserializer;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

import javax.validation.constraints.NotBlank;
Expand All @@ -38,14 +39,17 @@ public class ExternalReference implements Serializable {

private static final long serialVersionUID = -5885851731192037664L;

@JsonView(JsonViews.MetadataTools.class)
private org.cyclonedx.model.ExternalReference.Type type;

@NotBlank
@JsonDeserialize(using = TrimmedStringDeserializer.class)
@JsonView(JsonViews.MetadataTools.class)
private String url;

@JsonDeserialize(using = TrimmedStringDeserializer.class)
@Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The comment may only contain printable characters")
@JsonView(JsonViews.MetadataTools.class)
private String comment;

public org.cyclonedx.model.ExternalReference.Type getType() {
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/org/dependencytrack/model/JsonViews.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.dependencytrack.model;

import com.fasterxml.jackson.annotation.JsonView;

/**
* Marker interfaces to be used in conjunction with Jackson's {@link JsonView} annotation.
*/
public class JsonViews {

/**
* Marks fields to be included when (de-)serializing {@link Tools}.
*/
public interface MetadataTools {
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import alpine.server.json.TrimmedStringDeserializer;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

import java.io.Serializable;
Expand All @@ -37,12 +38,15 @@ public class OrganizationalContact implements Serializable {
private static final long serialVersionUID = -1026863376484187244L;

@JsonDeserialize(using = TrimmedStringDeserializer.class)
@JsonView(JsonViews.MetadataTools.class)
private String name;

@JsonDeserialize(using = TrimmedStringDeserializer.class)
@JsonView(JsonViews.MetadataTools.class)
private String email;

@JsonDeserialize(using = TrimmedStringDeserializer.class)
@JsonView(JsonViews.MetadataTools.class)
private String phone;

public String getName() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import alpine.server.json.TrimmedStringArrayDeserializer;
import alpine.server.json.TrimmedStringDeserializer;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

import java.io.Serializable;
Expand All @@ -41,11 +42,14 @@ public class OrganizationalEntity implements Serializable {
private static final long serialVersionUID = 5333594855427723634L;

@JsonDeserialize(using = TrimmedStringDeserializer.class)
@JsonView(JsonViews.MetadataTools.class)
private String name;

@JsonDeserialize(using = TrimmedStringArrayDeserializer.class)
@JsonView(JsonViews.MetadataTools.class)
private String[] urls;

@JsonView(JsonViews.MetadataTools.class)
private List<OrganizationalContact> contacts;

public String getName() {
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/org/dependencytrack/model/ProjectMetadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import org.dependencytrack.persistence.converter.OrganizationalContactsJsonConverter;
import org.dependencytrack.persistence.converter.OrganizationalEntityJsonConverter;
import org.dependencytrack.persistence.converter.ToolsJsonConverter;

import javax.jdo.annotations.Column;
import javax.jdo.annotations.Convert;
Expand Down Expand Up @@ -66,6 +67,11 @@ public class ProjectMetadata {
@Column(name = "AUTHORS", jdbcType = "CLOB", allowsNull = "true")
private List<OrganizationalContact> authors;

@Persistent(defaultFetchGroup = "true")
@Convert(ToolsJsonConverter.class)
@Column(name = "TOOLS", jdbcType = "CLOB", allowsNull = "true")
private Tools tools;

public long getId() {
return id;
}
Expand Down Expand Up @@ -98,4 +104,12 @@ public void setAuthors(final List<OrganizationalContact> authors) {
this.authors = authors;
}

public Tools getTools() {
return tools;
}

public void setTools(final Tools tools) {
this.tools = tools;
}

}
11 changes: 11 additions & 0 deletions src/main/java/org/dependencytrack/model/ServiceComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import alpine.server.json.TrimmedStringDeserializer;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

import javax.jdo.annotations.Column;
Expand Down Expand Up @@ -86,12 +87,14 @@ public enum FetchGroup {
@Persistent(defaultFetchGroup = "true")
@Column(name = "PROVIDER_ID")
@Serialized
@JsonView(JsonViews.MetadataTools.class)
private OrganizationalEntity provider;

@Persistent
@Column(name = "GROUP", jdbcType = "VARCHAR")
@Size(max = 255)
@Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The group may only contain printable characters")
@JsonView(JsonViews.MetadataTools.class)
private String group;

@Persistent
Expand All @@ -100,46 +103,54 @@ public enum FetchGroup {
@Size(min = 1, max = 255)
@JsonDeserialize(using = TrimmedStringDeserializer.class)
@Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The name may only contain printable characters")
@JsonView(JsonViews.MetadataTools.class)
private String name;

@Persistent
@Column(name = "VERSION", jdbcType = "VARCHAR")
@Size(max = 255)
@JsonDeserialize(using = TrimmedStringDeserializer.class)
@Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The version may only contain printable characters")
@JsonView(JsonViews.MetadataTools.class)
private String version;

@Persistent
@Column(name = "DESCRIPTION", jdbcType = "VARCHAR", length = 1024)
@Size(max = 1024)
@JsonDeserialize(using = TrimmedStringDeserializer.class)
@Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The description may only contain printable characters")
@JsonView(JsonViews.MetadataTools.class)
private String description;

@Persistent(defaultFetchGroup = "true")
@Serialized
@Column(name = "ENDPOINTS", jdbcType = "LONGVARBINARY")
@JsonDeserialize(using = TrimmedStringArrayDeserializer.class)
@JsonView(JsonViews.MetadataTools.class)
private String[] endpoints;

@Persistent
@Column(name = "AUTHENTICATED")
@JsonView(JsonViews.MetadataTools.class)
private Boolean authenticated;

@Persistent
@Column(name = "X_TRUST_BOUNDARY")
@JsonView(JsonViews.MetadataTools.class)
private Boolean crossesTrustBoundary;

@Persistent(defaultFetchGroup = "true")
@Column(name = "DATA")
@Serialized
@JsonView(JsonViews.MetadataTools.class)
private List<DataClassification> data;

//TODO add license support once Component license support is refactored

@Persistent(defaultFetchGroup = "true")
@Column(name = "EXTERNAL_REFERENCES")
@Serialized
@JsonView(JsonViews.MetadataTools.class)
private List<ExternalReference> externalReferences;

@Persistent
Expand Down
Loading

0 comments on commit 101b84b

Please sign in to comment.