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 92750e2165cd5c51dd412da877da3b90d6d8c664 Author: Rémi KOWALSKI <[email protected]> AuthorDate: Wed Nov 6 15:06:25 2019 +0100 JAMES-2964 forbid to create quotas with negative number --- .../org/apache/james/core/quota/QuotaCount.java | 2 + .../org/apache/james/core/quota/QuotaSize.java | 2 + .../org/apache/james/core/quota/QuotaValue.java | 6 ++ .../org/apache/james/webadmin/dto/QuotaDTO.java | 21 ++--- .../apache/james/webadmin/dto/QuotaDetailsDTO.java | 36 ++++---- .../apache/james/webadmin/dto/QuotaDomainDTO.java | 26 +++--- .../dto/{QuotaDTO.java => ValidatedQuotaDTO.java} | 15 ++-- .../james/webadmin/routes/DomainQuotaRoutes.java | 44 ++++------ .../james/webadmin/routes/GlobalQuotaRoutes.java | 15 ++-- .../james/webadmin/routes/UserQuotaRoutes.java | 22 ++++- .../james/webadmin/service/DomainQuotaService.java | 10 +-- .../james/webadmin/service/GlobalQuotaService.java | 8 +- .../james/webadmin/service/UserQuotaService.java | 12 +-- .../webadmin/validation/QuotaDTOValidator.java | 70 ++++++++++++++++ .../webadmin/dto/QuotaValueDeserializerTest.java | 4 +- .../webadmin/routes/DomainQuotaRoutesTest.java | 73 ++++++++++++++++ .../webadmin/routes/GlobalQuotaRoutesTest.java | 80 ++++++++++++++++++ .../james/webadmin/routes/UserQuotaRoutesTest.java | 97 +++++++++++++++++++++- 18 files changed, 436 insertions(+), 107 deletions(-) diff --git a/core/src/main/java/org/apache/james/core/quota/QuotaCount.java b/core/src/main/java/org/apache/james/core/quota/QuotaCount.java index eef03fa..0eb6915 100644 --- a/core/src/main/java/org/apache/james/core/quota/QuotaCount.java +++ b/core/src/main/java/org/apache/james/core/quota/QuotaCount.java @@ -22,6 +22,7 @@ import java.util.Optional; import com.google.common.base.MoreObjects; import com.google.common.base.Objects; +import com.google.common.base.Preconditions; public class QuotaCount implements QuotaValue<QuotaCount> { @@ -40,6 +41,7 @@ public class QuotaCount implements QuotaValue<QuotaCount> { private final Optional<Long> value; private QuotaCount(Optional<Long> value) { + Preconditions.checkArgument(QuotaValue.isValidValue(value), "Quota limit should be positive"); this.value = value; } diff --git a/core/src/main/java/org/apache/james/core/quota/QuotaSize.java b/core/src/main/java/org/apache/james/core/quota/QuotaSize.java index 6d1f2ac..22d788f 100644 --- a/core/src/main/java/org/apache/james/core/quota/QuotaSize.java +++ b/core/src/main/java/org/apache/james/core/quota/QuotaSize.java @@ -22,6 +22,7 @@ import java.util.Optional; import com.google.common.base.MoreObjects; import com.google.common.base.Objects; +import com.google.common.base.Preconditions; public class QuotaSize implements QuotaValue<QuotaSize> { @@ -42,6 +43,7 @@ public class QuotaSize implements QuotaValue<QuotaSize> { private final Optional<Long> value; private QuotaSize(Optional<Long> value) { + Preconditions.checkArgument(QuotaValue.isValidValue(value), "Quota limit should be positive"); this.value = value; } diff --git a/core/src/main/java/org/apache/james/core/quota/QuotaValue.java b/core/src/main/java/org/apache/james/core/quota/QuotaValue.java index f4342d3..4f07eec 100644 --- a/core/src/main/java/org/apache/james/core/quota/QuotaValue.java +++ b/core/src/main/java/org/apache/james/core/quota/QuotaValue.java @@ -18,8 +18,14 @@ ****************************************************************/ package org.apache.james.core.quota; +import java.util.Optional; + public interface QuotaValue<T extends QuotaValue<T>> { + static boolean isValidValue(Optional<Long> value) { + return !value.isPresent() || value.get() >= 0; + } + long asLong(); boolean isLimited(); diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDTO.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDTO.java index 9a02cc6..f7a1ba7 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDTO.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDTO.java @@ -23,9 +23,6 @@ package org.apache.james.webadmin.dto; import java.util.Objects; import java.util.Optional; -import org.apache.james.core.quota.QuotaCount; -import org.apache.james.core.quota.QuotaSize; - import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import com.google.common.base.MoreObjects; @@ -39,20 +36,20 @@ public class QuotaDTO { @JsonPOJOBuilder(withPrefix = "") public static class Builder { - private Optional<QuotaCount> count; - private Optional<QuotaSize> size; + private Optional<Long> count; + private Optional<Long> size; private Builder() { count = Optional.empty(); size = Optional.empty(); } - public Builder count(Optional<QuotaCount> count) { + public Builder count(Optional<Long> count) { this.count = count; return this; } - public Builder size(Optional<QuotaSize> size) { + public Builder size(Optional<Long> size) { this.size = size; return this; } @@ -62,19 +59,19 @@ public class QuotaDTO { } } - private final Optional<QuotaCount> count; - private final Optional<QuotaSize> size; + private final Optional<Long> count; + private final Optional<Long> size; - private QuotaDTO(Optional<QuotaCount> count, Optional<QuotaSize> size) { + private QuotaDTO(Optional<Long> count, Optional<Long> size) { this.count = count; this.size = size; } - public Optional<QuotaCount> getCount() { + public Optional<Long> getCount() { return count; } - public Optional<QuotaSize> getSize() { + public Optional<Long> getSize() { return size; } diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDetailsDTO.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDetailsDTO.java index 9042122..7449c90 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDetailsDTO.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDetailsDTO.java @@ -35,10 +35,10 @@ public class QuotaDetailsDTO { } public static class Builder { - private Optional<QuotaDTO> global; - private Optional<QuotaDTO> domain; - private Optional<QuotaDTO> user; - private Optional<QuotaDTO> computed; + private Optional<ValidatedQuotaDTO> global; + private Optional<ValidatedQuotaDTO> domain; + private Optional<ValidatedQuotaDTO> user; + private Optional<ValidatedQuotaDTO> computed; private OccupationDTO occupation; private Builder() { @@ -47,22 +47,22 @@ public class QuotaDetailsDTO { computed = Optional.empty(); } - public Builder global(QuotaDTO global) { + public Builder global(ValidatedQuotaDTO global) { this.global = Optional.of(global); return this; } - public Builder domain(QuotaDTO domain) { + public Builder domain(ValidatedQuotaDTO domain) { this.domain = Optional.of(domain); return this; } - public Builder user(QuotaDTO user) { + public Builder user(ValidatedQuotaDTO user) { this.user = Optional.of(user); return this; } - public Builder computed(QuotaDTO computed) { + public Builder computed(ValidatedQuotaDTO computed) { this.computed = Optional.of(computed); return this; } @@ -72,7 +72,7 @@ public class QuotaDetailsDTO { return this; } - public Builder valueForScope(Quota.Scope scope, QuotaDTO value) { + public Builder valueForScope(Quota.Scope scope, ValidatedQuotaDTO value) { switch (scope) { case Global: return global(value); @@ -90,13 +90,13 @@ public class QuotaDetailsDTO { } } - private final Optional<QuotaDTO> global; - private final Optional<QuotaDTO> domain; - private final Optional<QuotaDTO> user; - private final Optional<QuotaDTO> computed; + private final Optional<ValidatedQuotaDTO> global; + private final Optional<ValidatedQuotaDTO> domain; + private final Optional<ValidatedQuotaDTO> user; + private final Optional<ValidatedQuotaDTO> computed; private final OccupationDTO occupation; - private QuotaDetailsDTO(Optional<QuotaDTO> global, Optional<QuotaDTO> domain, Optional<QuotaDTO> user, Optional<QuotaDTO> computed, OccupationDTO occupation) { + private QuotaDetailsDTO(Optional<ValidatedQuotaDTO> global, Optional<ValidatedQuotaDTO> domain, Optional<ValidatedQuotaDTO> user, Optional<ValidatedQuotaDTO> computed, OccupationDTO occupation) { this.global = global; this.domain = domain; this.user = user; @@ -104,19 +104,19 @@ public class QuotaDetailsDTO { this.occupation = occupation; } - public Optional<QuotaDTO> getGlobal() { + public Optional<ValidatedQuotaDTO> getGlobal() { return global; } - public Optional<QuotaDTO> getDomain() { + public Optional<ValidatedQuotaDTO> getDomain() { return domain; } - public Optional<QuotaDTO> getUser() { + public Optional<ValidatedQuotaDTO> getUser() { return user; } - public Optional<QuotaDTO> getComputed() { + public Optional<ValidatedQuotaDTO> getComputed() { return computed; } diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDomainDTO.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDomainDTO.java index 527491f..4113418 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDomainDTO.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDomainDTO.java @@ -29,26 +29,26 @@ public class QuotaDomainDTO { } public static class Builder { - private Optional<QuotaDTO> global; - private Optional<QuotaDTO> domain; - private Optional<QuotaDTO> computed; + private Optional<ValidatedQuotaDTO> global; + private Optional<ValidatedQuotaDTO> domain; + private Optional<ValidatedQuotaDTO> computed; private Builder() { global = Optional.empty(); computed = Optional.empty(); } - public Builder global(QuotaDTO.Builder global) { + public Builder global(ValidatedQuotaDTO.Builder global) { this.global = Optional.of(global.build()); return this; } - public Builder domain(QuotaDTO.Builder domain) { + public Builder domain(ValidatedQuotaDTO.Builder domain) { this.domain = Optional.of(domain.build()); return this; } - public Builder computed(QuotaDTO.Builder computed) { + public Builder computed(ValidatedQuotaDTO.Builder computed) { this.computed = Optional.of(computed.build()); return this; } @@ -58,25 +58,25 @@ public class QuotaDomainDTO { } } - private final Optional<QuotaDTO> global; - private final Optional<QuotaDTO> domain; - private final Optional<QuotaDTO> computed; + private final Optional<ValidatedQuotaDTO> global; + private final Optional<ValidatedQuotaDTO> domain; + private final Optional<ValidatedQuotaDTO> computed; - private QuotaDomainDTO(Optional<QuotaDTO> global, Optional<QuotaDTO> domain, Optional<QuotaDTO> computed) { + private QuotaDomainDTO(Optional<ValidatedQuotaDTO> global, Optional<ValidatedQuotaDTO> domain, Optional<ValidatedQuotaDTO> computed) { this.global = global; this.domain = domain; this.computed = computed; } - public Optional<QuotaDTO> getGlobal() { + public Optional<ValidatedQuotaDTO> getGlobal() { return global; } - public Optional<QuotaDTO> getDomain() { + public Optional<ValidatedQuotaDTO> getDomain() { return domain; } - public Optional<QuotaDTO> getComputed() { + public Optional<ValidatedQuotaDTO> getComputed() { return computed; } } diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDTO.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/ValidatedQuotaDTO.java similarity index 88% copy from server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDTO.java copy to server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/ValidatedQuotaDTO.java index 9a02cc6..6023096 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDTO.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/ValidatedQuotaDTO.java @@ -30,8 +30,8 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import com.google.common.base.MoreObjects; -@JsonDeserialize(builder = QuotaDTO.Builder.class) -public class QuotaDTO { +@JsonDeserialize(builder = ValidatedQuotaDTO.Builder.class) +public class ValidatedQuotaDTO { public static Builder builder() { return new Builder(); @@ -57,15 +57,16 @@ public class QuotaDTO { return this; } - public QuotaDTO build() { - return new QuotaDTO(count, size); + public ValidatedQuotaDTO build() { + return new ValidatedQuotaDTO(count, size); } } + private final Optional<QuotaCount> count; private final Optional<QuotaSize> size; - private QuotaDTO(Optional<QuotaCount> count, Optional<QuotaSize> size) { + private ValidatedQuotaDTO(Optional<QuotaCount> count, Optional<QuotaSize> size) { this.count = count; this.size = size; } @@ -80,8 +81,8 @@ public class QuotaDTO { @Override public boolean equals(Object o) { - if (o instanceof QuotaDTO) { - QuotaDTO that = (QuotaDTO) o; + if (o instanceof ValidatedQuotaDTO) { + ValidatedQuotaDTO that = (ValidatedQuotaDTO) o; return Objects.equals(this.count, that.count) && Objects.equals(this.size, that.size); diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/DomainQuotaRoutes.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/DomainQuotaRoutes.java index 115bb83..c080910 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/DomainQuotaRoutes.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/DomainQuotaRoutes.java @@ -40,14 +40,15 @@ import org.apache.james.user.api.UsersRepositoryException; import org.apache.james.webadmin.Routes; import org.apache.james.webadmin.dto.QuotaDTO; import org.apache.james.webadmin.dto.QuotaDomainDTO; +import org.apache.james.webadmin.dto.ValidatedQuotaDTO; import org.apache.james.webadmin.service.DomainQuotaService; import org.apache.james.webadmin.utils.ErrorResponder; import org.apache.james.webadmin.utils.ErrorResponder.ErrorType; -import org.apache.james.webadmin.utils.JsonExtractException; import org.apache.james.webadmin.utils.JsonExtractor; import org.apache.james.webadmin.utils.JsonTransformer; import org.apache.james.webadmin.utils.JsonTransformerModule; import org.apache.james.webadmin.utils.Responses; +import org.apache.james.webadmin.validation.QuotaDTOValidator; import org.apache.james.webadmin.validation.Quotas; import org.eclipse.jetty.http.HttpStatus; @@ -76,6 +77,7 @@ public class DomainQuotaRoutes implements Routes { private final UsersRepository usersRepository; private final JsonTransformer jsonTransformer; private final JsonExtractor<QuotaDTO> jsonExtractor; + private final QuotaDTOValidator quotaDTOValidator; private Service service; @Inject @@ -85,6 +87,7 @@ public class DomainQuotaRoutes implements Routes { this.usersRepository = usersRepository; this.jsonTransformer = jsonTransformer; this.jsonExtractor = new JsonExtractor<>(QuotaDTO.class, modules.stream().map(JsonTransformerModule::asJacksonModule).collect(Collectors.toList())); + this.quotaDTOValidator = new QuotaDTOValidator(); } @Override @@ -130,10 +133,20 @@ public class DomainQuotaRoutes implements Routes { }) public void defineUpdateQuota() { service.put(QUOTA_ENDPOINT, ((request, response) -> { - Domain domain = checkDomainExist(request); - QuotaDTO quotaDTO = parseQuotaDTO(request); - domainQuotaService.defineQuota(domain, quotaDTO); - return Responses.returnNoContent(response); + try { + Domain domain = checkDomainExist(request); + QuotaDTO quotaDTO = jsonExtractor.parse(request.body()); + ValidatedQuotaDTO validatedQuotaDTO = quotaDTOValidator.validatedQuotaDTO(quotaDTO); + domainQuotaService.defineQuota(domain, validatedQuotaDTO); + return Responses.returnNoContent(response); + } catch (IllegalArgumentException e) { + throw ErrorResponder.builder() + .statusCode(HttpStatus.BAD_REQUEST_400) + .type(ErrorType.INVALID_ARGUMENT) + .message("Quota should be positive or unlimited (-1)") + .cause(e) + .haltError(); + } })); } @@ -307,25 +320,4 @@ public class DomainQuotaRoutes implements Routes { .haltError(); } } - - private QuotaDTO parseQuotaDTO(Request request) { - try { - return jsonExtractor.parse(request.body()); - } catch (IllegalArgumentException e) { - throw ErrorResponder.builder() - .statusCode(HttpStatus.BAD_REQUEST_400) - .type(ErrorType.INVALID_ARGUMENT) - .message("Quota should be positive or unlimited (-1)") - .cause(e) - .haltError(); - } catch (JsonExtractException e) { - throw ErrorResponder.builder() - .statusCode(HttpStatus.BAD_REQUEST_400) - .type(ErrorType.INVALID_ARGUMENT) - .message("Malformed JSON input") - .cause(e) - .haltError(); - } - } - } diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/GlobalQuotaRoutes.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/GlobalQuotaRoutes.java index a1c4cb6..a4c255f 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/GlobalQuotaRoutes.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/GlobalQuotaRoutes.java @@ -33,14 +33,15 @@ import org.apache.james.core.quota.QuotaSize; import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.webadmin.Routes; import org.apache.james.webadmin.dto.QuotaDTO; +import org.apache.james.webadmin.dto.ValidatedQuotaDTO; import org.apache.james.webadmin.jackson.QuotaModule; import org.apache.james.webadmin.service.GlobalQuotaService; import org.apache.james.webadmin.utils.ErrorResponder; import org.apache.james.webadmin.utils.ErrorResponder.ErrorType; -import org.apache.james.webadmin.utils.JsonExtractException; import org.apache.james.webadmin.utils.JsonExtractor; import org.apache.james.webadmin.utils.JsonTransformer; import org.apache.james.webadmin.utils.Responses; +import org.apache.james.webadmin.validation.QuotaDTOValidator; import org.apache.james.webadmin.validation.Quotas; import org.eclipse.jetty.http.HttpStatus; @@ -65,6 +66,7 @@ public class GlobalQuotaRoutes implements Routes { private final JsonTransformer jsonTransformer; private final JsonExtractor<QuotaDTO> jsonExtractor; + private final QuotaDTOValidator quotaDTOValidator; private final GlobalQuotaService globalQuotaService; private Service service; @@ -73,6 +75,7 @@ public class GlobalQuotaRoutes implements Routes { this.globalQuotaService = globalQuotaService; this.jsonTransformer = jsonTransformer; this.jsonExtractor = new JsonExtractor<>(QuotaDTO.class, new QuotaModule().asJacksonModule()); + quotaDTOValidator = new QuotaDTOValidator(); } @Override @@ -115,15 +118,9 @@ public class GlobalQuotaRoutes implements Routes { service.put(QUOTA_ENDPOINT, ((request, response) -> { try { QuotaDTO quotaDTO = jsonExtractor.parse(request.body()); - globalQuotaService.defineQuota(quotaDTO); + ValidatedQuotaDTO validatedQuotaDTO = quotaDTOValidator.validatedQuotaDTO(quotaDTO); + globalQuotaService.defineQuota(validatedQuotaDTO); return Responses.returnNoContent(response); - } catch (JsonExtractException e) { - throw ErrorResponder.builder() - .statusCode(HttpStatus.BAD_REQUEST_400) - .type(ErrorType.INVALID_ARGUMENT) - .message("Malformed JSON input") - .cause(e) - .haltError(); } catch (IllegalArgumentException e) { throw ErrorResponder.builder() .statusCode(HttpStatus.BAD_REQUEST_400) diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserQuotaRoutes.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserQuotaRoutes.java index e06818c..4fbf4cc 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserQuotaRoutes.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserQuotaRoutes.java @@ -46,6 +46,7 @@ import org.apache.james.user.api.UsersRepositoryException; import org.apache.james.webadmin.Routes; import org.apache.james.webadmin.dto.QuotaDTO; import org.apache.james.webadmin.dto.QuotaDetailsDTO; +import org.apache.james.webadmin.dto.ValidatedQuotaDTO; import org.apache.james.webadmin.service.UserQuotaService; import org.apache.james.webadmin.utils.ErrorResponder; import org.apache.james.webadmin.utils.ErrorResponder.ErrorType; @@ -55,6 +56,7 @@ import org.apache.james.webadmin.utils.JsonTransformer; import org.apache.james.webadmin.utils.JsonTransformerModule; import org.apache.james.webadmin.utils.ParametersExtractor; import org.apache.james.webadmin.utils.Responses; +import org.apache.james.webadmin.validation.QuotaDTOValidator; import org.apache.james.webadmin.validation.Quotas; import org.eclipse.jetty.http.HttpStatus; @@ -85,6 +87,7 @@ public class UserQuotaRoutes implements Routes { private final UserQuotaService userQuotaService; private final JsonTransformer jsonTransformer; private final JsonExtractor<QuotaDTO> jsonExtractor; + private final QuotaDTOValidator quotaDTOValidator; private Service service; @Inject @@ -93,6 +96,7 @@ public class UserQuotaRoutes implements Routes { this.userQuotaService = userQuotaService; this.jsonTransformer = jsonTransformer; this.jsonExtractor = new JsonExtractor<>(QuotaDTO.class, modules.stream().map(JsonTransformerModule::asJacksonModule).collect(Collectors.toList())); + this.quotaDTOValidator = new QuotaDTOValidator(); } @Override @@ -131,10 +135,20 @@ public class UserQuotaRoutes implements Routes { }) public void defineUpdateQuota() { service.put(QUOTA_ENDPOINT, ((request, response) -> { - Username username = checkUserExist(request); - QuotaDTO quotaDTO = parseQuotaDTO(request); - userQuotaService.defineQuota(username, quotaDTO); - return Responses.returnNoContent(response); + try { + Username username = checkUserExist(request); + QuotaDTO quotaDTO = jsonExtractor.parse(request.body()); + ValidatedQuotaDTO validatedQuotaDTO = quotaDTOValidator.validatedQuotaDTO(quotaDTO); + userQuotaService.defineQuota(username, validatedQuotaDTO); + return Responses.returnNoContent(response); + } catch (IllegalArgumentException e) { + throw ErrorResponder.builder() + .statusCode(HttpStatus.BAD_REQUEST_400) + .type(ErrorType.INVALID_ARGUMENT) + .message("Quota should be positive or unlimited (-1)") + .cause(e) + .haltError(); + } })); } 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 0c30c19..e9b7491 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 @@ -28,8 +28,8 @@ import org.apache.james.core.quota.QuotaCount; import org.apache.james.core.quota.QuotaSize; import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.quota.MaxQuotaManager; -import org.apache.james.webadmin.dto.QuotaDTO; import org.apache.james.webadmin.dto.QuotaDomainDTO; +import org.apache.james.webadmin.dto.ValidatedQuotaDTO; public class DomainQuotaService { @@ -66,22 +66,22 @@ public class DomainQuotaService { public QuotaDomainDTO getQuota(Domain domain) throws MailboxException { return QuotaDomainDTO.builder() - .domain(QuotaDTO + .domain(ValidatedQuotaDTO .builder() .count(maxQuotaManager.getDomainMaxMessage(domain)) .size(maxQuotaManager.getDomainMaxStorage(domain))) - .global(QuotaDTO + .global(ValidatedQuotaDTO .builder() .count(maxQuotaManager.getGlobalMaxMessage()) .size(maxQuotaManager.getGlobalMaxStorage())) - .computed(QuotaDTO + .computed(ValidatedQuotaDTO .builder() .count(maxQuotaManager.getComputedMaxMessage(domain)) .size(maxQuotaManager.getComputedMaxStorage(domain))) .build(); } - public void defineQuota(Domain domain, QuotaDTO quota) { + public void defineQuota(Domain domain, ValidatedQuotaDTO quota) { try { if (quota.getCount().isPresent()) { maxQuotaManager.setDomainMaxMessage(domain, quota.getCount().get()); diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/GlobalQuotaService.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/GlobalQuotaService.java index 83e7a32..abd3aed 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/GlobalQuotaService.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/GlobalQuotaService.java @@ -26,7 +26,7 @@ import org.apache.james.core.quota.QuotaCount; import org.apache.james.core.quota.QuotaSize; import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.quota.MaxQuotaManager; -import org.apache.james.webadmin.dto.QuotaDTO; +import org.apache.james.webadmin.dto.ValidatedQuotaDTO; public class GlobalQuotaService { @@ -37,7 +37,7 @@ public class GlobalQuotaService { this.maxQuotaManager = maxQuotaManager; } - public void defineQuota(QuotaDTO quota) throws MailboxException { + public void defineQuota(ValidatedQuotaDTO quota) throws MailboxException { Optional<QuotaCount> count = quota.getCount(); if (count.isPresent()) { maxQuotaManager.setGlobalMaxMessage(count.get()); @@ -53,8 +53,8 @@ public class GlobalQuotaService { } } - public QuotaDTO getQuota() throws MailboxException { - return QuotaDTO + public ValidatedQuotaDTO getQuota() throws MailboxException { + return ValidatedQuotaDTO .builder() .count(maxQuotaManager.getGlobalMaxMessage()) .size(maxQuotaManager.getGlobalMaxStorage()) 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 0edddc8..1aaf012 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 @@ -37,9 +37,9 @@ import org.apache.james.mailbox.quota.QuotaManager; import org.apache.james.mailbox.quota.UserQuotaRootResolver; import org.apache.james.quota.search.QuotaQuery; import org.apache.james.quota.search.QuotaSearcher; -import org.apache.james.webadmin.dto.QuotaDTO; import org.apache.james.webadmin.dto.QuotaDetailsDTO; import org.apache.james.webadmin.dto.UsersQuotaDetailsDTO; +import org.apache.james.webadmin.dto.ValidatedQuotaDTO; import com.github.fge.lambdas.Throwing; import com.github.steveash.guavate.Guavate; @@ -60,7 +60,7 @@ public class UserQuotaService { this.quotaSearcher = quotaSearcher; } - public void defineQuota(Username username, QuotaDTO quota) { + public void defineQuota(Username username, ValidatedQuotaDTO quota) { try { QuotaRoot quotaRoot = userQuotaRootResolver.forUser(username); if (quota.getCount().isPresent()) { @@ -94,19 +94,19 @@ public class UserQuotaService { return quotaDetails.build(); } - private QuotaDTO computedQuota(QuotaRoot quotaRoot) throws MailboxException { - return QuotaDTO + private ValidatedQuotaDTO computedQuota(QuotaRoot quotaRoot) throws MailboxException { + return ValidatedQuotaDTO .builder() .count(maxQuotaManager.getMaxMessage(quotaRoot)) .size(maxQuotaManager.getMaxStorage(quotaRoot)) .build(); } - private Map<Quota.Scope, QuotaDTO> mergeMaps(Map<Quota.Scope, QuotaCount> counts, Map<Quota.Scope, QuotaSize> sizes) { + private Map<Quota.Scope, ValidatedQuotaDTO> mergeMaps(Map<Quota.Scope, QuotaCount> counts, Map<Quota.Scope, QuotaSize> sizes) { return Sets.union(counts.keySet(), sizes.keySet()) .stream() .collect(Collectors.toMap(Function.identity(), - scope -> QuotaDTO + scope -> ValidatedQuotaDTO .builder() .count(Optional.ofNullable(counts.get(scope))) .size(Optional.ofNullable(sizes.get(scope))) diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/validation/QuotaDTOValidator.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/validation/QuotaDTOValidator.java new file mode 100644 index 0000000..63de521 --- /dev/null +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/validation/QuotaDTOValidator.java @@ -0,0 +1,70 @@ +/**************************************************************** + * 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.validation; + +import java.util.Optional; + +import org.apache.james.core.quota.QuotaCount; +import org.apache.james.core.quota.QuotaSize; +import org.apache.james.webadmin.dto.QuotaDTO; +import org.apache.james.webadmin.dto.ValidatedQuotaDTO; +import org.apache.james.webadmin.utils.ErrorResponder; +import org.eclipse.jetty.http.HttpStatus; + +public class QuotaDTOValidator { + + private static final int UNLIMITED = -1; + + public ValidatedQuotaDTO validatedQuotaDTO(QuotaDTO quotaDTO) { + try { + Optional<QuotaCount> count = quotaDTO.getCount() + .map(this::getQuotaCount); + Optional<QuotaSize> size = quotaDTO.getSize() + .map(this::getQuotaSize); + + return ValidatedQuotaDTO.builder() + .count(count) + .size(size) + .build(); + } catch (IllegalArgumentException e) { + throw ErrorResponder.builder() + .statusCode(HttpStatus.BAD_REQUEST_400) + .type(ErrorResponder.ErrorType.INVALID_ARGUMENT) + .message("Invalid quota. Need to be an integer value greater or equal to -1") + .cause(e) + .haltError(); + } + } + + private QuotaSize getQuotaSize(Long quotaValue) { + if (quotaValue == UNLIMITED) { + return QuotaSize.unlimited(); + } else { + return QuotaSize.size(quotaValue); + } + } + + private QuotaCount getQuotaCount(Long quotaValue) { + if (quotaValue == UNLIMITED) { + return QuotaCount.unlimited(); + } else { + return QuotaCount.count(quotaValue); + } + } +} diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/dto/QuotaValueDeserializerTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/dto/QuotaValueDeserializerTest.java index 8cb7f28..fd0d679 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/dto/QuotaValueDeserializerTest.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/dto/QuotaValueDeserializerTest.java @@ -32,14 +32,14 @@ class QuotaValueDeserializerTest { @Test void objectDeserializeShouldContainGivenValues() throws JsonExtractException { String payload = "{\"count\":52,\"size\":42}"; - QuotaDTO actual = new JsonExtractor<>(QuotaDTO.class, + ValidatedQuotaDTO actual = new JsonExtractor<>(ValidatedQuotaDTO.class, new SimpleModule() .addDeserializer(QuotaCount.class, new QuotaValueDeserializer<>(QuotaCount.unlimited(), QuotaCount::count)) .addDeserializer(QuotaSize.class, new QuotaValueDeserializer<>(QuotaSize.unlimited(), QuotaSize::size)) ).parse(payload); Assertions.assertThat(actual) .isEqualTo( - QuotaDTO + ValidatedQuotaDTO .builder() .count(java.util.Optional.of(QuotaCount.count(52))) .size(java.util.Optional.of(QuotaSize.size(42))) 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 17c1770..df823e3 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 @@ -29,6 +29,7 @@ import java.util.Map; import org.apache.james.core.Domain; import org.apache.james.core.quota.QuotaCount; import org.apache.james.core.quota.QuotaSize; +import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.quota.MaxQuotaManager; import org.eclipse.jetty.http.HttpStatus; import org.junit.jupiter.api.BeforeEach; @@ -448,6 +449,78 @@ class DomainQuotaRoutesTest { } @Test + void putQuotaWithNegativeCountShouldFail() throws MailboxException { + maxQuotaManager.setDomainMaxMessage(TROUVÉ_COM, QuotaCount.count(52)); + maxQuotaManager.setDomainMaxStorage(TROUVÉ_COM, QuotaSize.size(42)); + Map<String, Object> errors = given() + .body("{\"count\":-5,\"size\":30}") + .put(QUOTA_DOMAINS + "/" + TROUVÉ_COM.name()) + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .contentType(ContentType.JSON) + .extract() + .body() + .jsonPath() + .getMap("."); + + assertThat(errors) + .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) + .containsEntry("type", "InvalidArgument") + .containsEntry("message", "Invalid quota. Need to be an integer value greater or equal to -1"); + } + + @Test + void putQuotaWithNegativeCountShouldNotUpdatePreviousQuota() throws MailboxException { + maxQuotaManager.setDomainMaxMessage(TROUVÉ_COM, QuotaCount.count(52)); + maxQuotaManager.setDomainMaxStorage(TROUVÉ_COM, QuotaSize.size(42)); + given() + .body("{\"count\":-5,\"size\":30}") + .put(QUOTA_DOMAINS + "/" + TROUVÉ_COM.name()) + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .contentType(ContentType.JSON); + + assertThat(maxQuotaManager.getDomainMaxMessage(TROUVÉ_COM)).contains(QuotaCount.count(52)); + assertThat(maxQuotaManager.getDomainMaxStorage(TROUVÉ_COM)).contains(QuotaSize.size(42)); + } + + @Test + void putQuotaWithNegativeSizeShouldFail() throws MailboxException { + maxQuotaManager.setDomainMaxMessage(TROUVÉ_COM, QuotaCount.count(52)); + maxQuotaManager.setDomainMaxStorage(TROUVÉ_COM, QuotaSize.size(42)); + Map<String, Object> errors = given() + .body("{\"count\":40,\"size\":-19}") + .put(QUOTA_DOMAINS + "/" + TROUVÉ_COM.name()) + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .contentType(ContentType.JSON) + .extract() + .body() + .jsonPath() + .getMap("."); + + assertThat(errors) + .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) + .containsEntry("type", "InvalidArgument") + .containsEntry("message", "Invalid quota. Need to be an integer value greater or equal to -1"); + } + + @Test + void putQuotaWithNegativeSizeShouldNotUpdatePreviousQuota() throws MailboxException { + maxQuotaManager.setDomainMaxMessage(TROUVÉ_COM, QuotaCount.count(52)); + maxQuotaManager.setDomainMaxStorage(TROUVÉ_COM, QuotaSize.size(42)); + given() + .body("{\"count\":40,\"size\":-19}") + .put(QUOTA_DOMAINS + "/" + TROUVÉ_COM.name()) + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .contentType(ContentType.JSON); + + assertThat(maxQuotaManager.getDomainMaxMessage(TROUVÉ_COM)).contains(QuotaCount.count(52)); + assertThat(maxQuotaManager.getDomainMaxStorage(TROUVÉ_COM)).contains(QuotaSize.size(42)); + } + + @Test void putQuotaShouldBeAbleToRemoveBothQuota() { given() .body("{\"count\":52,\"size\":42}") diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/GlobalQuotaRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/GlobalQuotaRoutesTest.java index 48032b0..2132646 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/GlobalQuotaRoutesTest.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/GlobalQuotaRoutesTest.java @@ -371,6 +371,86 @@ class GlobalQuotaRoutesTest { } @Test + void putQuotaWithNegativeCountShouldFail() throws Exception { + maxQuotaManager.setGlobalMaxMessage(QuotaCount.count(42)); + maxQuotaManager.setGlobalMaxStorage(QuotaSize.size(43)); + + Map<String, Object> errors = given() + .body("{\"count\":-2,\"size\":43}") + .when() + .put("/quota") + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .contentType(ContentType.JSON) + .extract() + .body() + .jsonPath() + .getMap("."); + + assertThat(errors) + .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) + .containsEntry("type", "InvalidArgument") + .containsEntry("message", "Invalid quota. Need to be an integer value greater or equal to -1"); + } + + @Test + void putQuotaWithNegativeCountShouldNotUpdatePreviousQuota() throws Exception { + maxQuotaManager.setGlobalMaxMessage(QuotaCount.count(42)); + maxQuotaManager.setGlobalMaxStorage(QuotaSize.size(43)); + + given() + .body("{\"count\":-2,\"size\":43}") + .when() + .put("/quota") + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .contentType(ContentType.JSON); + + assertThat(maxQuotaManager.getGlobalMaxMessage()).contains(QuotaCount.count(42)); + assertThat(maxQuotaManager.getGlobalMaxStorage()).contains(QuotaSize.size(43)); + } + + @Test + void putQuotaWithNegativeSizeShouldFail() throws Exception { + maxQuotaManager.setGlobalMaxMessage(QuotaCount.count(42)); + maxQuotaManager.setGlobalMaxStorage(QuotaSize.size(43)); + + Map<String, Object> errors = given() + .body("{\"count\":42,\"size\":-2}") + .when() + .put("/quota") + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .contentType(ContentType.JSON) + .extract() + .body() + .jsonPath() + .getMap("."); + + assertThat(errors) + .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) + .containsEntry("type", "InvalidArgument") + .containsEntry("message", "Invalid quota. Need to be an integer value greater or equal to -1"); + } + + @Test + void putQuotaWithNegativeSizeShouldNotUpdatePreviousQuota() throws Exception { + maxQuotaManager.setGlobalMaxMessage(QuotaCount.count(42)); + maxQuotaManager.setGlobalMaxStorage(QuotaSize.size(43)); + + given() + .body("{\"count\":42,\"size\":-2}") + .when() + .put("/quota") + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .contentType(ContentType.JSON); + + assertThat(maxQuotaManager.getGlobalMaxMessage()).contains(QuotaCount.count(42)); + assertThat(maxQuotaManager.getGlobalMaxStorage()).contains(QuotaSize.size(43)); + } + + @Test void putQuotaShouldUnsetCountWhenNull() throws Exception { maxQuotaManager.setGlobalMaxMessage(QuotaCount.count(42)); given() 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 1cfe929..8841e27 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 @@ -57,7 +57,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import com.google.common.base.Strings; - import io.restassured.RestAssured; import io.restassured.http.ContentType; import io.restassured.path.json.JsonPath; @@ -1055,6 +1054,102 @@ class UserQuotaRoutesTest { } @Test + void putQuotaWithNegativeCountShouldFail(WebAdminQuotaSearchTestSystem testSystem) throws Exception { + MaxQuotaManager maxQuotaManager = testSystem.getQuotaSearchTestSystem().getMaxQuotaManager(); + UserQuotaRootResolver userQuotaRootResolver = testSystem.getQuotaSearchTestSystem().getQuotaRootResolver(); + + maxQuotaManager.setMaxMessage(userQuotaRootResolver.forUser(BOB), QuotaCount.count(52)); + maxQuotaManager.setMaxStorage(userQuotaRootResolver.forUser(BOB), QuotaSize.size(42)); + + Map<String, Object> errors = with() + .body("{\"count\":-2,\"size\":42}") + .put(QUOTA_USERS + "/" + BOB.asString()) + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .contentType(ContentType.JSON) + .extract() + .body() + .jsonPath() + .getMap("."); + + assertThat(errors) + .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) + .containsEntry("type", "InvalidArgument") + .containsEntry("message", "Invalid quota. Need to be an integer value greater or equal to -1"); + } + + @Test + void putQuotaWithNegativeCountShouldNotUpdatePreviousQuota(WebAdminQuotaSearchTestSystem testSystem) throws Exception { + MaxQuotaManager maxQuotaManager = testSystem.getQuotaSearchTestSystem().getMaxQuotaManager(); + UserQuotaRootResolver userQuotaRootResolver = testSystem.getQuotaSearchTestSystem().getQuotaRootResolver(); + + maxQuotaManager.setMaxMessage(userQuotaRootResolver.forUser(BOB), QuotaCount.count(52)); + maxQuotaManager.setMaxStorage(userQuotaRootResolver.forUser(BOB), QuotaSize.size(42)); + + with() + .body("{\"count\":-2,\"size\":42}") + .put(QUOTA_USERS + "/" + BOB.asString()) + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .contentType(ContentType.JSON); + + SoftAssertions softly = new SoftAssertions(); + softly.assertThat(maxQuotaManager.getMaxMessage(userQuotaRootResolver.forUser(BOB))) + .contains(QuotaCount.count(52)); + softly.assertThat(maxQuotaManager.getMaxStorage(userQuotaRootResolver.forUser(BOB))) + .contains(QuotaSize.size(42)); + softly.assertAll(); + } + + @Test + void putQuotaWithNegativeSizeShouldFail(WebAdminQuotaSearchTestSystem testSystem) throws Exception { + MaxQuotaManager maxQuotaManager = testSystem.getQuotaSearchTestSystem().getMaxQuotaManager(); + UserQuotaRootResolver userQuotaRootResolver = testSystem.getQuotaSearchTestSystem().getQuotaRootResolver(); + + maxQuotaManager.setMaxMessage(userQuotaRootResolver.forUser(BOB), QuotaCount.count(52)); + maxQuotaManager.setMaxStorage(userQuotaRootResolver.forUser(BOB), QuotaSize.size(42)); + + Map<String, Object> errors = with() + .body("{\"count\":52,\"size\":-3}") + .put(QUOTA_USERS + "/" + BOB.asString()) + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .contentType(ContentType.JSON) + .extract() + .body() + .jsonPath() + .getMap("."); + + assertThat(errors) + .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) + .containsEntry("type", "InvalidArgument") + .containsEntry("message", "Invalid quota. Need to be an integer value greater or equal to -1"); + } + + @Test + void putQuotaWithNegativeSizeShouldNotUpdatePreviousQuota(WebAdminQuotaSearchTestSystem testSystem) throws Exception { + MaxQuotaManager maxQuotaManager = testSystem.getQuotaSearchTestSystem().getMaxQuotaManager(); + UserQuotaRootResolver userQuotaRootResolver = testSystem.getQuotaSearchTestSystem().getQuotaRootResolver(); + + maxQuotaManager.setMaxMessage(userQuotaRootResolver.forUser(BOB), QuotaCount.count(52)); + maxQuotaManager.setMaxStorage(userQuotaRootResolver.forUser(BOB), QuotaSize.size(42)); + + with() + .body("{\"count\":52,\"size\":-3}") + .put(QUOTA_USERS + "/" + BOB.asString()) + .then() + .statusCode(HttpStatus.BAD_REQUEST_400) + .contentType(ContentType.JSON); + + SoftAssertions softly = new SoftAssertions(); + softly.assertThat(maxQuotaManager.getMaxMessage(userQuotaRootResolver.forUser(BOB))) + .contains(QuotaCount.count(52)); + softly.assertThat(maxQuotaManager.getMaxStorage(userQuotaRootResolver.forUser(BOB))) + .contains(QuotaSize.size(42)); + softly.assertAll(); + } + + @Test void putQuotaShouldUpdateBothQuota(WebAdminQuotaSearchTestSystem testSystem) throws Exception { MaxQuotaManager maxQuotaManager = testSystem.getQuotaSearchTestSystem().getMaxQuotaManager(); UserQuotaRootResolver userQuotaRootResolver = testSystem.getQuotaSearchTestSystem().getQuotaRootResolver(); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
