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/11/05 09:02:15 UTC

[james-project] branch master updated (d9e694d -> 4bac9ab)

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git.


    from d9e694d  JAMES-2933 Define mailetdocs-maven-plugin version globally
     new 982c430  JAMES-2946 Return InvalidArgument when a MailRepository is tried to be created with an unsupported protocol
     new c133ac9  JAMES-2954 Correct error root cause in WebAdmin's addresses groups error messages
     new f1e5546  JAMES-2955 updating a domain quota with null value should reset it
     new 5eef771  JAMES-2955 updating a user quota with null value should reset it
     new 4bac9ab  JAMES-2962 Check if user exists before getting, setting or removing its sieve quota

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../modules/server/GuiceMailRepositoryLoader.java  |  2 +-
 .../MailRepositoryStoreBeanFactory.java            |  2 +-
 .../mailrepository/api/MailRepositoryStore.java    | 10 ++++
 .../memory/MemoryMailRepositoryStore.java          |  4 +-
 .../memory/MemoryMailRepositoryStoreTest.java      |  2 +-
 .../memory/TestingMailRepositoryLoader.java        |  2 +-
 .../apache/james/webadmin/routes/GroupsRoutes.java | 17 +++---
 .../james/webadmin/routes/SieveQuotaRoutes.java    | 26 +++++++--
 .../james/webadmin/routes/GroupsRoutesTest.java    |  4 +-
 .../webadmin/routes/SieveQuotaRoutesTest.java      | 53 ++++++++++++++----
 .../james/webadmin/service/DomainQuotaService.java | 21 +++++--
 .../james/webadmin/service/UserQuotaService.java   | 21 +++++--
 .../webadmin/routes/DomainQuotaRoutesTest.java     | 48 +++++++++++++++-
 .../james/webadmin/routes/UserQuotaRoutesTest.java | 64 ++++++++++++++++++++++
 .../webadmin/routes/MailRepositoriesRoutes.java    |  7 +++
 .../routes/MailRepositoriesRoutesTest.java         | 16 ++++++
 16 files changed, 257 insertions(+), 42 deletions(-)


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 03/05: JAMES-2955 updating a domain quota with null value should reset it

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit f1e5546f04041e78d95a50b85756638d1fa74bb0
Author: Rémi KOWALSKI <rk...@linagora.com>
AuthorDate: Thu Oct 31 17:20:02 2019 +0100

    JAMES-2955 updating a domain quota with null value should reset it
---
 .../james/webadmin/service/DomainQuotaService.java | 21 +++++++---
 .../webadmin/routes/DomainQuotaRoutesTest.java     | 48 +++++++++++++++++++++-
 2 files changed, 62 insertions(+), 7 deletions(-)

diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/DomainQuotaService.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/DomainQuotaService.java
index 2b59837..0c30c19 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/DomainQuotaService.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/DomainQuotaService.java
@@ -31,8 +31,6 @@ import org.apache.james.mailbox.quota.MaxQuotaManager;
 import org.apache.james.webadmin.dto.QuotaDTO;
 import org.apache.james.webadmin.dto.QuotaDomainDTO;
 
