This is an automated email from the ASF dual-hosted git repository.
rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
The following commit(s) were added to refs/heads/master by this push:
new 920c19b0e8 JAMES-3897: Implement CrowdsecHttpClient (#1788)
920c19b0e8 is described below
commit 920c19b0e8268223171d3d2958c97a85d224fcc3
Author: vtbui <[email protected]>
AuthorDate: Mon Nov 27 11:19:42 2023 +0700
JAMES-3897: Implement CrowdsecHttpClient (#1788)
---
third-party/crowdsec/pom.xml | 57 +++++----
.../sample-configuration/crowdsec.properties | 2 +
.../sample-configuration/extensions.properties | 1 +
.../james/model/CrowdsecClientConfiguration.java | 61 ++++++++++
.../org/apache/james/model/CrowdsecDecision.java | 28 +++++
.../org/apache/james/model/CrowdsecHttpClient.java | 96 ++++++++++++++++
.../org/apache/james/module/CrowdsecModule.java | 46 ++++++++
.../james/CrowdsecDecisionDeserializerTest.java | 51 ++++++++
.../java/org/apache/james/CrowdsecExtension.java | 5 +-
.../org/apache/james/CrowdsecHttpClientTest.java | 128 +++++++++++++++++++++
10 files changed, 453 insertions(+), 22 deletions(-)
diff --git a/third-party/crowdsec/pom.xml b/third-party/crowdsec/pom.xml
index 65f039d456..b839b1ba6f 100644
--- a/third-party/crowdsec/pom.xml
+++ b/third-party/crowdsec/pom.xml
@@ -25,13 +25,9 @@
<version>3.9.0-SNAPSHOT</version>
</parent>
- <artifactId>crowdsec</artifactId>
+ <artifactId>apache-james-crowdsec</artifactId>
<name>Apache James :: Third Party :: Crowdsec</name>
- <description>Crowdsec Java client (HTTP) and testing
utilities</description>
-
- <properties>
- <james.baseVersion>${project.version}</james.baseVersion>
- </properties>
+ <description>Crowdsec extension for Apache James</description>
<dependencies>
<dependency>
@@ -41,45 +37,65 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
+ <groupId>${james.groupId}</groupId>
+ <artifactId>james-server-guice-configuration</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
+ <artifactId>testing-base</artifactId>
+ <scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
- <scope>test</scope>
+ <scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.fge</groupId>
<artifactId>throwing-lambdas</artifactId>
+ <scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
+ <scope>provided</scope>
</dependency>
<dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-configuration2</artifactId>
+ <groupId>com.google.inject</groupId>
+ <artifactId>guice</artifactId>
+ <scope>provided</scope>
</dependency>
<dependency>
- <groupId>org.apache.james</groupId>
- <artifactId>james-server-testing</artifactId>
- <scope>test</scope>
+ <groupId>io.projectreactor.netty</groupId>
+ <artifactId>reactor-netty-http</artifactId>
+ <scope>provided</scope>
</dependency>
<dependency>
- <groupId>org.assertj</groupId>
- <artifactId>assertj-core</artifactId>
- <scope>test</scope>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-configuration2</artifactId>
+ <scope>provided</scope>
</dependency>
<dependency>
- <groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter</artifactId>
- <version>RELEASE</version>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.james</groupId>
+ <artifactId>james-server-testing</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
+ <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
@@ -87,5 +103,4 @@
<scope>test</scope>
</dependency>
</dependencies>
-
</project>
diff --git a/third-party/crowdsec/sample-configuration/crowdsec.properties
b/third-party/crowdsec/sample-configuration/crowdsec.properties
new file mode 100644
index 0000000000..ce0863c4a0
--- /dev/null
+++ b/third-party/crowdsec/sample-configuration/crowdsec.properties
@@ -0,0 +1,2 @@
+crowdsecUrl=http://127.0.0.1:8082/v1
+apiKey=default_api_key
\ No newline at end of file
diff --git a/third-party/crowdsec/sample-configuration/extensions.properties
b/third-party/crowdsec/sample-configuration/extensions.properties
new file mode 100644
index 0000000000..e17656b5f7
--- /dev/null
+++ b/third-party/crowdsec/sample-configuration/extensions.properties
@@ -0,0 +1 @@
+guice.extension.module=org.apache.james.module.CrowdsecModule
\ No newline at end of file
diff --git
a/third-party/crowdsec/src/main/java/org/apache/james/model/CrowdsecClientConfiguration.java
b/third-party/crowdsec/src/main/java/org/apache/james/model/CrowdsecClientConfiguration.java
new file mode 100644
index 0000000000..31ffc89c9f
--- /dev/null
+++
b/third-party/crowdsec/src/main/java/org/apache/james/model/CrowdsecClientConfiguration.java
@@ -0,0 +1,61 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you 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. *
+ ****************************************************************/
+
+package org.apache.james.model;
+
+import java.net.URL;
+import java.time.Duration;
+import java.util.Optional;
+
+import org.apache.commons.configuration2.Configuration;
+
+import com.github.fge.lambdas.Throwing;
+
+
+public class CrowdsecClientConfiguration {
+ public static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(5L);
+ public static final String DEFAULT_API_KEY = "default_api_key";
+
+ private final URL url;
+ private final String apiKey;
+
+ public static CrowdsecClientConfiguration from(Configuration config) {
+ URL crowdsecUrl = Optional.ofNullable(config.getString("crowdsecUrl",
null))
+ .filter(s -> !s.isEmpty())
+ .map(Throwing.function(URL::new))
+ .orElseThrow(() -> new IllegalArgumentException("Crowdsec's url is
invalid."));
+
+ String apiKey = Optional.of(config.getString("apiKey"))
+ .orElseThrow(() -> new IllegalArgumentException("Missing
apiKey!"));
+ return new CrowdsecClientConfiguration(crowdsecUrl, apiKey);
+ }
+
+ public CrowdsecClientConfiguration(URL url, String apiKey) {
+ this.url = url;
+ this.apiKey = apiKey;
+ }
+
+ public URL getUrl() {
+ return this.url;
+ }
+
+ public String getApiKey() {
+ return this.apiKey;
+ }
+}
diff --git
a/third-party/crowdsec/src/main/java/org/apache/james/model/CrowdsecDecision.java
b/third-party/crowdsec/src/main/java/org/apache/james/model/CrowdsecDecision.java
index b3a3f2ea7c..c5d10efc3f 100644
---
a/third-party/crowdsec/src/main/java/org/apache/james/model/CrowdsecDecision.java
+++
b/third-party/crowdsec/src/main/java/org/apache/james/model/CrowdsecDecision.java
@@ -57,6 +57,34 @@ public class CrowdsecDecision {
this.duration = duration;
}
+ public Duration getDuration() {
+ return duration;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public String getOrigin() {
+ return origin;
+ }
+
+ public String getScenario() {
+ return scenario;
+ }
+
+ public String getScope() {
+ return scope;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
public final boolean equals(Object o) {
if (!(o instanceof CrowdsecDecision)) {
return false;
diff --git
a/third-party/crowdsec/src/main/java/org/apache/james/model/CrowdsecHttpClient.java
b/third-party/crowdsec/src/main/java/org/apache/james/model/CrowdsecHttpClient.java
new file mode 100644
index 0000000000..e537d158d1
--- /dev/null
+++
b/third-party/crowdsec/src/main/java/org/apache/james/model/CrowdsecHttpClient.java
@@ -0,0 +1,96 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you 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. *
+ ****************************************************************/
+
+package org.apache.james.model;
+
+import static
org.apache.james.model.CrowdsecClientConfiguration.DEFAULT_TIMEOUT;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.http.HttpStatus;
+import org.apache.http.entity.ContentType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+import com.google.common.collect.ImmutableList;
+
+import io.netty.handler.codec.http.HttpHeaderNames;
+import reactor.core.publisher.Mono;
+import reactor.netty.http.client.HttpClient;
+
+public class CrowdsecHttpClient {
+ private static final Logger LOGGER =
LoggerFactory.getLogger(CrowdsecHttpClient.class);
+ private static final String GET_DECISION = "/decisions";
+
+ private final HttpClient httpClient;
+ private final ObjectMapper mapper;
+
+ @Inject
+ public CrowdsecHttpClient(CrowdsecClientConfiguration configuration) {
+ this.httpClient = buildReactorNettyHttpClient(configuration);
+ this.mapper = new ObjectMapper().registerModule(new Jdk8Module());
+ }
+
+ public Mono<List<CrowdsecDecision>> getCrowdsecDecisions() {
+ return httpClient.get()
+ .uri(GET_DECISION)
+ .responseSingle((response, body) -> {
+ switch (response.status().code()) {
+ case HttpStatus.SC_OK:
+ return
body.asString().map(this::parseCrowdsecDecisions);
+ case HttpStatus.SC_FORBIDDEN:
+ return Mono.error(new RuntimeException("Invalid
api-key bouncer"));
+ case HttpStatus.SC_NOT_FOUND:
+ return Mono.error(new RuntimeException("Crowdsec url
not found"));
+ default:
+ return Mono.error(new RuntimeException("Request failed
with status code " + response.status().code()));
+ }
+ });
+ }
+
+ private List<CrowdsecDecision> parseCrowdsecDecisions(String json) {
+ if (noCrowdsecDecision(json)) {
+ return ImmutableList.of();
+ } else {
+ try {
+ return mapper.readValue(json, new TypeReference<>() {});
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ private static boolean noCrowdsecDecision(String json) {
+ return json.equals("null");
+ }
+
+ private HttpClient buildReactorNettyHttpClient(CrowdsecClientConfiguration
configuration) {
+ return HttpClient.create()
+ .responseTimeout(DEFAULT_TIMEOUT)
+ .baseUrl(configuration.getUrl().toString())
+ .headers(headers -> headers.add("X-Api-Key",
configuration.getApiKey()))
+ .headers(headers -> headers.add(HttpHeaderNames.ACCEPT,
ContentType.APPLICATION_JSON.getMimeType()));
+ }
+}
diff --git
a/third-party/crowdsec/src/main/java/org/apache/james/module/CrowdsecModule.java
b/third-party/crowdsec/src/main/java/org/apache/james/module/CrowdsecModule.java
new file mode 100644
index 0000000000..05df517650
--- /dev/null
+++
b/third-party/crowdsec/src/main/java/org/apache/james/module/CrowdsecModule.java
@@ -0,0 +1,46 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you 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. *
+ ****************************************************************/
+
+package org.apache.james.module;
+
+import java.io.FileNotFoundException;
+
+import org.apache.commons.configuration2.ex.ConfigurationException;
+import org.apache.james.model.CrowdsecClientConfiguration;
+import org.apache.james.model.CrowdsecHttpClient;
+import org.apache.james.utils.PropertiesProvider;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+import com.google.inject.Singleton;
+
+public class CrowdsecModule extends AbstractModule {
+
+ @Provides
+ @Singleton
+ public CrowdsecClientConfiguration
crowdsecClientConfiguration(PropertiesProvider propertiesProvider) throws
ConfigurationException, FileNotFoundException {
+ return
CrowdsecClientConfiguration.from(propertiesProvider.getConfiguration("crowdsec"));
+ }
+
+ @Provides
+ @Singleton
+ public CrowdsecHttpClient crowdsecHttpClient(CrowdsecClientConfiguration
crowdsecClientConfiguration) {
+ return new CrowdsecHttpClient(crowdsecClientConfiguration);
+ }
+}
diff --git
a/third-party/crowdsec/src/test/java/org/apache/james/CrowdsecDecisionDeserializerTest.java
b/third-party/crowdsec/src/test/java/org/apache/james/CrowdsecDecisionDeserializerTest.java
new file mode 100644
index 0000000000..88ebfc0776
--- /dev/null
+++
b/third-party/crowdsec/src/test/java/org/apache/james/CrowdsecDecisionDeserializerTest.java
@@ -0,0 +1,51 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you 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. *
+ ****************************************************************/
+
+package org.apache.james;
+
+import java.time.Duration;
+import java.util.List;
+
+import org.apache.james.model.CrowdsecDecision;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+
+class CrowdsecDecisionDeserializerTest {
+ @Test
+ void deserializeCrowdsecDecisionTest() throws Exception {
+ String json = "[\n{\n \"duration\": \"3h47m14.654059061s\",\n
\"id\": 3,\n \"origin\": \"cscli\",\n \"scenario\": \"manual 'ban' from
'localhost'\",\n \"scope\": \"Ip\",\n \"type\": \"ban\",\n \"value\":
\"1.1.2.54\"\n}\n]";
+ ObjectMapper objectMapper = (new ObjectMapper()).registerModule(new
Jdk8Module());
+ List<CrowdsecDecision> decisions = objectMapper.readValue(json, new
TypeReference<>() {});
+
+ Assertions.assertThat(decisions.get(0))
+ .isEqualTo(CrowdsecDecision.builder()
+ .duration(Duration.parse("PT3h47m14.654059061s"))
+ .id(3L)
+ .origin("cscli")
+ .scenario("manual 'ban' from 'localhost'")
+ .scope("Ip")
+ .value("1.1.2.54")
+ .type("ban")
+ .build());
+ }
+}
\ No newline at end of file
diff --git
a/third-party/crowdsec/src/test/java/org/apache/james/CrowdsecExtension.java
b/third-party/crowdsec/src/test/java/org/apache/james/CrowdsecExtension.java
index 45edba2068..f683c5673e 100644
--- a/third-party/crowdsec/src/test/java/org/apache/james/CrowdsecExtension.java
+++ b/third-party/crowdsec/src/test/java/org/apache/james/CrowdsecExtension.java
@@ -28,9 +28,12 @@ import org.junit.jupiter.api.extension.ExtensionContext;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.HostPortWaitStrategy;
+import com.google.common.collect.ImmutableList;
+
public class CrowdsecExtension implements GuiceModuleTestExtension {
public static final Duration STARTUP_TIMEOUT = Duration.ofMinutes(5);
public static final int CROWDSEC_PORT = 8080;
+ public static final int EXPOSED_PORT = 8082;
public static final String CROWDSEC_IMAGE =
"crowdsecurity/crowdsec:v1.5.4";
private final GenericContainer<?> crowdsecContainer;
@@ -40,7 +43,7 @@ public class CrowdsecExtension implements
GuiceModuleTestExtension {
.withCreateContainerCmdModifier(cmd ->
cmd.withName("james-crowdsec-test-" + UUID.randomUUID()))
.withExposedPorts(CROWDSEC_PORT)
.withStartupTimeout(STARTUP_TIMEOUT)
- .waitingFor(new
HostPortWaitStrategy().withRateLimiter(RateLimiters.TWENTIES_PER_SECOND));;
+ .waitingFor(new
HostPortWaitStrategy().withRateLimiter(RateLimiters.TWENTIES_PER_SECOND));
}
@Override
diff --git
a/third-party/crowdsec/src/test/java/org/apache/james/CrowdsecHttpClientTest.java
b/third-party/crowdsec/src/test/java/org/apache/james/CrowdsecHttpClientTest.java
new file mode 100644
index 0000000000..38cf40a08f
--- /dev/null
+++
b/third-party/crowdsec/src/test/java/org/apache/james/CrowdsecHttpClientTest.java
@@ -0,0 +1,128 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you 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. *
+ ****************************************************************/
+
+package org.apache.james;
+
+import static org.apache.james.CrowdsecExtension.CROWDSEC_PORT;
+import static
org.apache.james.model.CrowdsecClientConfiguration.DEFAULT_API_KEY;
+import static org.apache.james.model.CrowdsecDecision.BAN;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.List;
+
+import org.apache.james.model.CrowdsecClientConfiguration;
+import org.apache.james.model.CrowdsecDecision;
+import org.apache.james.model.CrowdsecHttpClient;
+import org.assertj.core.api.SoftAssertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+class CrowdsecHttpClientTest {
+ @RegisterExtension
+ static CrowdsecExtension crowdsecExtension = new CrowdsecExtension();
+
+ @BeforeAll
+ static void setUp() throws IOException, InterruptedException {
+ crowdsecExtension.getCrowdsecContainer().execInContainer("cscli",
"bouncer", "add", "bouncer", "-k", DEFAULT_API_KEY);
+ }
+
+ @Test
+ void getDecisionsWhenBanningAnIP() throws IOException,
InterruptedException {
+ banIP("--ip", "192.168.0.4");
+ int port =
crowdsecExtension.getCrowdsecContainer().getMappedPort(CROWDSEC_PORT);
+ CrowdsecClientConfiguration config = new
CrowdsecClientConfiguration(new URL("http://localhost:" + port + "/v1"),
DEFAULT_API_KEY);
+ CrowdsecHttpClient httpClient = new CrowdsecHttpClient(config);
+ List<CrowdsecDecision> decisions =
httpClient.getCrowdsecDecisions().block();
+
+ SoftAssertions.assertSoftly(softly -> {
+ softly.assertThat(decisions).hasSize(1);
+
softly.assertThat(decisions.get(0).getValue().equals("192.168.0.4") &&
decisions.get(0).getType().equals(BAN));
+ });
+ }
+
+ @Test
+ void getDecisionsWhenBanningAnIPRange() throws IOException,
InterruptedException {
+ banIP("--range", "192.168.0.0/16");
+ int port =
crowdsecExtension.getCrowdsecContainer().getMappedPort(CROWDSEC_PORT);
+ CrowdsecClientConfiguration config = new
CrowdsecClientConfiguration(new URL("http://localhost:" + port + "/v1"),
DEFAULT_API_KEY);
+ CrowdsecHttpClient httpClient = new CrowdsecHttpClient(config);
+ List<CrowdsecDecision> decisions =
httpClient.getCrowdsecDecisions().block();
+
+ SoftAssertions.assertSoftly(softly -> {
+ softly.assertThat(decisions).hasSize(1);
+
softly.assertThat(decisions.get(0).getValue().equals("192.168.0.0/16") &&
decisions.get(0).getType().equals(BAN));
+ });
+ }
+
+ @Test
+ void getDecisionsWithWrongApiKey() throws IOException,
InterruptedException {
+ banIP("--range", "192.168.0.0/16");
+ int port =
crowdsecExtension.getCrowdsecContainer().getMappedPort(CROWDSEC_PORT);
+ CrowdsecClientConfiguration config = new
CrowdsecClientConfiguration(new URL("http://localhost:" + port + "/v1"),
"wrong-key");
+ CrowdsecHttpClient httpClient = new CrowdsecHttpClient(config);
+
+ assertThatThrownBy(() -> httpClient.getCrowdsecDecisions().block())
+ .hasMessage("Invalid api-key bouncer");
+ }
+
+ @Test
+ void getDecisionsWithWrongCrowdsecUrl() throws IOException,
InterruptedException {
+ banIP("--range", "192.168.0.0/16");
+ int port =
crowdsecExtension.getCrowdsecContainer().getMappedPort(CROWDSEC_PORT);
+ CrowdsecClientConfiguration config = new
CrowdsecClientConfiguration(new URL("http://localhost:" + port + "/v2"),
DEFAULT_API_KEY);
+ CrowdsecHttpClient httpClient = new CrowdsecHttpClient(config);
+
+ assertThatThrownBy(() -> httpClient.getCrowdsecDecisions().block())
+ .hasMessage("Crowdsec url not found");
+ }
+
+ @Test
+ void getDecisionsWhenNoBanning() throws IOException {
+ int port =
crowdsecExtension.getCrowdsecContainer().getMappedPort(CROWDSEC_PORT);
+ CrowdsecClientConfiguration config = new
CrowdsecClientConfiguration(new URL("http://localhost:" + port + "/v1"),
DEFAULT_API_KEY);
+ CrowdsecHttpClient httpClient = new CrowdsecHttpClient(config);
+ List<CrowdsecDecision> decisions =
httpClient.getCrowdsecDecisions().block();
+
+ assertThat(decisions).hasSize(0);
+ }
+
+ @Test
+ void getDecisionsWhenBanningMultipleIP() throws IOException,
InterruptedException {
+ banIP("--ip", "192.168.0.4");
+ banIP("--ip", "192.168.0.5");
+ int port =
crowdsecExtension.getCrowdsecContainer().getMappedPort(CROWDSEC_PORT);
+ CrowdsecClientConfiguration config = new
CrowdsecClientConfiguration(new URL("http://localhost:" + port + "/v1"),
DEFAULT_API_KEY);
+ CrowdsecHttpClient httpClient = new CrowdsecHttpClient(config);
+ List<CrowdsecDecision> decisions =
httpClient.getCrowdsecDecisions().block();
+
+ SoftAssertions.assertSoftly(softly -> {
+ softly.assertThat(decisions).hasSize(2);
+
softly.assertThat(decisions.get(0).getValue().equals("192.168.0.4") &&
decisions.get(0).getType().equals(BAN));
+
softly.assertThat(decisions.get(1).getValue().equals("192.168.0.5") &&
decisions.get(1).getType().equals(BAN));
+ });
+ }
+
+ private static void banIP(String type, String value) throws IOException,
InterruptedException {
+ crowdsecExtension.getCrowdsecContainer().execInContainer("cscli",
"decision", "add", type, value);
+ }
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]