Browse Source

SONAR-8351 limit number of webhooks to 10

tags/6.2-RC1
Simon Brandhof 7 years ago
parent
commit
fc8fa7830f

+ 2
- 0
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPostTask.java View File

@@ -33,6 +33,7 @@ import org.sonar.server.computation.task.projectanalysis.component.SettingsRepos
import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolder;

import static java.lang.String.format;
import static org.sonar.core.config.WebhookProperties.MAX_WEBHOOKS_PER_TYPE;

public class WebhookPostTask implements PostProjectAnalysisTask {

@@ -68,6 +69,7 @@ public class WebhookPostTask implements PostProjectAnalysisTask {
String[] webhookIds = settings.getStringArray(propertyKey);
return Arrays.stream(webhookIds)
.map(webhookId -> format("%s.%s", propertyKey, webhookId))
.limit(MAX_WEBHOOKS_PER_TYPE)
.collect(Collectors.toList(webhookIds.length));
}


+ 28
- 0
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/webhook/WebhookPostTaskTest.java View File

@@ -21,6 +21,8 @@ package org.sonar.server.computation.task.projectanalysis.webhook;

import java.io.IOException;
import java.util.Date;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.ce.posttask.CeTask;
@@ -85,6 +87,7 @@ public class WebhookPostTaskTest {
verify(deliveryStorage, times(2)).persist(any(WebhookDelivery.class));
verify(deliveryStorage).purge(PROJECT_UUID);
}

@Test
public void send_project_webhooks() {
settings.setProperty("sonar.webhooks.project", "1");
@@ -100,6 +103,31 @@ public class WebhookPostTaskTest {
verify(deliveryStorage).purge(PROJECT_UUID);
}

@Test
public void process_only_the_10_first_global_webhooks() {
testMaxWebhooks("sonar.webhooks.global");
}

@Test
public void process_only_the_10_first_project_webhooks() {
testMaxWebhooks("sonar.webhooks.project");
}

private void testMaxWebhooks(String property) {
IntStream.range(1, 15)
.forEach(i -> {
settings.setProperty(property + "." + i + ".name", "First");
settings.setProperty(property + "." + i + ".url", "http://url");
caller.enqueueSuccess(NOW, 200, 1_234);
});
settings.setProperty(property, IntStream.range(1, 15).mapToObj(String::valueOf).collect(Collectors.joining(",")));

execute();

assertThat(caller.countSent()).isEqualTo(10);
assertThat(logTester.logs(LoggerLevel.DEBUG).stream().filter(log -> log.contains("Sent"))).hasSize(10);
}

private void execute() {
SettingsRepository settingsRepository = new TestSettingsRepository(settings);
WebhookPostTask task = new WebhookPostTask(rootHolder, settingsRepository, caller, deliveryStorage);

+ 9
- 1
sonar-core/src/main/java/org/sonar/core/config/WebhookProperties.java View File

@@ -33,6 +33,13 @@ public class WebhookProperties {
public static final String NAME_FIELD = "name";
public static final String URL_FIELD = "url";

/**
* Maximum allowed number of webhooks per type (globally or per project).
* That is required to not become a DoS attacker, for instance
* if thousands of webhooks are configured.
*/
public static final long MAX_WEBHOOKS_PER_TYPE = 10;

/**
* Prefix of the properties to be automatically exported from scanner to payload
*/
@@ -40,7 +47,8 @@ public class WebhookProperties {

private static final String CATEGORY = "webhooks";
private static final String DESCRIPTION = "Webhooks are used to notify external services when a project analysis is done. " +
"A HTTP POST request including a JSON payload is sent to each of the provided URLs. " +
"A HTTP POST request including a JSON payload is sent to each of the provided URLs. <br/>" +
"Maximum " + MAX_WEBHOOKS_PER_TYPE + " webhooks are allowed. <br/>" +
"Learn more in the <a href=\"#\">Webhooks documentation</a>.";

private WebhookProperties() {

Loading…
Cancel
Save