-import com.github.fge.lambdas.Throwing;
-
 public class DomainQuotaService {
 
     private final MaxQuotaManager maxQuotaManager;
@@ -84,9 +82,20 @@ public class DomainQuotaService {
     }
 
     public void defineQuota(Domain domain, QuotaDTO quota) {
-        quota.getCount()
-            .ifPresent(Throwing.consumer(count -> maxQuotaManager.setDomainMaxMessage(domain, count)));
-        quota.getSize()
-            .ifPresent(Throwing.consumer(size -> maxQuotaManager.setDomainMaxStorage(domain, size)));
+        try {
+            if (quota.getCount().isPresent()) {
+                maxQuotaManager.setDomainMaxMessage(domain, quota.getCount().get());
+            } else {
+                maxQuotaManager.removeDomainMaxMessage(domain);
+            }
+
+            if (quota.getSize().isPresent()) {
+                maxQuotaManager.setDomainMaxStorage(domain, quota.getSize().get());
+            } else {
+                maxQuotaManager.removeDomainMaxStorage(domain);
+            }
+        } catch (MailboxException e) {
+            throw new RuntimeException(e);
+        }
     }
 }
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/DomainQuotaRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/DomainQuotaRoutesTest.java
index 482d241..2c654e2 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/DomainQuotaRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/DomainQuotaRoutesTest.java
@@ -450,7 +450,14 @@ class DomainQuotaRoutesTest {
     @Test
     void putQuotaShouldBeAbleToRemoveBothQuota() {
         given()
-            .body("{\"count\":null,\"count\":null}")
+            .body("{\"count\":52,\"size\":42}")
+            .put(QUOTA_DOMAINS + "/" + TROUVÉ_COM.name())
+        .then()
+            .statusCode(HttpStatus.NO_CONTENT_204);
+
+
+        given()
+            .body("{\"count\":null,\"size\":null}")
             .put(QUOTA_DOMAINS + "/" + TROUVÉ_COM.name())
         .then()
             .statusCode(HttpStatus.NO_CONTENT_204);
@@ -459,4 +466,43 @@ class DomainQuotaRoutesTest {
         assertThat(maxQuotaManager.getDomainMaxMessage(TROUVÉ_COM)).isEmpty();
     }
 
+    @Test
+    void putQuotaShouldBeAbleToRemoveCountQuota() {
+        given()
+            .body("{\"count\":52,\"size\":42}")
+            .put(QUOTA_DOMAINS + "/" + TROUVÉ_COM.name())
+        .then()
+            .statusCode(HttpStatus.NO_CONTENT_204);
+
+
+        given()
+            .body("{\"count\":null,\"size\":42}")
+            .put(QUOTA_DOMAINS + "/" + TROUVÉ_COM.name())
+        .then()
+            .statusCode(HttpStatus.NO_CONTENT_204);
+
+        assertThat(maxQuotaManager.getDomainMaxStorage(TROUVÉ_COM)).contains(QuotaSize.size(42));
+        assertThat(maxQuotaManager.getDomainMaxMessage(TROUVÉ_COM)).isEmpty();
+    }
+
+    @Test
+    void putQuotaShouldBeAbleToRemoveSizeQuota() {
+        given()
+            .body("{\"count\":52,\"size\":42}")
+            .put(QUOTA_DOMAINS + "/" + TROUVÉ_COM.name())
+        .then()
+            .statusCode(HttpStatus.NO_CONTENT_204);
+
+
+        given()
+            .body("{\"count\":52,\"size\":null}")
+            .put(QUOTA_DOMAINS + "/" + TROUVÉ_COM.name())
+        .then()
+            .statusCode(HttpStatus.NO_CONTENT_204);
+
+        assertThat(maxQuotaManager.getDomainMaxStorage(TROUVÉ_COM)).isEmpty();
+        assertThat(maxQuotaManager.getDomainMaxMessage(TROUVÉ_COM)).contains(QuotaCount.count(52));
+    }
+
+
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 01/05: JAMES-2946 Return InvalidArgument when a MailRepository is tried to be created with an unsupported protocol

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 982c4309a910e634e420e635a7c9c8a18d3c8f7d
Author: Gautier DI FOLCO <gd...@linagora.com>
AuthorDate: Wed Oct 30 12:48:47 2019 +0100

    JAMES-2946 Return InvalidArgument when a MailRepository is tried to be created with an unsupported protocol
---
 .../james/modules/server/GuiceMailRepositoryLoader.java  |  2 +-
 .../MailRepositoryStoreBeanFactory.java                  |  2 +-
 .../james/mailrepository/api/MailRepositoryStore.java    | 10 ++++++++++
 .../mailrepository/memory/MemoryMailRepositoryStore.java |  4 ++--
 .../memory/MemoryMailRepositoryStoreTest.java            |  2 +-
 .../memory/TestingMailRepositoryLoader.java              |  2 +-
 .../james/webadmin/routes/MailRepositoriesRoutes.java    |  7 +++++++
 .../webadmin/routes/MailRepositoriesRoutesTest.java      | 16 ++++++++++++++++
 8 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/GuiceMailRepositoryLoader.java b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/GuiceMailRepositoryLoader.java
index ef70d35..2c62334 100644
--- a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/GuiceMailRepositoryLoader.java
+++ b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/GuiceMailRepositoryLoader.java
@@ -45,7 +45,7 @@ public class GuiceMailRepositoryLoader implements MailRepositoryLoader {
             return genericLoader.<MailRepository>withChildModule(urlModule)
                 .instantiate(new ClassName(fullyQualifiedClassName));
         } catch (ClassNotFoundException e) {
-            throw new MailRepositoryStore.MailRepositoryStoreException("No Mail Repository found with class name " + fullyQualifiedClassName);
+            throw new MailRepositoryStore.UnsupportedRepositoryStoreException("No Mail Repository found with class name " + fullyQualifiedClassName);
         } catch (ClassCastException e) {
             throw new MailRepositoryStore.MailRepositoryStoreException(fullyQualifiedClassName + " is not a MailRepository");
         }
diff --git a/server/container/spring/src/main/java/org/apache/james/container/spring/bean/factory/mailrepositorystore/MailRepositoryStoreBeanFactory.java b/server/container/spring/src/main/java/org/apache/james/container/spring/bean/factory/mailrepositorystore/MailRepositoryStoreBeanFactory.java
index 3f529af..91002ba 100644
--- a/server/container/spring/src/main/java/org/apache/james/container/spring/bean/factory/mailrepositorystore/MailRepositoryStoreBeanFactory.java
+++ b/server/container/spring/src/main/java/org/apache/james/container/spring/bean/factory/mailrepositorystore/MailRepositoryStoreBeanFactory.java
@@ -206,7 +206,7 @@ public class MailRepositoryStoreBeanFactory extends AbstractBeanFactory implemen
                 return reply;
             } catch (Exception e) {
                 LOGGER.warn("Exception while creating repository: {}", e.getMessage(), e);
-                throw new MailRepositoryStoreException("Cannot find or init repository", e);
+                throw new UnsupportedRepositoryStoreException("Cannot find or init repository", e);
             }
         }
 
