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 ad...@apache.org on 2017/11/16 14:19:50 UTC

[03/18] james-project git commit: JAMES-2218 Disable moving / copying draft message

JAMES-2218 Disable moving / copying draft message


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/4ad9a0b7
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/4ad9a0b7
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/4ad9a0b7

Branch: refs/heads/master
Commit: 4ad9a0b730c8b776b1e8a2399169192a9bd24172
Parents: ad893d0
Author: benwa <bt...@linagora.com>
Authored: Wed Nov 15 16:34:42 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Nov 16 12:28:58 2017 +0100

----------------------------------------------------------------------
 .../test/resources/cucumber/SetMessages.feature | 24 ++++++++++-
 .../DraftMessageMailboxUpdateException.java     | 29 +++++++++++++
 .../methods/SetMessagesUpdateProcessor.java     | 44 ++++++++++++++++++--
 .../methods/SetMessagesUpdateProcessorTest.java | 14 ++++++-
 4 files changed, 105 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/4ad9a0b7/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/SetMessages.feature
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/SetMessages.feature b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/SetMessages.feature
index 9e6dcce..ac816e4 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/SetMessages.feature
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/SetMessages.feature
@@ -127,4 +127,26 @@ Feature: SetMessages method on shared folders
   Scenario: Draft creation in outbox is not allowed
     Given "bob@domain.tld" has a mailbox "Outbox"
     When "bob@domain.tld" creates a draft message "mDraft" in mailbox "Outbox"
