You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2018/06/20 02:08:30 UTC
[1/3] james-project git commit: JAMES-2428 [DLP] Web admin endpoint
to update DLP configuration
Repository: james-project
Updated Branches:
refs/heads/master 23d22a0e9 -> 536f3caab
JAMES-2428 [DLP] Web admin endpoint to update DLP configuration
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/dec6e890
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/dec6e890
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/dec6e890
Branch: refs/heads/master
Commit: dec6e89024f78f3ddbe7e24157d9f7d991381d54
Parents: 23d22a0
Author: duc <dt...@linagora.com>
Authored: Thu Jun 14 15:49:47 2018 +0700
Committer: duc <dt...@linagora.com>
Committed: Tue Jun 19 16:59:52 2018 +0700
----------------------------------------------------------------------
.../james/modules/server/DataRoutesModules.java | 2 +
.../james/webadmin/utils/JsonExtractor.java | 1 +
server/protocols/webadmin/webadmin-data/pom.xml | 19 +
.../org/apache/james/webadmin/DLPModule.java | 36 ++
.../james/webadmin/dto/DLPConfigurationDTO.java | 64 +++
.../webadmin/dto/DLPConfigurationItemDTO.java | 127 +++++
.../webadmin/routes/DLPConfigurationRoutes.java | 217 +++++++
.../dto/DLPConfigurationItemDTOTest.java | 105 ++++
.../routes/DLPConfigurationRoutesTest.java | 571 +++++++++++++++++++
9 files changed, 1142 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/dec6e890/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DataRoutesModules.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DataRoutesModules.java b/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DataRoutesModules.java
index 2ae64ec..2cb95c5 100644
--- a/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DataRoutesModules.java
+++ b/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DataRoutesModules.java
@@ -20,6 +20,7 @@
package org.apache.james.modules.server;
import org.apache.james.webadmin.Routes;
+import org.apache.james.webadmin.routes.DLPConfigurationRoutes;
import org.apache.james.webadmin.routes.DomainsRoutes;
import org.apache.james.webadmin.routes.ForwardRoutes;
import org.apache.james.webadmin.routes.GroupsRoutes;
@@ -33,6 +34,7 @@ public class DataRoutesModules extends AbstractModule {
@Override
protected void configure() {
Multibinder<Routes> routesMultibinder = Multibinder.newSetBinder(binder(), Routes.class);
+ routesMultibinder.addBinding().to(DLPConfigurationRoutes.class);
routesMultibinder.addBinding().to(DomainsRoutes.class);
routesMultibinder.addBinding().to(ForwardRoutes.class);
routesMultibinder.addBinding().to(GroupsRoutes.class);
http://git-wip-us.apache.org/repos/asf/james-project/blob/dec6e890/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java
index 3f62d89..fcecc3d 100644
--- a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java
@@ -20,6 +20,7 @@
package org.apache.james.webadmin.utils;
import java.io.IOException;
+import java.util.Collection;
import java.util.List;
import com.fasterxml.jackson.databind.Module;
http://git-wip-us.apache.org/repos/asf/james-project/blob/dec6e890/server/protocols/webadmin/webadmin-data/pom.xml
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/pom.xml b/server/protocols/webadmin/webadmin-data/pom.xml
index e6c876b..f4b1d20 100644
--- a/server/protocols/webadmin/webadmin-data/pom.xml
+++ b/server/protocols/webadmin/webadmin-data/pom.xml
@@ -35,6 +35,11 @@
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
+ <artifactId>event-sourcing-event-store-memory</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
<artifactId>james-core</artifactId>
</dependency>
<dependency>
@@ -67,6 +72,10 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>com.fasterxml.jackson.datatype</groupId>
+ <artifactId>jackson-datatype-guava</artifactId>
+ </dependency>
+ <dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
@@ -80,6 +89,16 @@
<artifactId>javax.inject</artifactId>
</dependency>
<dependency>
+ <groupId>net.javacrumbs.json-unit</groupId>
+ <artifactId>json-unit-fluent</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>nl.jqno.equalsverifier</groupId>
+ <artifactId>equalsverifier</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
http://git-wip-us.apache.org/repos/asf/james-project/blob/dec6e890/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/DLPModule.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/DLPModule.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/DLPModule.java
new file mode 100644
index 0000000..0363ca3
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/DLPModule.java
@@ -0,0 +1,36 @@
+/****************************************************************
+ * 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.webadmin;
+
+import org.apache.james.webadmin.utils.JsonTransformerModule;
+
+import com.fasterxml.jackson.databind.Module;
+import com.fasterxml.jackson.datatype.guava.GuavaModule;
+
+public class DLPModule implements JsonTransformerModule {
+
+ public DLPModule() {
+ }
+
+ @Override
+ public Module asJacksonModule() {
+ return new GuavaModule();
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/dec6e890/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationDTO.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationDTO.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationDTO.java
new file mode 100644
index 0000000..d1265a6
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationDTO.java
@@ -0,0 +1,64 @@
+/****************************************************************
+ * 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.webadmin.dto;
+
+import java.util.List;
+
+import org.apache.james.dlp.api.DLPConfigurationItem;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.github.steveash.guavate.Guavate;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+public class DLPConfigurationDTO {
+
+ public static List<DLPConfigurationItem> toDLPConfigurations(DLPConfigurationDTO dto) {
+ Preconditions.checkNotNull(dto);
+
+ return dto.rules
+ .stream()
+ .map(DLPConfigurationItemDTO::toDLPConfiguration)
+ .collect(Guavate.toImmutableList());
+ }
+
+ public static DLPConfigurationDTO toDTO(List<DLPConfigurationItem> dlpConfigurations) {
+ Preconditions.checkNotNull(dlpConfigurations);
+
+ return new DLPConfigurationDTO(
+ dlpConfigurations
+ .stream()
+ .map(DLPConfigurationItemDTO::toDTO)
+ .collect(Guavate.toImmutableList()));
+ }
+
+ private final ImmutableList<DLPConfigurationItemDTO> rules;
+
+ @JsonCreator
+ public DLPConfigurationDTO(
+ @JsonProperty("rules") ImmutableList<DLPConfigurationItemDTO> rules) {
+ this.rules = rules;
+ }
+
+ public ImmutableList<DLPConfigurationItemDTO> getRules() {
+ return rules;
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/dec6e890/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTO.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTO.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTO.java
new file mode 100644
index 0000000..502615a
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTO.java
@@ -0,0 +1,127 @@
+/****************************************************************
+ * 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.webadmin.dto;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+import org.apache.james.dlp.api.DLPConfigurationItem;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.github.steveash.guavate.Guavate;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+
+public class DLPConfigurationItemDTO {
+
+ @VisibleForTesting
+ static DLPConfigurationItem toDLPConfiguration(DLPConfigurationItemDTO dto) {
+ return DLPConfigurationItem.builder()
+ .id(DLPConfigurationItem.Id.of(dto.id))
+ .expression(dto.expression)
+ .explanation(dto.explanation)
+ .targetsSender(dto.targetsSender)
+ .targetsRecipients(dto.targetsRecipients)
+ .targetsContent(dto.targetsContent)
+ .build();
+ }
+
+ @VisibleForTesting
+ static DLPConfigurationItemDTO toDTO(DLPConfigurationItem dlpConfiguration) {
+ DLPConfigurationItem.Targets targets = dlpConfiguration.getTargets();
+ return new DLPConfigurationItemDTO(
+ dlpConfiguration.getId().asString(),
+ dlpConfiguration.getRegexp(),
+ dlpConfiguration.getExplanation(),
+ Optional.of(targets.isSenderTargeted()),
+ Optional.of(targets.isRecipientTargeted()),
+ Optional.of(targets.isContentTargeted()));
+ }
+
+ private final String id;
+ private final String expression;
+ private final Optional<String> explanation;
+ private final Optional<Boolean> targetsSender;
+ private final Optional<Boolean> targetsRecipients;
+ private final Optional<Boolean> targetsContent;
+
+ @JsonCreator
+ public DLPConfigurationItemDTO(@JsonProperty("id") String id,
+ @JsonProperty("expression") String expression,
+ @JsonProperty("explanation") Optional<String> explanation,
+ @JsonProperty("targetsSender") Optional<Boolean> targetsSender,
+ @JsonProperty("targetsRecipients") Optional<Boolean> targetsRecipients,
+ @JsonProperty("targetsContent") Optional<Boolean> targetsContent) {
+ Preconditions.checkNotNull(id, "'id' is mandatory");
+ Preconditions.checkNotNull(expression, "'expression' is mandatory");
+ this.id = id;
+ this.expression = expression;
+ this.explanation = explanation;
+ this.targetsSender = targetsSender;
+ this.targetsRecipients = targetsRecipients;
+ this.targetsContent = targetsContent;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getExpression() {
+ return expression;
+ }
+
+ public Optional<String> getExplanation() {
+ return explanation;
+ }
+
+ public Optional<Boolean> getTargetsSender() {
+ return targetsSender;
+ }
+
+ public Optional<Boolean> getTargetsRecipients() {
+ return targetsRecipients;
+ }
+
+ public Optional<Boolean> getTargetsContent() {
+ return targetsContent;
+ }
+
+ @Override
+ public final boolean equals(Object o) {
+ if (o instanceof DLPConfigurationItemDTO) {
+ DLPConfigurationItemDTO that = (DLPConfigurationItemDTO) o;
+
+ return Objects.equals(this.id, that.id)
+ && Objects.equals(this.expression, that.expression)
+ && Objects.equals(this.explanation, that.explanation)
+ && Objects.equals(this.targetsSender, that.targetsSender)
+ && Objects.equals(this.targetsRecipients, that.targetsRecipients)
+ && Objects.equals(this.targetsContent, that.targetsContent);
+ }
+ return false;
+ }
+
+ @Override
+ public final int hashCode() {
+ return Objects.hash(id, expression, explanation, targetsSender, targetsRecipients, targetsContent);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/dec6e890/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DLPConfigurationRoutes.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DLPConfigurationRoutes.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DLPConfigurationRoutes.java
new file mode 100644
index 0000000..73b1d33
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DLPConfigurationRoutes.java
@@ -0,0 +1,217 @@
+/****************************************************************
+ * 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.webadmin.routes;
+
+import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
+import static org.apache.james.webadmin.Constants.EMPTY_BODY;
+import static org.apache.james.webadmin.Constants.JSON_CONTENT_TYPE;
+import static org.apache.james.webadmin.Constants.SEPARATOR;
+
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+
+import org.apache.james.core.Domain;
+import org.apache.james.dlp.api.DLPConfigurationItem;
+import org.apache.james.dlp.api.DLPConfigurationStore;
+import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.domainlist.api.DomainListException;
+import org.apache.james.webadmin.Routes;
+import org.apache.james.webadmin.dto.DLPConfigurationDTO;
+import org.apache.james.webadmin.utils.ErrorResponder;
+import org.apache.james.webadmin.utils.ErrorResponder.ErrorType;
+import org.apache.james.webadmin.utils.JsonExtractor;
+import org.apache.james.webadmin.utils.JsonTransformer;
+import org.eclipse.jetty.http.HttpStatus;
+
+import com.fasterxml.jackson.datatype.guava.GuavaModule;
+import com.github.steveash.guavate.Guavate;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import spark.HaltException;
+import spark.Request;
+import spark.Service;
+
+@Api(tags = "DLPRules")
+@Path(DLPConfigurationRoutes.BASE_PATH)
+@Produces(JSON_CONTENT_TYPE)
+public class DLPConfigurationRoutes implements Routes {
+
+ static final String BASE_PATH = "/dlp/rules";
+
+ private static final String DOMAIN_NAME = ":senderDomain";
+ private static final String SPECIFIC_DLP_RULE_DOMAIN = BASE_PATH + SEPARATOR + DOMAIN_NAME;
+
+ private final JsonTransformer jsonTransformer;
+ private final DLPConfigurationStore dlpConfigurationStore;
+ private final JsonExtractor<DLPConfigurationDTO> jsonExtractor;
+ private final DomainList domainList;
+
+ private Service service;
+
+ @Inject
+ public DLPConfigurationRoutes(DLPConfigurationStore dlpConfigurationStore, DomainList domainList, JsonTransformer jsonTransformer) {
+ this.dlpConfigurationStore = dlpConfigurationStore;
+ this.domainList = domainList;
+ this.jsonTransformer = jsonTransformer;
+ this.jsonExtractor = new JsonExtractor<>(DLPConfigurationDTO.class, new GuavaModule());
+ }
+
+ @Override
+ public void define(Service service) {
+ this.service = service;
+
+ defineStore();
+
+ defineList();
+
+ defineClear();
+ }
+
+ @PUT
+ @Path("/{senderDomain}")
+ @ApiOperation(value = "Store a list of dlp configs for given senderDomain")
+ @ApiImplicitParams({
+ @ApiImplicitParam(required = true, dataType = "string", name = "senderDomain", paramType = "path")
+ })
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.NO_CONTENT_204, message = "OK. dlp config is stored."),
+ @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid senderDomain or payload in request"),
+ @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "The domain does not exist."),
+ @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
+ message = "Internal server error - Something went bad on the server side.")
+ })
+ public void defineStore() {
+ service.put(SPECIFIC_DLP_RULE_DOMAIN, (request, response) -> {
+ Domain senderDomain = parseDomain(request);
+ DLPConfigurationDTO dto = jsonExtractor.parse(request.body());
+
+ dlpConfigurationStore.store(senderDomain, DLPConfigurationDTO.toDLPConfigurations(dto));
+
+ response.status(HttpStatus.NO_CONTENT_204);
+ return EMPTY_BODY;
+ });
+ }
+
+ @GET
+ @Path("/{senderDomain}")
+ @ApiOperation(value = "Retrieve a list of dlp configs for given senderDomain")
+ @ApiImplicitParams({
+ @ApiImplicitParam(required = true, dataType = "string", name = "senderDomain", paramType = "path")
+ })
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.OK_200, message = "OK. dlp configs returned"),
+ @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid senderDomain in request"),
+ @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "The domain does not exist."),
+ @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
+ message = "Internal server error - Something went bad on the server side.")
+ })
+ public void defineList() {
+ service.get(SPECIFIC_DLP_RULE_DOMAIN, (request, response) -> {
+ Domain senderDomain = parseDomain(request);
+ List<DLPConfigurationItem> dlpConfigurations = dlpConfigurationStore
+ .list(senderDomain)
+ .collect(Guavate.toImmutableList());
+
+ DLPConfigurationDTO dto = DLPConfigurationDTO.toDTO(dlpConfigurations);
+ response.status(HttpStatus.OK_200);
+ response.header(CONTENT_TYPE, JSON_CONTENT_TYPE);
+ return dto;
+ }, jsonTransformer);
+ }
+
+ @DELETE
+ @Path("/{senderDomain}")
+ @ApiOperation(value = "Clear all dlp configs for given senderDomain")
+ @ApiImplicitParams({
+ @ApiImplicitParam(required = true, dataType = "string", name = "senderDomain", paramType = "path")
+ })
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.NO_CONTENT_204, message = "OK. dlp configs are cleared"),
+ @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid senderDomain in request"),
+ @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "The domain does not exist."),
+ @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
+ message = "Internal server error - Something went bad on the server side.")
+ })
+ public void defineClear() {
+ service.delete(SPECIFIC_DLP_RULE_DOMAIN, (request, response) -> {
+ Domain senderDomain = parseDomain(request);
+ dlpConfigurationStore.clear(senderDomain);
+
+ response.status(HttpStatus.NO_CONTENT_204);
+ return EMPTY_BODY;
+ }, jsonTransformer);
+ }
+
+ private Domain parseDomain(Request request) {
+ String domainName = request.params(DOMAIN_NAME);
+ try {
+ Domain domain = Domain.of(domainName);
+ validateDomainInList(domain);
+
+ return domain;
+ } catch (IllegalArgumentException e) {
+ throw invalidDomain(String.format("Invalid request for domain: %s", domainName), e);
+ } catch (DomainListException e) {
+ throw serverError(String.format("Cannot recognize domain: %s in domain list", domainName), e);
+ }
+ }
+
+ private void validateDomainInList(Domain domain) throws DomainListException {
+ if (!domainList.containsDomain(domain)) {
+ throw notFound(String.format("'%s' is not managed by this James server", domain.name()));
+ }
+ }
+
+ private HaltException invalidDomain(String message, Exception e) {
+ return ErrorResponder.builder()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .type(ErrorType.INVALID_ARGUMENT)
+ .message(message)
+ .cause(e)
+ .haltError();
+ }
+
+ private HaltException serverError(String message, Exception e) {
+ return ErrorResponder.builder()
+ .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500)
+ .type(ErrorType.SERVER_ERROR)
+ .message(message)
+ .cause(e)
+ .haltError();
+ }
+
+ private HaltException notFound(String message) {
+ return ErrorResponder.builder()
+ .statusCode(HttpStatus.NOT_FOUND_404)
+ .type(ErrorType.INVALID_ARGUMENT)
+ .message(message)
+ .haltError();
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/dec6e890/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTOTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTOTest.java b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTOTest.java
new file mode 100644
index 0000000..a4b0da8
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTOTest.java
@@ -0,0 +1,105 @@
+/****************************************************************
+ * 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.webadmin.dto;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.james.dlp.api.DLPConfigurationItem;
+import org.assertj.core.api.SoftAssertions;
+import org.junit.jupiter.api.Test;
+
+import com.google.common.collect.ImmutableList;
+
+class DLPConfigurationItemDTOTest {
+
+ private static final String ID = "id";
+ private static final String EXPRESSION = "expression";
+ private static final String EXPLANATION = "explanation";
+ private static final String NULL_ID = null;
+ private static final String NULL_EXPRESSION = null;
+
+ @Test
+ void toDTOsShouldBeSetAllFields() {
+ DLPConfigurationItemDTO dto = DLPConfigurationItemDTO.toDTO(
+ DLPConfigurationItem.builder()
+ .id(DLPConfigurationItem.Id.of(ID))
+ .expression(EXPRESSION)
+ .explanation(EXPLANATION)
+ .targetsSender(Optional.of(true))
+ .targetsRecipients(Optional.of(true))
+ .targetsContent(Optional.of(true))
+ .build());
+
+ SoftAssertions.assertSoftly(softly -> {
+ softly.assertThat(dto.getId()).isEqualTo(ID);
+ softly.assertThat(dto.getExpression()).isEqualTo(EXPRESSION);
+ softly.assertThat(dto.getExplanation().get()).isEqualTo(EXPLANATION);
+ softly.assertThat(dto.getTargetsSender().get()).isTrue();
+ softly.assertThat(dto.getTargetsRecipients().get()).isTrue();
+ softly.assertThat(dto.getTargetsContent().get()).isTrue();
+ });
+ }
+
+ @Test
+ void toDLPConfigurationsShouldBeSetAllFields() {
+ DLPConfigurationItem item = DLPConfigurationItemDTO.toDLPConfiguration(
+ new DLPConfigurationItemDTO(
+ ID,
+ EXPRESSION,
+ Optional.of(EXPLANATION),
+ Optional.of(true),
+ Optional.of(true),
+ Optional.of(true)));
+
+ SoftAssertions.assertSoftly(softly -> {
+ softly.assertThat(item.getId().asString()).isEqualTo(ID);
+ softly.assertThat(item.getRegexp()).isEqualTo(EXPRESSION);
+ softly.assertThat(item.getExplanation().get()).isEqualTo(EXPLANATION);
+ softly.assertThat(item.getTargets().isSenderTargeted()).isTrue();
+ softly.assertThat(item.getTargets().isRecipientTargeted()).isTrue();
+ softly.assertThat(item.getTargets().isContentTargeted()).isTrue();
+ });
+ }
+
+ @Test
+ void constructorShouldThrowWhenIdIsNull() {
+ assertThatThrownBy(() -> new DLPConfigurationItemDTO(NULL_ID,
+ EXPRESSION,
+ Optional.of(EXPLANATION),
+ Optional.of(true),
+ Optional.of(true),
+ Optional.of(true)))
+ .isInstanceOf(NullPointerException.class);
+ }
+
+ @Test
+ void constructorShouldThrowWhenExpressionIsNull() {
+ assertThatThrownBy(() -> new DLPConfigurationItemDTO(ID,
+ NULL_EXPRESSION,
+ Optional.of(EXPLANATION),
+ Optional.of(true),
+ Optional.of(true),
+ Optional.of(true)))
+ .isInstanceOf(NullPointerException.class);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/dec6e890/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DLPConfigurationRoutesTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DLPConfigurationRoutesTest.java b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DLPConfigurationRoutesTest.java
new file mode 100644
index 0000000..74d3468
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DLPConfigurationRoutesTest.java
@@ -0,0 +1,571 @@
+/****************************************************************
+ * 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.webadmin.routes;
+
+import static com.jayway.restassured.RestAssured.given;
+import static com.jayway.restassured.RestAssured.requestSpecification;
+import static com.jayway.restassured.RestAssured.when;
+import static com.jayway.restassured.RestAssured.with;
+import static net.javacrumbs.jsonunit.fluent.JsonFluentAssert.assertThatJson;
+import static org.apache.james.webadmin.Constants.JSON_CONTENT_TYPE;
+import static org.apache.james.webadmin.WebAdminServer.NO_CONFIGURATION;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+
+import java.net.InetAddress;
+import java.util.List;
+
+import org.apache.james.core.Domain;
+import org.apache.james.dlp.api.DLPConfigurationItem;
+import org.apache.james.dlp.api.DLPConfigurationStore;
+import org.apache.james.dlp.eventsourcing.EventSourcingDLPConfigurationStore;
+import org.apache.james.dnsservice.api.DNSService;
+import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.domainlist.memory.MemoryDomainList;
+import org.apache.james.eventsourcing.eventstore.memory.InMemoryEventStore;
+import org.apache.james.metrics.logger.DefaultMetricFactory;
+import org.apache.james.webadmin.DLPModule;
+import org.apache.james.webadmin.WebAdminServer;
+import org.apache.james.webadmin.WebAdminUtils;
+import org.apache.james.webadmin.utils.JsonTransformer;
+import org.eclipse.jetty.http.HttpStatus;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import com.google.common.collect.ImmutableList;
+import com.jayway.restassured.RestAssured;
+import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.specification.RequestSpecification;
+
+class DLPConfigurationRoutesTest {
+
+ private static final String DEFAULT_DOMAIN = "james.org";
+ private static final Domain SENDER_DOMAIN = Domain.of(DEFAULT_DOMAIN);
+ private static final String DOMAIN_2 = "apache.org";
+ private static final Domain SENDER_DOMAIN_2 = Domain.of(DOMAIN_2);
+
+ private static final DLPConfigurationItem CONFIGURATION_ITEM_1 = DLPConfigurationItem.builder()
+ .id(DLPConfigurationItem.Id.of("1"))
+ .explanation("explanation 1")
+ .expression(DEFAULT_DOMAIN)
+ .targetsSender()
+ .targetsRecipients()
+ .targetsContent()
+ .build();
+ private static final DLPConfigurationItem CONFIGURATION_ITEM_2 = DLPConfigurationItem.builder()
+ .id(DLPConfigurationItem.Id.of("2"))
+ .expression(DEFAULT_DOMAIN)
+ .targetsSender()
+ .build();
+
+ private static final List<DLPConfigurationItem> CONFIGURATION_ITEMS_FOR_DOMAIN_2 = ImmutableList.of(DLPConfigurationItem.builder()
+ .id(DLPConfigurationItem.Id.of("3"))
+ .expression(DOMAIN_2)
+ .targetsSender()
+ .build());
+
+ private static final List<DLPConfigurationItem> CONFIGURATION_ITEMS = ImmutableList.of(CONFIGURATION_ITEM_1, CONFIGURATION_ITEM_2);
+
+ private WebAdminServer webAdminServer;
+ private EventSourcingDLPConfigurationStore dlpStore;
+
+ private void createServer(DLPConfigurationStore dlpConfigurationStore, DomainList domainList) throws Exception {
+ webAdminServer = WebAdminUtils.createWebAdminServer(
+ new DefaultMetricFactory(),
+ new DLPConfigurationRoutes(dlpConfigurationStore, domainList, new JsonTransformer(new DLPModule())));
+ webAdminServer.configure(NO_CONFIGURATION);
+ webAdminServer.await();
+
+ requestSpecification = buildRequestSpecification(webAdminServer);
+ }
+
+ RequestSpecification buildRequestSpecification(WebAdminServer server) {
+ RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
+
+ return WebAdminUtils
+ .buildRequestSpecification(server)
+ .setBasePath(DLPConfigurationRoutes.BASE_PATH)
+ .build();
+ }
+
+
+ @BeforeEach
+ void setup() throws Exception {
+ DNSService dnsService = mock(DNSService.class);
+ Mockito.when(dnsService.getHostName(any())).thenReturn("localhost");
+ Mockito.when(dnsService.getLocalHost()).thenReturn(InetAddress.getByName("localhost"));
+
+ MemoryDomainList domainList = new MemoryDomainList(dnsService);
+ domainList.setAutoDetectIP(false);
+ domainList.setAutoDetect(false);
+ domainList.addDomain(SENDER_DOMAIN);
+ domainList.addDomain(SENDER_DOMAIN_2);
+
+ dlpStore = new EventSourcingDLPConfigurationStore(new InMemoryEventStore());
+ createServer(dlpStore, domainList);
+ }
+
+
+ @Nested
+ class DefineStore {
+
+ @Test
+ void putShouldStoreTheConfigurations() {
+ String storeBody =
+ "{\"rules\": [" +
+ " {" +
+ " \"id\": \"1\"," +
+ " \"expression\": \"expression 1\"," +
+ " \"explanation\": \"explanation 1\"," +
+ " \"targetsSender\": true," +
+ " \"targetsRecipients\": true," +
+ " \"targetsContent\": true" +
+ " }," +
+ " {" +
+ " \"id\": \"2\"," +
+ " \"expression\": \"expression 2\"," +
+ " \"explanation\": \"explanation 2\"," +
+ " \"targetsSender\": false," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": false" +
+ " }]}";
+
+ given()
+ .body(storeBody)
+ .when()
+ .put(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.NO_CONTENT_204);
+
+ String retrievedBody = with()
+ .get(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .contentType(ContentType.JSON)
+ .extract()
+ .body().asString();
+
+ assertThatJson(retrievedBody).isEqualTo(storeBody);
+ }
+
+ @Test
+ void putShouldStoreTheConfigurationsWhenTargetsAreNotSpecified() {
+ String storeBody =
+ "{\"rules\": [" +
+ " {" +
+ " \"id\": \"3\"," +
+ " \"expression\": \"expression 3\"," +
+ " \"explanation\": \"explanation 3\"" +
+ " }]}";
+
+ given()
+ .body(storeBody)
+ .when()
+ .put(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.NO_CONTENT_204);
+
+ String retrievedBody = with()
+ .get(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .contentType(ContentType.JSON)
+ .extract()
+ .body().asString();
+
+ assertThatJson(retrievedBody)
+ .isEqualTo(
+ "{\"rules\": [" +
+ " {" +
+ " \"id\": \"3\"," +
+ " \"expression\": \"expression 3\"," +
+ " \"explanation\": \"explanation 3\"," +
+ " \"targetsSender\": false," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": false" +
+ " }" +
+ "]}");
+ }
+
+ @Test
+ void putShouldStoreTheConfigurationsWhenExplanationNotSpecified() {
+ String storeBody =
+ "{\"rules\": [{" +
+ " \"id\": \"3\"," +
+ " \"expression\": \"expression 3\"" +
+ "}]}";
+
+ given()
+ .body(storeBody)
+ .when()
+ .put(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.NO_CONTENT_204);
+
+ String retrievedBody = with()
+ .get(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .contentType(ContentType.JSON)
+ .extract()
+ .body().asString();
+
+ assertThatJson(retrievedBody)
+ .isEqualTo(
+ "{\"rules\": [" +
+ " {" +
+ " \"id\": \"3\"," +
+ " \"expression\": \"expression 3\"," +
+ " \"explanation\": null," +
+ " \"targetsSender\": false," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": false" +
+ " }" +
+ "]}");
+ }
+
+ @Test
+ void putShouldReturnBadRequestWhenIdIsNotSpecified() {
+ String body =
+ "{" +
+ " \"expression\": \"expression 4\"," +
+ " \"explanation\": \"explanation 4\"," +
+ " \"targetsSender\": false," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": false" +
+ "}";
+
+ given()
+ .body(body)
+ .when()
+ .put(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .contentType(JSON_CONTENT_TYPE)
+ .body("statusCode", is(400))
+ .body("type", is("InvalidArgument"))
+ .body("message", is("JSON payload of the request is not valid"));
+ }
+
+ @Test
+ void putShouldReturnBadRequestWhenExpressionIsNotSpecified() {
+ String body =
+ "{" +
+ " \"id\": \"5\"," +
+ " \"explanation\": \"explanation 5\"," +
+ " \"targetsSender\": false," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": false" +
+ "}";
+
+ given()
+ .body(body)
+ .when()
+ .put(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .contentType(JSON_CONTENT_TYPE)
+ .body("statusCode", is(400))
+ .body("type", is("InvalidArgument"))
+ .body("message", is("JSON payload of the request is not valid"));
+ }
+
+ @Test
+ void putShouldReturnNotFoundWhenDomainNotInList() {
+ String body =
+ "[{" +
+ " \"id\": \"1\"," +
+ " \"expression\": \"expression 1\"," +
+ " \"explanation\": \"explanation 1\"," +
+ " \"targetsSender\": true," +
+ " \"targetsRecipients\": true," +
+ " \"targetsContent\": true" +
+ "}," +
+ "{" +
+ " \"id\": \"2\"," +
+ " \"expression\": \"expression 2\"," +
+ " \"explanation\": \"explanation 2\"," +
+ " \"targetsSender\": false," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": false" +
+ "}]";
+
+ given()
+ .body(body)
+ .when()
+ .put("strange.com")
+ .then()
+ .statusCode(HttpStatus.NOT_FOUND_404)
+ .contentType(JSON_CONTENT_TYPE)
+ .body("statusCode", is(HttpStatus.NOT_FOUND_404))
+ .body("type", is("InvalidArgument"))
+ .body("message", is("'strange.com' is not managed by this James server"));
+ }
+
+ @Test
+ void putShouldReturnBadRequestWhenDomainIsNotValid() {
+ String body =
+ "[{" +
+ " \"id\": \"1\"," +
+ " \"expression\": \"expression 1\"," +
+ " \"explanation\": \"explanation 1\"," +
+ " \"targetsSender\": true," +
+ " \"targetsRecipients\": true," +
+ " \"targetsContent\": true" +
+ "}," +
+ "{" +
+ " \"id\": \"2\"," +
+ " \"expression\": \"expression 2\"," +
+ " \"explanation\": \"explanation 2\"," +
+ " \"targetsSender\": false," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": false" +
+ "}]";
+
+ given()
+ .body(body)
+ .when()
+ .put("dr@strange.com")
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .contentType(JSON_CONTENT_TYPE)
+ .body("statusCode", is(HttpStatus.BAD_REQUEST_400))
+ .body("type", is("InvalidArgument"))
+ .body("message", is("Invalid request for domain: dr@strange.com"));
+ }
+ }
+
+ @Nested
+ class DefineClear {
+
+ @Test
+ void deleteShouldRemoveTheConfigurations() {
+ dlpStore.store(SENDER_DOMAIN, CONFIGURATION_ITEMS);
+
+ when()
+ .delete(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.NO_CONTENT_204);
+
+ String retrievedBody = with()
+ .get(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .contentType(ContentType.JSON)
+ .extract()
+ .body().asString();
+
+ assertThatJson(retrievedBody).isEqualTo("{\"rules\":[]}");
+ }
+
+ @Test
+ void deleteShouldRemoveOnlyConfigurationsFromCorrespondingDomain() {
+ dlpStore.store(SENDER_DOMAIN, CONFIGURATION_ITEMS);
+ dlpStore.store(SENDER_DOMAIN_2, CONFIGURATION_ITEMS_FOR_DOMAIN_2);
+
+ when()
+ .delete(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.NO_CONTENT_204);
+
+ String retrievedBody = with()
+ .get(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .contentType(ContentType.JSON)
+ .extract()
+ .body().asString();
+
+ assertThatJson(retrievedBody).isEqualTo("{\"rules\":[]}");
+
+ String retrievedBodyDomain2 = when()
+ .get(DOMAIN_2)
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .contentType(ContentType.JSON)
+ .extract()
+ .body().asString();
+
+ assertThatJson(retrievedBodyDomain2)
+ .isEqualTo(
+ "{\"rules\": [" +
+ " {" +
+ " \"id\": \"3\"," +
+ " \"expression\": \"apache.org\"," +
+ " \"explanation\": null," +
+ " \"targetsSender\": true," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": false" +
+ " }" +
+ "]}");
+ }
+
+ @Test
+ void deleteShouldReturnNotFoundWhenDomainNotInList() {
+ when()
+ .delete("strange.com")
+ .then()
+ .statusCode(HttpStatus.NOT_FOUND_404)
+ .contentType(JSON_CONTENT_TYPE)
+ .body("statusCode", is(HttpStatus.NOT_FOUND_404))
+ .body("type", is("InvalidArgument"))
+ .body("message", is("'strange.com' is not managed by this James server"));
+ }
+
+ @Test
+ void deleteShouldReturnBadRequestWhenDomainIsNotValid() {
+ when()
+ .delete("dr@strange.com")
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .contentType(JSON_CONTENT_TYPE)
+ .body("statusCode", is(HttpStatus.BAD_REQUEST_400))
+ .body("type", is("InvalidArgument"))
+ .body("message", is("Invalid request for domain: dr@strange.com"));
+ }
+ }
+
+ @Nested
+ class DefineList {
+
+ @Test
+ void getShouldReturnOK() {
+ dlpStore.store(SENDER_DOMAIN, CONFIGURATION_ITEMS);
+
+ when()
+ .get(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .contentType(ContentType.JSON);
+ }
+
+ @Test
+ void getShouldReturnABody() {
+ dlpStore.store(SENDER_DOMAIN, CONFIGURATION_ITEMS);
+
+ String body = when()
+ .get(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .contentType(ContentType.JSON)
+ .extract()
+ .body()
+ .asString();
+
+ assertThatJson(body).isEqualTo(
+ "{\"rules\": [" +
+ " {" +
+ " \"id\": \"1\"," +
+ " \"expression\": \"james.org\"," +
+ " \"explanation\": \"explanation 1\"," +
+ " \"targetsSender\": true," +
+ " \"targetsRecipients\": true," +
+ " \"targetsContent\": true" +
+ " }," +
+ " {" +
+ " \"id\": \"2\"," +
+ " \"expression\": \"james.org\"," +
+ " \"explanation\": null," +
+ " \"targetsSender\": true," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": false" +
+ " }" +
+ "]}");
+ }
+
+ @Test
+ void getShouldReturnAnEmptyBodyWhenDLPStoreIsEmpty() {
+ dlpStore.store(SENDER_DOMAIN, ImmutableList.of());
+
+ String body = when()
+ .get(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .contentType(ContentType.JSON)
+ .extract()
+ .body()
+ .asString();
+
+ assertThatJson(body).isEqualTo("{\"rules\":[]}");
+ }
+
+ @Test
+ void getShouldReturnOnlyConfigurationsFromCorrespondingDomain() {
+ dlpStore.store(SENDER_DOMAIN, CONFIGURATION_ITEMS);
+ dlpStore.store(SENDER_DOMAIN_2, CONFIGURATION_ITEMS_FOR_DOMAIN_2);
+
+ String body = when()
+ .get(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.OK_200)
+ .contentType(ContentType.JSON)
+ .extract()
+ .body()
+ .asString();
+
+ assertThatJson(body).isEqualTo(
+ "{\"rules\": [" +
+ " {" +
+ " \"id\": \"1\"," +
+ " \"expression\": \"james.org\"," +
+ " \"explanation\": \"explanation 1\"," +
+ " \"targetsSender\": true," +
+ " \"targetsRecipients\": true," +
+ " \"targetsContent\": true" +
+ " }," +
+ " {" +
+ " \"id\": \"2\"," +
+ " \"expression\": \"james.org\"," +
+ " \"explanation\": null," +
+ " \"targetsSender\": true," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": false" +
+ " }" +
+ "]}");
+ }
+
+ @Test
+ void getShouldReturnNotFoundWhenDomainNotInList() {
+ when()
+ .get("strange.com")
+ .then()
+ .statusCode(HttpStatus.NOT_FOUND_404)
+ .contentType(JSON_CONTENT_TYPE)
+ .body("statusCode", is(HttpStatus.NOT_FOUND_404))
+ .body("type", is("InvalidArgument"))
+ .body("message", is("'strange.com' is not managed by this James server"));
+ }
+
+ @Test
+ void getShouldReturnBadRequestWhenDomainIsNotValid() {
+ when()
+ .get("dr@strange.com")
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .contentType(JSON_CONTENT_TYPE)
+ .body("statusCode", is(HttpStatus.BAD_REQUEST_400))
+ .body("type", is("InvalidArgument"))
+ .body("message", is("Invalid request for domain: dr@strange.com"));
+ }
+ }
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[2/3] james-project git commit: JAMES-2428 [DLP] Webadmin DLP
markdown documentation
Posted by bt...@apache.org.
JAMES-2428 [DLP] Webadmin DLP markdown documentation
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/55cd111c
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/55cd111c
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/55cd111c
Branch: refs/heads/master
Commit: 55cd111c6ef2e5db545bd1101a8034515f69e623
Parents: dec6e89
Author: duc <dt...@linagora.com>
Authored: Fri Jun 15 15:13:47 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Wed Jun 20 09:08:10 2018 +0700
----------------------------------------------------------------------
.../main/java/org/apache/james/core/Domain.java | 5 +-
.../apache/james/CassandraJamesServerMain.java | 4 +-
.../org/apache/james/MemoryJamesServerMain.java | 4 +-
.../james/modules/server/DLPRoutesModule.java | 35 +++
.../james/modules/server/DataRoutesModules.java | 2 -
.../james/webadmin/utils/ErrorResponder.java | 2 +-
.../james/webadmin/utils/JsonExtractor.java | 3 +-
.../org/apache/james/webadmin/DLPModule.java | 36 ---
.../james/webadmin/dto/DLPConfigurationDTO.java | 20 +-
.../webadmin/dto/DLPConfigurationItemDTO.java | 55 ++---
.../webadmin/routes/DLPConfigurationRoutes.java | 67 +++---
.../dto/DLPConfigurationItemDTOTest.java | 49 ++--
.../routes/DLPConfigurationRoutesTest.java | 225 +++++++++++++++----
src/site/markdown/server/manage-webadmin.md | 115 ++++++++++
14 files changed, 440 insertions(+), 182 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/55cd111c/core/src/main/java/org/apache/james/core/Domain.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/james/core/Domain.java b/core/src/main/java/org/apache/james/core/Domain.java
index 808de41..1bcea59 100644
--- a/core/src/main/java/org/apache/james/core/Domain.java
+++ b/core/src/main/java/org/apache/james/core/Domain.java
@@ -37,8 +37,9 @@ public class Domain implements Serializable {
}
public static Domain of(String domain) {
- Preconditions.checkNotNull(domain);
- Preconditions.checkArgument(!domain.isEmpty() && !domain.contains("@"));
+ Preconditions.checkNotNull(domain, "Domain can not be null");
+ Preconditions.checkArgument(!domain.isEmpty() && !domain.contains("@"),
+ "Domain can not be empty nor contain `@`");
return new Domain(domain);
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/55cd111c/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java
index 035a272..4878e1e 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/CassandraJamesServerMain.java
@@ -44,6 +44,7 @@ import org.apache.james.modules.protocols.ProtocolHandlerModule;
import org.apache.james.modules.protocols.SMTPServerModule;
import org.apache.james.modules.server.ActiveMQQueueModule;
import org.apache.james.modules.server.CassandraRoutesModule;
+import org.apache.james.modules.server.DLPRoutesModule;
import org.apache.james.modules.server.DataRoutesModules;
import org.apache.james.modules.server.ElasticSearchMetricReporterModule;
import org.apache.james.modules.server.JMXServerModule;
@@ -67,7 +68,8 @@ public class CassandraJamesServerMain {
new MailQueueRoutesModule(),
new MailRepositoriesRoutesModule(),
new SwaggerRoutesModule(),
- new WebAdminServerModule());
+ new WebAdminServerModule(),
+ new DLPRoutesModule());
public static final Module PROTOCOLS = Modules.combine(
new CassandraJmapModule(),
http://git-wip-us.apache.org/repos/asf/james-project/blob/55cd111c/server/container/guice/memory-guice/src/main/java/org/apache/james/MemoryJamesServerMain.java
----------------------------------------------------------------------
diff --git a/server/container/guice/memory-guice/src/main/java/org/apache/james/MemoryJamesServerMain.java b/server/container/guice/memory-guice/src/main/java/org/apache/james/MemoryJamesServerMain.java
index 99783fd..fc80fe6 100644
--- a/server/container/guice/memory-guice/src/main/java/org/apache/james/MemoryJamesServerMain.java
+++ b/server/container/guice/memory-guice/src/main/java/org/apache/james/MemoryJamesServerMain.java
@@ -33,6 +33,7 @@ import org.apache.james.modules.protocols.POP3ServerModule;
import org.apache.james.modules.protocols.ProtocolHandlerModule;
import org.apache.james.modules.protocols.SMTPServerModule;
import org.apache.james.modules.server.CamelMailetContainerModule;
+import org.apache.james.modules.server.DLPRoutesModule;
import org.apache.james.modules.server.DataRoutesModules;
import org.apache.james.modules.server.JMXServerModule;
import org.apache.james.modules.server.MailQueueRoutesModule;
@@ -56,7 +57,8 @@ public class MemoryJamesServerMain {
new MailboxRoutesModule(),
new MailQueueRoutesModule(),
new MailRepositoriesRoutesModule(),
- new SwaggerRoutesModule());
+ new SwaggerRoutesModule(),
+ new DLPRoutesModule());
public static final Module PROTOCOLS = Modules.combine(
new IMAPServerModule(),
http://git-wip-us.apache.org/repos/asf/james-project/blob/55cd111c/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DLPRoutesModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DLPRoutesModule.java b/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DLPRoutesModule.java
new file mode 100644
index 0000000..96fcdde
--- /dev/null
+++ b/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DLPRoutesModule.java
@@ -0,0 +1,35 @@
+/****************************************************************
+ * 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.modules.server;
+
+import org.apache.james.webadmin.Routes;
+import org.apache.james.webadmin.routes.DLPConfigurationRoutes;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.multibindings.Multibinder;
+
+public class DLPRoutesModule extends AbstractModule {
+ @Override
+ protected void configure() {
+ Multibinder.newSetBinder(binder(), Routes.class)
+ .addBinding()
+ .to(DLPConfigurationRoutes.class);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/55cd111c/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DataRoutesModules.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DataRoutesModules.java b/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DataRoutesModules.java
index 2cb95c5..2ae64ec 100644
--- a/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DataRoutesModules.java
+++ b/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/DataRoutesModules.java
@@ -20,7 +20,6 @@
package org.apache.james.modules.server;
import org.apache.james.webadmin.Routes;
-import org.apache.james.webadmin.routes.DLPConfigurationRoutes;
import org.apache.james.webadmin.routes.DomainsRoutes;
import org.apache.james.webadmin.routes.ForwardRoutes;
import org.apache.james.webadmin.routes.GroupsRoutes;
@@ -34,7 +33,6 @@ public class DataRoutesModules extends AbstractModule {
@Override
protected void configure() {
Multibinder<Routes> routesMultibinder = Multibinder.newSetBinder(binder(), Routes.class);
- routesMultibinder.addBinding().to(DLPConfigurationRoutes.class);
routesMultibinder.addBinding().to(DomainsRoutes.class);
routesMultibinder.addBinding().to(ForwardRoutes.class);
routesMultibinder.addBinding().to(GroupsRoutes.class);
http://git-wip-us.apache.org/repos/asf/james-project/blob/55cd111c/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/ErrorResponder.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/ErrorResponder.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/ErrorResponder.java
index 73dde47..e72cbec 100644
--- a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/ErrorResponder.java
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/ErrorResponder.java
@@ -115,7 +115,7 @@ public class ErrorResponder {
cause.map(Throwable::getMessage)));
}
- static class ErrorDetail {
+ public static class ErrorDetail {
private final int statusCode;
private final String type;
private final String message;
http://git-wip-us.apache.org/repos/asf/james-project/blob/55cd111c/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java
index fcecc3d..83be263 100644
--- a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/utils/JsonExtractor.java
@@ -20,11 +20,11 @@
package org.apache.james.webadmin.utils;
import java.io.IOException;
-import java.util.Collection;
import java.util.List;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.guava.GuavaModule;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.google.common.collect.ImmutableList;
@@ -40,6 +40,7 @@ public class JsonExtractor<RequestT> {
public JsonExtractor(Class<RequestT> type, List<Module> modules) {
this.objectMapper = new ObjectMapper()
.registerModule(new Jdk8Module())
+ .registerModule(new GuavaModule())
.registerModules(modules);
this.type = type;
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/55cd111c/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/DLPModule.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/DLPModule.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/DLPModule.java
deleted file mode 100644
index 0363ca3..0000000
--- a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/DLPModule.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/****************************************************************
- * 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.webadmin;
-
-import org.apache.james.webadmin.utils.JsonTransformerModule;
-
-import com.fasterxml.jackson.databind.Module;
-import com.fasterxml.jackson.datatype.guava.GuavaModule;
-
-public class DLPModule implements JsonTransformerModule {
-
- public DLPModule() {
- }
-
- @Override
- public Module asJacksonModule() {
- return new GuavaModule();
- }
-}
http://git-wip-us.apache.org/repos/asf/james-project/blob/55cd111c/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationDTO.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationDTO.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationDTO.java
index d1265a6..5849f71 100644
--- a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationDTO.java
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationDTO.java
@@ -24,6 +24,7 @@ import java.util.List;
import org.apache.james.dlp.api.DLPConfigurationItem;
import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.steveash.guavate.Guavate;
import com.google.common.base.Preconditions;
@@ -31,15 +32,6 @@ import com.google.common.collect.ImmutableList;
public class DLPConfigurationDTO {
- public static List<DLPConfigurationItem> toDLPConfigurations(DLPConfigurationDTO dto) {
- Preconditions.checkNotNull(dto);
-
- return dto.rules
- .stream()
- .map(DLPConfigurationItemDTO::toDLPConfiguration)
- .collect(Guavate.toImmutableList());
- }
-
public static DLPConfigurationDTO toDTO(List<DLPConfigurationItem> dlpConfigurations) {
Preconditions.checkNotNull(dlpConfigurations);
@@ -54,11 +46,19 @@ public class DLPConfigurationDTO {
@JsonCreator
public DLPConfigurationDTO(
- @JsonProperty("rules") ImmutableList<DLPConfigurationItemDTO> rules) {
+ @JsonProperty("rules") ImmutableList<DLPConfigurationItemDTO> rules) {
this.rules = rules;
}
public ImmutableList<DLPConfigurationItemDTO> getRules() {
return rules;
}
+
+ @JsonIgnore
+ public List<DLPConfigurationItem> toDLPConfigurations() {
+ return rules
+ .stream()
+ .map(DLPConfigurationItemDTO::toDLPConfiguration)
+ .collect(Guavate.toImmutableList());
+ }
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/55cd111c/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTO.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTO.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTO.java
index 502615a..5f3da5f 100644
--- a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTO.java
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTO.java
@@ -19,58 +19,47 @@
package org.apache.james.webadmin.dto;
-import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.apache.james.dlp.api.DLPConfigurationItem;
import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.github.steveash.guavate.Guavate;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
public class DLPConfigurationItemDTO {
@VisibleForTesting
- static DLPConfigurationItem toDLPConfiguration(DLPConfigurationItemDTO dto) {
- return DLPConfigurationItem.builder()
- .id(DLPConfigurationItem.Id.of(dto.id))
- .expression(dto.expression)
- .explanation(dto.explanation)
- .targetsSender(dto.targetsSender)
- .targetsRecipients(dto.targetsRecipients)
- .targetsContent(dto.targetsContent)
- .build();
- }
-
- @VisibleForTesting
static DLPConfigurationItemDTO toDTO(DLPConfigurationItem dlpConfiguration) {
DLPConfigurationItem.Targets targets = dlpConfiguration.getTargets();
return new DLPConfigurationItemDTO(
dlpConfiguration.getId().asString(),
- dlpConfiguration.getRegexp(),
+ dlpConfiguration.getRegexp().pattern(),
dlpConfiguration.getExplanation(),
- Optional.of(targets.isSenderTargeted()),
- Optional.of(targets.isRecipientTargeted()),
- Optional.of(targets.isContentTargeted()));
+ targets.isSenderTargeted(),
+ targets.isRecipientTargeted(),
+ targets.isRecipientTargeted());
}
+
+
private final String id;
private final String expression;
private final Optional<String> explanation;
- private final Optional<Boolean> targetsSender;
- private final Optional<Boolean> targetsRecipients;
- private final Optional<Boolean> targetsContent;
+ private final boolean targetsSender;
+ private final boolean targetsRecipients;
+ private final boolean targetsContent;
@JsonCreator
public DLPConfigurationItemDTO(@JsonProperty("id") String id,
@JsonProperty("expression") String expression,
@JsonProperty("explanation") Optional<String> explanation,
- @JsonProperty("targetsSender") Optional<Boolean> targetsSender,
- @JsonProperty("targetsRecipients") Optional<Boolean> targetsRecipients,
- @JsonProperty("targetsContent") Optional<Boolean> targetsContent) {
+ @JsonProperty("targetsSender") boolean targetsSender,
+ @JsonProperty("targetsRecipients") boolean targetsRecipients,
+ @JsonProperty("targetsContent") boolean targetsContent) {
Preconditions.checkNotNull(id, "'id' is mandatory");
Preconditions.checkNotNull(expression, "'expression' is mandatory");
this.id = id;
@@ -93,18 +82,30 @@ public class DLPConfigurationItemDTO {
return explanation;
}
- public Optional<Boolean> getTargetsSender() {
+ public boolean getTargetsSender() {
return targetsSender;
}
- public Optional<Boolean> getTargetsRecipients() {
+ public boolean getTargetsRecipients() {
return targetsRecipients;
}
- public Optional<Boolean> getTargetsContent() {
+ public boolean getTargetsContent() {
return targetsContent;
}
+ @JsonIgnore
+ public DLPConfigurationItem toDLPConfiguration() {
+ return DLPConfigurationItem.builder()
+ .id(DLPConfigurationItem.Id.of(id))
+ .expression(expression)
+ .explanation(explanation)
+ .targetsSender(targetsSender)
+ .targetsRecipients(targetsRecipients)
+ .targetsContent(targetsContent)
+ .build();
+ }
+
@Override
public final boolean equals(Object o) {
if (o instanceof DLPConfigurationItemDTO) {
http://git-wip-us.apache.org/repos/asf/james-project/blob/55cd111c/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DLPConfigurationRoutes.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DLPConfigurationRoutes.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DLPConfigurationRoutes.java
index 73b1d33..c735337 100644
--- a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DLPConfigurationRoutes.java
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DLPConfigurationRoutes.java
@@ -46,11 +46,12 @@ import org.apache.james.webadmin.utils.JsonExtractor;
import org.apache.james.webadmin.utils.JsonTransformer;
import org.eclipse.jetty.http.HttpStatus;
-import com.fasterxml.jackson.datatype.guava.GuavaModule;
import com.github.steveash.guavate.Guavate;
+
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
@@ -59,6 +60,9 @@ import spark.Request;
import spark.Service;
@Api(tags = "DLPRules")
+@ApiModel(description = "DLP (stands for Data Leak Prevention) is supported by James. A DLP matcher will, on incoming emails, " +
+ "execute regular expressions on email sender, recipients or content, in order to report suspicious emails to" +
+ "an administrator. WebAdmin can be used to manage these DLP rules on a per sender-domain basis.")
@Path(DLPConfigurationRoutes.BASE_PATH)
@Produces(JSON_CONTENT_TYPE)
public class DLPConfigurationRoutes implements Routes {
@@ -73,46 +77,47 @@ public class DLPConfigurationRoutes implements Routes {
private final JsonExtractor<DLPConfigurationDTO> jsonExtractor;
private final DomainList domainList;
- private Service service;
-
@Inject
public DLPConfigurationRoutes(DLPConfigurationStore dlpConfigurationStore, DomainList domainList, JsonTransformer jsonTransformer) {
this.dlpConfigurationStore = dlpConfigurationStore;
this.domainList = domainList;
this.jsonTransformer = jsonTransformer;
- this.jsonExtractor = new JsonExtractor<>(DLPConfigurationDTO.class, new GuavaModule());
+ this.jsonExtractor = new JsonExtractor<>(DLPConfigurationDTO.class);
}
@Override
public void define(Service service) {
- this.service = service;
- defineStore();
+ defineStore(service);
- defineList();
+ defineList(service);
- defineClear();
+ defineClear(service);
}
@PUT
@Path("/{senderDomain}")
- @ApiOperation(value = "Store a list of dlp configs for given senderDomain")
+ @ApiOperation(value = "Store a DLP configuration for given senderDomain")
@ApiImplicitParams({
- @ApiImplicitParam(required = true, dataType = "string", name = "senderDomain", paramType = "path")
+ @ApiImplicitParam(required = true, dataType = "string", name = "senderDomain", paramType = "path"),
+ @ApiImplicitParam(required = true, dataType = "org.apache.james.webadmin.dto.DLPConfigurationDTO", paramType = "body")
})
@ApiResponses(value = {
- @ApiResponse(code = HttpStatus.NO_CONTENT_204, message = "OK. dlp config is stored."),
- @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid senderDomain or payload in request"),
- @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "The domain does not exist."),
+ @ApiResponse(code = HttpStatus.NO_CONTENT_204, message = "OK. DLP configuration is stored."),
+ @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid senderDomain or payload in request",
+ response = ErrorResponder.ErrorDetail.class),
+ @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "The domain does not exist.",
+ response = ErrorResponder.ErrorDetail.class),
@ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
- message = "Internal server error - Something went bad on the server side.")
+ message = "Internal server error - Something went bad on the server side.",
+ response = ErrorResponder.ErrorDetail.class)
})
- public void defineStore() {
+ public void defineStore(Service service) {
service.put(SPECIFIC_DLP_RULE_DOMAIN, (request, response) -> {
Domain senderDomain = parseDomain(request);
DLPConfigurationDTO dto = jsonExtractor.parse(request.body());
- dlpConfigurationStore.store(senderDomain, DLPConfigurationDTO.toDLPConfigurations(dto));
+ dlpConfigurationStore.store(senderDomain, dto.toDLPConfigurations());
response.status(HttpStatus.NO_CONTENT_204);
return EMPTY_BODY;
@@ -121,18 +126,21 @@ public class DLPConfigurationRoutes implements Routes {
@GET
@Path("/{senderDomain}")
- @ApiOperation(value = "Retrieve a list of dlp configs for given senderDomain")
+ @ApiOperation(value = "Return a DLP configuration for given senderDomain")
@ApiImplicitParams({
@ApiImplicitParam(required = true, dataType = "string", name = "senderDomain", paramType = "path")
})
@ApiResponses(value = {
- @ApiResponse(code = HttpStatus.OK_200, message = "OK. dlp configs returned"),
- @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid senderDomain in request"),
- @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "The domain does not exist."),
+ @ApiResponse(code = HttpStatus.OK_200, message = "OK. DLP configuration is returned", response = DLPConfigurationDTO.class),
+ @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid senderDomain in request",
+ response = ErrorResponder.ErrorDetail.class),
+ @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "The domain does not exist.",
+ response = ErrorResponder.ErrorDetail.class),
@ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
- message = "Internal server error - Something went bad on the server side.")
+ message = "Internal server error - Something went bad on the server side.",
+ response = ErrorResponder.ErrorDetail.class)
})
- public void defineList() {
+ public void defineList(Service service) {
service.get(SPECIFIC_DLP_RULE_DOMAIN, (request, response) -> {
Domain senderDomain = parseDomain(request);
List<DLPConfigurationItem> dlpConfigurations = dlpConfigurationStore
@@ -148,18 +156,21 @@ public class DLPConfigurationRoutes implements Routes {
@DELETE
@Path("/{senderDomain}")
- @ApiOperation(value = "Clear all dlp configs for given senderDomain")
+ @ApiOperation(value = "Clear a DLP configuration for a given senderDomain")
@ApiImplicitParams({
@ApiImplicitParam(required = true, dataType = "string", name = "senderDomain", paramType = "path")
})
@ApiResponses(value = {
- @ApiResponse(code = HttpStatus.NO_CONTENT_204, message = "OK. dlp configs are cleared"),
- @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid senderDomain in request"),
- @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "The domain does not exist."),
+ @ApiResponse(code = HttpStatus.NO_CONTENT_204, message = "OK. DLP configuration is cleared"),
+ @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid senderDomain in request",
+ response = ErrorResponder.ErrorDetail.class),
+ @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "The domain does not exist.",
+ response = ErrorResponder.ErrorDetail.class),
@ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
- message = "Internal server error - Something went bad on the server side.")
+ message = "Internal server error - Something went bad on the server side.",
+ response = ErrorResponder.ErrorDetail.class)
})
- public void defineClear() {
+ public void defineClear(Service service) {
service.delete(SPECIFIC_DLP_RULE_DOMAIN, (request, response) -> {
Domain senderDomain = parseDomain(request);
dlpConfigurationStore.clear(senderDomain);
http://git-wip-us.apache.org/repos/asf/james-project/blob/55cd111c/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTOTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTOTest.java b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTOTest.java
index a4b0da8..1c8f1f6 100644
--- a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTOTest.java
+++ b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/dto/DLPConfigurationItemDTOTest.java
@@ -21,15 +21,12 @@ package org.apache.james.webadmin.dto;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import java.util.List;
import java.util.Optional;
import org.apache.james.dlp.api.DLPConfigurationItem;
import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.Test;
-import com.google.common.collect.ImmutableList;
-
class DLPConfigurationItemDTOTest {
private static final String ID = "id";
@@ -39,41 +36,41 @@ class DLPConfigurationItemDTOTest {
private static final String NULL_EXPRESSION = null;
@Test
- void toDTOsShouldBeSetAllFields() {
+ void toDTOsShouldSetAllFields() {
DLPConfigurationItemDTO dto = DLPConfigurationItemDTO.toDTO(
DLPConfigurationItem.builder()
.id(DLPConfigurationItem.Id.of(ID))
.expression(EXPRESSION)
.explanation(EXPLANATION)
- .targetsSender(Optional.of(true))
- .targetsRecipients(Optional.of(true))
- .targetsContent(Optional.of(true))
+ .targetsSender(true)
+ .targetsRecipients(true)
+ .targetsContent(true)
.build());
SoftAssertions.assertSoftly(softly -> {
softly.assertThat(dto.getId()).isEqualTo(ID);
softly.assertThat(dto.getExpression()).isEqualTo(EXPRESSION);
softly.assertThat(dto.getExplanation().get()).isEqualTo(EXPLANATION);
- softly.assertThat(dto.getTargetsSender().get()).isTrue();
- softly.assertThat(dto.getTargetsRecipients().get()).isTrue();
- softly.assertThat(dto.getTargetsContent().get()).isTrue();
+ softly.assertThat(dto.getTargetsSender()).isTrue();
+ softly.assertThat(dto.getTargetsRecipients()).isTrue();
+ softly.assertThat(dto.getTargetsContent()).isTrue();
});
}
@Test
- void toDLPConfigurationsShouldBeSetAllFields() {
- DLPConfigurationItem item = DLPConfigurationItemDTO.toDLPConfiguration(
- new DLPConfigurationItemDTO(
- ID,
- EXPRESSION,
- Optional.of(EXPLANATION),
- Optional.of(true),
- Optional.of(true),
- Optional.of(true)));
+ void toDLPConfigurationsShouldSetAllFields() {
+ DLPConfigurationItemDTO itemDTO = new DLPConfigurationItemDTO(
+ ID,
+ EXPRESSION,
+ Optional.of(EXPLANATION),
+ true,
+ true,
+ true);
+ DLPConfigurationItem item = itemDTO.toDLPConfiguration();
SoftAssertions.assertSoftly(softly -> {
softly.assertThat(item.getId().asString()).isEqualTo(ID);
- softly.assertThat(item.getRegexp()).isEqualTo(EXPRESSION);
+ softly.assertThat(item.getRegexp().pattern()).isEqualTo(EXPRESSION);
softly.assertThat(item.getExplanation().get()).isEqualTo(EXPLANATION);
softly.assertThat(item.getTargets().isSenderTargeted()).isTrue();
softly.assertThat(item.getTargets().isRecipientTargeted()).isTrue();
@@ -86,9 +83,9 @@ class DLPConfigurationItemDTOTest {
assertThatThrownBy(() -> new DLPConfigurationItemDTO(NULL_ID,
EXPRESSION,
Optional.of(EXPLANATION),
- Optional.of(true),
- Optional.of(true),
- Optional.of(true)))
+ true,
+ true,
+ true))
.isInstanceOf(NullPointerException.class);
}
@@ -97,9 +94,9 @@ class DLPConfigurationItemDTOTest {
assertThatThrownBy(() -> new DLPConfigurationItemDTO(ID,
NULL_EXPRESSION,
Optional.of(EXPLANATION),
- Optional.of(true),
- Optional.of(true),
- Optional.of(true)))
+ true,
+ true,
+ true))
.isInstanceOf(NullPointerException.class);
}
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/55cd111c/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DLPConfigurationRoutesTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DLPConfigurationRoutesTest.java b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DLPConfigurationRoutesTest.java
index 74d3468..49b6614 100644
--- a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DLPConfigurationRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DLPConfigurationRoutesTest.java
@@ -31,10 +31,8 @@ import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import java.net.InetAddress;
-import java.util.List;
import org.apache.james.core.Domain;
-import org.apache.james.dlp.api.DLPConfigurationItem;
import org.apache.james.dlp.api.DLPConfigurationStore;
import org.apache.james.dlp.eventsourcing.EventSourcingDLPConfigurationStore;
import org.apache.james.dnsservice.api.DNSService;
@@ -42,7 +40,6 @@ import org.apache.james.domainlist.api.DomainList;
import org.apache.james.domainlist.memory.MemoryDomainList;
import org.apache.james.eventsourcing.eventstore.memory.InMemoryEventStore;
import org.apache.james.metrics.logger.DefaultMetricFactory;
-import org.apache.james.webadmin.DLPModule;
import org.apache.james.webadmin.WebAdminServer;
import org.apache.james.webadmin.WebAdminUtils;
import org.apache.james.webadmin.utils.JsonTransformer;
@@ -52,7 +49,6 @@ import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
-import com.google.common.collect.ImmutableList;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.specification.RequestSpecification;
@@ -64,35 +60,13 @@ class DLPConfigurationRoutesTest {
private static final String DOMAIN_2 = "apache.org";
private static final Domain SENDER_DOMAIN_2 = Domain.of(DOMAIN_2);
- private static final DLPConfigurationItem CONFIGURATION_ITEM_1 = DLPConfigurationItem.builder()
- .id(DLPConfigurationItem.Id.of("1"))
- .explanation("explanation 1")
- .expression(DEFAULT_DOMAIN)
- .targetsSender()
- .targetsRecipients()
- .targetsContent()
- .build();
- private static final DLPConfigurationItem CONFIGURATION_ITEM_2 = DLPConfigurationItem.builder()
- .id(DLPConfigurationItem.Id.of("2"))
- .expression(DEFAULT_DOMAIN)
- .targetsSender()
- .build();
-
- private static final List<DLPConfigurationItem> CONFIGURATION_ITEMS_FOR_DOMAIN_2 = ImmutableList.of(DLPConfigurationItem.builder()
- .id(DLPConfigurationItem.Id.of("3"))
- .expression(DOMAIN_2)
- .targetsSender()
- .build());
-
- private static final List<DLPConfigurationItem> CONFIGURATION_ITEMS = ImmutableList.of(CONFIGURATION_ITEM_1, CONFIGURATION_ITEM_2);
-
private WebAdminServer webAdminServer;
private EventSourcingDLPConfigurationStore dlpStore;
private void createServer(DLPConfigurationStore dlpConfigurationStore, DomainList domainList) throws Exception {
webAdminServer = WebAdminUtils.createWebAdminServer(
new DefaultMetricFactory(),
- new DLPConfigurationRoutes(dlpConfigurationStore, domainList, new JsonTransformer(new DLPModule())));
+ new DLPConfigurationRoutes(dlpConfigurationStore, domainList, new JsonTransformer()));
webAdminServer.configure(NO_CONFIGURATION);
webAdminServer.await();
@@ -247,13 +221,13 @@ class DLPConfigurationRoutesTest {
@Test
void putShouldReturnBadRequestWhenIdIsNotSpecified() {
String body =
- "{" +
+ "{\"rules\": [{" +
" \"expression\": \"expression 4\"," +
" \"explanation\": \"explanation 4\"," +
" \"targetsSender\": false," +
" \"targetsRecipients\": false," +
" \"targetsContent\": false" +
- "}";
+ "}]}";
given()
.body(body)
@@ -264,19 +238,20 @@ class DLPConfigurationRoutesTest {
.contentType(JSON_CONTENT_TYPE)
.body("statusCode", is(400))
.body("type", is("InvalidArgument"))
- .body("message", is("JSON payload of the request is not valid"));
+ .body("message", is("JSON payload of the request is not valid"))
+ .body("details", is("Instantiation of [simple type, class org.apache.james.webadmin.dto.DLPConfigurationItemDTO] value failed: 'id' is mandatory (through reference chain: org.apache.james.webadmin.dto.DLPConfigurationDTO[\"rules\"])"));
}
@Test
void putShouldReturnBadRequestWhenExpressionIsNotSpecified() {
String body =
- "{" +
+ "{\"rules\": [{" +
" \"id\": \"5\"," +
" \"explanation\": \"explanation 5\"," +
" \"targetsSender\": false," +
" \"targetsRecipients\": false," +
" \"targetsContent\": false" +
- "}";
+ "}]}";
given()
.body(body)
@@ -287,7 +262,8 @@ class DLPConfigurationRoutesTest {
.contentType(JSON_CONTENT_TYPE)
.body("statusCode", is(400))
.body("type", is("InvalidArgument"))
- .body("message", is("JSON payload of the request is not valid"));
+ .body("message", is("JSON payload of the request is not valid"))
+ .body("details", is("Instantiation of [simple type, class org.apache.james.webadmin.dto.DLPConfigurationItemDTO] value failed: 'expression' is mandatory (through reference chain: org.apache.james.webadmin.dto.DLPConfigurationDTO[\"rules\"])"));
}
@Test
@@ -351,7 +327,8 @@ class DLPConfigurationRoutesTest {
.contentType(JSON_CONTENT_TYPE)
.body("statusCode", is(HttpStatus.BAD_REQUEST_400))
.body("type", is("InvalidArgument"))
- .body("message", is("Invalid request for domain: dr@strange.com"));
+ .body("message", is("Invalid request for domain: dr@strange.com"))
+ .body("details", is("Domain can not be empty nor contain `@`"));
}
}
@@ -360,7 +337,31 @@ class DLPConfigurationRoutesTest {
@Test
void deleteShouldRemoveTheConfigurations() {
- dlpStore.store(SENDER_DOMAIN, CONFIGURATION_ITEMS);
+ String storeBody =
+ "{\"rules\": [" +
+ " {" +
+ " \"id\": \"1\"," +
+ " \"expression\": \"expression 1\"," +
+ " \"explanation\": \"explanation 1\"," +
+ " \"targetsSender\": true," +
+ " \"targetsRecipients\": true," +
+ " \"targetsContent\": true" +
+ " }," +
+ " {" +
+ " \"id\": \"2\"," +
+ " \"expression\": \"expression 2\"," +
+ " \"explanation\": \"explanation 2\"," +
+ " \"targetsSender\": false," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": false" +
+ " }]}";
+
+ given()
+ .body(storeBody)
+ .when()
+ .put(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.NO_CONTENT_204);
when()
.delete(DEFAULT_DOMAIN)
@@ -380,8 +381,48 @@ class DLPConfigurationRoutesTest {
@Test
void deleteShouldRemoveOnlyConfigurationsFromCorrespondingDomain() {
- dlpStore.store(SENDER_DOMAIN, CONFIGURATION_ITEMS);
- dlpStore.store(SENDER_DOMAIN_2, CONFIGURATION_ITEMS_FOR_DOMAIN_2);
+ String storeBody =
+ "{\"rules\": [" +
+ " {" +
+ " \"id\": \"1\"," +
+ " \"expression\": \"expression 1\"," +
+ " \"explanation\": \"explanation 1\"," +
+ " \"targetsSender\": true," +
+ " \"targetsRecipients\": true," +
+ " \"targetsContent\": true" +
+ " }," +
+ " {" +
+ " \"id\": \"2\"," +
+ " \"expression\": \"expression 2\"," +
+ " \"explanation\": \"explanation 2\"," +
+ " \"targetsSender\": false," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": false" +
+ " }]}";
+
+ given()
+ .body(storeBody)
+ .when()
+ .put(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.NO_CONTENT_204);
+
+
+ String storeDomain2Body =
+ "{\"rules\": [" +
+ " {" +
+ " \"id\": \"3\"," +
+ " \"expression\": \"apache.org\"," +
+ " \"targetsSender\": true" +
+ " }" +
+ "]}";
+
+ given()
+ .body(storeDomain2Body)
+ .when()
+ .put(DOMAIN_2)
+ .then()
+ .statusCode(HttpStatus.NO_CONTENT_204);
when()
.delete(DEFAULT_DOMAIN)
@@ -441,7 +482,8 @@ class DLPConfigurationRoutesTest {
.contentType(JSON_CONTENT_TYPE)
.body("statusCode", is(HttpStatus.BAD_REQUEST_400))
.body("type", is("InvalidArgument"))
- .body("message", is("Invalid request for domain: dr@strange.com"));
+ .body("message", is("Invalid request for domain: dr@strange.com"))
+ .body("details", is("Domain can not be empty nor contain `@`"));
}
}
@@ -450,7 +492,24 @@ class DLPConfigurationRoutesTest {
@Test
void getShouldReturnOK() {
- dlpStore.store(SENDER_DOMAIN, CONFIGURATION_ITEMS);
+ String storeBody =
+ "{\"rules\": [" +
+ " {" +
+ " \"id\": \"1\"," +
+ " \"expression\": \"expression 1\"," +
+ " \"explanation\": \"explanation 1\"," +
+ " \"targetsSender\": true," +
+ " \"targetsRecipients\": true," +
+ " \"targetsContent\": true" +
+ " }" +
+ "]}";
+
+ given()
+ .body(storeBody)
+ .when()
+ .put(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.NO_CONTENT_204);
when()
.get(DEFAULT_DOMAIN)
@@ -461,7 +520,31 @@ class DLPConfigurationRoutesTest {
@Test
void getShouldReturnABody() {
- dlpStore.store(SENDER_DOMAIN, CONFIGURATION_ITEMS);
+ String storeBody =
+ "{\"rules\": [" +
+ " {" +
+ " \"id\": \"1\"," +
+ " \"expression\": \"james.org\"," +
+ " \"explanation\": \"explanation 1\"," +
+ " \"targetsSender\": true," +
+ " \"targetsRecipients\": true," +
+ " \"targetsContent\": true" +
+ " }," +
+ " {" +
+ " \"id\": \"2\"," +
+ " \"expression\": \"james.org\"," +
+ " \"explanation\": \"explanation 2\"," +
+ " \"targetsSender\": true," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": false" +
+ " }]}";
+
+ given()
+ .body(storeBody)
+ .when()
+ .put(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.NO_CONTENT_204);
String body = when()
.get(DEFAULT_DOMAIN)
@@ -485,7 +568,7 @@ class DLPConfigurationRoutesTest {
" {" +
" \"id\": \"2\"," +
" \"expression\": \"james.org\"," +
- " \"explanation\": null," +
+ " \"explanation\": \"explanation 2\"," +
" \"targetsSender\": true," +
" \"targetsRecipients\": false," +
" \"targetsContent\": false" +
@@ -495,7 +578,14 @@ class DLPConfigurationRoutesTest {
@Test
void getShouldReturnAnEmptyBodyWhenDLPStoreIsEmpty() {
- dlpStore.store(SENDER_DOMAIN, ImmutableList.of());
+ String storeBody = "{\"rules\": []}";
+
+ given()
+ .body(storeBody)
+ .when()
+ .put(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.NO_CONTENT_204);
String body = when()
.get(DEFAULT_DOMAIN)
@@ -511,8 +601,48 @@ class DLPConfigurationRoutesTest {
@Test
void getShouldReturnOnlyConfigurationsFromCorrespondingDomain() {
- dlpStore.store(SENDER_DOMAIN, CONFIGURATION_ITEMS);
- dlpStore.store(SENDER_DOMAIN_2, CONFIGURATION_ITEMS_FOR_DOMAIN_2);
+ String storeBody =
+ "{\"rules\": [" +
+ " {" +
+ " \"id\": \"1\"," +
+ " \"expression\": \"james.org\"," +
+ " \"explanation\": \"explanation 1\"," +
+ " \"targetsSender\": true," +
+ " \"targetsRecipients\": true," +
+ " \"targetsContent\": true" +
+ " }," +
+ " {" +
+ " \"id\": \"2\"," +
+ " \"expression\": \"james.org\"," +
+ " \"explanation\": \"explanation 2\"," +
+ " \"targetsSender\": false," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": false" +
+ " }]}";
+
+ given()
+ .body(storeBody)
+ .when()
+ .put(DEFAULT_DOMAIN)
+ .then()
+ .statusCode(HttpStatus.NO_CONTENT_204);
+
+
+ String storeDomain2Body =
+ "{\"rules\": [" +
+ " {" +
+ " \"id\": \"3\"," +
+ " \"expression\": \"apache.org\"," +
+ " \"targetsSender\": true" +
+ " }" +
+ "]}";
+
+ given()
+ .body(storeDomain2Body)
+ .when()
+ .put(DOMAIN_2)
+ .then()
+ .statusCode(HttpStatus.NO_CONTENT_204);
String body = when()
.get(DEFAULT_DOMAIN)
@@ -536,8 +666,8 @@ class DLPConfigurationRoutesTest {
" {" +
" \"id\": \"2\"," +
" \"expression\": \"james.org\"," +
- " \"explanation\": null," +
- " \"targetsSender\": true," +
+ " \"explanation\": \"explanation 2\"," +
+ " \"targetsSender\": false," +
" \"targetsRecipients\": false," +
" \"targetsContent\": false" +
" }" +
@@ -565,7 +695,8 @@ class DLPConfigurationRoutesTest {
.contentType(JSON_CONTENT_TYPE)
.body("statusCode", is(HttpStatus.BAD_REQUEST_400))
.body("type", is("InvalidArgument"))
- .body("message", is("Invalid request for domain: dr@strange.com"));
+ .body("message", is("Invalid request for domain: dr@strange.com"))
+ .body("details", is("Domain can not be empty nor contain `@`"));
}
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/james-project/blob/55cd111c/src/site/markdown/server/manage-webadmin.md
----------------------------------------------------------------------
diff --git a/src/site/markdown/server/manage-webadmin.md b/src/site/markdown/server/manage-webadmin.md
index 1a574d3..7ba63af 100644
--- a/src/site/markdown/server/manage-webadmin.md
+++ b/src/site/markdown/server/manage-webadmin.md
@@ -33,6 +33,7 @@ In case of any error, the system will return an error message which is json form
- [Creating address forwards](#Creating_address_forwards)
- [Administrating mail repositories](#Administrating_mail_repositories)
- [Administrating mail queues](#Administrating_mail_queues)
+ - [Administrating DLP Configuration](#Administrating_dlp_configuration)
- [Task management](#Task_management)
## Administrating domains
@@ -1754,6 +1755,120 @@ Response codes:
- 404: The mail queue does not exist
- 500: Internal error
+## Administrating DLP Configuration
+
+DLP (stands for Data Leak Prevention) is supported by James. A DLP matcher will, on incoming emails,
+execute regular expressions on email sender, recipients or content, in order to report suspicious emails to
+an administrator. WebAdmin can be used to manage these DLP rules on a per `senderDomain` basis.
+
+`senderDomain` is domain of the sender of incoming emails, for example: `apache.org`, `james.org`,...
+Each `senderDomain` correspond to a distinct DLP configuration.
+
+- [List DLP configuration by sender domain](List_dlp_configuration_by_sender_domain)
+- [Store DLP configuration by sender domain](Store_dlp_configuration_by_sender_domain)
+- [Remove DLP configuration by sender domain](Remove_dlp_configuration_by_sender_domain)
+
+### List DLP configuration by sender domain
+
+Retrieve a DLP configuration for corresponding `senderDomain`, a configuration contains list of configuration items
+
+```
+curl -XGET http://ip:port/dlp/rules/senderDomain
+```
+
+Response codes:
+
+ - 200: A list of dlp configuration items is returned
+ - 400: Invalid senderDomain or payload in request
+ - 404: The domain does not exist.
+ - 500: Internal error
+
+This is an example of returned body. The rules field is a list of rules as described below.
+
+```
+{"rules : [
+ {
+ "id": "1",
+ "expression": "james.org",
+ "explanation": "Find senders or recipients containing james[any char]org",
+ "targetsSender": true,
+ "targetsRecipients": true,
+ "targetsContent": false
+ },
+ {
+ "id": "2",
+ "expression": "Find senders containing apache[any char]org",
+ "explanation": "apache.org",
+ "targetsSender": true,
+ "targetsRecipients": false,
+ "targetsContent": false
+ }
+]}
+```
+
+### Store DLP configuration by sender domain
+
+Store a DLP configuration for corresponding `senderDomain`, if any item of DLP configuration in the request is stored before,
+it will not be stored anymore
+
+```
+curl -XPUT http://ip:port/dlp/rules/senderDomain
+```
+
+The body can contain a list of DLP configuration items formed by those fields:
+- `id`(String) is mandatory, unique identifier of the configuration item
+- `expression`(String) is mandatory, regular expression to match contents of targets
+- `explanation`(String) is optional, description of the configuration item
+- `targetsSender`(boolean) is optional and defaults to false. If true, `expression` will be applied to Sender and to From headers of the mail
+- `targetsContent`(boolean) is optional and defaults to false. If true, `expression` will be applied to Subject headers and textual bodies (text/plain and text/html) of the mail
+- `targetsRecipients`(boolean) is optional and defaults to false. If true, `expression` will be applied to recipients of the mail
+
+This is an example of returned body. The rules field is a list of rules as described below.
+
+```
+{"rules": [
+ {
+ "id": "1",
+ "expression": "james.org",
+ "explanation": "Find senders or recipients containing james[any char]org",
+ "targetsSender": true,
+ "targetsRecipients": true,
+ "targetsContent": false
+ },
+ {
+ "id": "2",
+ "expression": "Find senders containing apache[any char]org",
+ "explanation": "apache.org",
+ "targetsSender": true,
+ "targetsRecipients": false,
+ "targetsContent": false
+ }
+]}
+```
+
+Response codes:
+
+ - 204: List of dlp configuration items is stored
+ - 400: Invalid senderDomain or payload in request
+ - 404: The domain does not exist.
+ - 500: Internal error
+
+### Remove DLP configuration by sender domain
+
+Remove a DLP configuration for corresponding `senderDomain`
+
+```
+curl -XDELETE http://ip:port/dlp/rules/senderDomain
+```
+
+Response codes:
+
+ - 204: DLP configuration is removed
+ - 400: Invalid senderDomain or payload in request
+ - 404: The domain does not exist.
+ - 500: Internal error
+
+
## Task management
Some webadmin features schedules tasks. The task management API allow to monitor and manage the execution of the following tasks.
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org
[3/3] james-project git commit: JAMES-2430 Write an integration test
for DLP matcher
Posted by bt...@apache.org.
JAMES-2430 Write an integration test for DLP matcher
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/536f3caa
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/536f3caa
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/536f3caa
Branch: refs/heads/master
Commit: 536f3caab4744f777cd449a0c94ce08476bae4d3
Parents: 55cd111
Author: benwa <bt...@linagora.com>
Authored: Fri Jun 15 15:48:25 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Wed Jun 20 09:08:10 2018 +0700
----------------------------------------------------------------------
.../james/modules/data/MemoryDataModule.java | 3 +
.../transport/mailets/DlpIntegrationTest.java | 265 +++++++++++++++++++
.../mailets/ToSenderDomainRepository.java | 9 +-
.../james/transport/matchers/dlp/Dlp.java | 7 +-
4 files changed, 280 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/536f3caa/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
index 90fdd43..44e7496 100644
--- a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
+++ b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
@@ -64,6 +64,9 @@ public class MemoryDataModule extends AbstractModule {
bind(MemoryUsersRepository.class).toInstance(MemoryUsersRepository.withVirtualHosting());
bind(UsersRepository.class).to(MemoryUsersRepository.class);
+ bind(EventSourcingDLPConfigurationStore.class).in(Scopes.SINGLETON);
+ bind(DLPConfigurationStore.class).to(EventSourcingDLPConfigurationStore.class);
+
Multibinder.newSetBinder(binder(), ConfigurationPerformer.class).addBinding().to(MemoryDataConfigurationPerformer.class);
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/536f3caa/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/DlpIntegrationTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/DlpIntegrationTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/DlpIntegrationTest.java
new file mode 100644
index 0000000..0762995
--- /dev/null
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/DlpIntegrationTest.java
@@ -0,0 +1,265 @@
+/****************************************************************
+ * 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.transport.mailets;
+
+import static com.jayway.restassured.RestAssured.given;
+import static org.apache.james.mailets.configuration.Constants.DEFAULT_DOMAIN;
+import static org.apache.james.mailets.configuration.Constants.FROM;
+import static org.apache.james.mailets.configuration.Constants.LOCALHOST_IP;
+import static org.apache.james.mailets.configuration.Constants.PASSWORD;
+import static org.apache.james.mailets.configuration.Constants.RECIPIENT;
+import static org.apache.james.mailets.configuration.Constants.RECIPIENT2;
+import static org.apache.james.mailets.configuration.Constants.SMTP_PORT;
+import static org.apache.james.mailets.configuration.Constants.awaitAtMostOneMinute;
+
+import java.util.Optional;
+
+import org.apache.james.MemoryJamesServerMain;
+import org.apache.james.core.builder.MimeMessageBuilder;
+import org.apache.james.jwt.JwtConfiguration;
+import org.apache.james.mailets.TemporaryJamesServer;
+import org.apache.james.mailets.configuration.MailetConfiguration;
+import org.apache.james.mailets.configuration.MailetContainer;
+import org.apache.james.mailets.configuration.ProcessorConfiguration;
+import org.apache.james.mailrepository.api.MailRepositoryUrl;
+import org.apache.james.transport.matchers.All;
+import org.apache.james.transport.matchers.dlp.Dlp;
+import org.apache.james.utils.DataProbeImpl;
+import org.apache.james.utils.IMAPMessageReader;
+import org.apache.james.utils.SMTPMessageSender;
+import org.apache.james.utils.WebAdminGuiceProbe;
+import org.apache.james.webadmin.WebAdminConfiguration;
+import org.apache.james.webadmin.WebAdminUtils;
+import org.apache.james.webadmin.authentication.AuthenticationFilter;
+import org.apache.james.webadmin.authentication.NoAuthenticationFilter;
+import org.apache.mailet.base.test.FakeMail;
+import org.eclipse.jetty.http.HttpStatus;
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import com.google.inject.util.Modules;
+import com.jayway.restassured.specification.RequestSpecification;
+
+public class DlpIntegrationTest {
+ public static final String REPOSITORY_PREFIX = "file://var/mail/dlp/quarantine/";
+ public static final JwtConfiguration NO_JWT_CONFIGURATION = new JwtConfiguration(Optional.empty());
+
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder();
+
+ @Rule
+ public IMAPMessageReader imapMessageReader = new IMAPMessageReader();
+ @Rule
+ public SMTPMessageSender messageSender = new SMTPMessageSender(DEFAULT_DOMAIN);
+
+ private TemporaryJamesServer jamesServer;
+ private RequestSpecification specification;
+
+ private void createJamesServer(MailetConfiguration.Builder dlpMailet) throws Exception {
+ MailetContainer.Builder mailets = TemporaryJamesServer.DEFAULT_MAILET_CONTAINER_CONFIGURATION
+ .putProcessor(
+ ProcessorConfiguration.transport()
+ .addMailet(MailetConfiguration.BCC_STRIPPER)
+ .addMailet(dlpMailet)
+ .addMailet(MailetConfiguration.builder()
+ .matcher(All.class)
+ .mailet(Null.class)));
+
+ jamesServer = TemporaryJamesServer.builder()
+ .withBase(Modules.override(
+ MemoryJamesServerMain.SMTP_AND_IMAP_MODULE,
+ MemoryJamesServerMain.WEBADMIN)
+ .with(
+ binder -> binder.bind(JwtConfiguration.class).toInstance(NO_JWT_CONFIGURATION),
+ binder -> binder.bind(AuthenticationFilter.class).to(NoAuthenticationFilter.class),
+ binder -> binder.bind(WebAdminConfiguration.class).toInstance(WebAdminConfiguration.TEST_CONFIGURATION)))
+ .withMailetContainer(mailets)
+ .build(folder);
+
+ jamesServer.getProbe(DataProbeImpl.class)
+ .fluent()
+ .addDomain(DEFAULT_DOMAIN)
+ .addUser(FROM, PASSWORD)
+ .addUser(RECIPIENT, PASSWORD)
+ .addUser(RECIPIENT2, PASSWORD);
+ WebAdminGuiceProbe webAdminGuiceProbe = jamesServer.getProbe(WebAdminGuiceProbe.class);
+ webAdminGuiceProbe.await();
+ specification = WebAdminUtils.buildRequestSpecification(webAdminGuiceProbe.getWebAdminPort()).build();
+ }
+
+ @After
+ public void tearDown() {
+ jamesServer.shutdown();
+ }
+
+ @Test
+ public void dlpShouldStoreMatchingEmails() throws Exception {
+ createJamesServer(MailetConfiguration.builder()
+ .matcher(Dlp.class)
+ .mailet(ToSenderDomainRepository.class)
+ .addProperty(ToSenderDomainRepository.URL_PREFIX, REPOSITORY_PREFIX));
+
+ given()
+ .spec(specification)
+ .body("{\"rules\":[{" +
+ " \"id\": \"1\"," +
+ " \"expression\": \"match me\"," +
+ " \"explanation\": \"A simple DLP rule.\"," +
+ " \"targetsSender\": false," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": true" +
+ "}]}")
+ .put("/dlp/rules/" + DEFAULT_DOMAIN);
+
+ messageSender.connect(LOCALHOST_IP, SMTP_PORT)
+ .sendMessage(FakeMail.builder()
+ .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
+ .addToRecipient(RECIPIENT)
+ .setSender(FROM)
+ .setText("match me"))
+ .sender(FROM)
+ .recipient(RECIPIENT));
+
+ awaitAtMostOneMinute.until(() -> containsExactlyOneMail(MailRepositoryUrl.from(REPOSITORY_PREFIX + DEFAULT_DOMAIN)));
+ }
+
+ @Test
+ public void dlpShouldNotCreateRepositoryWhenNotAllowed() throws Exception {
+ createJamesServer(MailetConfiguration.builder()
+ .matcher(Dlp.class)
+ .mailet(ToSenderDomainRepository.class)
+ .addProperty(ToSenderDomainRepository.URL_PREFIX, REPOSITORY_PREFIX)
+ .addProperty(ToSenderDomainRepository.ALLOW_REPOSITORY_CREATION, "false"));
+
+ given()
+ .spec(specification)
+ .body("{\"rules\":[[{" +
+ " \"id\": \"1\"," +
+ " \"expression\": \"match me\"," +
+ " \"explanation\": \"A simple DLP rule.\"," +
+ " \"targetsSender\": false," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": true" +
+ "}]}")
+ .put("/dlp/rules/" + DEFAULT_DOMAIN);
+
+ messageSender.connect(LOCALHOST_IP, SMTP_PORT)
+ .sendMessage(FakeMail.builder()
+ .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
+ .addToRecipient(RECIPIENT)
+ .setSender(FROM)
+ .setText("match me"))
+ .sender(FROM)
+ .recipient(RECIPIENT));
+
+ MailRepositoryUrl repositoryUrl = MailRepositoryUrl.from(REPOSITORY_PREFIX + DEFAULT_DOMAIN);
+ given()
+ .spec(specification)
+ .get("/mailRepositories/" + repositoryUrl.urlEncoded() + "/mails")
+ .then()
+ .statusCode(HttpStatus.NOT_FOUND_404);
+ }
+
+ @Test
+ public void dlpShouldCreateRepositoryWhenAllowed() throws Exception {
+ createJamesServer(MailetConfiguration.builder()
+ .matcher(Dlp.class)
+ .mailet(ToSenderDomainRepository.class)
+ .addProperty(ToSenderDomainRepository.URL_PREFIX, REPOSITORY_PREFIX)
+ .addProperty(ToSenderDomainRepository.ALLOW_REPOSITORY_CREATION, "true"));
+ MailRepositoryUrl repositoryUrl = MailRepositoryUrl.from(REPOSITORY_PREFIX + DEFAULT_DOMAIN);
+
+ given()
+ .spec(specification)
+ .body("{\"rules\":[{" +
+ " \"id\": \"1\"," +
+ " \"expression\": \"match me\"," +
+ " \"explanation\": \"A simple DLP rule.\"," +
+ " \"targetsSender\": false," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": true" +
+ "}]}")
+ .put("/dlp/rules/" + DEFAULT_DOMAIN);
+
+ messageSender.connect(LOCALHOST_IP, SMTP_PORT)
+ .sendMessage(FakeMail.builder()
+ .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
+ .addToRecipient(RECIPIENT)
+ .setSender(FROM)
+ .setText("match me"))
+ .sender(FROM)
+ .recipient(RECIPIENT));
+
+ awaitAtMostOneMinute.until(() -> containsExactlyOneMail(repositoryUrl));
+ }
+
+ @Test
+ public void dlpShouldStoreMailWhenNotAllowedButRepositoryExists() throws Exception {
+ createJamesServer(MailetConfiguration.builder()
+ .matcher(Dlp.class)
+ .mailet(ToSenderDomainRepository.class)
+ .addProperty(ToSenderDomainRepository.URL_PREFIX, REPOSITORY_PREFIX)
+ .addProperty(ToSenderDomainRepository.ALLOW_REPOSITORY_CREATION, "false"));
+
+ MailRepositoryUrl repositoryUrl = MailRepositoryUrl.from(REPOSITORY_PREFIX + DEFAULT_DOMAIN);
+ given()
+ .spec(specification)
+ .put("/mailRepositories/" + repositoryUrl.urlEncoded());
+
+ given()
+ .spec(specification)
+ .body("{\"rules\":[{" +
+ " \"id\": \"1\"," +
+ " \"expression\": \"match me\"," +
+ " \"explanation\": \"A simple DLP rule.\"," +
+ " \"targetsSender\": false," +
+ " \"targetsRecipients\": false," +
+ " \"targetsContent\": true" +
+ "}]}")
+ .put("/dlp/rules/" + DEFAULT_DOMAIN);
+
+ messageSender.connect(LOCALHOST_IP, SMTP_PORT)
+ .sendMessage(FakeMail.builder()
+ .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
+ .addToRecipient(RECIPIENT)
+ .setSender(FROM)
+ .setText("match me"))
+ .sender(FROM)
+ .recipient(RECIPIENT));
+
+ awaitAtMostOneMinute.until(() -> containsExactlyOneMail(repositoryUrl));
+ }
+
+ private boolean containsExactlyOneMail(MailRepositoryUrl repositoryUrl) {
+ try {
+ return given()
+ .spec(specification)
+ .get("/mailRepositories/" + repositoryUrl.urlEncoded() + "/mails")
+ .prettyPeek()
+ .jsonPath()
+ .getList(".")
+ .size() == 1;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/536f3caa/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
index 5992f85..2dce4e6 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderDomainRepository.java
@@ -61,6 +61,9 @@ import com.github.fge.lambdas.consumers.ThrowingConsumer;
* </mailet>
*/
public class ToSenderDomainRepository extends GenericMailet {
+ public static final String URL_PREFIX = "urlPrefix";
+ public static final String PASS_THROUGH = "passThrough";
+ public static final String ALLOW_REPOSITORY_CREATION = "allowRepositoryCreation";
private static final Logger LOGGER = LoggerFactory.getLogger(ToSenderDomainRepository.class);
private static final boolean DEFAULT_CONSUME = false;
@@ -78,10 +81,10 @@ public class ToSenderDomainRepository extends GenericMailet {
@Override
public void init() throws MessagingException {
- urlPrefix = Optional.ofNullable(getInitParameter("urlPrefix"))
+ urlPrefix = Optional.ofNullable(getInitParameter(URL_PREFIX))
.orElseThrow(() -> new MessagingException("'urlPrefix' is a mandatory configuration property"));
- passThrough = getInitParameter("passThrough", DEFAULT_CONSUME);
- allowRepositoryCreation = getInitParameter("allowRepositoryCreation", DEFAULT_ALLOW_REPOSITORY_CREATION);
+ passThrough = getInitParameter(PASS_THROUGH, DEFAULT_CONSUME);
+ allowRepositoryCreation = getInitParameter(ALLOW_REPOSITORY_CREATION, DEFAULT_ALLOW_REPOSITORY_CREATION);
}
@Override
http://git-wip-us.apache.org/repos/asf/james-project/blob/536f3caa/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/Dlp.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/Dlp.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/Dlp.java
index cb7fc72..1f65082 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/Dlp.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/dlp/Dlp.java
@@ -27,6 +27,7 @@ import javax.mail.MessagingException;
import org.apache.james.core.MailAddress;
import org.apache.james.dlp.api.DLPConfigurationItem;
+import org.apache.james.dlp.api.DLPConfigurationStore;
import org.apache.mailet.Mail;
import org.apache.mailet.base.GenericMatcher;
@@ -39,12 +40,16 @@ public class Dlp extends GenericMatcher {
private final DlpRulesLoader rulesLoader;
- @Inject
@VisibleForTesting
Dlp(DlpRulesLoader rulesLoader) {
this.rulesLoader = rulesLoader;
}
+ @Inject
+ public Dlp(DLPConfigurationStore configurationStore) {
+ this(new DlpRulesLoader.Impl(configurationStore));
+ }
+
@Override
public Collection<MailAddress> match(Mail mail) throws MessagingException {
Optional<DLPConfigurationItem.Id> firstMatchingRuleId = findFirstMatchingRule(mail);
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org