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 2019/01/16 06:59:20 UTC
[12/17] james-project git commit: JAMES-2637 add rest of the routes
for alias routes
JAMES-2637 add rest of the routes for alias routes
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/b312b877
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/b312b877
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/b312b877
Branch: refs/heads/master
Commit: b312b877cf92e2930d15f222462e97c7bd1799fc
Parents: 5b9b106
Author: Rene Cordier <rc...@linagora.com>
Authored: Thu Jan 10 17:33:34 2019 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Wed Jan 16 13:48:56 2019 +0700
----------------------------------------------------------------------
.../rrt/api/MappingAlreadyExistsException.java | 4 -
.../api/SameSourceAndDestinationException.java | 4 -
.../integration/UnauthorizedEndpointsTest.java | 3 +
.../webadmin/dto/AliasSourcesResponse.java | 32 ++
.../james/webadmin/routes/AliasRoutes.java | 95 +++++-
.../james/webadmin/routes/AliasRoutesTest.java | 299 +++++++++++++++++--
src/site/markdown/server/manage-webadmin.md | 53 ++++
7 files changed, 457 insertions(+), 33 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/b312b877/server/data/data-api/src/main/java/org/apache/james/rrt/api/MappingAlreadyExistsException.java
----------------------------------------------------------------------
diff --git a/server/data/data-api/src/main/java/org/apache/james/rrt/api/MappingAlreadyExistsException.java b/server/data/data-api/src/main/java/org/apache/james/rrt/api/MappingAlreadyExistsException.java
index 4d80ad8..ef0d49f 100644
--- a/server/data/data-api/src/main/java/org/apache/james/rrt/api/MappingAlreadyExistsException.java
+++ b/server/data/data-api/src/main/java/org/apache/james/rrt/api/MappingAlreadyExistsException.java
@@ -23,8 +23,4 @@ public class MappingAlreadyExistsException extends RecipientRewriteTableExceptio
public MappingAlreadyExistsException(String msg) {
super(msg);
}
-
- public MappingAlreadyExistsException(String msg, Throwable t) {
- super(msg, t);
- }
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/b312b877/server/data/data-api/src/main/java/org/apache/james/rrt/api/SameSourceAndDestinationException.java
----------------------------------------------------------------------
diff --git a/server/data/data-api/src/main/java/org/apache/james/rrt/api/SameSourceAndDestinationException.java b/server/data/data-api/src/main/java/org/apache/james/rrt/api/SameSourceAndDestinationException.java
index d76ffcb..c675c2c 100644
--- a/server/data/data-api/src/main/java/org/apache/james/rrt/api/SameSourceAndDestinationException.java
+++ b/server/data/data-api/src/main/java/org/apache/james/rrt/api/SameSourceAndDestinationException.java
@@ -24,8 +24,4 @@ public class SameSourceAndDestinationException extends RecipientRewriteTableExce
public SameSourceAndDestinationException(String msg) {
super(msg);
}
-
- public SameSourceAndDestinationException(String msg, Throwable t) {
- super(msg, t);
- }
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/b312b877/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/UnauthorizedEndpointsTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/UnauthorizedEndpointsTest.java b/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/UnauthorizedEndpointsTest.java
index f20b041..14abe53 100644
--- a/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/UnauthorizedEndpointsTest.java
+++ b/server/protocols/webadmin-integration-test/src/test/java/org/apache/james/webadmin/integration/UnauthorizedEndpointsTest.java
@@ -79,6 +79,8 @@ class UnauthorizedEndpointsTest {
UserRoutes.USERS,
ForwardRoutes.ROOT_PATH,
ForwardRoutes.ROOT_PATH + "/alice@james.org",
+ AliasRoutes.ROOT_PATH,
+ AliasRoutes.ROOT_PATH + "/bob@james.org",
GlobalQuotaRoutes.QUOTA_ENDPOINT,
GlobalQuotaRoutes.QUOTA_ENDPOINT + "/count",
GlobalQuotaRoutes.QUOTA_ENDPOINT + "/size",
@@ -157,6 +159,7 @@ class UnauthorizedEndpointsTest {
UserQuotaRoutes.USERS_QUOTA_ENDPOINT + "/joe@perdu.com/size",
UserRoutes.USERS + "/user@james.org",
ForwardRoutes.ROOT_PATH + "/alice@james.org/bob@james.org",
+ AliasRoutes.ROOT_PATH + "/bob@james.org/sources/bob-alias@james.org",
GlobalQuotaRoutes.QUOTA_ENDPOINT + "/count",
GlobalQuotaRoutes.QUOTA_ENDPOINT + "/size",
GroupsRoutes.ROOT_PATH + "/group@james.org/user@james.org",
http://git-wip-us.apache.org/repos/asf/james-project/blob/b312b877/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/AliasSourcesResponse.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/AliasSourcesResponse.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/AliasSourcesResponse.java
new file mode 100644
index 0000000..a57988b
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/AliasSourcesResponse.java
@@ -0,0 +1,32 @@
+/****************************************************************
+ * 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;
+
+public class AliasSourcesResponse {
+ private final String source;
+
+ public AliasSourcesResponse(String source) {
+ this.source = source;
+ }
+
+ public String getSource() {
+ return source;
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/b312b877/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/AliasRoutes.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/AliasRoutes.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/AliasRoutes.java
index 0a06aa0..43004d0 100644
--- a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/AliasRoutes.java
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/AliasRoutes.java
@@ -22,7 +22,12 @@ package org.apache.james.webadmin.routes;
import static org.apache.james.webadmin.Constants.SEPARATOR;
import static spark.Spark.halt;
+import java.util.List;
+import java.util.Map;
+
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;
@@ -33,15 +38,22 @@ import org.apache.james.rrt.api.MappingAlreadyExistsException;
import org.apache.james.rrt.api.RecipientRewriteTable;
import org.apache.james.rrt.api.RecipientRewriteTableException;
import org.apache.james.rrt.api.SameSourceAndDestinationException;
+import org.apache.james.rrt.lib.Mapping;
import org.apache.james.rrt.lib.MappingSource;
+import org.apache.james.rrt.lib.Mappings;
import org.apache.james.user.api.UsersRepository;
import org.apache.james.user.api.UsersRepositoryException;
+import org.apache.james.util.OptionalUtils;
import org.apache.james.webadmin.Constants;
import org.apache.james.webadmin.Routes;
+import org.apache.james.webadmin.dto.AliasSourcesResponse;
import org.apache.james.webadmin.utils.ErrorResponder;
+import org.apache.james.webadmin.utils.JsonTransformer;
import org.eclipse.jetty.http.HttpStatus;
+import com.github.steveash.guavate.Guavate;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableSet;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
@@ -70,12 +82,14 @@ public class AliasRoutes implements Routes {
private static final String ADDRESS_TYPE = "alias";
private final UsersRepository usersRepository;
+ private final JsonTransformer jsonTransformer;
private final RecipientRewriteTable recipientRewriteTable;
@Inject
@VisibleForTesting
- AliasRoutes(RecipientRewriteTable recipientRewriteTable, UsersRepository usersRepository) {
+ AliasRoutes(RecipientRewriteTable recipientRewriteTable, UsersRepository usersRepository, JsonTransformer jsonTransformer) {
this.usersRepository = usersRepository;
+ this.jsonTransformer = jsonTransformer;
this.recipientRewriteTable = recipientRewriteTable;
}
@@ -86,7 +100,29 @@ public class AliasRoutes implements Routes {
@Override
public void define(Service service) {
- service.put(USER_IN_ALIAS_SOURCES_ADDRESSES_PATH, this::addToAliasSources);
+ service.get(ROOT_PATH, this::listAddressesWithAliases, jsonTransformer);
+ service.get(ALIAS_ADDRESS_PATH, this::listAliasesOfAddress, jsonTransformer);
+ service.put(USER_IN_ALIAS_SOURCES_ADDRESSES_PATH, this::addAlias);
+ service.delete(USER_IN_ALIAS_SOURCES_ADDRESSES_PATH, this::deleteAlias);
+ }
+
+ @GET
+ @Path(ROOT_PATH)
+ @ApiOperation(value = "getting addresses containing aliases list")
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.OK_200, message = "OK", response = List.class),
+ @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
+ message = "Internal server error - Something went bad on the server side.")
+ })
+ public ImmutableSet<String> listAddressesWithAliases(Request request, Response response) throws RecipientRewriteTableException {
+ return recipientRewriteTable.getAllMappings()
+ .entrySet().stream()
+ .filter(e -> e.getValue().contains(Mapping.Type.Alias))
+ .map(Map.Entry::getValue)
+ .flatMap(Mappings::asStream)
+ .flatMap(mapping -> OptionalUtils.toStream(mapping.asMailAddress()))
+ .map(MailAddress::asString)
+ .collect(Guavate.toImmutableSortedSet());
}
@PUT
@@ -106,10 +142,11 @@ public class AliasRoutes implements Routes {
@ApiResponse(code = HttpStatus.NO_CONTENT_204, message = "OK"),
@ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = ALIAS_DESTINATION_ADDRESS + " or alias structure format is not valid"),
@ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "The alias source exists as an user already"),
+ @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Source and destination can't be the same!"),
@ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
message = "Internal server error - Something went bad on the server side.")
})
- public HaltException addToAliasSources(Request request, Response response) throws UsersRepositoryException, RecipientRewriteTableException {
+ public HaltException addAlias(Request request, Response response) throws UsersRepositoryException, RecipientRewriteTableException {
MailAddress aliasSourceAddress = MailAddressParser.parseMailAddress(request.params(ALIAS_SOURCE_ADDRESS), ADDRESS_TYPE);
ensureUserDoesNotExist(aliasSourceAddress);
MailAddress destinationAddress = MailAddressParser.parseMailAddress(request.params(ALIAS_DESTINATION_ADDRESS), ADDRESS_TYPE);
@@ -143,4 +180,56 @@ public class AliasRoutes implements Routes {
.haltError();
}
}
+
+ @DELETE
+ @Path(ROOT_PATH + "/{" + ALIAS_DESTINATION_ADDRESS + "}/sources/{" + ALIAS_SOURCE_ADDRESS + "}")
+ @ApiOperation(value = "remove an alias from a destination address")
+ @ApiImplicitParams({
+ @ApiImplicitParam(required = true, dataType = "string", name = ALIAS_DESTINATION_ADDRESS, paramType = "path",
+ value = "Destination mail address of the alias to remove.\n" +
+ MAILADDRESS_ASCII_DISCLAIMER),
+ @ApiImplicitParam(required = true, dataType = "string", name = ALIAS_SOURCE_ADDRESS, paramType = "path",
+ value = "Source mail address of the alias to remove.\n" +
+ MAILADDRESS_ASCII_DISCLAIMER)
+ })
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.NO_CONTENT_204, message = "OK"),
+ @ApiResponse(code = HttpStatus.BAD_REQUEST_400,
+ message = ALIAS_DESTINATION_ADDRESS + " or alias structure format is not valid"),
+ @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
+ message = "Internal server error - Something went bad on the server side.")
+ })
+ public HaltException deleteAlias(Request request, Response response) throws RecipientRewriteTableException {
+ MailAddress destinationAddress = MailAddressParser.parseMailAddress(request.params(ALIAS_DESTINATION_ADDRESS), ADDRESS_TYPE);
+ MailAddress aliasToBeRemoved = MailAddressParser.parseMailAddress(request.params(ALIAS_SOURCE_ADDRESS), ADDRESS_TYPE);
+ MappingSource source = MappingSource.fromMailAddress(aliasToBeRemoved);
+ recipientRewriteTable.removeAliasMapping(source, destinationAddress.asString());
+ return halt(HttpStatus.NO_CONTENT_204);
+ }
+
+ @GET
+ @Path(ROOT_PATH + "/{" + ALIAS_DESTINATION_ADDRESS + "}")
+ @ApiOperation(value = "listing alias sources of an address")
+ @ApiImplicitParams({
+ @ApiImplicitParam(required = true, dataType = "string", name = ALIAS_DESTINATION_ADDRESS, paramType = "path")
+ })
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.OK_200, message = "OK", response = List.class),
+ @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "The destination is not an address"),
+ @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
+ message = "Internal server error - Something went bad on the server side.")
+ })
+ public ImmutableSet<AliasSourcesResponse> listAliasesOfAddress(Request request, Response response) throws RecipientRewriteTableException {
+ MailAddress baseAddress = MailAddressParser.parseMailAddress(request.params(ALIAS_DESTINATION_ADDRESS), ADDRESS_TYPE);
+
+ return recipientRewriteTable.getAllMappings()
+ .entrySet().stream()
+ .filter(e -> e.getValue().contains(Mapping.alias(baseAddress.asString())))
+ .map(Map.Entry::getKey)
+ .flatMap(source -> OptionalUtils.toStream(source.asMailAddress()))
+ .map(MailAddress::asString)
+ .sorted()
+ .map(AliasSourcesResponse::new)
+ .collect(Guavate.toImmutableSet());
+ }
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/b312b877/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/AliasRoutesTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/AliasRoutesTest.java b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/AliasRoutesTest.java
index 5faad03..af6e4e1 100644
--- a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/AliasRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/AliasRoutesTest.java
@@ -31,13 +31,13 @@ import org.apache.james.domainlist.memory.MemoryDomainList;
import org.apache.james.metrics.logger.DefaultMetricFactory;
import org.apache.james.rrt.api.RecipientRewriteTable;
import org.apache.james.rrt.api.RecipientRewriteTableException;
-import org.apache.james.rrt.lib.Mapping;
import org.apache.james.rrt.lib.MappingSource;
import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
import org.apache.james.user.api.UsersRepository;
import org.apache.james.user.memory.MemoryUsersRepository;
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.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@@ -45,6 +45,7 @@ import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
+import java.util.List;
import java.util.Map;
import static io.restassured.RestAssured.given;
@@ -53,6 +54,8 @@ import static io.restassured.RestAssured.with;
import static org.apache.james.webadmin.Constants.SEPARATOR;
import static org.apache.james.webadmin.WebAdminServer.NO_CONFIGURATION;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.CoreMatchers.hasItems;
+import static org.hamcrest.CoreMatchers.is;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doThrow;
@@ -69,15 +72,11 @@ class AliasRoutesTest {
public static final String BOB_ALIAS_WITH_SLASH = "bob-alias/@" + DOMAIN.name();
public static final String BOB_ALIAS_WITH_ENCODED_SLASH = "bob-alias%2F@" + DOMAIN.name();
public static final String ALICE = "alice@" + DOMAIN.name();
+ public static final String ALICE_ALIAS = "alice-alias@" + DOMAIN.name();
public static final String BOB_PASSWORD = "123456";
public static final String BOB_WITH_SLASH_PASSWORD = "abcdef";
public static final String ALICE_PASSWORD = "789123";
- private static final MappingSource BOB_ALIAS_SOURCE = MappingSource.fromUser("bob-alias", DOMAIN);
- private static final MappingSource BOB_ALIAS_WITH_ENCODED_SLASH_SOURCE = MappingSource.fromUser("bob-alias/", DOMAIN);
- private static final Mapping BOB_MAPPING = Mapping.alias(BOB);
- private static final Mapping BOB_WITH_ENCODED_SLASH_MAPPING = Mapping.alias(BOB_WITH_SLASH);
-
private WebAdminServer webAdminServer;
private void createServer(AliasRoutes aliasRoutes) throws Exception {
@@ -123,7 +122,58 @@ class AliasRoutesTest {
usersRepository.addUser(BOB_WITH_SLASH, BOB_WITH_SLASH_PASSWORD);
usersRepository.addUser(ALICE, ALICE_PASSWORD);
- createServer(new AliasRoutes(memoryRecipientRewriteTable, usersRepository));
+ createServer(new AliasRoutes(memoryRecipientRewriteTable, usersRepository, new JsonTransformer()));
+ }
+
+ @Test
+ void getAliasesShouldBeEmpty() {
+ when()
+ .get()
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body(is("[]"));
+ }
+
+ @Test
+ void getAliasesShouldListExistingAliasesInAlphabeticOrder() {
+ with()
+ .put(ALICE + SEPARATOR + "sources" + SEPARATOR + ALICE_ALIAS);
+
+ with()
+ .put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
+
+ List<String> addresses =
+ when()
+ .get()
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .extract()
+ .body()
+ .jsonPath()
+ .getList(".");
+ assertThat(addresses).containsExactly(ALICE, BOB);
+ }
+
+ @Test
+ void getNotRegisteredAliasesShouldReturnEmptyList() {
+ when()
+ .get("unknown@domain.travel")
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body(is("[]"));
+ }
+
+ @Test
+ void getAliasesShouldReturnEmptyListWhenNoAliasMappings() {
+ when()
+ .get(BOB)
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body(is("[]"));
}
@Test
@@ -202,7 +252,12 @@ class AliasRoutesTest {
with()
.put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
- assertThat(memoryRecipientRewriteTable.getStoredMappings(BOB_ALIAS_SOURCE)).containsOnly(BOB_MAPPING);
+ when()
+ .get(BOB)
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body("source", hasItems(BOB_ALIAS));
}
@Test
@@ -210,15 +265,25 @@ class AliasRoutesTest {
with()
.put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS_WITH_ENCODED_SLASH);
- assertThat(memoryRecipientRewriteTable.getStoredMappings(BOB_ALIAS_WITH_ENCODED_SLASH_SOURCE)).containsOnly(BOB_MAPPING);
+ when()
+ .get(BOB)
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body("source", hasItems(BOB_ALIAS_WITH_SLASH));
}
@Test
- void putAliasForUserWithEncodedSlashShouldCreateForward() {
+ void putAliasForUserWithEncodedSlashShouldCreateAlias() {
with()
.put(BOB_WITH_ENCODED_SLASH + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
- assertThat(memoryRecipientRewriteTable.getStoredMappings(BOB_ALIAS_SOURCE)).containsOnly(BOB_WITH_ENCODED_SLASH_MAPPING);
+ when()
+ .get(BOB_WITH_ENCODED_SLASH)
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body("source", hasItems(BOB_ALIAS));
}
@Test
@@ -229,34 +294,106 @@ class AliasRoutesTest {
with()
.put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
- assertThat(memoryRecipientRewriteTable.getStoredMappings(BOB_ALIAS_SOURCE)).containsOnly(BOB_MAPPING);
+ when()
+ .get(BOB)
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body("source", hasItems(BOB_ALIAS));
}
@Test
- void putAliasForUserShouldAllowSeveralSources() {
- MappingSource source2 = MappingSource.fromUser("bob-alias2", DOMAIN);
-
+ void putAliasForUserShouldAllowSeveralSourcesAndReturnThemInAlphabeticalOrder() {
with()
.put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
with()
.put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS_2);
- assertThat(memoryRecipientRewriteTable.getStoredMappings(BOB_ALIAS_SOURCE)).containsOnly(BOB_MAPPING);
- assertThat(memoryRecipientRewriteTable.getStoredMappings(source2)).containsOnly(BOB_MAPPING);
+ when()
+ .get(BOB)
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body("source", hasItems(BOB_ALIAS, BOB_ALIAS_2));
}
@Test
void putAliasForUserShouldAllowSeveralDestinations() {
- Mapping aliceMapping = Mapping.alias(ALICE);
-
with()
.put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
with()
.put(ALICE + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
- assertThat(memoryRecipientRewriteTable.getStoredMappings(BOB_ALIAS_SOURCE)).containsOnly(BOB_MAPPING, aliceMapping);
+ when()
+ .get(BOB)
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body("source", hasItems(BOB_ALIAS));
+
+ when()
+ .get(ALICE)
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body("source", hasItems(BOB_ALIAS));
+ }
+
+ @Test
+ void putAliasForUserShouldNotRequireExistingBaseUser() {
+ String notExistingAddress = "notFound@" + DOMAIN.name();
+
+ with()
+ .put(notExistingAddress + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
+
+ when()
+ .get(notExistingAddress)
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body("source", hasItems(BOB_ALIAS));
+ }
+
+ @Test
+ void deleteAliasNotInAliasesShouldReturnOK() {
+ when()
+ .delete(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS)
+ .then()
+ .statusCode(HttpStatus.NO_CONTENT_204);
+ }
+
+ @Test
+ void deleteAliasInAliasesShouldDeleteAliasForUser() {
+ with()
+ .put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
+
+ with()
+ .delete(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
+
+ when()
+ .get(BOB_ALIAS)
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body(is("[]"));
+ }
+
+ @Test
+ void deleteLastAliasOfUserInAliasesShouldDeleteUserFromAliasList() {
+ with()
+ .put(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
+
+ with()
+ .delete(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS);
+
+ when()
+ .get()
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body(is("[]"));
}
}
@@ -284,7 +421,7 @@ class AliasRoutesTest {
UsersRepository userRepository = mock(UsersRepository.class);
DomainList domainList = mock(DomainList.class);
Mockito.when(domainList.containsDomain(any())).thenReturn(true);
- createServer(new AliasRoutes(memoryRecipientRewriteTable, userRepository));
+ createServer(new AliasRoutes(memoryRecipientRewriteTable, userRepository, new JsonTransformer()));
}
@Test
@@ -326,7 +463,7 @@ class AliasRoutesTest {
}
@Test
- void putUserDestinationInForwardWithSlashShouldReturnNotFound() {
+ void putUserDestinationInAliasWithSlashShouldReturnNotFound() {
when()
.put(BOB_WITH_SLASH + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS)
.then()
@@ -350,6 +487,52 @@ class AliasRoutesTest {
}
@Test
+ void deleteMalformedUserDestinationShouldReturnBadRequest() {
+ Map<String, Object> errors = when()
+ .delete("not-an-address" + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS)
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .contentType(ContentType.JSON)
+ .extract()
+ .body()
+ .jsonPath()
+ .getMap(".");
+
+ assertThat(errors)
+ .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400)
+ .containsEntry("type", "InvalidArgument")
+ .containsEntry("message", "The alias is not an email address")
+ .containsEntry("details", "Out of data at position 1 in 'not-an-address'");
+ }
+
+ @Test
+ void deleteMalformedAliasShouldReturnBadRequest() {
+ Map<String, Object> errors = when()
+ .delete(BOB + SEPARATOR + "sources" + SEPARATOR + "not-an-address")
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .contentType(ContentType.JSON)
+ .extract()
+ .body()
+ .jsonPath()
+ .getMap(".");
+
+ assertThat(errors)
+ .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400)
+ .containsEntry("type", "InvalidArgument")
+ .containsEntry("message", "The alias is not an email address")
+ .containsEntry("details", "Out of data at position 1 in 'not-an-address'");
+ }
+
+ @Test
+ void deleteRequiresTwoPathParams() {
+ when()
+ .delete(BOB)
+ .then()
+ .statusCode(HttpStatus.NOT_FOUND_404);
+ }
+
+ @Test
void putShouldReturnErrorWhenRecipientRewriteTableExceptionIsThrown() throws Exception {
doThrow(RecipientRewriteTableException.class)
.when(memoryRecipientRewriteTable)
@@ -372,5 +555,77 @@ class AliasRoutesTest {
.then()
.statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500);
}
+
+ @Test
+ void getAllShouldReturnErrorWhenRecipientRewriteTableExceptionIsThrown() throws Exception {
+ doThrow(RecipientRewriteTableException.class)
+ .when(memoryRecipientRewriteTable)
+ .getAllMappings();
+
+ when()
+ .get()
+ .then()
+ .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500);
+ }
+
+ @Test
+ void getAllShouldReturnErrorWhenRuntimeExceptionIsThrown() throws Exception {
+ doThrow(RuntimeException.class)
+ .when(memoryRecipientRewriteTable)
+ .getAllMappings();
+
+ when()
+ .get()
+ .then()
+ .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500);
+ }
+
+ @Test
+ void deleteShouldReturnErrorWhenRecipientRewriteTableExceptionIsThrown() throws Exception {
+ doThrow(RecipientRewriteTableException.class)
+ .when(memoryRecipientRewriteTable)
+ .removeAliasMapping(any(), anyString());
+
+ when()
+ .delete(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS)
+ .then()
+ .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500);
+ }
+
+ @Test
+ void deleteShouldReturnErrorWhenRuntimeExceptionIsThrown() throws Exception {
+ doThrow(RuntimeException.class)
+ .when(memoryRecipientRewriteTable)
+ .removeAliasMapping(any(), anyString());
+
+ when()
+ .delete(BOB + SEPARATOR + "sources" + SEPARATOR + BOB_ALIAS)
+ .then()
+ .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500);
+ }
+
+ @Test
+ void getShouldReturnErrorWhenRecipientRewriteTableExceptionIsThrown() throws Exception {
+ doThrow(RecipientRewriteTableException.class)
+ .when(memoryRecipientRewriteTable)
+ .getAllMappings();
+
+ when()
+ .get(BOB)
+ .then()
+ .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500);
+ }
+
+ @Test
+ void getShouldReturnErrorWhenRuntimeExceptionIsThrown() throws Exception {
+ doThrow(RuntimeException.class)
+ .when(memoryRecipientRewriteTable)
+ .getAllMappings();
+
+ when()
+ .get(BOB)
+ .then()
+ .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500);
+ }
}
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/b312b877/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 c0a7b8b..65d28d6 100644
--- a/src/site/markdown/server/manage-webadmin.md
+++ b/src/site/markdown/server/manage-webadmin.md
@@ -1314,7 +1314,46 @@ to be configured.
Note that email addresses are restricted to ASCII character set. Mail addresses not matching this criteria will be rejected.
+ - [Listing users with aliases](#Listing_users_with_aliases)
+ - [Listing alias sources of an user](#Listing_alias_sources_of_an_user)
- [Adding a new alias to an user](#Adding_a_new_alias_to_an_user)
+ - [Removing an alias of an user](#Removing_an_alias_of_an_user)
+
+### Listing users with aliases
+
+```
+curl -XGET http://ip:port/address/aliases
+```
+
+Will return the users having aliases configured as a list of JSON Strings representing mail addresses. For instance:
+
+```
+["user1@domain.com", "user2@domain.com"]
+```
+
+Response codes:
+
+ - 200: Success
+
+### Listing alias sources of an user
+
+```
+curl -XGET http://ip:port/address/aliases/user@domain.com
+```
+
+Will return the aliases of this user as a list of JSON Strings representing mail addresses. For instance:
+
+```
+[
+ {"source":"alias1@domain.com"},
+ {"source":"alias2@domain.com"}
+]
+```
+
+Response codes:
+
+ - 200: Success
+ - 400: Alias structure is not valid
### Adding a new alias to an user
@@ -1329,6 +1368,20 @@ Response codes:
- 204: OK
- 400: Alias structure or member is not valid
- 400: The alias source exists as an user already
+ - 400: Source and destination can't be the same!
+
+### Removing an alias of an user
+
+```
+curl -XDELETE http://ip:port/address/aliases/user@domain.com/sources/alias@domain.com
+```
+
+Will remove alias@domain.com from user@domain.com, removing the alias if needed
+
+Response codes:
+
+ - 204: OK
+ - 400: Alias structure or member is not valid
## Administrating mail repositories
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org