Skip to content

Commit

Permalink
JAMES-2729 AliasRoutes validating source domain existence
Browse files Browse the repository at this point in the history
  • Loading branch information
trantienduchn authored and Arsnael committed Apr 29, 2019
1 parent 403471a commit c8aed2d
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 6 deletions.
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.apache.james.rrt.api.RecipientRewriteTable; import org.apache.james.rrt.api.RecipientRewriteTable;
import org.apache.james.rrt.api.RecipientRewriteTableException; import org.apache.james.rrt.api.RecipientRewriteTableException;
import org.apache.james.rrt.api.SameSourceAndDestinationException; import org.apache.james.rrt.api.SameSourceAndDestinationException;
import org.apache.james.rrt.api.SourceDomainIsNotInDomainListException;
import org.apache.james.rrt.lib.Mapping; import org.apache.james.rrt.lib.Mapping;
import org.apache.james.rrt.lib.MappingSource; import org.apache.james.rrt.lib.MappingSource;
import org.apache.james.user.api.UsersRepository; import org.apache.james.user.api.UsersRepository;
Expand Down Expand Up @@ -139,6 +140,7 @@ public ImmutableSet<String> listAddressesWithAliases(Request request, Response r
@ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = ALIAS_DESTINATION_ADDRESS + " or alias structure format is not valid"), @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 = "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.BAD_REQUEST_400, message = "Source and destination can't be the same!"),
@ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Domain in the source is not managed by the DomainList"),
@ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500, @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.")
}) })
Expand All @@ -156,7 +158,7 @@ private void addAlias(MappingSource source, MailAddress aliasSourceAddress) thro
recipientRewriteTable.addAliasMapping(source, aliasSourceAddress.asString()); recipientRewriteTable.addAliasMapping(source, aliasSourceAddress.asString());
} catch (MappingAlreadyExistsException e) { } catch (MappingAlreadyExistsException e) {
// ignore // ignore
} catch (SameSourceAndDestinationException e) { } catch (SameSourceAndDestinationException | SourceDomainIsNotInDomainListException e) {
throw ErrorResponder.builder() throw ErrorResponder.builder()
.statusCode(HttpStatus.BAD_REQUEST_400) .statusCode(HttpStatus.BAD_REQUEST_400)
.type(ErrorResponder.ErrorType.INVALID_ARGUMENT) .type(ErrorResponder.ErrorType.INVALID_ARGUMENT)
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;


import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
Expand All @@ -42,7 +43,6 @@
import org.apache.james.domainlist.lib.DomainListConfiguration; import org.apache.james.domainlist.lib.DomainListConfiguration;
import org.apache.james.domainlist.memory.MemoryDomainList; import org.apache.james.domainlist.memory.MemoryDomainList;
import org.apache.james.metrics.logger.DefaultMetricFactory; 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.api.RecipientRewriteTableException;
import org.apache.james.rrt.lib.MappingSource; import org.apache.james.rrt.lib.MappingSource;
import org.apache.james.rrt.memory.MemoryRecipientRewriteTable; import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
Expand All @@ -66,6 +66,7 @@
class AliasRoutesTest { class AliasRoutesTest {


private static final Domain DOMAIN = Domain.of("b.com"); private static final Domain DOMAIN = Domain.of("b.com");
private static final Domain ALIAS_DOMAIN = Domain.of("alias");
public static final String BOB = "bob@" + DOMAIN.name(); public static final String BOB = "bob@" + DOMAIN.name();
public static final String BOB_WITH_SLASH = "bob/@" + DOMAIN.name(); public static final String BOB_WITH_SLASH = "bob/@" + DOMAIN.name();
public static final String BOB_WITH_ENCODED_SLASH = "bob%2F@" + DOMAIN.name(); public static final String BOB_WITH_ENCODED_SLASH = "bob%2F@" + DOMAIN.name();
Expand Down Expand Up @@ -115,7 +116,9 @@ void setUp() throws Exception {
.autoDetect(false) .autoDetect(false)
.autoDetectIp(false)); .autoDetectIp(false));
domainList.addDomain(DOMAIN); domainList.addDomain(DOMAIN);
domainList.addDomain(ALIAS_DOMAIN);
MappingSourceModule module = new MappingSourceModule(); MappingSourceModule module = new MappingSourceModule();
memoryRecipientRewriteTable.setDomainList(domainList);


usersRepository = MemoryUsersRepository.withVirtualHosting(); usersRepository = MemoryUsersRepository.withVirtualHosting();
usersRepository.setDomainList(domainList); usersRepository.setDomainList(domainList);
Expand Down Expand Up @@ -408,25 +411,48 @@ void setup() throws Exception {
super.setUp(); super.setUp();
memoryRecipientRewriteTable.addErrorMapping(MappingSource.fromUser("error", DOMAIN), "disabled"); memoryRecipientRewriteTable.addErrorMapping(MappingSource.fromUser("error", DOMAIN), "disabled");
memoryRecipientRewriteTable.addRegexMapping(MappingSource.fromUser("regex", DOMAIN), ".*@b\\.com"); memoryRecipientRewriteTable.addRegexMapping(MappingSource.fromUser("regex", DOMAIN), ".*@b\\.com");
memoryRecipientRewriteTable.addAliasDomainMapping(MappingSource.fromDomain(Domain.of("alias")), DOMAIN); memoryRecipientRewriteTable.addAliasDomainMapping(MappingSource.fromDomain(ALIAS_DOMAIN), DOMAIN);
} }


} }


