Skip to content

Commit

Permalink
Merge pull request #493 from DependencyTrack/notification-regression
Browse files Browse the repository at this point in the history
Fix regression in `NEW_VULNERABILITY` and `NEW_VULNERABLE_DEPENDENCY` title & content
  • Loading branch information
nscuro authored Dec 18, 2023
2 parents 1ac8e4c + 0b10799 commit ca08224
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@
import static org.dependencytrack.proto.notification.v1.Scope.SCOPE_PORTFOLIO;
import static org.dependencytrack.proto.vulnanalysis.v1.ScanStatus.SCAN_STATUS_FAILED;
import static org.dependencytrack.proto.vulnanalysis.v1.Scanner.SCANNER_INTERNAL;
import static org.dependencytrack.util.NotificationUtil.generateNotificationContent;
import static org.dependencytrack.util.NotificationUtil.generateNotificationTitle;
import static org.dependencytrack.util.VulnerabilityUtil.canBeMirrored;
import static org.dependencytrack.util.VulnerabilityUtil.isAuthoritativeSource;
import static org.dependencytrack.util.VulnerabilityUtil.isMirroringEnabled;
Expand Down Expand Up @@ -634,6 +636,8 @@ private void maybeSendNotifications(final QueryManager qm, final Component compo
.setGroup(GROUP_NEW_VULNERABLE_DEPENDENCY)
.setLevel(LEVEL_INFORMATIONAL)
.setTimestamp(notificationTimestamp)
.setTitle(generateNotificationTitle(NotificationConstants.Title.NEW_VULNERABLE_DEPENDENCY, subject.getProject()))
.setContent(generateNotificationContent(subject.getComponent(), subject.getVulnerabilitiesList()))
.setSubject(Any.pack(subject))
.build())
.ifPresent(notifications::add);
Expand All @@ -645,6 +649,8 @@ private void maybeSendNotifications(final QueryManager qm, final Component compo
.setGroup(GROUP_NEW_VULNERABILITY)
.setLevel(LEVEL_INFORMATIONAL)
.setTimestamp(notificationTimestamp)
.setTitle(generateNotificationTitle(NotificationConstants.Title.NEW_VULNERABILITY, subject.getProject()))
.setContent(generateNotificationContent(subject.getVulnerability()))
.setSubject(Any.pack(subject))
.build())
.forEach(notifications::add);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ public interface NotificationSubjectDao {
) AS "vulnSeverity",
STRING_TO_ARRAY("V"."CWES", ',') AS "vulnCwes",
"vulnAliasesJson",
:vulnAnalysisLevel AS "vulnAnalysisLevel"
:vulnAnalysisLevel AS "vulnAnalysisLevel",
'/api/v1/vulnerability/source/' || "V"."SOURCE" || '/vuln/' || "V"."VULNID" || '/projects' AS "affectedProjectsApiUrl",
'/vulnerabilities/' || "V"."SOURCE" || '/' || "V"."VULNID" || '/affectedProjects' AS "affectedProjectsFrontendUrl"
FROM
"COMPONENT" AS "C"
INNER JOIN
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.dependencytrack.persistence.jdbi.mapping;

import org.dependencytrack.proto.notification.v1.BackReference;
import org.dependencytrack.proto.notification.v1.Component;
import org.dependencytrack.proto.notification.v1.NewVulnerabilitySubject;
import org.dependencytrack.proto.notification.v1.Project;
Expand All @@ -26,6 +27,12 @@ public NewVulnerabilitySubject map(final ResultSet rs, final StatementContext ct
.setVulnerability(vulnRowMapper.map(rs, ctx));
builder.addAffectedProjects(builder.getProject());
maybeSet(rs, "vulnAnalysisLevel", ResultSet::getString, builder::setVulnerabilityAnalysisLevel);
final BackReference.Builder backRefBuilder = BackReference.newBuilder();
maybeSet(rs, "affectedProjectsApiUrl", ResultSet::getString, backRefBuilder::setApiUri);
maybeSet(rs, "affectedProjectsFrontendUrl", ResultSet::getString, backRefBuilder::setFrontendUri);
if (backRefBuilder.hasApiUri() || backRefBuilder.hasFrontendUri()) {
builder.setAffectedProjectsReference(backRefBuilder);
}
return builder.build();
}

