Skip to content

Commit

Permalink
Merge pull request #430 from DependencyTrack/fix-published-at-cel-query
Browse files Browse the repository at this point in the history
Fix invalid SQL query when `published_at` field is required by CEL policy
  • Loading branch information
nscuro authored Nov 6, 2023
2 parents 140e315 + 69dda89 commit 51b9ea8
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -454,9 +454,7 @@ private static org.dependencytrack.proto.policy.v1.Component mapToProto(final Co
.setBlake2B384(trimToEmpty(projection.blake2b_384))
.setBlake2B512(trimToEmpty(projection.blake2b_512))
.setBlake3(trimToEmpty(projection.blake3));
if (projection.getPublishedAt() != null) {
componentBuilder.setPublishedAt(Timestamps.fromDate(projection.getPublishedAt())).build();
}
Optional.ofNullable(projection.publishedAt).map(Timestamps::fromDate).ifPresent(componentBuilder::setPublishedAt);

if (projection.resolvedLicenseId != null && projection.resolvedLicenseId > 0) {
final org.dependencytrack.proto.policy.v1.License protoLicense = protoLicenseById.get(projection.resolvedLicenseId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,30 @@ List<ComponentProjection> fetchAllComponents(final long projectId, final Collect
.map(mapping -> "\"C\".\"%s\" AS \"%s\"".formatted(mapping.sqlColumnName(), mapping.javaFieldName()))
.collect(Collectors.joining(", "));

if (protoFieldNames.contains("published_at")) {
sqlSelectColumns += ", \"publishedAt\"";
}

final Query<?> query = pm.newQuery(Query.SQL, """
SELECT %s , "IMC"."PUBLISHED_AT" AS "publishedAt" FROM "COMPONENT" "C" LEFT JOIN "INTEGRITY_META_COMPONENT" "IMC" ON "C"."PURL"="IMC"."PURL" WHERE "PROJECT_ID" = ?
SELECT
%s
FROM
"COMPONENT" AS "C"
LEFT JOIN LATERAL (
SELECT
"IMC"."PUBLISHED_AT" AS "publishedAt"
FROM
"INTEGRITY_META_COMPONENT" AS "IMC"
WHERE
"IMC"."PURL" = "C"."PURL"
) AS "metadata" ON :shouldFetchPublishedAt
WHERE
"PROJECT_ID" = :projectId
""".formatted(sqlSelectColumns));
query.setParameters(projectId);
query.setNamedParameters(Map.of(
"shouldFetchPublishedAt", protoFieldNames.contains("published_at"),
"projectId", projectId
));
try {
return List.copyOf(query.executeResultList(ComponentProjection.class));
} finally {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.List;
import java.util.concurrent.locks.Lock;

import static org.dependencytrack.policy.cel.CelPolicyLibrary.FUNC_COMPARE_AGE;
import static org.dependencytrack.policy.cel.CelPolicyLibrary.FUNC_DEPENDS_ON;
import static org.dependencytrack.policy.cel.CelPolicyLibrary.FUNC_IS_DEPENDENCY_OF;
import static org.dependencytrack.policy.cel.CelPolicyLibrary.FUNC_MATCHES_RANGE;
Expand Down Expand Up @@ -168,6 +169,11 @@ private static MultiValuedMap<Type, String> analyzeRequirements(final CheckedExp
requirements.put(TYPE_COMPONENT, "version");
}
}
case FUNC_COMPARE_AGE -> {
if (TYPE_COMPONENT.equals(functionSignature.targetType())) {
requirements.put(TYPE_COMPONENT, "published_at");
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import java.util.Date;

public class ComponentProjection {
public static FieldMapping ID_FIELD_MAPPING = new FieldMapping("id", /* protoFieldName */ null, "ID");

public static FieldMapping ID_FIELD_MAPPING = new FieldMapping("id", /* protoFieldName */ null, "ID");

public long id;

Expand Down Expand Up @@ -77,18 +77,9 @@ public class ComponentProjection {
@MappedField(protoFieldName = "license_name", sqlColumnName = "LICENSE")
public String licenseName;

public Date getPublishedAt() {
return publishedAt;
}

public void setPublishedAt(Date currentVersionLastModified) {
this.publishedAt = currentVersionLastModified;
}

@MappedField(protoFieldName = "published_at", sqlColumnName = "PUBLISHED_AT")
public Date publishedAt;

@MappedField(protoFieldName = "license_expression", sqlColumnName = "LICENSE_EXPRESSION")
public String licenseExpression;

public Date publishedAt;

}
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ public void testEvaluateProjectWithAllFields() {
component.setResolvedLicense(license);
qm.persist(component);

final var metaComponent = new IntegrityMetaComponent();
metaComponent.setPurl("componentPurl");
metaComponent.setPublishedAt(new java.util.Date(222));
metaComponent.setStatus(FetchStatus.PROCESSED);
metaComponent.setLastFetch(new Date());
qm.persist(metaComponent);

final var vuln = new Vulnerability();
vuln.setUuid(UUID.fromString("ffe9743f-b916-431e-8a68-9b3ac56db72c"));
vuln.setVulnId("CVE-001");
Expand Down Expand Up @@ -210,6 +217,7 @@ public void testEvaluateProjectWithAllFields() {
licenseGroup.uuid == "__LICENSE_GROUP_UUID__"
&& licenseGroup.name == "licenseGroupName"
)
&& component.published_at == timestamp("1970-01-01T00:00:00.222Z")
&& project.uuid == "__PROJECT_UUID__"
&& project.group == "projectGroup"
&& project.name == "projectName"
Expand Down

0 comments on commit 51b9ea8

Please sign in to comment.