diff --git a/server/data/data-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryStore.java b/server/data/data-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryStore.java
index 7d0c520..f220775 100644
--- a/server/data/data-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryStore.java
+++ b/server/data/data-api/src/main/java/org/apache/james/mailrepository/api/MailRepositoryStore.java
@@ -92,4 +92,14 @@ public interface MailRepositoryStore {
             super(msg);
         }
     }
+
+    class UnsupportedRepositoryStoreException extends MailRepositoryStoreException {
+        public UnsupportedRepositoryStoreException(String msg, Throwable t) {
+            super(msg, t);
+        }
+
+        public UnsupportedRepositoryStoreException(String msg) {
+            super(msg);
+        }
+    }
 }
diff --git a/server/data/data-memory/src/main/java/org/apache/james/mailrepository/memory/MemoryMailRepositoryStore.java b/server/data/data-memory/src/main/java/org/apache/james/mailrepository/memory/MemoryMailRepositoryStore.java
index 61c1069..da5d546 100644
--- a/server/data/data-memory/src/main/java/org/apache/james/mailrepository/memory/MemoryMailRepositoryStore.java
+++ b/server/data/data-memory/src/main/java/org/apache/james/mailrepository/memory/MemoryMailRepositoryStore.java
@@ -133,7 +133,7 @@ public class MemoryMailRepositoryStore implements MailRepositoryStore, Startable
                 ((Initializable) mailRepository).init();
             }
         } catch (Exception e) {
-            throw new MailRepositoryStoreException("Cannot init mail repository", e);
+            throw new UnsupportedRepositoryStoreException("Cannot init mail repository", e);
         }
     }
 
@@ -145,6 +145,6 @@ public class MemoryMailRepositoryStore implements MailRepositoryStore, Startable
 
         return fullyQualifiedClass
             .map(Throwing.function(fqcnToMailRepository).sneakyThrow())
-            .orElseThrow(() -> new MailRepositoryStoreException("No Mail Repository associated with " + protocol.getValue()));
+            .orElseThrow(() -> new UnsupportedRepositoryStoreException("No Mail Repository associated with " + protocol.getValue()));
     }
 }
diff --git a/server/data/data-memory/src/test/java/org/apache/james/mailrepository/memory/MemoryMailRepositoryStoreTest.java b/server/data/data-memory/src/test/java/org/apache/james/mailrepository/memory/MemoryMailRepositoryStoreTest.java
index b430595..ffb36e2 100644
--- a/server/data/data-memory/src/test/java/org/apache/james/mailrepository/memory/MemoryMailRepositoryStoreTest.java
+++ b/server/data/data-memory/src/test/java/org/apache/james/mailrepository/memory/MemoryMailRepositoryStoreTest.java
@@ -69,7 +69,7 @@ public class MemoryMailRepositoryStoreTest {
         repositoryStore.init();
     }
 
-    @Test(expected = MailRepositoryStore.MailRepositoryStoreException.class)
+    @Test(expected = MailRepositoryStore.UnsupportedRepositoryStoreException.class)
     public void selectingANonRegisteredProtocolShouldFail() {
         repositoryStore.select(MailRepositoryUrl.from("proto://repo"));
     }
