JAMES-2585 Add Sieve script 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/08aaabc5 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/08aaabc5 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/08aaabc5 Branch: refs/heads/master Commit: 08aaabc5e40862d9a53c1b177521d506c52a87ad Parents: 71872d1 Author: datph <dphamho...@linagora.com> Authored: Mon Nov 5 21:00:23 2018 +0700 Committer: Benoit Tellier <btell...@linagora.com> Committed: Wed Nov 14 16:27:09 2018 +0700 ---------------------------------------------------------------------- .../apache/james/CassandraJamesServerMain.java | 4 +- .../org/apache/james/JPAJamesServerMain.java | 4 +- .../org/apache/james/MemoryJamesServerMain.java | 4 +- .../modules/server/SieveQuotaRoutesModule.java | 35 --- .../james/modules/server/SieveRoutesModule.java | 40 +++ server/protocols/webadmin/webadmin-data/pom.xml | 10 + .../webadmin/routes/SieveScriptRoutes.java | 192 ++++++++++++++ .../webadmin/routes/SieveScriptRoutesTest.java | 261 +++++++++++++++++++ .../src/test/resources/sieve/my_sieve | 5 + 9 files changed, 514 insertions(+), 41 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/08aaabc5/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 13cdd68..697c7d7 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 @@ -54,7 +54,7 @@ import org.apache.james.modules.server.MailRepositoriesRoutesModule; import org.apache.james.modules.server.MailboxRoutesModule; import org.apache.james.modules.server.MessageIdReIndexingModule; import org.apache.james.modules.server.ReIndexingModule; -import org.apache.james.modules.server.SieveQuotaRoutesModule; +import org.apache.james.modules.server.SieveRoutesModule; import org.apache.james.modules.server.SwaggerRoutesModule; import org.apache.james.modules.server.WebAdminServerModule; import org.apache.james.modules.spamassassin.SpamAssassinListenerModule; @@ -74,7 +74,7 @@ public class CassandraJamesServerMain { new SwaggerRoutesModule(), new WebAdminServerModule(), new DLPRoutesModule(), - new SieveQuotaRoutesModule(), + new SieveRoutesModule(), new ReIndexingModule(), new MessageIdReIndexingModule()); http://git-wip-us.apache.org/repos/asf/james-project/blob/08aaabc5/server/container/guice/jpa-guice/src/main/java/org/apache/james/JPAJamesServerMain.java ---------------------------------------------------------------------- diff --git a/server/container/guice/jpa-guice/src/main/java/org/apache/james/JPAJamesServerMain.java b/server/container/guice/jpa-guice/src/main/java/org/apache/james/JPAJamesServerMain.java index f12f7ec..30a6322 100644 --- a/server/container/guice/jpa-guice/src/main/java/org/apache/james/JPAJamesServerMain.java +++ b/server/container/guice/jpa-guice/src/main/java/org/apache/james/JPAJamesServerMain.java @@ -42,7 +42,7 @@ import org.apache.james.modules.server.MailboxRoutesModule; import org.apache.james.modules.server.NoJwtModule; import org.apache.james.modules.server.RawPostDequeueDecoratorModule; import org.apache.james.modules.server.ReIndexingModule; -import org.apache.james.modules.server.SieveQuotaRoutesModule; +import org.apache.james.modules.server.SieveRoutesModule; import org.apache.james.modules.server.SwaggerRoutesModule; import org.apache.james.modules.server.WebAdminServerModule; import org.apache.james.modules.spamassassin.SpamAssassinListenerModule; @@ -60,7 +60,7 @@ public class JPAJamesServerMain { new MailQueueRoutesModule(), new MailRepositoriesRoutesModule(), new SwaggerRoutesModule(), - new SieveQuotaRoutesModule(), + new SieveRoutesModule(), new ReIndexingModule()); public static final Module PROTOCOLS = Modules.combine( http://git-wip-us.apache.org/repos/asf/james-project/blob/08aaabc5/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 18a3f2f..b72810e 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 @@ -41,7 +41,7 @@ import org.apache.james.modules.server.MailRepositoriesRoutesModule; import org.apache.james.modules.server.MailboxRoutesModule; import org.apache.james.modules.server.MemoryMailQueueModule; import org.apache.james.modules.server.RawPostDequeueDecoratorModule; -import org.apache.james.modules.server.SieveQuotaRoutesModule; +import org.apache.james.modules.server.SieveRoutesModule; import org.apache.james.modules.server.SwaggerRoutesModule; import org.apache.james.modules.server.WebAdminServerModule; import org.apache.james.modules.spamassassin.SpamAssassinListenerModule; @@ -60,7 +60,7 @@ public class MemoryJamesServerMain { new MailRepositoriesRoutesModule(), new SwaggerRoutesModule(), new DLPRoutesModule(), - new SieveQuotaRoutesModule()); + new SieveRoutesModule()); public static final Module PROTOCOLS = Modules.combine( new IMAPServerModule(), http://git-wip-us.apache.org/repos/asf/james-project/blob/08aaabc5/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/SieveQuotaRoutesModule.java ---------------------------------------------------------------------- diff --git a/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/SieveQuotaRoutesModule.java b/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/SieveQuotaRoutesModule.java deleted file mode 100644 index 27fdcbb..0000000 --- a/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/SieveQuotaRoutesModule.java +++ /dev/null @@ -1,35 +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.modules.server; - -import org.apache.james.webadmin.Routes; -import org.apache.james.webadmin.routes.SieveQuotaRoutes; - -import com.google.inject.AbstractModule; -import com.google.inject.multibindings.Multibinder; - -public class SieveQuotaRoutesModule extends AbstractModule { - @Override - protected void configure() { - Multibinder.newSetBinder(binder(), Routes.class) - .addBinding() - .to(SieveQuotaRoutes.class); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/08aaabc5/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/SieveRoutesModule.java ---------------------------------------------------------------------- diff --git a/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/SieveRoutesModule.java b/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/SieveRoutesModule.java new file mode 100644 index 0000000..31193e7 --- /dev/null +++ b/server/container/guice/protocols/webadmin-data/src/main/java/org/apache/james/modules/server/SieveRoutesModule.java @@ -0,0 +1,40 @@ +/**************************************************************** + * 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.SieveQuotaRoutes; +import org.apache.james.webadmin.routes.SieveScriptRoutes; + +import com.google.inject.AbstractModule; +import com.google.inject.multibindings.Multibinder; + +public class SieveRoutesModule extends AbstractModule { + @Override + protected void configure() { + Multibinder.newSetBinder(binder(), Routes.class) + .addBinding() + .to(SieveQuotaRoutes.class); + + Multibinder.newSetBinder(binder(), Routes.class) + .addBinding() + .to(SieveScriptRoutes.class); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/08aaabc5/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 3a17b66..73c8f05 100644 --- a/server/protocols/webadmin/webadmin-data/pom.xml +++ b/server/protocols/webadmin/webadmin-data/pom.xml @@ -107,6 +107,16 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-data-file</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-testing</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/08aaabc5/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/SieveScriptRoutes.java ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/SieveScriptRoutes.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/SieveScriptRoutes.java new file mode 100644 index 0000000..2fa7a44 --- /dev/null +++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/SieveScriptRoutes.java @@ -0,0 +1,192 @@ +/**************************************************************** + * 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 org.apache.james.webadmin.Constants.SEPARATOR; +import static spark.Spark.halt; + +import java.util.Optional; + +import javax.inject.Inject; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; + +import org.apache.james.core.User; +import org.apache.james.sieverepository.api.ScriptContent; +import org.apache.james.sieverepository.api.ScriptName; +import org.apache.james.sieverepository.api.SieveRepository; +import org.apache.james.sieverepository.api.exception.QuotaExceededException; +import org.apache.james.sieverepository.api.exception.ScriptNotFoundException; +import org.apache.james.sieverepository.api.exception.StorageException; +import org.apache.james.user.api.UsersRepository; +import org.apache.james.user.api.UsersRepositoryException; +import org.apache.james.webadmin.Routes; +import org.apache.james.webadmin.utils.ErrorResponder; +import org.eclipse.jetty.http.HttpStatus; + +import com.google.common.base.Joiner; + +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.Response; +import spark.Service; +import spark.utils.StringUtils; + +@Api(tags = "SieveScript") +@Path(value = "/sieve") +public class SieveScriptRoutes implements Routes { + + public static final String ROOT_PATH = "/sieve"; + public static final String SCRIPTS = "scripts"; + private static final String USER_NAME = "userName"; + private static final String SCRIPT_NAME = "scriptName"; + private static final String ACTIVATE_PARAMS = "activate"; + private static final String USER_SCRIPT_PATH = Joiner.on(SEPARATOR) + .join(ROOT_PATH, ":" + USER_NAME, SCRIPTS, ":" + SCRIPT_NAME); + + private final SieveRepository sieveRepository; + private final UsersRepository usersRepository; + + @Inject + public SieveScriptRoutes(SieveRepository sieveRepository, UsersRepository usersRepository) { + this.sieveRepository = sieveRepository; + this.usersRepository = usersRepository; + } + + @Override + public String getBasePath() { + return ROOT_PATH; + } + + @Override + public void define(Service service) { + defineAddActiveSieveScript(service); + } + + @PUT + @ApiOperation(value = "Upload a new Sieve Script") + @Path(value = ROOT_PATH + "/{" + USER_NAME + "}/" + SCRIPTS + "/{" + SCRIPT_NAME + "}") + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.NO_CONTENT_204, message = "OK"), + @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid username"), + @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Invalid Sieve script name"), + @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Empty script is not accepted"), + @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "User not found") + }) + @ApiImplicitParams({ + @ApiImplicitParam( + name = USER_NAME, + required = true, + paramType = "path", + dataType = "String", + example = ROOT_PATH + "/userNameA/" + SCRIPTS + "/scriptName1", + value = "Username"), + @ApiImplicitParam( + name = SCRIPT_NAME, + required = true, + paramType = "path", + dataType = "String", + example = ROOT_PATH + "/userNameA/" + SCRIPTS + "/scriptName1", + value = "Script name"), + @ApiImplicitParam( + required = false, + paramType = "query parameter", + dataType = "Boolean", + defaultValue = "False", + example = "?activate=true", + value = "If present, automatically activating the script.") + }) + public void defineAddActiveSieveScript(Service service) { + service.put(USER_SCRIPT_PATH, this::addActiveSieveScript); + } + + private HaltException addActiveSieveScript(Request request, Response response) throws UsersRepositoryException, QuotaExceededException, StorageException, ScriptNotFoundException { + User user = extractUser(request); + ScriptName script = extractScriptName(request); + boolean isActivated = isActivated(request.queryParams(ACTIVATE_PARAMS)); + sieveRepository.putScript(user, script, extractSieveScriptFromRequest(request)); + if (isActivated) { + sieveRepository.setActive(user, script); + } + return halt(HttpStatus.NO_CONTENT_204); + } + + private User extractUser(Request request) throws UsersRepositoryException { + String userName = Optional.ofNullable(request.params(USER_NAME)) + .map(String::trim) + .filter(StringUtils::isNotEmpty) + .orElseThrow(() -> throw400withInvalidArgument("Invalid username")); + + if (!usersRepository.contains(userName)) { + throw404("User not found"); + } + return User.fromUsername(userName); + } + + private ScriptName extractScriptName(Request request) { + return Optional.ofNullable(request.params(SCRIPT_NAME)) + .map(String::trim) + .filter(StringUtils::isNotEmpty) + .map(ScriptName::new) + .orElseThrow(() -> throw400withInvalidArgument("Invalid Sieve script name")); + } + + private ScriptContent extractSieveScriptFromRequest(Request request) { + return new ScriptContent(request.body()); + } + + private boolean isActivated(String activateParam) { + return Optional.ofNullable(activateParam) + .map(String::trim) + .map(this::parseActivateParam) + .orElse(false); + } + + private boolean parseActivateParam(String activateParam) { + if (activateParam.equalsIgnoreCase(Boolean.TRUE.toString()) + || activateParam.equalsIgnoreCase(Boolean.FALSE.toString())) { + return Boolean.parseBoolean(activateParam); + } + + throw throw400withInvalidArgument("Invalid activate query parameter"); + } + + private HaltException throw400withInvalidArgument(String message) { + throw ErrorResponder.builder() + .statusCode(HttpStatus.BAD_REQUEST_400) + .type(ErrorResponder.ErrorType.INVALID_ARGUMENT) + .message(message) + .haltError(); + } + + private HaltException throw404(String message) { + throw ErrorResponder.builder() + .statusCode(HttpStatus.NOT_FOUND_404) + .type(ErrorResponder.ErrorType.NOT_FOUND) + .message(message) + .haltError(); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/08aaabc5/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/SieveScriptRoutesTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/SieveScriptRoutesTest.java b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/SieveScriptRoutesTest.java new file mode 100644 index 0000000..5c3fb28 --- /dev/null +++ b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/SieveScriptRoutesTest.java @@ -0,0 +1,261 @@ +/**************************************************************** + * 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 io.restassured.RestAssured.given; +import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; +import static org.apache.james.webadmin.WebAdminServer.NO_CONFIGURATION; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.hamcrest.Matchers.equalTo; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.charset.StandardCharsets; + +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.io.IOUtils; +import org.apache.james.core.User; +import org.apache.james.filesystem.api.FileSystem; +import org.apache.james.junit.TemporaryFolderExtension; +import org.apache.james.metrics.logger.DefaultMetricFactory; +import org.apache.james.sieverepository.api.ScriptContent; +import org.apache.james.sieverepository.api.ScriptName; +import org.apache.james.sieverepository.api.SieveRepository; +import org.apache.james.sieverepository.api.exception.ScriptNotFoundException; +import org.apache.james.sieverepository.api.exception.StorageException; +import org.apache.james.sieverepository.file.SieveFileRepository; +import org.apache.james.user.api.UsersRepository; +import org.apache.james.user.api.UsersRepositoryException; +import org.apache.james.user.memory.MemoryUsersRepository; +import org.apache.james.webadmin.WebAdminServer; +import org.apache.james.webadmin.WebAdminUtils; +import org.eclipse.jetty.http.HttpStatus; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import io.restassured.RestAssured; + +@ExtendWith(TemporaryFolderExtension.class) +public class SieveScriptRoutesTest { + + private FileSystem fileSystem; + private WebAdminServer webAdminServer; + private SieveRepository sieveRepository; + private UsersRepository usersRepository; + private String sieveContent; + + @BeforeEach + public void setUp(TemporaryFolderExtension.TemporaryFolder temporaryFolder) throws ConfigurationException, IOException, UsersRepositoryException { + this.fileSystem = new FileSystem() { + @Override + public File getBasedir() { + return temporaryFolder.getTempDir(); + } + + @Override + public InputStream getResource(String url) throws IOException { + return new FileInputStream(getFile(url)); + } + + @Override + public File getFile(String fileURL) { + return new File(getBasedir(), fileURL.substring(FileSystem.FILE_PROTOCOL.length())); + } + }; + + sieveRepository = new SieveFileRepository(fileSystem); + usersRepository = MemoryUsersRepository.withoutVirtualHosting(); + usersRepository.addUser("userA", "password"); + + URL sieveResource = ClassLoader.getSystemResource("sieve/my_sieve"); + sieveContent = IOUtils.toString(sieveResource, StandardCharsets.UTF_8); + + webAdminServer = WebAdminUtils.createWebAdminServer( + new DefaultMetricFactory(), + new SieveScriptRoutes(sieveRepository, usersRepository)); + webAdminServer.configure(NO_CONFIGURATION); + webAdminServer.await(); + + RestAssured.requestSpecification = WebAdminUtils + .buildRequestSpecification(webAdminServer) + .build(); + } + + @AfterEach + public void tearDown() { + webAdminServer.destroy(); + } + + @Test + public void defineAddActiveSieveScriptShouldReturnNotFoundWhenUserNotExisted() throws IOException { + given() + .pathParam("userName", "unknown") + .pathParam("scriptName", "scriptA") + .body(sieveContent) + .when() + .put("sieve/{userName}/scripts/{scriptName}") + .then() + .statusCode(HttpStatus.NOT_FOUND_404); + } + + @Test + public void defineAddActiveSieveScriptShouldReturnNotFoundWhenScriptNameIsWhiteSpace() throws IOException { + String errorBody = + "{\"statusCode\": 400," + + " \"type\":\"InvalidArgument\"," + + " \"message\":\"Invalid Sieve script name\"," + + " \"details\":null" + + "}"; + String body = given() + .pathParam("userName", "userA") + .pathParam("scriptName", " ") + .body(sieveContent) + .when() + .put("sieve/{userName}/scripts/{scriptName}") + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .extract() + .body().asString(); + + assertThatJson(body).isEqualTo(errorBody); + } + + @Test + public void defineAddActiveSieveScriptShouldReturnNotFoundWhenUserNameWhiteSpace() { + String errorBody = + "{\"statusCode\": 400," + + " \"type\":\"InvalidArgument\"," + + " \"message\":\"Invalid username\"," + + " \"details\":null" + + "}"; + String body = given() + .pathParam("userName", " ") + .pathParam("scriptName", "scriptA") + .body(sieveContent) + .when() + .put("sieve/{userName}/scripts/{scriptName}") + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .extract() + .body().asString(); + + assertThatJson(body).isEqualTo(errorBody); + } + + @Test + public void defineAddActiveSieveScriptShouldReturnInternalErrorWhenScriptIsNotSet() { + given() + .pathParam("userName", "userA") + .pathParam("scriptName", "scriptA") + .when() + .put("sieve/{userName}/scripts/{scriptName}") + .then() + .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500); + } + + @Test + public void defineAddActiveSieveScriptShouldReturnSucceededWhenScriptIsWhiteSpace() throws ScriptNotFoundException, StorageException, IOException { + given() + .pathParam("userName", "userA") + .pathParam("scriptName", "scriptA") + .body(" ") + .when() + .put("sieve/{userName}/scripts/{scriptName}") + .then() + .statusCode(HttpStatus.NO_CONTENT_204); + + assertThat(getScriptContent(sieveRepository + .getScript(User.fromUsername("userA"), new ScriptName("scriptA")))) + .isEqualTo(new ScriptContent(" ")); + } + + @Test + public void defineAddActiveSieveScriptAddScriptSucceededOneWhenNotAddActivateParam() throws Exception { + given() + .pathParam("userName", "userA") + .pathParam("scriptName", "scriptA") + .body(sieveContent) + .when() + .put("sieve/{userName}/scripts/{scriptName}") + .then() + .statusCode(HttpStatus.NO_CONTENT_204); + + assertThat(getScriptContent(sieveRepository + .getScript(User.fromUsername("userA"), new ScriptName("scriptA")))) + .isEqualTo(new ScriptContent(sieveContent)); + } + + @Test + public void defineAddActiveSieveScriptSetActiveTrueWhenAddActivateParamTrue() throws Exception { + given() + .pathParam("userName", "userA") + .pathParam("scriptName", "scriptA") + .queryParam("activate", true) + .body(sieveContent) + .when() + .put("sieve/{userName}/scripts/{scriptName}") + .then() + .statusCode(HttpStatus.NO_CONTENT_204); + + assertThat(getScriptContent(sieveRepository + .getActive(User.fromUsername("userA")))) + .isEqualTo(new ScriptContent(sieveContent)); + } + + @Test + public void defineAddActiveSieveScriptGetActiveShouldThrowsExceptionWhenAddActivateParamFalse() { + given() + .pathParam("userName", "userA") + .pathParam("scriptName", "scriptA") + .queryParam("activate", false) + .body(sieveContent) + .when() + .put("sieve/{userName}/scripts/{scriptName}") + .then() + .statusCode(HttpStatus.NO_CONTENT_204); + + assertThatThrownBy(() -> sieveRepository.getActive(User.fromUsername("userA"))) + .isInstanceOf(ScriptNotFoundException.class); + } + + @Test + public void defineAddActiveSieveScriptInvokeShouldReturnBadRequestWhenAddActivateParamWithNotBooleanValue() { + given() + .pathParam("userName", "userA") + .pathParam("scriptName", "scriptA") + .queryParam("activate", "activate") + .body(sieveContent) + .when() + .put("sieve/{userName}/scripts/{scriptName}") + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .body("message", equalTo("Invalid activate query parameter")); + } + + protected ScriptContent getScriptContent(InputStream inputStream) throws IOException { + return new ScriptContent(IOUtils.toString(inputStream, StandardCharsets.UTF_8)); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/08aaabc5/server/protocols/webadmin/webadmin-data/src/test/resources/sieve/my_sieve ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin/webadmin-data/src/test/resources/sieve/my_sieve b/server/protocols/webadmin/webadmin-data/src/test/resources/sieve/my_sieve new file mode 100644 index 0000000..eb859b0 --- /dev/null +++ b/server/protocols/webadmin/webadmin-data/src/test/resources/sieve/my_sieve @@ -0,0 +1,5 @@ +require ["reject"]; + +if size :over 100K { + reject "Email too big"; +} \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org