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 35c669e3e5120e3c3334e7a6ebfb72b4146f75aa Author: Benoit Tellier <btell...@linagora.com> AuthorDate: Mon Jun 1 13:17:03 2020 +0700 JAMES-3182 Explicitly reject nested mailbox filters for GetMessageList --- .../integration/GetMessageListMethodTest.java | 18 +++----- .../jmap/draft/methods/GetMessageListMethod.java | 48 +++++++++++++++++++++- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/GetMessageListMethodTest.java b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/GetMessageListMethodTest.java index 6464d1d..7ba3326 100644 --- a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/GetMessageListMethodTest.java +++ b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/java/org/apache/james/jmap/draft/methods/integration/GetMessageListMethodTest.java @@ -94,7 +94,6 @@ import org.awaitility.Duration; import org.hamcrest.Matchers; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -669,12 +668,11 @@ public abstract class GetMessageListMethodTest { messageNotSeenFlaggedInOtherMailbox.getMessageId().serialize())))); } - @Ignore("To fix in JAMES-3182") - @Category(BasicFeature.class) @Test public void getMessageListShouldFetchUnreadMessagesInMailboxUsingACombinationOfFilter() throws Exception { - MailboxId mailboxId = mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, ALICE.asString(), "mailbox"); - mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, ALICE.asString(), "othermailbox"); + MailboxId mailboxId = mailboxProbe.createMailbox(MailboxPath.forUser(ALICE, "mailbox")); + mailboxProbe.createMailbox(MailboxPath.forUser(ALICE, "othermailbox")); + mailboxProbe.createMailbox(MailboxPath.inbox(ALICE)); ComposedMessageId messageNotSeenNotFlagged = mailboxProbe.appendMessage(ALICE.asString(), ALICE_MAILBOX, new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags()); @@ -700,13 +698,9 @@ public abstract class GetMessageListMethodTest { .post("/jmap") .then() .statusCode(200) - .body(NAME, equalTo("messageList")) - .body(ARGUMENTS + ".messageIds", allOf( - containsInAnyOrder(messageNotSeenNotFlagged.getMessageId().serialize(), messageNotSeenFlagged.getMessageId().serialize()), - not(containsInAnyOrder(messageSeenNotFlagged.getMessageId().serialize(), - messageSeenFlagged.getMessageId().serialize(), - messageSeenInOtherMailbox.getMessageId().serialize(), - messageNotSeenFlaggedInOtherMailbox.getMessageId().serialize())))); + .body(NAME, equalTo("error")) + .body(ARGUMENTS + ".type", equalTo("invalidArguments")) + .body(ARGUMENTS + ".description", equalTo("'inMailboxes' and 'notInMailboxes' wrapped within Filter Operators are not implemented. Review your search request.")); } @Test diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessageListMethod.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessageListMethod.java index cd31826..3f4b54f 100644 --- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessageListMethod.java +++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/GetMessageListMethod.java @@ -30,8 +30,10 @@ import java.util.stream.Stream; import javax.inject.Inject; import javax.inject.Named; +import org.apache.commons.lang3.NotImplementedException; import org.apache.james.jmap.draft.model.Filter; import org.apache.james.jmap.draft.model.FilterCondition; +import org.apache.james.jmap.draft.model.FilterOperator; import org.apache.james.jmap.draft.model.GetMessageListRequest; import org.apache.james.jmap.draft.model.GetMessageListResponse; import org.apache.james.jmap.draft.model.GetMessagesRequest; @@ -128,7 +130,15 @@ public class GetMessageListMethod implements Method { .response(messageListResponse) .responseName(RESPONSE_NAME) .build()), - processGetMessages(messageListRequest, messageListResponse, methodCallId, mailboxSession))); + processGetMessages(messageListRequest, messageListResponse, methodCallId, mailboxSession))) + .onErrorResume(NotImplementedException.class, e -> Mono.just(JmapResponse.builder() + .methodCallId(methodCallId) + .responseName(RESPONSE_NAME) + .error(ErrorResponse.builder() + .type("invalidArguments") + .description(e.getMessage()) + .build()) + .build())); } private Mono<GetMessageListResponse> getMessageListResponse(GetMessageListRequest messageListRequest, MailboxSession mailboxSession) { @@ -145,6 +155,11 @@ public class GetMessageListMethod implements Method { } private MultimailboxesSearchQuery convertToSearchQuery(GetMessageListRequest messageListRequest) { + if (messageListRequest.getFilter().map(this::containsNestedMailboxFilters).orElse(false)) { + throw new NotImplementedException("'inMailboxes' and 'notInMailboxes' wrapped within Filter Operators are not " + + "implemented. Review your search request."); + } + SearchQuery searchQuery = messageListRequest.getFilter() .map(filter -> new FilterToSearchQuery().convert(filter)) .orElse(new SearchQuery()); @@ -161,6 +176,37 @@ public class GetMessageListMethod implements Method { .build(); } + private boolean containsNestedMailboxFilters(Filter filter) { + if (filter instanceof FilterOperator) { + FilterOperator operator = (FilterOperator) filter; + + return operator.getConditions() + .stream() + .anyMatch(this::containsMailboxFilters); + } + if (filter instanceof FilterCondition) { + // The condition is not nested + return false; + } + throw new RuntimeException("Unsupported Filter implementation " + filter); + } + + private boolean containsMailboxFilters(Filter filter) { + if (filter instanceof FilterOperator) { + FilterOperator operator = (FilterOperator) filter; + + return operator.getConditions() + .stream() + .anyMatch(this::containsMailboxFilters); + } + if (filter instanceof FilterCondition) { + FilterCondition condition = (FilterCondition) filter; + + return condition.getInMailboxes().isPresent() || condition.getInMailboxes().isPresent(); + } + throw new RuntimeException("Unsupported Filter implementation " + filter); + } + private Set<MailboxId> buildFilterMailboxesSet(Optional<Filter> maybeFilter, Function<FilterCondition, Optional<List<String>>> mailboxListExtractor) { return filterToFilterCondition(maybeFilter) .flatMap(condition -> Guavate.stream(mailboxListExtractor.apply(condition))) --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org