diff --git a/server/data/data-memory/src/test/java/org/apache/james/mailrepository/memory/TestingMailRepositoryLoader.java b/server/data/data-memory/src/test/java/org/apache/james/mailrepository/memory/TestingMailRepositoryLoader.java
index 93db1f9..025d5a6 100644
--- a/server/data/data-memory/src/test/java/org/apache/james/mailrepository/memory/TestingMailRepositoryLoader.java
+++ b/server/data/data-memory/src/test/java/org/apache/james/mailrepository/memory/TestingMailRepositoryLoader.java
@@ -29,6 +29,6 @@ public class TestingMailRepositoryLoader implements MailRepositoryLoader {
         if (fullyQualifiedClassName.equals(MemoryMailRepository.class.getCanonicalName())) {
             return new MemoryMailRepository();
         }
-        throw new MailRepositoryStore.MailRepositoryStoreException(fullyQualifiedClassName + " is not supported");
+        throw new MailRepositoryStore.UnsupportedRepositoryStoreException(fullyQualifiedClassName + " is not supported");
     }
 }
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/routes/MailRepositoriesRoutes.java b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/routes/MailRepositoriesRoutes.java
index c9fc45e..4bd881f 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/routes/MailRepositoriesRoutes.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/routes/MailRepositoriesRoutes.java
@@ -151,6 +151,13 @@ public class MailRepositoriesRoutes implements Routes {
             try {
                 repositoryStoreService.createMailRepository(path, protocol);
                 return Responses.returnNoContent(response);
+            } catch (MailRepositoryStore.UnsupportedRepositoryStoreException e) {
+                throw ErrorResponder.builder()
+                    .statusCode(HttpStatus.BAD_REQUEST_400)
+                    .type(ErrorType.INVALID_ARGUMENT)
+                    .cause(e)
+                    .message(String.format("'%s' is an unsupported protocol", protocol))
+                    .haltError();
             } catch (MailRepositoryStore.MailRepositoryStoreException e) {
                 throw ErrorResponder.builder()
                     .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500)
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/routes/MailRepositoriesRoutesTest.java b/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/routes/MailRepositoriesRoutesTest.java
index 967b260..00aeef4 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/routes/MailRepositoriesRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/routes/MailRepositoriesRoutesTest.java
@@ -177,6 +177,22 @@ public class MailRepositoriesRoutesTest {
     }
 
     @Test
+    public void putMailRepositoryShouldReturnInvalidArgumentWhenProtocolIsUnsupported() {
+        given()
+            .params("protocol", "unsupported")
+        .when()
+            .put(PATH_ESCAPED_MY_REPO)
+        .then()
+            .statusCode(HttpStatus.BAD_REQUEST_400)
+            .body("statusCode", is(400))
+            .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
+            .body("message", is("'unsupported' is an unsupported protocol"));
+
+        assertThat(mailRepositoryStore.get(URL_MY_REPO))
+            .isEmpty();
+    }
+
+    @Test
     public void getMailRepositoriesShouldReturnEmptyWhenEmpty() {
         List<Object> mailRepositories =
             when()


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 04/05: JAMES-2955 updating a user quota with null value should reset it

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 5eef771357f10771f95c372765b8fb7b054e6414
Author: Rémi KOWALSKI <rk...@linagora.com>
AuthorDate: Mon Nov 4 10:57:35 2019 +0100

    JAMES-2955 updating a user quota with null value should reset it
---
 .../james/webadmin/service/UserQuotaService.java   | 21 +++++--
 .../james/webadmin/routes/UserQuotaRoutesTest.java | 64 ++++++++++++++++++++++
 2 files changed, 80 insertions(+), 5 deletions(-)

diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserQuotaService.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserQuotaService.java
index 03969b4..0a4ff0c 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserQuotaService.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserQuotaService.java
@@ -61,11 +61,22 @@ public class UserQuotaService {
     }
 
     public void defineQuota(User user, QuotaDTO quota) {
-        QuotaRoot quotaRoot = userQuotaRootResolver.forUser(user);
-        quota.getCount()
-            .ifPresent(Throwing.consumer(count -> maxQuotaManager.setMaxMessage(quotaRoot, count)));
-        quota.getSize()
-            .ifPresent(Throwing.consumer(size -> maxQuotaManager.setMaxStorage(quotaRoot, size)));
+        try {
+            QuotaRoot quotaRoot = userQuotaRootResolver.forUser(user);
+            if (quota.getCount().isPresent()) {
+                maxQuotaManager.setMaxMessage(quotaRoot, quota.getCount().get());
+            } else {
+                maxQuotaManager.removeMaxMessage(quotaRoot);
+            }
+
+            if (quota.getSize().isPresent()) {
+                maxQuotaManager.setMaxStorage(quotaRoot, quota.getSize().get());
+            } else {
+                maxQuotaManager.removeMaxStorage(quotaRoot);
+            }
+        } catch (MailboxException e) {
+            throw new RuntimeException(e);
+        }
     }
 
     public QuotaDetailsDTO getQuota(User user) throws MailboxException {
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java
index af9f1aa..b4e48b8 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java
@@ -1091,5 +1091,69 @@ class UserQuotaRoutesTest {
                 .contains(QuotaSize.size(42));
             softly.assertAll();
         }
+
+        @Test
+        void putQuotaShouldRemoveCount(WebAdminQuotaSearchTestSystem testSystem) throws Exception {
+            MaxQuotaManager maxQuotaManager = testSystem.getQuotaSearchTestSystem().getMaxQuotaManager();
+            UserQuotaRootResolver userQuotaRootResolver = testSystem.getQuotaSearchTestSystem().getQuotaRootResolver();
+
+            maxQuotaManager.setMaxMessage(userQuotaRootResolver.forUser(BOB), QuotaCount.count(52));
+
+            with()
+                .body("{\"count\":null,\"size\":42}")
+                .put(QUOTA_USERS + "/" + BOB.asString())
+            .then()
+                .statusCode(HttpStatus.NO_CONTENT_204);
+
+            SoftAssertions softly = new SoftAssertions();
+            softly.assertThat(maxQuotaManager.getMaxMessage(userQuotaRootResolver.forUser(BOB)))
+                .isEmpty();
+            softly.assertThat(maxQuotaManager.getMaxStorage(userQuotaRootResolver.forUser(BOB)))
+                .contains(QuotaSize.size(42));
+            softly.assertAll();
+        }
+
+        @Test
+        void putQuotaShouldRemoveSize(WebAdminQuotaSearchTestSystem testSystem) throws Exception {
+            MaxQuotaManager maxQuotaManager = testSystem.getQuotaSearchTestSystem().getMaxQuotaManager();
+            UserQuotaRootResolver userQuotaRootResolver = testSystem.getQuotaSearchTestSystem().getQuotaRootResolver();
+
+            maxQuotaManager.setMaxStorage(userQuotaRootResolver.forUser(BOB), QuotaSize.size(42));
+
+            with()
+                .body("{\"count\":52,\"size\":null}")
+                .put(QUOTA_USERS + "/" + BOB.asString())
+            .then()
+                .statusCode(HttpStatus.NO_CONTENT_204);
+
+            SoftAssertions softly = new SoftAssertions();
+            softly.assertThat(maxQuotaManager.getMaxMessage(userQuotaRootResolver.forUser(BOB)))
+                .contains(QuotaCount.count(52));
+            softly.assertThat(maxQuotaManager.getMaxStorage(userQuotaRootResolver.forUser(BOB)))
+                .isEmpty();
+            softly.assertAll();
+        }
+
+        @Test
+        void putQuotaShouldRemoveBoth(WebAdminQuotaSearchTestSystem testSystem) throws Exception {
+            MaxQuotaManager maxQuotaManager = testSystem.getQuotaSearchTestSystem().getMaxQuotaManager();
+            UserQuotaRootResolver userQuotaRootResolver = testSystem.getQuotaSearchTestSystem().getQuotaRootResolver();
+
+            maxQuotaManager.setMaxStorage(userQuotaRootResolver.forUser(BOB), QuotaSize.size(42));
+
+            with()
+                .body("{\"count\":null,\"size\":null}")
+                .put(QUOTA_USERS + "/" + BOB.asString())
+            .then()
+                .statusCode(HttpStatus.NO_CONTENT_204);
+
+            SoftAssertions softly = new SoftAssertions();
+            softly.assertThat(maxQuotaManager.getMaxMessage(userQuotaRootResolver.forUser(BOB)))
+                .isEmpty();
+            softly.assertThat(maxQuotaManager.getMaxStorage(userQuotaRootResolver.forUser(BOB)))
+                .isEmpty();
+            softly.assertAll();
+        }
+
     }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 05/05: JAMES-2962 Check if user exists before getting, setting or removing its sieve quota

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 4bac9ab2f111c3fed8b95f645d79bbd79190e678
Author: Rene Cordier <rc...@linagora.com>
AuthorDate: Mon Nov 4 15:14:57 2019 +0700

    JAMES-2962 Check if user exists before getting, setting or removing its sieve quota
---
 .../james/webadmin/routes/SieveQuotaRoutes.java    | 26 +++++++++--
 .../webadmin/routes/SieveQuotaRoutesTest.java      | 53 ++++++++++++++++++----
 2 files changed, 65 insertions(+), 14 deletions(-)

diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/SieveQuotaRoutes.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/SieveQuotaRoutes.java
index de6f71c..8e9b236 100644
--- a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/SieveQuotaRoutes.java
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/SieveQuotaRoutes.java
@@ -32,6 +32,8 @@ import org.apache.james.core.User;
 import org.apache.james.core.quota.QuotaSize;
 import org.apache.james.sieverepository.api.SieveQuotaRepository;
 import org.apache.james.sieverepository.api.exception.QuotaNotFoundException;
+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.apache.james.webadmin.utils.JsonTransformer;
@@ -61,11 +63,13 @@ public class SieveQuotaRoutes implements Routes {
     private static final String REQUESTED_SIZE = "requestedSize";
 
     private final SieveQuotaRepository sieveQuotaRepository;
+    private final UsersRepository usersRepository;
     private final JsonTransformer jsonTransformer;
 
     @Inject
-    public SieveQuotaRoutes(SieveQuotaRepository sieveQuotaRepository, JsonTransformer jsonTransformer) {
+    public SieveQuotaRoutes(SieveQuotaRepository sieveQuotaRepository, UsersRepository usersRepository, JsonTransformer jsonTransformer) {
         this.sieveQuotaRepository = sieveQuotaRepository;
+        this.usersRepository = usersRepository;
         this.jsonTransformer = jsonTransformer;
     }
 
@@ -147,11 +151,12 @@ public class SieveQuotaRoutes implements Routes {
     @ApiResponses(value = {
             @ApiResponse(code = 200, message = "OK", response = Long.class),
             @ApiResponse(code = 204, message = "User sieve quota not set."),
+            @ApiResponse(code = 404, message = "The user name does not exist"),
             @ApiResponse(code = 500, message = "Internal server error - Something went bad on the server side.")
     })
     public void defineGetPerUserSieveQuota(Service service) {
         service.get(USER_SIEVE_QUOTA_PATH, (request, response) -> {
-            User userId = User.fromUsername(request.params(USER_ID));
+            User userId = getUser(request.params(USER_ID));
             try {
                 QuotaSize userQuota = sieveQuotaRepository.getQuota(userId);
                 response.status(HttpStatus.OK_200);
@@ -171,11 +176,12 @@ public class SieveQuotaRoutes implements Routes {
     @ApiResponses(value = {
             @ApiResponse(code = 204, message = "OK", response = Long.class),
             @ApiResponse(code = 400, message = "The body is not a positive integer."),
+            @ApiResponse(code = 404, message = "The user name does not exist"),
             @ApiResponse(code = 500, message = "Internal server error - Something went bad on the server side.")
     })
     public void defineUpdatePerUserSieveQuota(Service service) {
         service.put(USER_SIEVE_QUOTA_PATH, (request, response) -> {
-            User userId = User.fromUsername(request.params(USER_ID));
+            User userId = getUser(request.params(USER_ID));
             QuotaSize requestedSize = extractRequestedQuotaSizeFromRequest(request);
             sieveQuotaRepository.setQuota(userId, requestedSize);
             return Responses.returnNoContent(response);
@@ -189,11 +195,12 @@ public class SieveQuotaRoutes implements Routes {
     })
     @ApiResponses(value = {
             @ApiResponse(code = 204, message = "User sieve quota removed."),
+            @ApiResponse(code = 404, message = "The user name does not exist"),
             @ApiResponse(code = 500, message = "Internal server error - Something went bad on the server side.")
     })
     public void defineRemovePerUserSieveQuota(Service service) {
         service.delete(USER_SIEVE_QUOTA_PATH, (request, response) -> {
-            User userId = User.fromUsername(request.params(USER_ID));
+            User userId = getUser(request.params(USER_ID));
             try {
                 sieveQuotaRepository.removeQuota(userId);
             } catch (QuotaNotFoundException e) {
@@ -227,4 +234,15 @@ public class SieveQuotaRoutes implements Routes {
                 .haltError();
         }
     }
+
+    private User getUser(String username) throws UsersRepositoryException {
+        if (!usersRepository.contains(username)) {
+            throw ErrorResponder.builder()
+                .statusCode(HttpStatus.NOT_FOUND_404)
+                .type(ErrorResponder.ErrorType.INVALID_ARGUMENT)
+                .message("User " + username + " does not exist")
+                .haltError();
+        }
+        return User.fromUsername(username);
+    }
 }
diff --git a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/SieveQuotaRoutesTest.java b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/SieveQuotaRoutesTest.java
index 863cfb6..54c21c2 100644
--- a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/SieveQuotaRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/SieveQuotaRoutesTest.java
@@ -27,6 +27,8 @@ import org.apache.james.core.User;
 import org.apache.james.core.quota.QuotaSize;
 import org.apache.james.sieverepository.api.SieveQuotaRepository;
 import org.apache.james.sieverepository.memory.InMemorySieveQuotaRepository;
+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.apache.james.webadmin.utils.JsonTransformer;
@@ -40,15 +42,21 @@ import io.restassured.http.ContentType;
 
 class SieveQuotaRoutesTest {
 
-    private static final User USER_A = User.fromUsername("userA");
+    private static final String USER_NAME_A = "userA";
+    private static final String PASSWORD_A = "123456";
+    private static final User USER_A = User.fromUsername(USER_NAME_A);
 
     private WebAdminServer webAdminServer;
     private SieveQuotaRepository sieveRepository;
 
     @BeforeEach
-    void setUp() {
+    void setUp() throws UsersRepositoryException {
         sieveRepository = new InMemorySieveQuotaRepository();
-        webAdminServer = WebAdminUtils.createWebAdminServer(new SieveQuotaRoutes(sieveRepository, new JsonTransformer()))
+
+        MemoryUsersRepository usersRepository = MemoryUsersRepository.withoutVirtualHosting();
+        usersRepository.addUser(USER_NAME_A, PASSWORD_A);
+
+        webAdminServer = WebAdminUtils.createWebAdminServer(new SieveQuotaRoutes(sieveRepository, usersRepository, new JsonTransformer()))
             .start();
 
         RestAssured.requestSpecification = WebAdminUtils.buildRequestSpecification(webAdminServer)
@@ -149,7 +157,7 @@ class SieveQuotaRoutesTest {
     @Test
     void getPerUserQuotaShouldReturn204WhenNoQuotaSetForUser() {
         given()
-            .get("/sieve/quota/users/" + USER_A.asString())
+            .get("/sieve/quota/users/" + USER_NAME_A)
         .then()
             .statusCode(HttpStatus.NO_CONTENT_204);
     }
@@ -161,7 +169,7 @@ class SieveQuotaRoutesTest {
 
         long actual =
             given()
-                .get("/sieve/quota/users/" + USER_A.asString())
+                .get("/sieve/quota/users/" + USER_NAME_A)
             .then()
                 .statusCode(HttpStatus.OK_200)
                 .contentType(ContentType.JSON)
@@ -172,13 +180,21 @@ class SieveQuotaRoutesTest {
     }
 
     @Test
+    void getPerUserSieveQuotaShouldReturn404WhenUserDoesNotExist() {
+        given()
+            .get("/sieve/quota/users/not_exist")
+        .then()
+            .statusCode(HttpStatus.NOT_FOUND_404);
+    }
+
+    @Test
     void updatePerUserSieveQuotaShouldUpdateStoredValue() throws Exception {
         sieveRepository.setQuota(USER_A, QuotaSize.size(500L));
         long requiredSize = 1024L;
 
         given()
             .body(requiredSize)
-            .put("/sieve/quota/users/" + USER_A.asString())
+            .put("/sieve/quota/users/" + USER_NAME_A)
         .then()
             .statusCode(HttpStatus.NO_CONTENT_204);
 
@@ -189,7 +205,7 @@ class SieveQuotaRoutesTest {
     void updatePerUserSieveQuotaShouldReturn400WhenInvalidNumberFormatInTheBody() {
         given()
             .body("invalid")
-            .put("/sieve/quota/users/" + USER_A.asString())
+            .put("/sieve/quota/users/" + USER_NAME_A)
         .then()
             .statusCode(HttpStatus.BAD_REQUEST_400)
             .body("message", is("unrecognized integer number 'invalid'"));
@@ -209,15 +225,24 @@ class SieveQuotaRoutesTest {
     void updatePerUserSieveQuotaShouldReturn400WhenRequestedSizeNotPositiveInteger() {
         given()
             .body(-100L)
-            .put("/sieve/quota/users/" + USER_A.asString())
+            .put("/sieve/quota/users/" + USER_NAME_A)
         .then()
             .statusCode(HttpStatus.BAD_REQUEST_400);
     }
 
     @Test
+    void updatePerUserSieveQuotaShouldReturn404WhenUserDoesNotExist() {
+        given()
+            .body(500L)
+            .put("/sieve/quota/users/not_exist")
+        .then()
+            .statusCode(HttpStatus.NOT_FOUND_404);
+    }
+
+    @Test
     void removePerUserSieveQuotaShouldReturn204WhenNoQuotaSetForUser() {
         given()
-            .delete("/sieve/quota/users/" + USER_A.asString())
+            .delete("/sieve/quota/users/" + USER_NAME_A)
         .then()
             .statusCode(HttpStatus.NO_CONTENT_204);
     }
@@ -227,8 +252,16 @@ class SieveQuotaRoutesTest {
         sieveRepository.setQuota(USER_A, QuotaSize.size(1024));
 
         given()
-            .delete("/sieve/quota/users/" + USER_A.asString())
+            .delete("/sieve/quota/users/" + USER_NAME_A)
         .then()
             .statusCode(HttpStatus.NO_CONTENT_204);
     }
+
+    @Test
+    void removePerUserSieveQuotaShouldReturn404WhenUserDoesNotExist() {
+        given()
+            .delete("/sieve/quota/users/not_exist")
+        .then()
+            .statusCode(HttpStatus.NOT_FOUND_404);
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 02/05: JAMES-2954 Correct error root cause in WebAdmin's addresses groups error messages

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit c133ac9a7be33ce988592fcfc0bd81dbf60823f3
Author: Gautier DI FOLCO <gd...@linagora.com>
AuthorDate: Thu Oct 31 14:35:57 2019 +0100

    JAMES-2954 Correct error root cause in WebAdmin's addresses groups error messages
---
 .../org/apache/james/webadmin/routes/GroupsRoutes.java  | 17 +++++++++--------
 .../apache/james/webadmin/routes/GroupsRoutesTest.java  |  4 ++--
 2 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/GroupsRoutes.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/GroupsRoutes.java
index 756bd2c..646d1bf 100644
--- a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/GroupsRoutes.java
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/GroupsRoutes.java
@@ -80,7 +80,8 @@ public class GroupsRoutes implements Routes {
     private static final String USER_IN_GROUP_ADDRESS_PATH = GROUP_ADDRESS_PATH + SEPARATOR + ":" + USER_ADDRESS;
     private static final String MAILADDRESS_ASCII_DISCLAIMER = "Note that email addresses are restricted to ASCII character set. " +
         "Mail addresses not matching this criteria will be rejected.";
-    private static final String ADDRESS_TYPE = "group";
+    private static final String GROUP_ADDRESS_TYPE = "group";
+    private static final String USER_ADDRESS_TYPE = "group member";
 
     private final UsersRepository usersRepository;
     private final JsonTransformer jsonTransformer;
@@ -136,17 +137,17 @@ public class GroupsRoutes implements Routes {
     })
     @ApiResponses(value = {
         @ApiResponse(code = HttpStatus.NO_CONTENT_204, message = "OK", response = List.class),
-        @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = GROUP_ADDRESS + " or group structure format is not valid"),
+        @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = GROUP_ADDRESS + " or " + USER_ADDRESS + " format is not valid"),
         @ApiResponse(code = HttpStatus.BAD_REQUEST_400, message = "Domain in the source is not managed by the DomainList"),
         @ApiResponse(code = HttpStatus.CONFLICT_409, message = "requested group address is already used for another purpose"),
         @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
             message = "Internal server error - Something went bad on the server side.")
     })
     public HaltException addToGroup(Request request, Response response) throws RecipientRewriteTableException, UsersRepositoryException, DomainListException {
-        MailAddress groupAddress = MailAddressParser.parseMailAddress(request.params(GROUP_ADDRESS), ADDRESS_TYPE);
+        MailAddress groupAddress = MailAddressParser.parseMailAddress(request.params(GROUP_ADDRESS), GROUP_ADDRESS_TYPE);
         Domain domain = groupAddress.getDomain();
         ensureNotShadowingAnotherAddress(groupAddress);
-        MailAddress userAddress = MailAddressParser.parseMailAddress(request.params(USER_ADDRESS), ADDRESS_TYPE);
+        MailAddress userAddress = MailAddressParser.parseMailAddress(request.params(USER_ADDRESS), USER_ADDRESS_TYPE);
         MappingSource source = MappingSource.fromUser(User.fromLocalPartWithDomain(groupAddress.getLocalPart(), domain));
         addGroupMember(source, userAddress);
         return halt(HttpStatus.NO_CONTENT_204);
@@ -187,13 +188,13 @@ public class GroupsRoutes implements Routes {
     @ApiResponses(value = {
         @ApiResponse(code = HttpStatus.OK_200, message = "OK", response = List.class),
         @ApiResponse(code = HttpStatus.BAD_REQUEST_400,
-            message = GROUP_ADDRESS + " or group structure format is not valid"),
+            message = GROUP_ADDRESS + " or " + USER_ADDRESS + " format is not valid"),
         @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
             message = "Internal server error - Something went bad on the server side.")
     })
     public HaltException removeFromGroup(Request request, Response response) throws RecipientRewriteTableException {
-        MailAddress groupAddress = MailAddressParser.parseMailAddress(request.params(GROUP_ADDRESS), ADDRESS_TYPE);
-        MailAddress userAddress = MailAddressParser.parseMailAddress(request.params(USER_ADDRESS), ADDRESS_TYPE);
+        MailAddress groupAddress = MailAddressParser.parseMailAddress(request.params(GROUP_ADDRESS), GROUP_ADDRESS_TYPE);
+        MailAddress userAddress = MailAddressParser.parseMailAddress(request.params(USER_ADDRESS), USER_ADDRESS_TYPE);
         MappingSource source = MappingSource
             .fromUser(
                 User.fromLocalPartWithDomain(groupAddress.getLocalPart(), groupAddress.getDomain()));
@@ -215,7 +216,7 @@ public class GroupsRoutes implements Routes {
             message = "Internal server error - Something went bad on the server side.")
     })
     public ImmutableSortedSet<String> listGroupMembers(Request request, Response response) throws RecipientRewriteTableException {
-        MailAddress groupAddress = MailAddressParser.parseMailAddress(request.params(GROUP_ADDRESS), ADDRESS_TYPE);
+        MailAddress groupAddress = MailAddressParser.parseMailAddress(request.params(GROUP_ADDRESS), GROUP_ADDRESS_TYPE);
         Mappings mappings = recipientRewriteTable.getStoredMappings(MappingSource.fromMailAddress(groupAddress))
             .select(Mapping.Type.Group);
 
diff --git a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/GroupsRoutesTest.java b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/GroupsRoutesTest.java
index af8092a..77627fd 100644
--- a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/GroupsRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/GroupsRoutesTest.java
@@ -540,7 +540,7 @@ class GroupsRoutesTest {
             assertThat(errors)
                 .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400)
                 .containsEntry("type", "InvalidArgument")
-                .containsEntry("message", "The group is not an email address")
+                .containsEntry("message", "The group member is not an email address")
                 .containsEntry("details", "Out of data at position 1 in 'not-an-address'");
         }
 
@@ -587,7 +587,7 @@ class GroupsRoutesTest {
             assertThat(errors)
                 .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400)
                 .containsEntry("type", "InvalidArgument")
-                .containsEntry("message", "The group is not an email address")
+                .containsEntry("message", "The group member is not an email address")
                 .containsEntry("details", "Out of data at position 1 in 'not-an-address'");
         }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org