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 2020/06/04 02:18:04 UTC

[james-project] 05/07: JAMES-3182 Explicitly reject nested mailbox filters for GetMessageList

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 <bt...@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-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org