-    Then message "mDraft" is not created
\ No newline at end of file
+    Then message "mDraft" is not created
+
+  Scenario: A user can not move draft out of draft mailbox
+    Given "bob@domain.tld" has a mailbox "Drafts"
+    And "bob@domain.tld" creates a draft message "mDraft" in mailbox "Drafts"
+    When "bob@domain.tld" moves "mDraft" to user mailbox "shared"
+    Then message "mDraft" is not updated
+
+  Scenario: A user can not copy draft out of draft mailbox
+    Given "bob@domain.tld" has a mailbox "Drafts"
+    And "bob@domain.tld" creates a draft message "mDraft" in mailbox "Drafts"
+    When "bob@domain.tld" copies "mDraft" from mailbox "Drafts" to mailbox "shared"
+    Then message "mDraft" is not updated
+
+  Scenario: A user can not copy draft out of draft mailbox
+    Given "bob@domain.tld" has a mailbox "Drafts"
+    When "bob@domain.tld" moves "mBob" to user mailbox "Drafts"
+    Then message "mBob" is not updated
+
+  Scenario: A user can not copy draft out of draft mailbox
+    Given "bob@domain.tld" has a mailbox "Drafts"
+    When "bob@domain.tld" copies "mBob" from mailbox "shared" to mailbox "Drafts"
+    Then message "mBob" is not updated
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/4ad9a0b7/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/DraftMessageMailboxUpdateException.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/DraftMessageMailboxUpdateException.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/DraftMessageMailboxUpdateException.java
new file mode 100644
index 0000000..296dc9c
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/DraftMessageMailboxUpdateException.java
@@ -0,0 +1,29 @@
+/****************************************************************
+ * 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.jmap.exceptions;
+
+import org.apache.james.mailbox.exception.MailboxException;
+
+public class DraftMessageMailboxUpdateException extends MailboxException {
+
+    public DraftMessageMailboxUpdateException() {
+        super();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4ad9a0b7/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesUpdateProcessor.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesUpdateProcessor.java
index da7dceb..f23ba55 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesUpdateProcessor.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesUpdateProcessor.java
@@ -30,11 +30,14 @@ import java.util.stream.Stream;
 import javax.inject.Inject;
 import javax.mail.Flags;
 
+import org.apache.james.jmap.exceptions.DraftMessageMailboxUpdateException;
 import org.apache.james.jmap.model.MessageProperties;
 import org.apache.james.jmap.model.SetError;
 import org.apache.james.jmap.model.SetMessagesRequest;
 import org.apache.james.jmap.model.SetMessagesResponse;
 import org.apache.james.jmap.model.UpdateMessagePatch;
+import org.apache.james.jmap.model.mailbox.Role;
+import org.apache.james.jmap.utils.SystemMailboxesProvider;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageIdManager;
 import org.apache.james.mailbox.MessageManager;
@@ -61,6 +64,7 @@ public class SetMessagesUpdateProcessor implements SetMessagesProcessor {
 
     private final UpdateMessagePatchConverter updatePatchConverter;
     private final MessageIdManager messageIdManager;
+    private final SystemMailboxesProvider systemMailboxesProvider;
     private final Factory mailboxIdFactory;
     private final MetricFactory metricFactory;
 
@@ -68,9 +72,10 @@ public class SetMessagesUpdateProcessor implements SetMessagesProcessor {
     @VisibleForTesting SetMessagesUpdateProcessor(
         UpdateMessagePatchConverter updatePatchConverter,
         MessageIdManager messageIdManager,
-        Factory mailboxIdFactory, MetricFactory metricFactory) {
+        SystemMailboxesProvider systemMailboxesProvider, Factory mailboxIdFactory, MetricFactory metricFactory) {
         this.updatePatchConverter = updatePatchConverter;
         this.messageIdManager = messageIdManager;
+        this.systemMailboxesProvider = systemMailboxesProvider;
         this.mailboxIdFactory = mailboxIdFactory;
         this.metricFactory = metricFactory;
     }
@@ -99,7 +104,9 @@ public class SetMessagesUpdateProcessor implements SetMessagesProcessor {
             if (messages.isEmpty()) {
                 addMessageIdNotFoundToResponse(messageId, builder);
             } else {
-                setInMailboxes(messageId, updateMessagePatch, mailboxSession);
+                setInMailboxes(messageId, updateMessagePatch,
+                    messages.stream().map(MessageResult::getFlags),
+                    mailboxSession);
                 Optional<MailboxException> updateError = messages.stream()
                     .flatMap(message -> updateFlags(messageId, updateMessagePatch, mailboxSession, message))
                     .findAny();
@@ -109,6 +116,8 @@ public class SetMessagesUpdateProcessor implements SetMessagesProcessor {
                     builder.updated(ImmutableList.of(messageId));
                 }
             }
+        } catch (DraftMessageMailboxUpdateException e) {
+            handleDraftMessageMailboxUpdateException(messageId, builder);
         } catch (MailboxException e) {
             handleMessageUpdateException(messageId, builder, e);
         } catch (IllegalArgumentException e) {
@@ -134,7 +143,7 @@ public class SetMessagesUpdateProcessor implements SetMessagesProcessor {
         }
     }
 
-    private void setInMailboxes(MessageId messageId, UpdateMessagePatch updateMessagePatch, MailboxSession mailboxSession) throws MailboxException {
+    private void setInMailboxes(MessageId messageId, UpdateMessagePatch updateMessagePatch, Stream<Flags> originalFlags, MailboxSession mailboxSession) throws MailboxException {
         Optional<List<String>> serializedMailboxIds = updateMessagePatch.getMailboxIds();
         if (serializedMailboxIds.isPresent()) {
             List<MailboxId> mailboxIds = serializedMailboxIds.get()
@@ -142,10 +151,30 @@ public class SetMessagesUpdateProcessor implements SetMessagesProcessor {
                 .map(mailboxIdFactory::fromString)
                 .collect(Guavate.toImmutableList());
 
+            assertNotDraftMailbox(mailboxSession, mailboxIds);
+            assertNotDraftMessage(originalFlags);
+
             messageIdManager.setInMailboxes(messageId, mailboxIds, mailboxSession);
         }
     }
 
+    private void assertNotDraftMessage(Stream<Flags> originalFlags) throws DraftMessageMailboxUpdateException {
+        boolean isADraftMessage = originalFlags
+            .anyMatch(flags -> flags.contains(Flags.Flag.DRAFT));
+        if (isADraftMessage) {
+            throw new DraftMessageMailboxUpdateException();
+        }
+    }
+
+    private void assertNotDraftMailbox(MailboxSession mailboxSession, List<MailboxId> mailboxIds) throws MailboxException {
+        Stream<MessageManager> draftMailboxes = systemMailboxesProvider.getMailboxByRole(Role.DRAFTS, mailboxSession);
+
+        boolean containsDraftMailboxes = draftMailboxes.map(MessageManager::getId).anyMatch(mailboxIds::contains);
+        if (containsDraftMailboxes) {
+            throw new DraftMessageMailboxUpdateException();
+        }
+    }
+
     private void addMessageIdNotFoundToResponse(MessageId messageId, SetMessagesResponse.Builder builder) {
         builder.notUpdated(ImmutableMap.of(messageId,
                 SetError.builder()
@@ -155,6 +184,15 @@ public class SetMessagesUpdateProcessor implements SetMessagesProcessor {
                         .build()));
     }
 
+    private SetMessagesResponse.Builder handleDraftMessageMailboxUpdateException(MessageId messageId,
+                                                                     SetMessagesResponse.Builder builder) {
+        return builder.notUpdated(ImmutableMap.of(messageId, SetError.builder()
+            .type("invalidArguments")
+            .properties(MessageProperties.MessageProperty.mailboxIds)
+            .description("Draft messages can not be moved or copied out of the Draft mailbox")
+            .build()));
+    }
+
     private SetMessagesResponse.Builder handleMessageUpdateException(MessageId messageId,
                                               SetMessagesResponse.Builder builder,
                                               MailboxException e) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/4ad9a0b7/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMessagesUpdateProcessorTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMessagesUpdateProcessorTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMessagesUpdateProcessorTest.java
index 424f28f..de2f809 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMessagesUpdateProcessorTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMessagesUpdateProcessorTest.java
@@ -28,6 +28,9 @@ import org.apache.james.jmap.model.MessageProperties;
 import org.apache.james.jmap.model.SetMessagesRequest;
 import org.apache.james.jmap.model.SetMessagesResponse;
 import org.apache.james.jmap.model.UpdateMessagePatch;
+import org.apache.james.jmap.utils.SystemMailboxesProvider;
+import org.apache.james.mailbox.MessageIdManager;
+import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.metrics.api.NoopMetricFactory;
@@ -42,7 +45,14 @@ public class SetMessagesUpdateProcessorTest {
 
     @Test
     public void processShouldReturnEmptyUpdatedWhenRequestHasEmptyUpdate() {
-        SetMessagesUpdateProcessor sut = new SetMessagesUpdateProcessor(null, null, null, new NoopMetricFactory());
+        UpdateMessagePatchConverter updatePatchConverter = null;
+        MessageIdManager messageIdManager = null;
+        SystemMailboxesProvider systemMailboxesProvider = null;
+        MailboxId.Factory mailboxIdFactory = null;
+        SetMessagesUpdateProcessor sut = new SetMessagesUpdateProcessor(updatePatchConverter,
+            messageIdManager,
+            systemMailboxesProvider,
+            mailboxIdFactory, new NoopMetricFactory());
         SetMessagesRequest requestWithEmptyUpdate = SetMessagesRequest.builder().build();
 
         SetMessagesResponse result = sut.process(requestWithEmptyUpdate, null);
@@ -66,7 +76,7 @@ public class SetMessagesUpdateProcessorTest {
         when(mockConverter.fromJsonNode(any(ObjectNode.class)))
                 .thenReturn(mockInvalidPatch);
 
-        SetMessagesUpdateProcessor sut = new SetMessagesUpdateProcessor(mockConverter, null, null, new NoopMetricFactory());
+        SetMessagesUpdateProcessor sut = new SetMessagesUpdateProcessor(mockConverter, null, null, null, new NoopMetricFactory());
         MessageId requestMessageId = TestMessageId.of(1);
         SetMessagesRequest requestWithInvalidUpdate = SetMessagesRequest.builder()
                 .update(ImmutableMap.of(requestMessageId, JsonNodeFactory.instance.objectNode()))


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