findings = qm.getFindings(project);
- final InputStream inputStream = uploader.process(project, findings);
- uploader.upload(project, inputStream);
-
- verify(1, getRequestedFor(urlPathEqualTo("/api/v2/tests/")));
-
- verify(postRequestedFor(urlPathEqualTo("/api/v2/import-scan/"))
- .withHeader(HttpHeaders.AUTHORIZATION, equalTo("Token dojoApiKey"))
- .withAnyRequestBodyPart(aMultipart()
- .withName("file")
- .withBody(equalToJson("""
- {
- "version": "1.2",
- "meta": {
- "application": "Dependency-Track",
- "version": "${json-unit.any-string}",
- "timestamp": "${json-unit.any-string}"
- },
- "project": {
- "uuid": "${json-unit.any-string}",
- "name": "acme-app",
- "version": "1.0.0"
- },
- "findings": []
- }
- """, true, false))));
- }
-
- /**
- * Un-ignore this test to test the integration against a local DefectDojo deployment.
- *
- * Consult the documentation
- * for instructions on how to set it up.
- */
- @Test
- @Ignore
- public void testUploadIntegration() {
- final var baseUrl = "http://localhost:8080";
- final var apiKey = "";
- final var engagementId = "";
- final var globalReimport = false;
- final var projectReimport = false;
-
- qm.createConfigProperty(
- DEFECTDOJO_URL.getGroupName(),
- DEFECTDOJO_URL.getPropertyName(),
- baseUrl,
- DEFECTDOJO_URL.getPropertyType(),
- null
- );
- qm.createConfigProperty(
- DEFECTDOJO_API_KEY.getGroupName(),
- DEFECTDOJO_API_KEY.getPropertyName(),
- apiKey,
- DEFECTDOJO_API_KEY.getPropertyType(),
- null
- );
- qm.createConfigProperty(
- DEFECTDOJO_REIMPORT_ENABLED.getGroupName(),
- DEFECTDOJO_REIMPORT_ENABLED.getPropertyName(),
- Boolean.toString(globalReimport),
- DEFECTDOJO_REIMPORT_ENABLED.getPropertyType(),
- null
- );
-
- final var project = new Project();
- project.setName("acme-app");
- project.setVersion("1.0.0");
- qm.persist(project);
-
- final var component = new Component();
- component.setProject(project);
- component.setName("acme-lib");
- component.setVersion("1.2.3");
- qm.persist(component);
-
- final var vuln = new Vulnerability();
- vuln.setVulnId("INT-123");
- vuln.setSource(Vulnerability.Source.INTERNAL);
- vuln.setSeverity(Severity.HIGH);
- qm.persist(vuln);
-
- qm.addVulnerability(vuln, component, AnalyzerIdentity.INTERNAL_ANALYZER);
-
- qm.createProjectProperty(project, "integrations", "defectdojo.engagementId",
- engagementId, IConfigProperty.PropertyType.STRING, null);
- qm.createProjectProperty(project, "integrations", "defectdojo.reimport",
- Boolean.toString(projectReimport), IConfigProperty.PropertyType.BOOLEAN, null);
-
- final var uploader = new DefectDojoUploader();
- uploader.setQueryManager(qm);
-
- final List findings = qm.getFindings(project);
- final InputStream inputStream = uploader.process(project, findings);
- uploader.upload(project, inputStream);
- }
-
}
diff --git a/src/test/java/org/dependencytrack/model/ProjectTest.java b/src/test/java/org/dependencytrack/model/ProjectTest.java
index ed9fe924f4..9f1d5210e6 100644
--- a/src/test/java/org/dependencytrack/model/ProjectTest.java
+++ b/src/test/java/org/dependencytrack/model/ProjectTest.java
@@ -55,11 +55,9 @@ public void testProjectPersistActiveFieldDefaultsToTrue() {
project.setName("Example Project 1");
project.setDescription("Description 1");
project.setVersion("1.0");
- project.setActive(null);
Project persistedProject = qm.createProject(project, null, false);
- Assert.assertNotNull(persistedProject.isActive());
Assert.assertTrue(persistedProject.isActive());
}
}
diff --git a/src/test/java/org/dependencytrack/notification/NotificationRouterTest.java b/src/test/java/org/dependencytrack/notification/NotificationRouterTest.java
index 0ab6e2a3e7..78e1082715 100644
--- a/src/test/java/org/dependencytrack/notification/NotificationRouterTest.java
+++ b/src/test/java/org/dependencytrack/notification/NotificationRouterTest.java
@@ -99,7 +99,10 @@ public void testValidMatchingRule() {
Project affectedProject = qm.createProject("Test Project", null, "1.0", null, null, null, true, false);
Component affectedComponent = new Component();
affectedComponent.setProject(affectedProject);
- NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(new Vulnerability(), affectedComponent, null, null);
+ affectedComponent.setName("acme-lib");
+ qm.persist(affectedComponent);
+ NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(
+ new Vulnerability(), qm.detach(affectedComponent), null, null);
notification.setSubject(subject);
// Ok, let's test this
NotificationRouter router = new NotificationRouter();
@@ -130,7 +133,10 @@ public void testValidMatchingProjectLimitingRule() {
affectedProjects.add(project);
Component affectedComponent = new Component();
affectedComponent.setProject(project);
- NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(new Vulnerability(), affectedComponent, affectedProjects, null);
+ affectedComponent.setName("acme-lib");
+ qm.persist(affectedComponent);
+ NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(
+ new Vulnerability(), qm.detach(affectedComponent), qm.detach(affectedProjects), null);
notification.setSubject(subject);
// Ok, let's test this
NotificationRouter router = new NotificationRouter();
@@ -162,7 +168,10 @@ public void testValidNonMatchingProjectLimitingRule() {
affectedProjects.add(affectedProject);
Component affectedComponent = new Component();
affectedComponent.setProject(affectedProject);
- NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(new Vulnerability(), affectedComponent, affectedProjects, null);
+ affectedComponent.setName("acme-lib");
+ qm.persist(affectedComponent);
+ NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(
+ new Vulnerability(), qm.detach(affectedComponent), qm.detach(affectedProjects), null);
notification.setSubject(subject);
// Ok, let's test this
NotificationRouter router = new NotificationRouter();
@@ -188,7 +197,10 @@ public void testValidMatchingRuleAndPublisherInform() {
Project affectedProject = qm.createProject("Test Project", null, "1.0", null, null, null, true, false);
Component affectedComponent = new Component();
affectedComponent.setProject(affectedProject);
- NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(new Vulnerability(), affectedComponent, null, null);
+ affectedComponent.setName("acme-lib");
+ qm.persist(affectedComponent);
+ NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(
+ new Vulnerability(), qm.detach(affectedComponent), null, null);
notification.setSubject(subject);
// Ok, let's test this
NotificationRouter router = new NotificationRouter();
@@ -225,7 +237,10 @@ public void testValidMatchingProjectLimitingRuleAndPublisherInform() {
affectedProjects.add(secondProject);
Component affectedComponent = new Component();
affectedComponent.setProject(firstProject);
- NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(new Vulnerability(), affectedComponent, affectedProjects, null);
+ affectedComponent.setName("acme-lib");
+ qm.persist(affectedComponent);
+ NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(
+ new Vulnerability(), qm.detach(affectedComponent), qm.detach(affectedProjects), null);
notification.setSubject(subject);
// Ok, let's test this
NotificationRouter router = new NotificationRouter();
@@ -257,7 +272,10 @@ public void testValidNonMatchingRule() {
Project affectedProject = qm.createProject("Test Project 1", null, "1.0", null, null, null, true, false);
Component affectedComponent = new Component();
affectedComponent.setProject(affectedProject);
- NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(new Vulnerability(), affectedComponent, null, null);
+ affectedComponent.setName("acme-lib");
+ qm.persist(affectedComponent);
+ NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(
+ new Vulnerability(), qm.detach(affectedComponent), null, null);
notification.setSubject(subject);
// Ok, let's test this
NotificationRouter router = new NotificationRouter();
@@ -352,12 +370,12 @@ public void testNewVulnerabilityIdentifiedLimitedToProject() {
notification.setScope(NotificationScope.PORTFOLIO.name());
notification.setGroup(NotificationGroup.NEW_VULNERABILITY.name());
notification.setLevel(NotificationLevel.INFORMATIONAL);
- notification.setSubject(new NewVulnerabilityIdentified(null, componentB, Set.of(), null));
+ notification.setSubject(new NewVulnerabilityIdentified(null, qm.detach(componentB), Set.of(), null));
final var router = new NotificationRouter();
assertThat(router.resolveRules(PublishContext.from(notification), notification)).isEmpty();
- notification.setSubject(new NewVulnerabilityIdentified(null, componentA, Set.of(), null));
+ notification.setSubject(new NewVulnerabilityIdentified(null, qm.detach(componentA), Set.of(), null));
assertThat(router.resolveRules(PublishContext.from(notification), notification))
.satisfiesExactly(resolvedRule -> assertThat(resolvedRule.getName()).isEqualTo("Test Rule"));
}
@@ -386,12 +404,12 @@ public void testNewVulnerableDependencyLimitedToProject() {
notification.setScope(NotificationScope.PORTFOLIO.name());
notification.setGroup(NotificationGroup.NEW_VULNERABLE_DEPENDENCY.name());
notification.setLevel(NotificationLevel.INFORMATIONAL);
- notification.setSubject(new NewVulnerableDependency(componentB, null));
+ notification.setSubject(new NewVulnerableDependency(qm.detach(componentB), null));
final var router = new NotificationRouter();
assertThat(router.resolveRules(PublishContext.from(notification), notification)).isEmpty();
- notification.setSubject(new NewVulnerableDependency(componentA, null));
+ notification.setSubject(new NewVulnerableDependency(qm.detach(componentA), null));
assertThat(router.resolveRules(PublishContext.from(notification), notification))
.satisfiesExactly(resolvedRule -> assertThat(resolvedRule.getName()).isEqualTo("Test Rule"));
}
@@ -411,12 +429,12 @@ public void testBomConsumedOrProcessedLimitedToProject() {
notification.setScope(NotificationScope.PORTFOLIO.name());
notification.setGroup(NotificationGroup.BOM_CONSUMED.name());
notification.setLevel(NotificationLevel.INFORMATIONAL);
- notification.setSubject(new BomConsumedOrProcessed(projectB, "", Bom.Format.CYCLONEDX, ""));
+ notification.setSubject(new BomConsumedOrProcessed(qm.detach(projectB), "", Bom.Format.CYCLONEDX, ""));
final var router = new NotificationRouter();
assertThat(router.resolveRules(PublishContext.from(notification), notification)).isEmpty();
- notification.setSubject(new BomConsumedOrProcessed(projectA, "", Bom.Format.CYCLONEDX, ""));
+ notification.setSubject(new BomConsumedOrProcessed(qm.detach(projectA), "", Bom.Format.CYCLONEDX, ""));
assertThat(router.resolveRules(PublishContext.from(notification), notification))
.satisfiesExactly(resolvedRule -> assertThat(resolvedRule.getName()).isEqualTo("Test Rule"));
}
@@ -436,12 +454,12 @@ public void testBomProcessingFailedLimitedToProject() {
notification.setScope(NotificationScope.PORTFOLIO.name());
notification.setGroup(NotificationGroup.BOM_PROCESSING_FAILED.name());
notification.setLevel(NotificationLevel.INFORMATIONAL);
- notification.setSubject(new BomProcessingFailed(projectB, "", null, Bom.Format.CYCLONEDX, ""));
+ notification.setSubject(new BomProcessingFailed(qm.detach(projectB), "", null, Bom.Format.CYCLONEDX, ""));
final var router = new NotificationRouter();
assertThat(router.resolveRules(PublishContext.from(notification), notification)).isEmpty();
- notification.setSubject(new BomProcessingFailed(projectA, "", null, Bom.Format.CYCLONEDX, ""));
+ notification.setSubject(new BomProcessingFailed(qm.detach(projectA), "", null, Bom.Format.CYCLONEDX, ""));
assertThat(router.resolveRules(PublishContext.from(notification), notification))
.satisfiesExactly(resolvedRule -> assertThat(resolvedRule.getName()).isEqualTo("Test Rule"));
}
@@ -461,12 +479,12 @@ public void testBomValidationFailedLimitedToProject() {
notification.setScope(NotificationScope.PORTFOLIO.name());
notification.setGroup(NotificationGroup.BOM_VALIDATION_FAILED.name());
notification.setLevel(NotificationLevel.ERROR);
- notification.setSubject(new BomValidationFailed(projectB, "", null, Bom.Format.CYCLONEDX));
+ notification.setSubject(new BomValidationFailed(qm.detach(projectB), "", null, Bom.Format.CYCLONEDX));
final var router = new NotificationRouter();
assertThat(router.resolveRules(PublishContext.from(notification), notification)).isEmpty();
- notification.setSubject(new BomValidationFailed(projectA, "", null, Bom.Format.CYCLONEDX));
+ notification.setSubject(new BomValidationFailed(qm.detach(projectA), "", null, Bom.Format.CYCLONEDX));
assertThat(router.resolveRules(PublishContext.from(notification), notification))
.satisfiesExactly(resolvedRule -> assertThat(resolvedRule.getName()).isEqualTo("Test Rule"));
}
@@ -486,12 +504,12 @@ public void testVexConsumedOrProcessedLimitedToProject() {
notification.setScope(NotificationScope.PORTFOLIO.name());
notification.setGroup(NotificationGroup.VEX_CONSUMED.name());
notification.setLevel(NotificationLevel.INFORMATIONAL);
- notification.setSubject(new VexConsumedOrProcessed(projectB, "", Vex.Format.CYCLONEDX, ""));
+ notification.setSubject(new VexConsumedOrProcessed(qm.detach(projectB), "", Vex.Format.CYCLONEDX, ""));
final var router = new NotificationRouter();
assertThat(router.resolveRules(PublishContext.from(notification), notification)).isEmpty();
- notification.setSubject(new VexConsumedOrProcessed(projectA, "", Vex.Format.CYCLONEDX, ""));
+ notification.setSubject(new VexConsumedOrProcessed(qm.detach(projectA), "", Vex.Format.CYCLONEDX, ""));
assertThat(router.resolveRules(PublishContext.from(notification), notification))
.satisfiesExactly(resolvedRule -> assertThat(resolvedRule.getName()).isEqualTo("Test Rule"));
}
@@ -525,7 +543,7 @@ public void testPolicyViolationIdentifiedLimitedToProject() {
final var router = new NotificationRouter();
assertThat(router.resolveRules(PublishContext.from(notification), notification)).isEmpty();
- notification.setSubject(new PolicyViolationIdentified(null, componentA, projectA));
+ notification.setSubject(new PolicyViolationIdentified(null, qm.detach(componentA), projectA));
assertThat(router.resolveRules(PublishContext.from(notification), notification))
.satisfiesExactly(resolvedRule -> assertThat(resolvedRule.getName()).isEqualTo("Test Rule"));
}
@@ -545,7 +563,7 @@ public void testAnalysisDecisionChangeLimitedToProject() {
notification.setScope(NotificationScope.PORTFOLIO.name());
notification.setGroup(NotificationGroup.PROJECT_AUDIT_CHANGE.name());
notification.setLevel(NotificationLevel.INFORMATIONAL);
- notification.setSubject(new AnalysisDecisionChange(null, null, projectB, null));
+ notification.setSubject(new AnalysisDecisionChange(null, null, qm.detach(projectB), null));
final var router = new NotificationRouter();
assertThat(router.resolveRules(PublishContext.from(notification), notification)).isEmpty();
@@ -579,7 +597,7 @@ public void testViolationAnalysisDecisionChangeLimitedToProject() {
notification.setScope(NotificationScope.PORTFOLIO.name());
notification.setGroup(NotificationGroup.PROJECT_AUDIT_CHANGE.name());
notification.setLevel(NotificationLevel.INFORMATIONAL);
- notification.setSubject(new ViolationAnalysisDecisionChange(null, componentB, null));
+ notification.setSubject(new ViolationAnalysisDecisionChange(null, qm.detach(componentB), null));
final var router = new NotificationRouter();
assertThat(router.resolveRules(PublishContext.from(notification), notification)).isEmpty();
@@ -608,6 +626,8 @@ public void testAffectedChild() {
// Creates a new component
Component component = new Component();
component.setProject(grandChild);
+ component.setName("acme-lib");
+ qm.persist(component);
// Creates a new notification
Notification notification = new Notification();
notification.setScope(NotificationScope.PORTFOLIO.name());
@@ -616,7 +636,8 @@ public void testAffectedChild() {
// Notification should be limited to only specific projects - Set the projects which are affected by the notification event
Set affectedProjects = new HashSet<>();
affectedProjects.add(grandChild);
- NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(new Vulnerability(), component, affectedProjects, null);
+ NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(
+ new Vulnerability(), qm.detach(component), qm.detach(affectedProjects), null);
notification.setSubject(subject);
// Ok, let's test this
NotificationRouter router = new NotificationRouter();
@@ -645,6 +666,8 @@ public void testAffectedChildNotifyChildrenDisabled() {
// Creates a new component
Component component = new Component();
component.setProject(grandChild);
+ component.setName("acme-lib");
+ qm.persist(component);
// Creates a new notification
Notification notification = new Notification();
notification.setScope(NotificationScope.PORTFOLIO.name());
@@ -653,7 +676,8 @@ public void testAffectedChildNotifyChildrenDisabled() {
// Notification should be limited to only specific projects - Set the projects which are affected by the notification event
Set affectedProjects = new HashSet<>();
affectedProjects.add(grandChild);
- NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(new Vulnerability(), component, affectedProjects, null);
+ NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(
+ new Vulnerability(), qm.detach(component), qm.detach(affectedProjects), null);
notification.setSubject(subject);
// Ok, let's test this
NotificationRouter router = new NotificationRouter();
@@ -681,6 +705,8 @@ public void testAffectedInactiveChild() {
// Creates a new component
Component component = new Component();
component.setProject(grandChild);
+ component.setName("acme-lib");
+ qm.persist(component);
// Creates a new notification
Notification notification = new Notification();
notification.setScope(NotificationScope.PORTFOLIO.name());
@@ -689,7 +715,8 @@ public void testAffectedInactiveChild() {
// Notification should be limited to only specific projects - Set the projects which are affected by the notification event
Set affectedProjects = new HashSet<>();
affectedProjects.add(grandChild);
- NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(new Vulnerability(), component, affectedProjects, null);
+ NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(
+ new Vulnerability(), qm.detach(component), qm.detach(affectedProjects), null);
notification.setSubject(subject);
// Ok, let's test this
NotificationRouter router = new NotificationRouter();
@@ -698,43 +725,6 @@ public void testAffectedInactiveChild() {
Assert.assertEquals(0, rules.size());
}
- @Test
- public void testAffectedActiveNullChild() {
- NotificationPublisher publisher = createSlackPublisher();
- // Creates a new rule and defines when the rule should be triggered (notifyOn)
- NotificationRule rule = qm.createNotificationRule("Matching Test Rule", NotificationScope.PORTFOLIO, NotificationLevel.INFORMATIONAL, publisher);
- Set notifyOn = new HashSet<>();
- notifyOn.add(NotificationGroup.NEW_VULNERABILITY);
- rule.setNotifyOn(notifyOn);
- // Creates a project which will later be matched on
- List projects = new ArrayList<>();
- Project grandParent = qm.createProject("Test Project Grandparent", null, "1.0", null, null, null, true, false);
- Project parent = qm.createProject("Test Project Parent", null, "1.0", null, grandParent, null, true, false);
- Project child = qm.createProject("Test Project Child", null, "1.0", null, parent, null, true, false);
- Project grandChild = qm.createProject("Test Project Grandchild", null, "1.0", null, child, null, true, false);
- grandChild.setActive(null); // https://github.com/DependencyTrack/dependency-track/issues/3296
- projects.add(grandParent);
- rule.setProjects(projects);
- // Creates a new component
- Component component = new Component();
- component.setProject(grandChild);
- // Creates a new notification
- Notification notification = new Notification();
- notification.setScope(NotificationScope.PORTFOLIO.name());
- notification.setGroup(NotificationGroup.NEW_VULNERABILITY.name());
- notification.setLevel(NotificationLevel.INFORMATIONAL);
- // Notification should be limited to only specific projects - Set the projects which are affected by the notification event
- Set affectedProjects = new HashSet<>();
- affectedProjects.add(grandChild);
- NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(new Vulnerability(), component, affectedProjects, null);
- notification.setSubject(subject);
- // Ok, let's test this
- NotificationRouter router = new NotificationRouter();
- List rules = router.resolveRules(PublishContext.from(notification), notification);
- Assert.assertTrue(rule.isNotifyChildren());
- Assert.assertEquals(1, rules.size());
- }
-
@Test
public void testValidMatchingTagLimitingRule() {
NotificationPublisher publisher = createSlackPublisher();
@@ -758,7 +748,10 @@ public void testValidMatchingTagLimitingRule() {
affectedProjects.add(project);
Component affectedComponent = new Component();
affectedComponent.setProject(project);
- NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(new Vulnerability(), affectedComponent, affectedProjects, null);
+ affectedComponent.setName("acme-lib");
+ qm.persist(affectedComponent);
+ NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(
+ new Vulnerability(), qm.detach(affectedComponent), qm.detach(affectedProjects), null);
notification.setSubject(subject);
// Ok, let's test this
NotificationRouter router = new NotificationRouter();
@@ -791,7 +784,10 @@ public void testValidNonMatchingTagLimitingRule() {
affectedProjects.add(affectedProject);
Component affectedComponent = new Component();
affectedComponent.setProject(affectedProject);
- NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(new Vulnerability(), affectedComponent, affectedProjects, null);
+ affectedComponent.setName("acme-lib");
+ qm.persist(affectedComponent);
+ NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(
+ new Vulnerability(), qm.detach(affectedComponent), qm.detach(affectedProjects), null);
notification.setSubject(subject);
// Ok, let's test this
NotificationRouter router = new NotificationRouter();
@@ -828,7 +824,10 @@ public void testValidMatchingProjectAndTagLimitingRule() {
affectedProjects.add(otherAffectedProject);
Component affectedComponent = new Component();
affectedComponent.setProject(taggedProject);
- NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(new Vulnerability(), affectedComponent, affectedProjects, null);
+ affectedComponent.setName("acme-lib");
+ qm.persist(affectedComponent);
+ NewVulnerabilityIdentified subject = new NewVulnerabilityIdentified(
+ new Vulnerability(), qm.detach(affectedComponent), qm.detach(affectedProjects), null);
notification.setSubject(subject);
// Ok, let's test this
NotificationRouter router = new NotificationRouter();
diff --git a/src/test/java/org/dependencytrack/notification/publisher/AbstractPublisherTest.java b/src/test/java/org/dependencytrack/notification/publisher/AbstractPublisherTest.java
index cba787320c..139fd44260 100644
--- a/src/test/java/org/dependencytrack/notification/publisher/AbstractPublisherTest.java
+++ b/src/test/java/org/dependencytrack/notification/publisher/AbstractPublisherTest.java
@@ -20,6 +20,7 @@
import alpine.notification.Notification;
import alpine.notification.NotificationLevel;
+import io.pebbletemplates.pebble.error.ParserException;
import org.apache.commons.io.IOUtils;
import org.dependencytrack.PersistenceCapableTest;
import org.dependencytrack.model.Analysis;
@@ -39,7 +40,6 @@
import org.dependencytrack.notification.vo.BomProcessingFailed;
import org.dependencytrack.notification.vo.BomValidationFailed;
import org.dependencytrack.notification.vo.NewVulnerabilityIdentified;
-import org.dependencytrack.resources.v1.problems.InvalidBomProblemDetails;
import org.dependencytrack.notification.vo.NewVulnerableDependency;
import org.junit.Test;
@@ -54,6 +54,7 @@
import java.util.UUID;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatNoException;
public abstract class AbstractPublisherTest extends PersistenceCapableTest {
@@ -229,6 +230,24 @@ public void testInformWithEscapedData() {
.isThrownBy(() -> publisherInstance.inform(PublishContext.from(notification), notification, createConfig()));
}
+ @Test
+ public void testInformWithTemplateInclude() throws Exception {
+ final var notification = new Notification()
+ .scope(NotificationScope.SYSTEM)
+ .group(NotificationGroup.ANALYZER)
+ .title(NotificationConstants.Title.NOTIFICATION_TEST)
+ .level(NotificationLevel.ERROR)
+ .timestamp(LocalDateTime.ofEpochSecond(66666, 666, ZoneOffset.UTC));
+
+ final JsonObject config = Json.createObjectBuilder(createConfig())
+ .add(Publisher.CONFIG_TEMPLATE_KEY, "{% include '/some/path' %}")
+ .build();
+
+ assertThatExceptionOfType(ParserException.class)
+ .isThrownBy(() -> publisherInstance.inform(PublishContext.from(notification), notification, config))
+ .withMessage("Unexpected tag name \"include\" ({% include '/some/path' %}:1)");
+ }
+
private static Component createComponent(final Project project) {
final var component = new Component();
component.setProject(project);
@@ -287,7 +306,7 @@ private static Analysis createAnalysis(final Component component, final Vulnerab
return analysis;
}
- private JsonObject createConfig() throws Exception {
+ JsonObject createConfig() throws Exception {
return Json.createObjectBuilder()
.add(Publisher.CONFIG_TEMPLATE_MIME_TYPE_KEY, publisher.getTemplateMimeType())
.add(Publisher.CONFIG_TEMPLATE_KEY, IOUtils.resourceToString(publisher.getPublisherTemplateFile(), UTF_8))
diff --git a/src/test/java/org/dependencytrack/notification/publisher/SendMailPublisherTest.java b/src/test/java/org/dependencytrack/notification/publisher/SendMailPublisherTest.java
index 1388ac4540..aebe11f7ae 100644
--- a/src/test/java/org/dependencytrack/notification/publisher/SendMailPublisherTest.java
+++ b/src/test/java/org/dependencytrack/notification/publisher/SendMailPublisherTest.java
@@ -4,9 +4,14 @@
import alpine.model.ManagedUser;
import alpine.model.OidcUser;
import alpine.model.Team;
+import alpine.notification.Notification;
+import alpine.notification.NotificationLevel;
import alpine.security.crypto.DataEncryption;
import com.icegreen.greenmail.junit4.GreenMailRule;
import com.icegreen.greenmail.util.ServerSetup;
+import org.dependencytrack.notification.NotificationConstants;
+import org.dependencytrack.notification.NotificationGroup;
+import org.dependencytrack.notification.NotificationScope;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
@@ -17,11 +22,14 @@
import jakarta.json.JsonObjectBuilder;
import jakarta.mail.internet.MimeBodyPart;
import jakarta.mail.internet.MimeMultipart;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import static com.icegreen.greenmail.configuration.GreenMailConfiguration.aConfig;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatNoException;
import static org.dependencytrack.model.ConfigPropertyConstants.EMAIL_PREFIX;
import static org.dependencytrack.model.ConfigPropertyConstants.EMAIL_SMTP_ENABLED;
import static org.dependencytrack.model.ConfigPropertyConstants.EMAIL_SMTP_FROM_ADDR;
@@ -426,6 +434,28 @@ public void testInformWithEscapedData() {
}
+ @Override
+ public void testInformWithTemplateInclude() throws Exception {
+ final var notification = new Notification()
+ .scope(NotificationScope.SYSTEM)
+ .group(NotificationGroup.ANALYZER)
+ .title(NotificationConstants.Title.NOTIFICATION_TEST)
+ .level(NotificationLevel.ERROR)
+ .timestamp(LocalDateTime.ofEpochSecond(66666, 666, ZoneOffset.UTC));
+
+ final JsonObject config = Json.createObjectBuilder(createConfig())
+ .add(Publisher.CONFIG_TEMPLATE_KEY, "{% include '/etc/passwd' %}")
+ .build();
+
+ // NB: In contrast to other publishers, SendMailPublisher catches and logs
+ // failures during template evaluation. Instead of expecting an exception
+ // being thrown, we verify that no email was sent.
+ assertThatNoException()
+ .isThrownBy(() -> publisherInstance.inform(PublishContext.from(notification), notification, config));
+
+ assertThat(greenMail.getReceivedMessages()).isEmpty();
+ }
+
@Override
JsonObjectBuilder extraConfig() {
return super.extraConfig()
diff --git a/src/test/java/org/dependencytrack/parser/github/GitHubSecurityAdvisoryParserTest.java b/src/test/java/org/dependencytrack/parser/github/GitHubSecurityAdvisoryParserTest.java
deleted file mode 100644
index 617978af9c..0000000000
--- a/src/test/java/org/dependencytrack/parser/github/GitHubSecurityAdvisoryParserTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.dependencytrack.parser.github;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.List;
-
-import org.dependencytrack.parser.github.graphql.GitHubSecurityAdvisoryParser;
-import org.dependencytrack.parser.github.graphql.model.GitHubSecurityAdvisory;
-import org.json.JSONObject;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class GitHubSecurityAdvisoryParserTest {
-
- GitHubSecurityAdvisoryParser parser = new GitHubSecurityAdvisoryParser();
-
- @Test
- public void testWithdrawnAdvisory() throws IOException {
-
- String jsonFile = "src/test/resources/unit/github.jsons/GHSA-8v27-2fg9-7h62.json";
- String jsonString = new String(Files.readAllBytes(Paths.get(jsonFile)));
- JSONObject jsonObject = new JSONObject(jsonString);
- List advisories = parser.parse(jsonObject).getAdvisories();
- Assert.assertEquals(0, advisories.size());
- }
-
-}
diff --git a/src/test/java/org/dependencytrack/parser/vulndb/VulnDbParserTest.java b/src/test/java/org/dependencytrack/parser/vulndb/VulnDbParserTest.java
new file mode 100644
index 0000000000..253a352388
--- /dev/null
+++ b/src/test/java/org/dependencytrack/parser/vulndb/VulnDbParserTest.java
@@ -0,0 +1,42 @@
+/*
+ * This file is part of Dependency-Track.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * Copyright (c) OWASP Foundation. All Rights Reserved.
+ */
+package org.dependencytrack.parser.vulndb;
+
+import org.dependencytrack.model.Vulnerability;
+import org.dependencytrack.parser.vulndb.model.Results;
+import org.junit.Test;
+
+import java.io.File;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class VulnDbParserTest {
+
+ @Test
+ public void test() throws Exception {
+ String filePath = "src/test/resources/unit/vulndb.jsons/vulnerabilities_0.json";
+ File file = new File(filePath);
+ final VulnDbParser parser = new VulnDbParser();
+ final Results results = parser.parse(file, org.dependencytrack.parser.vulndb.model.Vulnerability.class);
+ final List