@Nested @Nested
class ExceptionHandling { class ExceptionHandling {


private RecipientRewriteTable memoryRecipientRewriteTable; private MemoryRecipientRewriteTable memoryRecipientRewriteTable;
private DomainList domainList;


@BeforeEach @BeforeEach
void setUp() throws Exception { void setUp() throws Exception {
memoryRecipientRewriteTable = mock(RecipientRewriteTable.class); memoryRecipientRewriteTable = spy(new MemoryRecipientRewriteTable());
UsersRepository userRepository = mock(UsersRepository.class); UsersRepository userRepository = mock(UsersRepository.class);
DomainList domainList = mock(DomainList.class); domainList = mock(DomainList.class);
memoryRecipientRewriteTable.setDomainList(domainList);
Mockito.when(domainList.containsDomain(any())).thenReturn(true); Mockito.when(domainList.containsDomain(any())).thenReturn(true);
createServer(new AliasRoutes(memoryRecipientRewriteTable, userRepository, new JsonTransformer())); createServer(new AliasRoutes(memoryRecipientRewriteTable, userRepository, new JsonTransformer()));
} }


@Test
void putAliasSourceContainingNotManagedDomainShouldReturnBadRequest() throws Exception {
Mockito.when(domainList.containsDomain(any()))
.thenReturn(false);

Map<String, Object> errors = when()
.put(BOB + SEPARATOR + "sources" + SEPARATOR + "bob@not-managed-domain.tld")
.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", "Source domain 'not-managed-domain.tld' is not managed by the domainList");
}

@Test @Test
void putMalformedUserDestinationShouldReturnBadRequest() { void putMalformedUserDestinationShouldReturnBadRequest() {
Map<String, Object> errors = when() Map<String, Object> errors = when()
Expand Down
1 change: 1 addition & 0 deletions src/site/markdown/server/manage-webadmin.md
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -1373,6 +1373,7 @@ Response codes:
- 400: Alias structure or member is not valid - 400: Alias structure or member is not valid
- 400: The alias source exists as an user already - 400: The alias source exists as an user already
- 400: Source and destination can't be the same! - 400: Source and destination can't be the same!
- 400: Domain in the source is not managed by the DomainList


### Removing an alias of an user ### Removing an alias of an user


Expand Down

0 comments on commit c8aed2d

Please sign in to comment.