Expand Down
32 changes: 27 additions & 5 deletions src/main/java/org/dependencytrack/util/NotificationUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

Expand Down Expand Up @@ -386,12 +386,12 @@ public static void loadDefaultNotificationPublishers(QueryManager qm) throws IOE
}
}

public static String generateNotificationContent(final Vulnerability vulnerability) {
public static String generateNotificationContent(final org.dependencytrack.proto.notification.v1.Vulnerability vulnerability) {
final String content;
if (vulnerability.getDescription() != null) {
if (vulnerability.hasDescription()) {
content = vulnerability.getDescription();
} else {
content = (vulnerability.getTitle() != null) ? vulnerability.getVulnId() + ": " + vulnerability.getTitle() : vulnerability.getVulnId();
content = vulnerability.hasTitle() ? vulnerability.getVulnId() + ": " + vulnerability.getTitle() : vulnerability.getVulnId();
}
return content;
}
Expand All @@ -400,7 +400,8 @@ private static String generateNotificationContent(final PolicyViolation policyVi
return "A " + policyViolation.getType().name().toLowerCase() + " policy violation occurred";
}

public static String generateNotificationContent(final Component component, final Set<Vulnerability> vulnerabilities) {
public static String generateNotificationContent(final org.dependencytrack.proto.notification.v1.Component component,
final Collection<org.dependencytrack.proto.notification.v1.Vulnerability> vulnerabilities) {
final String content;
if (vulnerabilities.size() == 1) {
content = "A dependency was introduced that contains 1 known vulnerability";
Expand Down Expand Up @@ -431,6 +432,27 @@ public static String generateNotificationTitle(String messageType, Project proje
return messageType;
}

public static String generateNotificationTitle(final String messageType, final org.dependencytrack.proto.notification.v1.Project project) {
if (project == null) {
return messageType;
}

// Emulate Project#toString()
final String projectStr;
if (project.hasPurl()) {
projectStr = project.getPurl();
} else {
StringBuilder sb = new StringBuilder();
sb.append(project.getName());
if (project.hasVersion()) {
sb.append(" : ").append(project.getVersion());
}
projectStr = sb.toString();
}

return messageType + " on Project: [" + projectStr + "]";
}

private static void sendNotificationToKafka(UUID projectUuid, Notification notification) {
new KafkaEventDispatcher().dispatchAsync(projectUuid, notification);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,11 @@ public void testGetForNewVulnerabilities() {
"uuid": "${json-unit.matches:vulnUuid}",
"vulnId": "CVE-100"
},
"vulnerabilityAnalysisLevel": "BOM_UPLOAD_ANALYSIS"
"vulnerabilityAnalysisLevel": "BOM_UPLOAD_ANALYSIS",
"affectedProjectsReference": {
"apiUri": "/api/v1/vulnerability/source/NVD/vuln/CVE-100/projects",
"frontendUri": "/vulnerabilities/NVD/CVE-100/affectedProjects"
}
}
"""));
}
Expand Down Expand Up @@ -242,7 +246,11 @@ public void testGetForNewVulnerabilityWithAnalysisRatingOverwrite() throws Excep
"uuid": "${json-unit.matches:projectUuid}",
"name": "projectName"
}
]
],
"affectedProjectsReference": {
"apiUri": "/api/v1/vulnerability/source/NVD/vuln/CVE-100/projects",
"frontendUri": "/vulnerabilities/NVD/CVE-100/affectedProjects"
}
}
""");
}
Expand Down

0 comments on commit ca08224

Please sign in to comment.