mirror of
https://github.com/DependencyTrack/dependency-track.git
synced 2025-12-08 06:09:51 +00:00
Merge pull request #5574 from snieguu/5561
This commit is contained in:
commit
01847b79fd
3 changed files with 64 additions and 11 deletions
|
|
@ -33,6 +33,7 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import jakarta.json.JsonObject;
|
import jakarta.json.JsonObject;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class AbstractWebhookPublisher implements Publisher {
|
public abstract class AbstractWebhookPublisher implements Publisher {
|
||||||
|
|
@ -48,13 +49,13 @@ public abstract class AbstractWebhookPublisher implements Publisher {
|
||||||
final Logger logger = LoggerFactory.getLogger(getClass());
|
final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
if (config == null) {
|
if (config == null) {
|
||||||
logger.warn("No publisher configuration found; Skipping notification (%s)".formatted(ctx));
|
logger.warn("No publisher configuration found; Skipping notification ({})", ctx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String destination = getDestinationUrl(config);
|
final String destination = getDestinationUrl(config);
|
||||||
if (destination == null) {
|
if (destination == null) {
|
||||||
logger.warn("No destination configured; Skipping notification (%s)".formatted(ctx));
|
logger.warn("No destination configured; Skipping notification ({})", ctx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,7 +65,7 @@ public abstract class AbstractWebhookPublisher implements Publisher {
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
logger.warn("""
|
logger.warn("""
|
||||||
An error occurred during the retrieval of credentials needed for notification \
|
An error occurred during the retrieval of credentials needed for notification \
|
||||||
publication; Skipping notification (%s)""".formatted(ctx), e);
|
publication; Skipping notification ({})""", ctx, e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,19 +92,19 @@ public abstract class AbstractWebhookPublisher implements Publisher {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
request.setEntity(new StringEntity(content));
|
request.setEntity(new StringEntity(content, StandardCharsets.UTF_8));
|
||||||
try (final CloseableHttpResponse response = HttpClientPool.getClient().execute(request)) {
|
try (final CloseableHttpResponse response = HttpClientPool.getClient().execute(request)) {
|
||||||
final int statusCode = response.getStatusLine().getStatusCode();
|
final int statusCode = response.getStatusLine().getStatusCode();
|
||||||
if (statusCode < 200 || statusCode >= 300) {
|
if (statusCode < 200 || statusCode >= 300) {
|
||||||
logger.warn("Destination responded with with status code %d, likely indicating a processing failure (%s)"
|
logger.warn("Destination responded with with status code {}, likely indicating a processing failure ({})",
|
||||||
.formatted(statusCode, ctx));
|
statusCode, ctx);
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Response headers: %s".formatted((Object[]) response.getAllHeaders()));
|
logger.debug("Response headers: {}", (Object[]) response.getAllHeaders());
|
||||||
logger.debug("Response body: %s".formatted(EntityUtils.toString(response.getEntity())));
|
logger.debug("Response body: {}", EntityUtils.toString(response.getEntity()));
|
||||||
}
|
}
|
||||||
} else if (ctx.shouldLogSuccess()) {
|
} else if (ctx.shouldLogSuccess()) {
|
||||||
logger.info("Destination acknowledged reception of notification with status code %d (%s)"
|
logger.info("Destination acknowledged reception of notification with status code {} ({})",
|
||||||
.formatted(statusCode, ctx));
|
statusCode, ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
|
|
@ -136,7 +137,7 @@ public abstract class AbstractWebhookPublisher implements Publisher {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handleRequestException(final PublishContext ctx, final Logger logger, final Exception e) {
|
protected void handleRequestException(final PublishContext ctx, final Logger logger, final Exception e) {
|
||||||
logger.error("Failed to send notification request (%s)".formatted(ctx), e);
|
logger.error("Failed to send notification request ({})", ctx, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -267,6 +267,35 @@ abstract class AbstractPublisherTest<T extends Publisher> extends PersistenceCap
|
||||||
.withMessage("Unexpected tag name \"include\" ({% include '/some/path' %}:1)");
|
.withMessage("Unexpected tag name \"include\" ({% include '/some/path' %}:1)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void baseTestInformWithNewVulnerabilityCustomUTF8TemplateNotification() throws Exception {
|
||||||
|
final var project = createProject();
|
||||||
|
final var component = createComponent(project);
|
||||||
|
final var vuln = createVulnerability();
|
||||||
|
|
||||||
|
final var subject = new NewVulnerabilityIdentified(vuln, component, Set.of(project),
|
||||||
|
VulnerabilityAnalysisLevel.BOM_UPLOAD_ANALYSIS);
|
||||||
|
|
||||||
|
|
||||||
|
final var notification = new Notification()
|
||||||
|
.scope(NotificationScope.SYSTEM)
|
||||||
|
.group(NotificationGroup.NEW_VULNERABILITY)
|
||||||
|
.title(NotificationConstants.Title.NOTIFICATION_TEST)
|
||||||
|
.level(NotificationLevel.INFORMATIONAL)
|
||||||
|
.timestamp(LocalDateTime.ofEpochSecond(66666, 666, ZoneOffset.UTC))
|
||||||
|
.subject(subject);
|
||||||
|
|
||||||
|
final JsonObject defaultConfig = createConfig();
|
||||||
|
final String defaultTemplate = defaultConfig.getString(Publisher.CONFIG_TEMPLATE_KEY);
|
||||||
|
final String template = defaultTemplate.replaceAll("Vulnerability", "Vulnérabilité");
|
||||||
|
|
||||||
|
final JsonObject config = Json.createObjectBuilder(createConfig())
|
||||||
|
.add(Publisher.CONFIG_TEMPLATE_KEY, template)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThatNoException()
|
||||||
|
.isThrownBy(() -> publisherInstance.inform(PublishContext.from(notification), notification, config));
|
||||||
|
}
|
||||||
|
|
||||||
public final void baseTestPublishWithScheduledNewVulnerabilitiesNotification() {
|
public final void baseTestPublishWithScheduledNewVulnerabilitiesNotification() {
|
||||||
final var project = createProject();
|
final var project = createProject();
|
||||||
final var component = createComponent(project);
|
final var component = createComponent(project);
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,29 @@ class JiraPublisherTest extends AbstractWebhookPublisherTest<JiraPublisher> {
|
||||||
""")));
|
""")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInformWithNewVulnerabilityCustomUTF8TemplateNotification() throws Exception {
|
||||||
|
super.baseTestInformWithNewVulnerabilityCustomUTF8TemplateNotification();
|
||||||
|
|
||||||
|
verify(postRequestedFor(urlPathEqualTo("/rest/api/2/issue"))
|
||||||
|
.withHeader("Authorization", equalTo("Basic amlyYVVzZXI6amlyYVBhc3N3b3Jk"))
|
||||||
|
.withHeader("Content-Type", equalTo("application/json"))
|
||||||
|
.withRequestBody(equalToJson("""
|
||||||
|
{
|
||||||
|
"fields" : {
|
||||||
|
"project" : {
|
||||||
|
"key" : "PROJECT"
|
||||||
|
},
|
||||||
|
"issuetype" : {
|
||||||
|
"name" : "Task"
|
||||||
|
},
|
||||||
|
"summary" : "[Dependency-Track] [NEW_VULNERABILITY] [] New vulnerability identified: ",
|
||||||
|
"description" : "A new vulnerability has been identified on your project(s).\\n\\\\\\\\\\n\\\\\\\\\\n*Vulnérabilité description*\\n{code:none|bgColor=white|borderStyle=none}{code}\\n\\n*VulnID*\\n\\n\\n*Severity*\\n\\n\\n*Component*\\n[|https://example.com/components/]\\n\\n*Affected project(s)*\\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInformWithNewVulnerabilityNotification() {
|
public void testInformWithNewVulnerabilityNotification() {
|
||||||
super.baseTestInformWithNewVulnerabilityNotification();
|
super.baseTestInformWithNewVulnerabilityNotification();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue