JAMES-2366 Add JMAP integration test with Forward RRT mapping
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/ce6e83dd Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/ce6e83dd Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/ce6e83dd Branch: refs/heads/master Commit: ce6e83dd65982729d36ab9175c90890952871be8 Parents: ba30683 Author: Antoine Duprat <adup...@linagora.com> Authored: Wed Apr 4 18:08:02 2018 +0200 Committer: Antoine Duprat <adup...@linagora.com> Committed: Fri Apr 6 15:04:48 2018 +0200 ---------------------------------------------------------------------- pom.xml | 5 + .../CassandraForwardIntegrationTest.java | 58 ++++ .../src/test/resources/mailetcontainer.xml | 1 + .../jmap-integration-testing-common/pom.xml | 10 + .../integration/ForwardIntegrationTest.java | 299 +++++++++++++++++++ .../memory/MemoryForwardIntegrationTest.java | 46 +++ .../src/test/resources/mailetcontainer.xml | 1 + 7 files changed, 420 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/ce6e83dd/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index fd60a8d..bc2ceb0 100644 --- a/pom.xml +++ b/pom.xml @@ -1182,6 +1182,11 @@ </dependency> <dependency> <groupId>${project.groupId}</groupId> + <artifactId>james-server-guice-webadmin</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> <artifactId>james-server-jetty</artifactId> <version>${project.version}</version> </dependency> http://git-wip-us.apache.org/repos/asf/james-project/blob/ce6e83dd/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraForwardIntegrationTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraForwardIntegrationTest.java b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraForwardIntegrationTest.java new file mode 100644 index 0000000..2630250 --- /dev/null +++ b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/CassandraForwardIntegrationTest.java @@ -0,0 +1,58 @@ +/**************************************************************** + * 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.jmap.cassandra; + +import org.apache.james.CassandraJmapTestRule; +import org.apache.james.DockerCassandraRule; +import org.apache.james.GuiceJamesServer; +import org.apache.james.backends.cassandra.ContainerLifecycleConfiguration; +import org.apache.james.jmap.methods.integration.ForwardIntegrationTest; +import org.apache.james.webadmin.RandomPortSupplier; +import org.apache.james.webadmin.WebAdminConfiguration; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.rules.TestRule; + +public class CassandraForwardIntegrationTest extends ForwardIntegrationTest { + + @ClassRule + public static DockerCassandraRule cassandra = new DockerCassandraRule(); + + public static ContainerLifecycleConfiguration cassandraLifecycleConfiguration = ContainerLifecycleConfiguration.withDefaultIterationsBetweenRestart().container(cassandra.getRawContainer()).build(); + + @Rule + public CassandraJmapTestRule rule = CassandraJmapTestRule.defaultTestRule(); + + @Rule + public TestRule cassandraLifecycleTestRule = cassandraLifecycleConfiguration.asTestRule(); + + @Override + protected GuiceJamesServer createJmapServer() { + return rule.jmapServer(cassandra.getModule(), + binder -> binder.bind(WebAdminConfiguration.class) + .toInstance(WebAdminConfiguration.builder() + .enabled() + .corsDisabled() + .host("127.0.0.1") + .port(new RandomPortSupplier()) + .build())); + } + +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ce6e83dd/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml ---------------------------------------------------------------------- diff --git a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml index 7148bac..0698316 100644 --- a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml +++ b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml @@ -51,6 +51,7 @@ <name>bcc</name> </mailet> <mailet match="All" class="org.apache.james.jmap.mailet.TextCalendarBodyToAttachment"/> + <mailet match="All" class="RecipientRewriteTable" /> <mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.VacationMailet"/> <mailet match="RecipientIsLocal" class="Sieve"/> <mailet match="RecipientIsLocal" class="SpamAssassin"> http://git-wip-us.apache.org/repos/asf/james-project/blob/ce6e83dd/server/protocols/jmap-integration-testing/jmap-integration-testing-common/pom.xml ---------------------------------------------------------------------- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/pom.xml b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/pom.xml index b7a87ac..fc05e0c 100644 --- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/pom.xml +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/pom.xml @@ -78,6 +78,11 @@ </dependency> <dependency> <groupId>${project.groupId}</groupId> + <artifactId>james-server-guice-webadmin</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> <artifactId>james-server-testing</artifactId> <scope>test</scope> </dependency> @@ -95,6 +100,11 @@ </dependency> <dependency> <groupId>${project.groupId}</groupId> + <artifactId>james-server-webadmin-core</artifactId> + <type>test-jar</type> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> <artifactId>javax-mail-extension</artifactId> <type>test-jar</type> <scope>test</scope> http://git-wip-us.apache.org/repos/asf/james-project/blob/ce6e83dd/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/ForwardIntegrationTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/ForwardIntegrationTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/ForwardIntegrationTest.java new file mode 100644 index 0000000..07ded58 --- /dev/null +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/ForwardIntegrationTest.java @@ -0,0 +1,299 @@ +/**************************************************************** + * 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.jmap.methods.integration; + +import static com.jayway.restassured.RestAssured.given; +import static com.jayway.restassured.RestAssured.with; +import static com.jayway.restassured.config.EncoderConfig.encoderConfig; +import static com.jayway.restassured.config.RestAssuredConfig.newConfig; +import static org.apache.james.jmap.TestingConstants.calmlyAwait; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; + +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.apache.http.client.utils.URIBuilder; +import org.apache.james.GuiceJamesServer; +import org.apache.james.jmap.HttpJmapAuthentication; +import org.apache.james.jmap.api.access.AccessToken; +import org.apache.james.mailbox.Role; +import org.apache.james.probe.DataProbe; +import org.apache.james.utils.DataProbeImpl; +import org.apache.james.utils.JmapGuiceProbe; +import org.apache.james.utils.WebAdminGuiceProbe; +import org.apache.james.webadmin.WebAdminUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.jayway.restassured.RestAssured; +import com.jayway.restassured.builder.RequestSpecBuilder; +import com.jayway.restassured.http.ContentType; +import com.jayway.restassured.specification.RequestSpecification; + +public abstract class ForwardIntegrationTest { + + private static final String DOMAIN = "domain"; + private static final String BOB = "bob@" + DOMAIN; + private static final String BOB_PASSWORD = "123456"; + private static final String ALICE = "alice@" + DOMAIN; + private static final String ALICE_PASSWORD = "789123"; + private static final String CEDRIC = "cedric@" + DOMAIN; + private static final String CEDRIC_PASSWORD = "456789"; + + private static final String NAME = "[0][0]"; + private static final String ARGUMENTS = "[0][1]"; + + protected abstract GuiceJamesServer createJmapServer(); + + private GuiceJamesServer jmapServer; + private RequestSpecification webAdminApi; + + @Before + public void setUp() throws Exception { + jmapServer = createJmapServer(); + jmapServer.start(); + + DataProbe dataProbe = jmapServer.getProbe(DataProbeImpl.class); + dataProbe.addDomain(DOMAIN); + dataProbe.addUser(BOB, BOB_PASSWORD); + dataProbe.addUser(ALICE, ALICE_PASSWORD); + dataProbe.addUser(CEDRIC, CEDRIC_PASSWORD); + + RestAssured.requestSpecification = new RequestSpecBuilder() + .setContentType(ContentType.JSON) + .setAccept(ContentType.JSON) + .setConfig(newConfig().encoderConfig(encoderConfig().defaultContentCharset(StandardCharsets.UTF_8))) + .setPort(jmapServer.getProbe(JmapGuiceProbe.class).getJmapPort()) + .build(); + + WebAdminGuiceProbe webAdminGuiceProbe = jmapServer.getProbe(WebAdminGuiceProbe.class); + webAdminGuiceProbe.await(); + webAdminApi = given() + .spec(WebAdminUtils.buildRequestSpecification(webAdminGuiceProbe.getWebAdminPort()).build()); + } + + @After + public void tearDown() { + jmapServer.stop(); + } + + @Test + public void messageShouldBeForwardedWhenDefinedInRESTAPI() { + webAdminApi.put(String.format("/address/forwards/%s/targets/%s", ALICE, BOB)); + + AccessToken cedricAccessToken = HttpJmapAuthentication.authenticateJamesUser(baseUri(), CEDRIC, CEDRIC_PASSWORD); + String messageCreationId = "creationId1337"; + String requestBody = "[" + + " [" + + " \"setMessages\"," + + " {" + + " \"create\": { \"" + messageCreationId + "\" : {" + + " \"from\": { \"name\": \"Me\", \"email\": \"" + CEDRIC + "\"}," + + " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," + + " \"subject\": \"subject\"," + + " \"isUnread\": true," + + " \"isFlagged\": true," + + " \"isAnswered\": true," + + " \"isDraft\": true," + + " \"isForwarded\": true," + + " \"mailboxIds\": [\"" + getOutboxId(cedricAccessToken) + "\"]" + + " }}" + + " }," + + " \"#0\"" + + " ]" + + "]"; + + with() + .header("Authorization", cedricAccessToken.serialize()) + .body(requestBody) + .post("/jmap"); + + AccessToken bobAccessToken = HttpJmapAuthentication.authenticateJamesUser(baseUri(), BOB, BOB_PASSWORD); + calmlyAwait.atMost(30, TimeUnit.SECONDS).until(() -> isAnyMessageFoundInRecipientsMailboxes(bobAccessToken)); + given() + .header("Authorization", bobAccessToken.serialize()) + .body("[[\"getMessageList\", {}, \"#0\"]]") + .when() + .post("/jmap") + .then() + .log().ifValidationFails() + .statusCode(200) + .body(NAME, equalTo("messageList")) + .body(ARGUMENTS + ".messageIds", hasSize(1)); + } + + @Test + public void messageShouldBeForwardedWhenBaseRecipientWhenInDestination() { + webAdminApi.put(String.format("/address/forwards/%s/targets/%s", ALICE, BOB)); + webAdminApi.put(String.format("/address/forwards/%s/targets/%s", ALICE, ALICE)); + + AccessToken cedricAccessToken = HttpJmapAuthentication.authenticateJamesUser(baseUri(), CEDRIC, CEDRIC_PASSWORD); + AccessToken aliceAccessToken = HttpJmapAuthentication.authenticateJamesUser(baseUri(), ALICE, ALICE_PASSWORD); + String messageCreationId = "creationId1337"; + String requestBody = "[" + + " [" + + " \"setMessages\"," + + " {" + + " \"create\": { \"" + messageCreationId + "\" : {" + + " \"from\": { \"name\": \"Me\", \"email\": \"" + CEDRIC + "\"}," + + " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," + + " \"subject\": \"subject\"," + + " \"isUnread\": true," + + " \"isFlagged\": true," + + " \"isAnswered\": true," + + " \"isDraft\": true," + + " \"isForwarded\": true," + + " \"mailboxIds\": [\"" + getOutboxId(cedricAccessToken) + "\"]" + + " }}" + + " }," + + " \"#0\"" + + " ]" + + "]"; + + with() + .header("Authorization", cedricAccessToken.serialize()) + .body(requestBody) + .post("/jmap"); + + AccessToken bobAccessToken = HttpJmapAuthentication.authenticateJamesUser(baseUri(), BOB, BOB_PASSWORD); + calmlyAwait.atMost(30, TimeUnit.SECONDS).until(() -> isAnyMessageFoundInRecipientsMailboxes(bobAccessToken)); + given() + .header("Authorization", bobAccessToken.serialize()) + .body("[[\"getMessageList\", {}, \"#0\"]]") + .when() + .post("/jmap") + .then() + .log().ifValidationFails() + .statusCode(200) + .body(NAME, equalTo("messageList")) + .body(ARGUMENTS + ".messageIds", hasSize(1)); + + given() + .header("Authorization", aliceAccessToken.serialize()) + .body("[[\"getMessageList\", {}, \"#0\"]]") + .when() + .post("/jmap") + .then() + .log().ifValidationFails() + .statusCode(200) + .body(NAME, equalTo("messageList")) + .body(ARGUMENTS + ".messageIds", hasSize(1)); + } + + @Test + public void baseRecipientShouldNotReceiveEmailOnDefaultForward() { + webAdminApi.put(String.format("/address/forwards/%s/targets/%s", ALICE, BOB)); + + AccessToken cedricAccessToken = HttpJmapAuthentication.authenticateJamesUser(baseUri(), CEDRIC, CEDRIC_PASSWORD); + AccessToken aliceAccessToken = HttpJmapAuthentication.authenticateJamesUser(baseUri(), ALICE, ALICE_PASSWORD); + String messageCreationId = "creationId1337"; + String requestBody = "[" + + " [" + + " \"setMessages\"," + + " {" + + " \"create\": { \"" + messageCreationId + "\" : {" + + " \"from\": { \"name\": \"Me\", \"email\": \"" + CEDRIC + "\"}," + + " \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + "\"}]," + + " \"subject\": \"subject\"," + + " \"isUnread\": true," + + " \"isFlagged\": true," + + " \"isAnswered\": true," + + " \"isDraft\": true," + + " \"isForwarded\": true," + + " \"mailboxIds\": [\"" + getOutboxId(cedricAccessToken) + "\"]" + + " }}" + + " }," + + " \"#0\"" + + " ]" + + "]"; + + with() + .header("Authorization", cedricAccessToken.serialize()) + .body(requestBody) + .post("/jmap"); + + AccessToken bobAccessToken = HttpJmapAuthentication.authenticateJamesUser(baseUri(), BOB, BOB_PASSWORD); + calmlyAwait.atMost(30, TimeUnit.SECONDS).until(() -> isAnyMessageFoundInRecipientsMailboxes(bobAccessToken)); + + given() + .header("Authorization", aliceAccessToken.serialize()) + .body("[[\"getMessageList\", {}, \"#0\"]]") + .when() + .post("/jmap") + .then() + .log().ifValidationFails() + .statusCode(200) + .body(NAME, equalTo("messageList")) + .body(ARGUMENTS + ".messageIds", hasSize(0)); + } + + private URIBuilder baseUri() { + return new URIBuilder() + .setScheme("http") + .setHost("localhost") + .setPort(jmapServer.getProbe(JmapGuiceProbe.class) + .getJmapPort()) + .setCharset(StandardCharsets.UTF_8); + } + + private String getOutboxId(AccessToken accessToken) { + return getMailboxId(accessToken, Role.OUTBOX); + } + + private String getMailboxId(AccessToken accessToken, Role role) { + return getAllMailboxesIds(accessToken).stream() + .filter(x -> x.get("role").equalsIgnoreCase(role.serialize())) + .map(x -> x.get("id")) + .findFirst().get(); + } + + private List<Map<String, String>> getAllMailboxesIds(AccessToken accessToken) { + return with() + .header("Authorization", accessToken.serialize()) + .body("[[\"getMailboxes\", {\"properties\": [\"role\", \"id\"]}, \"#0\"]]") + .post("/jmap") + .andReturn() + .body() + .jsonPath() + .getList(ARGUMENTS + ".list"); + } + + private boolean isAnyMessageFoundInRecipientsMailboxes(AccessToken recipientToken) { + try { + with() + .header("Authorization", recipientToken.serialize()) + .body("[[\"getMessageList\", {}, \"#0\"]]") + .when() + .post("/jmap") + .then() + .statusCode(200) + .body(NAME, equalTo("messageList")) + .body(ARGUMENTS + ".messageIds", hasSize(1)); + return true; + + } catch (AssertionError e) { + return false; + } + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ce6e83dd/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryForwardIntegrationTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryForwardIntegrationTest.java b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryForwardIntegrationTest.java new file mode 100644 index 0000000..458e1e3 --- /dev/null +++ b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryForwardIntegrationTest.java @@ -0,0 +1,46 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.jmap.memory; + +import org.apache.james.GuiceJamesServer; +import org.apache.james.MemoryJmapTestRule; +import org.apache.james.jmap.methods.integration.ForwardIntegrationTest; +import org.apache.james.webadmin.RandomPortSupplier; +import org.apache.james.webadmin.WebAdminConfiguration; +import org.junit.Rule; + +public class MemoryForwardIntegrationTest extends ForwardIntegrationTest { + + @Rule + public MemoryJmapTestRule memoryJmap = new MemoryJmapTestRule(); + + @Override + protected GuiceJamesServer createJmapServer() { + return memoryJmap + .jmapServer(binder -> binder.bind(WebAdminConfiguration.class) + .toInstance(WebAdminConfiguration.builder() + .enabled() + .corsDisabled() + .host("127.0.0.1") + .port(new RandomPortSupplier()) + .build())); + } + +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ce6e83dd/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailetcontainer.xml ---------------------------------------------------------------------- diff --git a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailetcontainer.xml b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailetcontainer.xml index c4ca2b1..fdbe341 100644 --- a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailetcontainer.xml +++ b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailetcontainer.xml @@ -51,6 +51,7 @@ <name>bcc</name> </mailet> <mailet match="All" class="org.apache.james.jmap.mailet.TextCalendarBodyToAttachment"/> + <mailet match="All" class="RecipientRewriteTable" /> <mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.VacationMailet"/> <mailet match="RecipientIsLocal" class="Sieve"/> <mailet match="RecipientIsLocal" class="SpamAssassin"> --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org