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 13:20:28 UTC

[1/8] james-project git commit: JAMES-2219 Check parent is not delegated during mailbox creation

Repository: james-project
Updated Branches:
  refs/heads/master 29510c2a3 -> 51cc52ae3


JAMES-2219 Check parent is not delegated during mailbox creation


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

Branch: refs/heads/master
Commit: 6a9f1f9309ed88ff4e703c63d4d408358158fde9
Parents: f656a9e
Author: benwa <bt...@linagora.com>
Authored: Thu Nov 16 10:05:44 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Nov 16 14:19:16 2017 +0100

----------------------------------------------------------------------
 .../apache/james/mailbox/model/MailboxPath.java |  4 +++
 .../mailbox/store/StoreMailboxManager.java      | 13 ++++-----
 .../james/mailbox/store/StoreRightManager.java  |  2 +-
 .../mailbox/store/StoreMailboxManagerTest.java  |  9 ++++--
 .../cucumber/SetMailboxesMethodStepdefs.java    | 29 ++++++++++++++++++++
 .../resources/cucumber/GetMailboxes.feature     |  9 ++++++
 .../methods/SetMailboxesCreationProcessor.java  | 14 ++++++++++
 .../methods/SetMessagesCreationProcessor.java   |  2 +-
 .../apache/james/jmap/model/MailboxFactory.java |  6 +---
 9 files changed, 71 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/6a9f1f93/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxPath.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxPath.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxPath.java
index 02daf0b..de5e9ef 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxPath.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxPath.java
@@ -99,6 +99,10 @@ public class MailboxPath {
         return name;
     }
 
+    public boolean belongsTo(MailboxSession mailboxSession) {
+        return mailboxSession.getUser().isSameUser(user);
+    }
+
     /**
      * Return a list of MailboxPath representing the hierarchy levels of this
      * MailboxPath. E.g. INBOX.main.sub would yield

http://git-wip-us.apache.org/repos/asf/james-project/blob/6a9f1f93/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
index 88c1aea..c813fb8 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
@@ -37,7 +37,6 @@ import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxPathLocker.LockAwareExecution;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSession.SessionType;
-import org.apache.james.mailbox.MailboxSession.User;
 import org.apache.james.mailbox.MailboxSessionIdGenerator;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.StandardMailboxMetaDataComparator;
@@ -477,7 +476,7 @@ public class StoreMailboxManager implements MailboxManager {
     }
 
     private boolean belongsToCurrentUser(Mailbox mailbox, MailboxSession session) {
-        return session.getUser().isSameUser(mailbox.getUser());
+        return mailbox.generateAssociatedPath().belongsTo(session);
     }
 
     private boolean userHasLookupRightsOn(Mailbox mailbox, MailboxSession session) throws MailboxException {
@@ -523,7 +522,7 @@ public class StoreMailboxManager implements MailboxManager {
     @Override
     public void deleteMailbox(final MailboxPath mailboxPath, final MailboxSession session) throws MailboxException {
         LOGGER.info("deleteMailbox " + mailboxPath);
-        assertIsOwner(session.getUser(), mailboxPath);
+        assertIsOwner(session, mailboxPath);
         final MailboxMapper mapper = mailboxSessionMapperFactory.getMailboxMapper(session);
 
         Mailbox mailbox = mapper.execute((Mapper.Transaction<Mailbox>) () -> {
@@ -550,14 +549,14 @@ public class StoreMailboxManager implements MailboxManager {
             throw new MailboxExistsException(to.toString());
         }
 
-        assertIsOwner(session.getUser(), from);
+        assertIsOwner(session, from);
         MailboxMapper mapper = mailboxSessionMapperFactory.getMailboxMapper(session);
         mapper.execute(Mapper.toTransaction(() -> doRenameMailbox(from, to, session, mapper)));
     }
 
-    private void assertIsOwner(User user, MailboxPath mailboxPath) throws MailboxNotFoundException {
-        if (!user.isSameUser(mailboxPath.getUser())) {
-            LOGGER.info("Mailbox " + mailboxPath.asString() + " does not belong to " + user.getUserName());
+    private void assertIsOwner(MailboxSession mailboxSession, MailboxPath mailboxPath) throws MailboxNotFoundException {
+        if (!mailboxPath.belongsTo(mailboxSession)) {
+            LOGGER.info("Mailbox " + mailboxPath.asString() + " does not belong to " + mailboxSession.getUser().getUserName());
             throw new MailboxNotFoundException(mailboxPath.asString());
         }
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/6a9f1f93/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java
index f3209d0..9c789aa 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreRightManager.java
@@ -241,7 +241,7 @@ public class StoreRightManager implements RightManager {
      */
     @VisibleForTesting
     static MailboxACL filteredForSession(Mailbox mailbox, MailboxACL acl, MailboxSession mailboxSession) throws UnsupportedRightException {
-        if (mailboxSession.getUser().isSameUser(mailbox.getUser())) {
+        if (mailbox.generateAssociatedPath().belongsTo(mailboxSession)) {
             return acl;
         }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/6a9f1f93/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerTest.java
index b97d993..7228e55 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/StoreMailboxManagerTest.java
@@ -99,7 +99,8 @@ public class StoreMailboxManagerTest {
     @Test
     public void getMailboxShouldReturnMailboxManagerWhenKnownId() throws Exception {
         Mailbox mockedMailbox = mock(Mailbox.class);
-        when(mockedMailbox.getUser()).thenReturn(CURRENT_USER);
+        when(mockedMailbox.generateAssociatedPath())
+            .thenReturn(MailboxPath.forUser(CURRENT_USER, "mailboxName"));
         when(mockedMailbox.getMailboxId()).thenReturn(MAILBOX_ID);
         when(mockedMailboxMapper.findMailboxById(MAILBOX_ID)).thenReturn(mockedMailbox);
 
@@ -111,7 +112,8 @@ public class StoreMailboxManagerTest {
     @Test
     public void getMailboxShouldReturnMailboxManagerWhenKnownIdAndDifferentCaseUser() throws Exception {
         Mailbox mockedMailbox = mock(Mailbox.class);
-        when(mockedMailbox.getUser()).thenReturn("uSEr");
+        when(mockedMailbox.generateAssociatedPath())
+            .thenReturn(MailboxPath.forUser("uSEr", "mailboxName"));
         when(mockedMailbox.getMailboxId()).thenReturn(MAILBOX_ID);
         when(mockedMailboxMapper.findMailboxById(MAILBOX_ID)).thenReturn(mockedMailbox);
 
@@ -124,7 +126,8 @@ public class StoreMailboxManagerTest {
     public void getMailboxShouldThrowWhenMailboxDoesNotMatchUserWithoutRight() throws Exception {
         Mailbox mockedMailbox = mock(Mailbox.class);
         when(mockedMailbox.getACL()).thenReturn(new MailboxACL());
-        when(mockedMailbox.getUser()).thenReturn("other.user");
+        when(mockedMailbox.generateAssociatedPath())
+            .thenReturn(MailboxPath.forUser("other.user", "mailboxName"));
         when(mockedMailbox.getMailboxId()).thenReturn(MAILBOX_ID);
         when(mockedMailboxMapper.findMailboxById(MAILBOX_ID)).thenReturn(mockedMailbox);
         when(mockedMailboxMapper.findMailboxByPath(any())).thenReturn(mockedMailbox);

http://git-wip-us.apache.org/repos/asf/james-project/blob/6a9f1f93/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java
index 9d35294..ef22490 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java
@@ -137,6 +137,28 @@ public class SetMailboxesMethodStepdefs {
         renamingMailbox(mailbox, newMailboxName);
     }
 
+    @When("^\"([^\"]*)\" creates mailbox \"([^\"]*)\" with creationId \"([^\"]*)\" in mailbox \"([^\"]*)\" owned by \"([^\"]*)\"$")
+    public void createChildMailbox(String user, String mailboxName, String creationId, String parentMailboxName, String parentOwner) throws Throwable {
+        Mailbox parentMailbox = mainStepdefs.mailboxProbe.getMailbox(MailboxConstants.USER_NAMESPACE, parentOwner, parentMailboxName);
+        userStepdefs.execWithUser(user, () -> {
+            String requestBody =
+                "[" +
+                    "  [ \"setMailboxes\"," +
+                    "    {" +
+                    "      \"create\": {" +
+                    "        \"" + creationId + "\" : {" +
+                    "          \"name\" : \"" + mailboxName + "\"," +
+                    "          \"parentId\" : \"" + parentMailbox.getMailboxId().serialize() + "\"" +
+                    "        }" +
+                    "      }" +
+                    "    }," +
+                    "    \"#0\"" +
+                    "  ]" +
+                    "]";
+            httpClient.post(requestBody);
+        });
+    }
+
     @When("^\"([^\"]*)\" renames (?:her|his) mailbox \"([^\"]*)\" to \"([^\"]*)\"$")
     public void renamingMailbox(String user, String actualMailboxName, String newMailboxName) throws Throwable {
         Mailbox mailbox = mainStepdefs.mailboxProbe.getMailbox("#private", user, actualMailboxName);
@@ -253,4 +275,11 @@ public class SetMailboxesMethodStepdefs {
         assertThat(httpClient.jsonPath.<Map<String, String>>read("[0][1].notDestroyed"))
             .containsOnlyKeys(mailbox.getMailboxId().serialize());
     }
+
+
+    @Then("^mailbox with creationId \"([^\"]*)\" is not created")
+    public void assertNotCreated(String creationId) throws Exception {
+        assertThat(httpClient.jsonPath.<Map<String, String>>read("[0][1].notCreated"))
+            .containsOnlyKeys(creationId);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/6a9f1f93/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature
index 9ec81e9..9d5dbb0 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature
@@ -286,3 +286,12 @@ Feature: GetMailboxes method
     Given "bob@domain.tld" deletes the mailbox "shared" owned by "alice@domain.tld"
     When "alice@domain.tld" lists mailboxes
     Then the mailboxes should contain "shared" in "Personal" namespace
+
+  Scenario: A sharee should not be able to create a shared mailbox child
+    Given "bob@domain.tld" creates mailbox "sharedChild" with creationId "c-01" in mailbox "shared" owned by "alice@domain.tld"
+    When "alice@domain.tld" lists mailboxes
+    Then the mailboxes should contain "shared" in "Personal" namespace
+
+  Scenario: A sharee should receive a not created response when trying to create a shared mailbox child
+    When "bob@domain.tld" creates mailbox "sharedChild" with creationId "c-01" in mailbox "shared" owned by "alice@domain.tld"
+    Then mailbox with creationId "c-01" is not created

http://git-wip-us.apache.org/repos/asf/james-project/blob/6a9f1f93/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
index 0f71d2e..39695b1 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
@@ -27,6 +27,7 @@ import java.util.Optional;
 
 import javax.inject.Inject;
 
+import org.apache.james.jmap.exceptions.MailboxNotOwnedException;
 import org.apache.james.jmap.exceptions.MailboxParentNotFoundException;
 import org.apache.james.jmap.model.MailboxCreationId;
 import org.apache.james.jmap.model.MailboxFactory;
@@ -134,6 +135,11 @@ public class SetMailboxesCreationProcessor implements SetMailboxesProcessor {
                 .type("invalidArguments")
                 .description("The mailbox name length is too long")
                 .build());
+        } catch (MailboxNotOwnedException e) {
+            builder.notCreated(mailboxCreationId, SetError.builder()
+                .type("invalidArguments")
+                .description("The mailbox can not be created with a parent mailbox belonging to another user")
+                .build());
         } catch (MailboxNameException | MailboxParentNotFoundException e) {
             builder.notCreated(mailboxCreationId, SetError.builder()
                     .type("invalidArguments")
@@ -168,12 +174,20 @@ public class SetMailboxesCreationProcessor implements SetMailboxesProcessor {
             MailboxCreationId parentId = mailboxRequest.getParentId().get();
             MailboxPath parentPath = getMailboxPath(creationIdsToCreatedMailboxId, mailboxSession, parentId);
 
+            assertBelongsToUser(parentPath, mailboxSession);
+
             return MailboxPath.forUser(mailboxSession.getUser().getUserName(),
                 parentPath.getName() + mailboxSession.getPathDelimiter() + mailboxRequest.getName());
         }
         return MailboxPath.forUser(mailboxSession.getUser().getUserName(), mailboxRequest.getName());
     }
 
+    private void assertBelongsToUser(MailboxPath mailboxPath, MailboxSession mailboxSession) throws MailboxNotOwnedException {
+        if (!mailboxPath.belongsTo(mailboxSession)) {
+            throw new MailboxNotOwnedException();
+        }
+    }
+
     private MailboxPath getMailboxPath(Map<MailboxCreationId, MailboxId> creationIdsToCreatedMailboxId, MailboxSession mailboxSession, MailboxCreationId parentId) throws MailboxException {
         Optional<MailboxId> mailboxId = getMailboxIdFromCreationId(parentId);
         Optional<MailboxId> mailboxIdFromCreationId = Optional.ofNullable(creationIdsToCreatedMailboxId.get(parentId));

http://git-wip-us.apache.org/repos/asf/james-project/blob/6a9f1f93/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesCreationProcessor.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesCreationProcessor.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesCreationProcessor.java
index 4bb43dc..3f81798 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesCreationProcessor.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesCreationProcessor.java
@@ -229,7 +229,7 @@ public class SetMessagesCreationProcessor implements SetMessagesProcessor {
             .map(mailboxIdFactory::fromString)
             .map(findMailbox.sneakyThrow())
             .map(Throwing.function(MessageManager::getMailboxPath))
-            .anyMatch(path -> !session.getUser().isSameUser(path.getUser()));
+            .anyMatch(path -> !path.belongsTo(session));
     }
 
     private MessageWithId handleOutboxMessages(CreationMessageEntry entry, MailboxSession session) throws MailboxException, MessagingException {

http://git-wip-us.apache.org/repos/asf/james-project/blob/6a9f1f93/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxFactory.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxFactory.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxFactory.java
index c20aaad..fca9da2 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxFactory.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxFactory.java
@@ -100,7 +100,7 @@ public class MailboxFactory {
     private Mailbox fromMessageManager(MessageManager messageManager, Optional<List<MailboxMetaData>> userMailboxesMetadata,
                                                  MailboxSession mailboxSession) throws MailboxException {
         MailboxPath mailboxPath = messageManager.getMailboxPath();
-        boolean isOwner = isSameUser(mailboxSession, mailboxPath);
+        boolean isOwner = mailboxPath.belongsTo(mailboxSession);
         Optional<Role> role = Role.from(mailboxPath.getName());
         MailboxCounters mailboxCounters = messageManager.getMailboxCounters(mailboxSession);
         MessageManager.MetaData metaData = messageManager.getMetaData(NO_RESET_RECENT, mailboxSession, MessageManager.MetaData.FetchGroup.NO_COUNT);
@@ -135,10 +135,6 @@ public class MailboxFactory {
         return MailboxNamespace.delegated(mailboxPath.getUser());
     }
 
-    private boolean isSameUser(MailboxSession mailboxSession, MailboxPath mailboxPath) {
-        return mailboxSession.getUser().isSameUser(mailboxPath.getUser());
-    }
-
     @VisibleForTesting String getName(MailboxPath mailboxPath, MailboxSession mailboxSession) {
         String name = mailboxPath.getName();
         if (name.contains(String.valueOf(mailboxSession.getPathDelimiter()))) {


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


[5/8] james-project git commit: JAMES-2219 Integration test about renaming a shared mailbox

Posted by ad...@apache.org.
JAMES-2219 Integration test about renaming a shared mailbox


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

Branch: refs/heads/master
Commit: 48979015080c1215089ac461ecec061bcbdcb156
Parents: 29510c2
Author: Antoine Duprat <ad...@linagora.com>
Authored: Wed Nov 15 15:32:43 2017 +0100
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Nov 16 14:19:16 2017 +0100

----------------------------------------------------------------------
 .../mailbox/store/StoreMailboxManager.java      |  9 +++
 .../cucumber/GetMailboxesMethodStepdefs.java    |  2 +-
 .../cucumber/SetMailboxesMethodStepdefs.java    | 29 ++++++-
 .../resources/cucumber/GetMailboxes.feature     | 82 ++++++++++++--------
 4 files changed, 87 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/48979015/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
index e76ea91..6a72340 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
@@ -37,6 +37,7 @@ import org.apache.james.mailbox.MailboxPathLocker;
 import org.apache.james.mailbox.MailboxPathLocker.LockAwareExecution;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSession.SessionType;
+import org.apache.james.mailbox.MailboxSession.User;
 import org.apache.james.mailbox.MailboxSessionIdGenerator;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.StandardMailboxMetaDataComparator;
@@ -548,10 +549,18 @@ public class StoreMailboxManager implements MailboxManager {
             throw new MailboxExistsException(to.toString());
         }
 
+        assertIsOwner(session.getUser(), from);
         MailboxMapper mapper = mailboxSessionMapperFactory.getMailboxMapper(session);
         mapper.execute(Mapper.toTransaction(() -> doRenameMailbox(from, to, session, mapper)));
     }
 
+    private void assertIsOwner(User user, MailboxPath mailboxPath) throws MailboxNotFoundException {
+        if (!user.isSameUser(mailboxPath.getUser())) {
+            LOGGER.info("Mailbox " + mailboxPath.asString() + " does not belong to " + user.getUserName());
+            throw new MailboxNotFoundException(mailboxPath.asString());
+        }
+    }
+
     private void doRenameMailbox(MailboxPath from, MailboxPath to, MailboxSession session, MailboxMapper mapper) throws MailboxException {
         // TODO put this into a serilizable transaction
         Mailbox mailbox = Optional.ofNullable(mapper.findMailboxByPath(from))

http://git-wip-us.apache.org/repos/asf/james-project/blob/48979015/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMailboxesMethodStepdefs.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMailboxesMethodStepdefs.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMailboxesMethodStepdefs.java
index 85e9af3..73272cf 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMailboxesMethodStepdefs.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMailboxesMethodStepdefs.java
@@ -46,7 +46,7 @@ public class GetMailboxesMethodStepdefs {
         this.httpClient = httpClient;
     }
 
-    @When("^\"([^\"]*)\" ask for mailboxes$")
+    @When("^\"([^\"]*)\" lists mailboxes$")
     public void getMailboxes(String user) throws Throwable {
         userStepdefs.execWithUser(user, 
                 () -> httpClient.post("[[\"getMailboxes\", {}, \"#0\"]]"));

http://git-wip-us.apache.org/repos/asf/james-project/blob/48979015/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java
index 3705db7..59c1fbd 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java
@@ -130,9 +130,20 @@ public class SetMailboxesMethodStepdefs {
         shareMailboxWithRight(owner, mailboxName, rights, shareTo);
     }
 
-    @When("^renaming mailbox \"([^\"]*)\" to \"([^\"]*)\"")
-    public void renamingMailbox(String actualMailboxName, String newMailboxName) throws Throwable {
-        Mailbox mailbox = mainStepdefs.mailboxProbe.getMailbox("#private", userStepdefs.getConnectedUser(), actualMailboxName);
+    @When("^\"([^\"]*)\" renames the mailbox, owned by \"([^\"]*)\", \"([^\"]*)\" to \"([^\"]*)\"$")
+    public void renamingMailbox(String user, String mailboxOwner, String currentMailboxName, String newMailboxName) throws Throwable {
+        Mailbox mailbox = mainStepdefs.mailboxProbe.getMailbox("#private", mailboxOwner, currentMailboxName);
+        userStepdefs.connectUser(user);
+        renamingMailbox(mailbox, newMailboxName);
+    }
+
+    @When("^\"([^\"]*)\" renames (?:her|his) mailbox \"([^\"]*)\" to \"([^\"]*)\"$")
+    public void renamingMailbox(String user, String actualMailboxName, String newMailboxName) throws Throwable {
+        Mailbox mailbox = mainStepdefs.mailboxProbe.getMailbox("#private", user, actualMailboxName);
+        renamingMailbox(mailbox, newMailboxName);
+    }
+
+    private void renamingMailbox(Mailbox mailbox, String newMailboxName) throws Exception {
         String mailboxId = mailbox.getMailboxId().serialize();
         String requestBody =
                 "[" +
@@ -150,6 +161,11 @@ public class SetMailboxesMethodStepdefs {
         httpClient.post(requestBody);
     }
 
+    @When("^renaming mailbox \"([^\"]*)\" to \"([^\"]*)\"")
+    public void renamingMailbox(String actualMailboxName, String newMailboxName) throws Throwable {
+        renamingMailbox(userStepdefs.getConnectedUser(), actualMailboxName, newMailboxName);
+    }
+
     @When("^moving mailbox \"([^\"]*)\" to \"([^\"]*)\"$")
     public void movingMailbox(String actualMailboxPath, String newParentMailboxPath) throws Throwable {
         String username = userStepdefs.getConnectedUser();
@@ -206,4 +222,11 @@ public class SetMailboxesMethodStepdefs {
         assertThat(parameters).contains(Maps.immutableEntry("type", type),
                 Maps.immutableEntry("description", message));
     }
+
+    @Then("^mailbox \"([^\"]*)\" owned by \"([^\"]*)\" is not updated")
+    public void assertNotUpdated(String mailboxName, String owner) throws Exception {
+        Mailbox mailbox = mainStepdefs.mailboxProbe.getMailbox(MailboxConstants.USER_NAMESPACE, owner, mailboxName);
+        assertThat(httpClient.jsonPath.<Map<String, String>>read("[0][1].notUpdated"))
+            .containsOnlyKeys(mailbox.getMailboxId().serialize());
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/48979015/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature
index 28f0011..34278c3 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature
@@ -32,63 +32,63 @@ Feature: GetMailboxes method
   Scenario: Sharer can read the total and unread counts on a shared folder
     Given "alice@domain.tld" has a message "m1" in "shared" mailbox
     And "alice@domain.tld" has a message "m2" in "shared" mailbox with subject "my test subject 2", content "testmail 2"
-    When "alice@domain.tld" ask for mailboxes
+    When "alice@domain.tld" lists mailboxes
     Then the mailbox "shared" has 2 messages
     And the mailbox "shared" has 2 unseen messages
 
   Scenario: Sharee can read the total and unread counts on a shared folder
     Given "alice@domain.tld" has a message "m1" in "shared" mailbox
     And "alice@domain.tld" has a message "m2" in "shared" mailbox with subject "my test subject 2", content "testmail 2"
-    When "bob@domain.tld" ask for mailboxes
+    When "bob@domain.tld" lists mailboxes
     Then the mailbox "shared" has 2 messages
     And the mailbox "shared" has 2 unseen messages
 
   Scenario: Copy message should update the total and the unread counts when asked by sharer
     Given "alice@domain.tld" has a message "m1" in "INBOX" mailbox
     And "alice@domain.tld" copies "m1" from mailbox "INBOX" to mailbox "shared"
-    When "alice@domain.tld" ask for mailboxes
+    When "alice@domain.tld" lists mailboxes
     Then the mailbox "shared" has 1 message
     And the mailbox "shared" has 1 unseen message
 
   Scenario: Copy message should update the total and the unread counts when asked by sharer / sharee view
     Given "alice@domain.tld" has a message "m1" in "INBOX" mailbox
     And "alice@domain.tld" copies "m1" from mailbox "INBOX" to mailbox "shared"
-    When "bob@domain.tld" ask for mailboxes
+    When "bob@domain.tld" lists mailboxes
     Then the mailbox "shared" has 1 message
     And the mailbox "shared" has 1 unseen message
 
   Scenario: Copy message should update the total and the unread counts when asked by sharee
     Given "bob@domain.tld" has a message "m1" in "bobMailbox" mailbox
     And "bob@domain.tld" copies "m1" from mailbox "bobMailbox" of user "bob@domain.tld" to mailbox "shared" of user "alice@domain.tld"
-    When "alice@domain.tld" ask for mailboxes
+    When "alice@domain.tld" lists mailboxes
     Then the mailbox "shared" has 1 message
     And the mailbox "shared" has 1 unseen message
 
   Scenario: Copy message should update the total and the unread counts when asked by sharee / sharee view
     Given "bob@domain.tld" has a message "m1" in "bobMailbox" mailbox
     And "bob@domain.tld" copies "m1" from mailbox "bobMailbox" of user "bob@domain.tld" to mailbox "shared" of user "alice@domain.tld"
-    When "bob@domain.tld" ask for mailboxes
+    When "bob@domain.tld" lists mailboxes
     Then the mailbox "shared" has 1 message
     And the mailbox "shared" has 1 unseen message
 
   Scenario: Move message should update the total and the unread counts when asked by sharer
     Given "alice@domain.tld" has a message "m1" in "INBOX" mailbox
     And "alice@domain.tld" moves "m1" to mailbox "shared" of user "alice@domain.tld"
-    When "alice@domain.tld" ask for mailboxes
+    When "alice@domain.tld" lists mailboxes
     Then the mailbox "shared" has 1 message
     And the mailbox "shared" has 1 unseen message
 
   Scenario: Move message should update the total and the unread counts of origin mailbox when asked by sharer
     Given "alice@domain.tld" has a message "m1" in "INBOX" mailbox
     And "alice@domain.tld" moves "m1" to mailbox "shared" of user "alice@domain.tld"
-    When "alice@domain.tld" ask for mailboxes
+    When "alice@domain.tld" lists mailboxes
     Then the mailbox "INBOX" has 0 messages
     And the mailbox "INBOX" has 0 unseen messages
 
   Scenario: Move message should update the total and the unread counts when asked by sharer / sharee view
     Given "alice@domain.tld" has a message "m1" in "INBOX" mailbox
     And "alice@domain.tld" moves "m1" to mailbox "shared" of user "alice@domain.tld"
-    When "bob@domain.tld" ask for mailboxes
+    When "bob@domain.tld" lists mailboxes
     Then the mailbox "shared" has 1 message
     And the mailbox "shared" has 1 unseen message
 
@@ -97,14 +97,14 @@ Feature: GetMailboxes method
     And "alice@domain.tld" has a message "m1" in "sharedBis" mailbox
     And "alice@domain.tld" shares her mailbox "sharedBis" with "bob@domain.tld" with "aeilrwt" rights
     And "alice@domain.tld" moves "m1" to mailbox "shared" of user "alice@domain.tld"
-    When "bob@domain.tld" ask for mailboxes
+    When "bob@domain.tld" lists mailboxes
     Then the mailbox "sharedBis" has 0 messages
     And the mailbox "sharedBis" has 0 unseen messages
 
   Scenario: Move message should update the total and the unread counts when asked by sharee
     Given "bob@domain.tld" has a message "m1" in "bobMailbox" mailbox
     And "bob@domain.tld" moves "m1" to mailbox "shared" of user "alice@domain.tld"
-    When "alice@domain.tld" ask for mailboxes
+    When "alice@domain.tld" lists mailboxes
     Then the mailbox "shared" has 1 message
     And the mailbox "shared" has 1 unseen message
 
@@ -113,21 +113,21 @@ Feature: GetMailboxes method
     And "bob@domain.tld" has a message "m1" in "sharedBis" mailbox
     And "bob@domain.tld" shares her mailbox "sharedBis" with "alice@domain.tld" with "aeilrwt" rights
     And "bob@domain.tld" moves "m1" to mailbox "shared" of user "alice@domain.tld"
-    When "alice@domain.tld" ask for mailboxes
+    When "alice@domain.tld" lists mailboxes
     Then the mailbox "sharedBis" has 0 messages
     And the mailbox "sharedBis" has 0 unseen messages
 
   Scenario: Move message should update the total and the unread counts when asked by sharee / sharee view
     Given "bob@domain.tld" has a message "m1" in "bobMailbox" mailbox
     And "bob@domain.tld" moves "m1" to mailbox "shared" of user "alice@domain.tld"
-    When "bob@domain.tld" ask for mailboxes
+    When "bob@domain.tld" lists mailboxes
     Then the mailbox "shared" has 1 message
     And the mailbox "shared" has 1 unseen message
 
   Scenario: Move message should update the total and the unread counts of origin mailbox when asked by sharee / sharee view
     Given "bob@domain.tld" has a message "m1" in "bobMailbox" mailbox
     And "bob@domain.tld" moves "m1" to mailbox "shared" of user "alice@domain.tld"
-    When "bob@domain.tld" ask for mailboxes
+    When "bob@domain.tld" lists mailboxes
     Then the mailbox "bobMailbox" has 0 messages
     And the mailbox "bobMailbox" has 0 unseen messages
 
@@ -136,7 +136,7 @@ Feature: GetMailboxes method
     And "alice@domain.tld" shares her mailbox "shared2" with "bob@domain.tld" with "lr" rights
     And "bob@domain.tld" has a message "m1" in "bobMailbox" mailbox
     And "bob@domain.tld" moves "m1" to mailbox "shared2" of user "alice@domain.tld"
-    When "alice@domain.tld" ask for mailboxes
+    When "alice@domain.tld" lists mailboxes
     Then the mailbox "shared" has 0 messages
     And the mailbox "shared" has 0 unseen messages
 
@@ -145,28 +145,28 @@ Feature: GetMailboxes method
     And "alice@domain.tld" shares her mailbox "shared2" with "bob@domain.tld" with "lr" rights
     And "bob@domain.tld" has a message "m1" in "bobMailbox" mailbox
     And "bob@domain.tld" moves "m1" to mailbox "shared2" of user "alice@domain.tld"
-    When "bob@domain.tld" ask for mailboxes
+    When "bob@domain.tld" lists mailboxes
     Then the mailbox "shared" has 0 messages
     And the mailbox "shared" has 0 unseen messages
 
   Scenario: Move message should update the total and the unread counts when asked by sharee and seen message
     Given "bob@domain.tld" has a message "m1" in the "bobMailbox" mailbox with flags "$Seen"
     And "bob@domain.tld" moves "m1" to mailbox "shared" of user "alice@domain.tld"
-    When "alice@domain.tld" ask for mailboxes
+    When "alice@domain.tld" lists mailboxes
     Then the mailbox "shared" has 1 message
     And the mailbox "shared" has 0 unseen message
 
   Scenario: Move message should update the total and the unread counts when asked by sharee / sharee view and seen message
     Given "bob@domain.tld" has a message "m1" in the "bobMailbox" mailbox with flags "$Seen"
     And "bob@domain.tld" moves "m1" to mailbox "shared" of user "alice@domain.tld"
-    When "bob@domain.tld" ask for mailboxes
+    When "bob@domain.tld" lists mailboxes
     Then the mailbox "shared" has 1 message
     And the mailbox "shared" has 0 unseen message
 
   Scenario: Move message should update the total and the unread counts of origin mailbox when asked by sharer and seen message
     Given "alice@domain.tld" has a message "m1" in the "INBOX" mailbox with flags "$Seen"
     And "alice@domain.tld" moves "m1" to mailbox "shared" of user "alice@domain.tld"
-    When "alice@domain.tld" ask for mailboxes
+    When "alice@domain.tld" lists mailboxes
     Then the mailbox "INBOX" has 0 messages
     And the mailbox "INBOX" has 0 unseen messages
 
@@ -175,7 +175,7 @@ Feature: GetMailboxes method
     And "alice@domain.tld" shares her mailbox "shared2" with "bob@domain.tld" with "lri" rights
     And "bob@domain.tld" has a message "m1" in the "bobMailbox" mailbox with flags "$Seen"
     And "bob@domain.tld" moves "m1" to mailbox "shared2" of user "alice@domain.tld"
-    When "alice@domain.tld" ask for mailboxes
+    When "alice@domain.tld" lists mailboxes
     Then the mailbox "shared" has 0 messages
     And the mailbox "shared" has 0 unseen messages
 
@@ -184,35 +184,35 @@ Feature: GetMailboxes method
     And "alice@domain.tld" shares her mailbox "shared2" with "bob@domain.tld" with "lri" rights
     And "bob@domain.tld" has a message "m1" in the "bobMailbox" mailbox with flags "$Seen"
     And "bob@domain.tld" moves "m1" to mailbox "shared2" of user "alice@domain.tld"
-    When "bob@domain.tld" ask for mailboxes
+    When "bob@domain.tld" lists mailboxes
     Then the mailbox "shared" has 0 messages
     And the mailbox "shared" has 0 unseen messages
 
   Scenario: Set flags by sharer should update unseen count when read by sharer
     Given "alice@domain.tld" has a message "m1" in "shared" mailbox
     When "alice@domain.tld" sets flags "$Seen" on message "m1"
-    When "alice@domain.tld" ask for mailboxes
+    When "alice@domain.tld" lists mailboxes
     Then the mailbox "shared" has 1 message
     And the mailbox "shared" has 0 unseen messages
 
   Scenario: Set flags by sharer should update unseen count when read by sharee
     Given "alice@domain.tld" has a message "m1" in "shared" mailbox
     When "alice@domain.tld" sets flags "$Seen" on message "m1"
-    When "bob@domain.tld" ask for mailboxes
+    When "bob@domain.tld" lists mailboxes
     Then the mailbox "shared" has 1 message
     And the mailbox "shared" has 0 unseen messages
 
   Scenario: Set flags by sharee should update unseen count when read by sharer
     Given "alice@domain.tld" has a message "m1" in "shared" mailbox
     When "bob@domain.tld" sets flags "$Seen" on message "m1"
-    When "alice@domain.tld" ask for mailboxes
+    When "alice@domain.tld" lists mailboxes
     Then the mailbox "shared" has 1 message
     And the mailbox "shared" has 0 unseen messages
 
   Scenario: Set flags by sharee should update unseen count when read by sharee
     Given "alice@domain.tld" has a message "m1" in "shared" mailbox
     When "bob@domain.tld" sets flags "$Seen" on message "m1"
-    When "bob@domain.tld" ask for mailboxes
+    When "bob@domain.tld" lists mailboxes
     Then the mailbox "shared" has 1 message
     And the mailbox "shared" has 0 unseen messages
 
@@ -221,7 +221,7 @@ Feature: GetMailboxes method
     And "alice@domain.tld" shares her mailbox "shared2" with "bob@domain.tld" with "lri" rights
     And "alice@domain.tld" has a message "m1" in "shared2" mailbox
     When "bob@domain.tld" sets flags "$Seen" on message "m1"
-    When "alice@domain.tld" ask for mailboxes
+    When "alice@domain.tld" lists mailboxes
     Then the mailbox "shared2" has 1 message
     And the mailbox "shared2" has 1 unseen message
 
@@ -230,7 +230,7 @@ Feature: GetMailboxes method
     And "alice@domain.tld" shares her mailbox "shared2" with "bob@domain.tld" with "lri" rights
     And "alice@domain.tld" has a message "m1" in "shared2" mailbox
     When "bob@domain.tld" sets flags "$Seen" on message "m1"
-    When "bob@domain.tld" ask for mailboxes
+    When "bob@domain.tld" lists mailboxes
     Then the mailbox "shared2" has 1 message
     And the mailbox "shared2" has 1 unseen message
 
@@ -238,7 +238,7 @@ Feature: GetMailboxes method
     Given "alice@domain.tld" has a mailbox "shared2"
     And "alice@domain.tld" shares her mailbox "shared2" with "bob@domain.tld" with "l" rights
     And "alice@domain.tld" has a message "m1" in "shared2" mailbox
-    When "bob@domain.tld" ask for mailboxes
+    When "bob@domain.tld" lists mailboxes
     Then the mailbox "shared2" has 0 messages
     And the mailbox "shared2" has 0 unseen messages
 
@@ -246,7 +246,7 @@ Feature: GetMailboxes method
     Given "alice@domain.tld" has a mailbox "mailbox1"
     And "alice@domain.tld" has a mailbox "mailbox1.shared"
     And "alice@domain.tld" shares her mailbox "mailbox1.shared" with "bob@domain.tld" with "aeirwt" rights
-    When "bob@domain.tld" ask for mailboxes
+    When "bob@domain.tld" lists mailboxes
     Then the mailboxes should contain "shared" in "Delegated" namespace
     And the mailboxes should not contain "mailbox1"
 
@@ -254,6 +254,26 @@ Feature: GetMailboxes method
     Given "alice@domain.tld" has a mailbox "mailbox1"
     And "alice@domain.tld" has a mailbox "mailbox1.shared"
     And "alice@domain.tld" shares her mailbox "mailbox1.shared" with "bob@domain.tld" with "l" rights
-    When "bob@domain.tld" ask for mailboxes
+    When "bob@domain.tld" lists mailboxes
     Then the mailboxes should contain "shared" in "Delegated" namespace
-    And the mailboxes should contain "mailbox1" in "Delegated" namespace
\ No newline at end of file
+    And the mailboxes should contain "mailbox1" in "Delegated" namespace
+
+  Scenario: A sharee should be able to access a shared mailbox after it has been renamed by the owner
+    Given "alice@domain.tld" renames her mailbox "shared" to "mySharedMailbox"
+    When "bob@domain.tld" lists mailboxes
+    Then the mailboxes should contain "mySharedMailbox" in "Delegated" namespace
+
+  Scenario: A sharee should not be able to rename a shared mailbox
+    Given "bob@domain.tld" renames the mailbox, owned by "alice@domain.tld", "shared" to "mySharedMailbox"
+    When "alice@domain.tld" lists mailboxes
+    Then the mailboxes should contain "shared" in "Personal" namespace
+
+  Scenario: A user should not be able to rename an other user mailbox
+    Given "alice@domain.tld" has a mailbox "mySecrets"
+    And "bob@domain.tld" renames the mailbox, owned by "alice@domain.tld", "mySecrets" to "revealMySecrets"
+    When "alice@domain.tld" lists mailboxes
+    Then the mailboxes should contain "mySecrets" in "Personal" namespace
+
+  Scenario: A sharee should receive a not updated response when trying to rename a shared mailbox
+    Given "bob@domain.tld" renames the mailbox, owned by "alice@domain.tld", "shared" to "mySharedMailbox"
+    Then mailbox "shared" owned by "alice@domain.tld" is not updated


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


[3/8] james-project git commit: JAMES-2219 User should not be able to delete a mailbox he doesn't own

Posted by ad...@apache.org.
JAMES-2219 User should not be able to delete a mailbox he doesn't own


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

Branch: refs/heads/master
Commit: 472447d423b3e00348517987f4b790b8640008fa
Parents: 4897901
Author: Antoine Duprat <ad...@linagora.com>
Authored: Wed Nov 15 23:12:38 2017 +0100
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Nov 16 14:19:16 2017 +0100

----------------------------------------------------------------------
 .../mailbox/store/StoreMailboxManager.java      |  1 +
 .../cucumber/SetMailboxesMethodStepdefs.java    | 24 ++++++++++++++++++++
 .../resources/cucumber/GetMailboxes.feature     |  9 ++++++++
 3 files changed, 34 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/472447d4/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
index 6a72340..88c1aea 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
@@ -523,6 +523,7 @@ public class StoreMailboxManager implements MailboxManager {
     @Override
     public void deleteMailbox(final MailboxPath mailboxPath, final MailboxSession session) throws MailboxException {
         LOGGER.info("deleteMailbox " + mailboxPath);
+        assertIsOwner(session.getUser(), mailboxPath);
         final MailboxMapper mapper = mailboxSessionMapperFactory.getMailboxMapper(session);
 
         Mailbox mailbox = mapper.execute((Mapper.Transaction<Mailbox>) () -> {

http://git-wip-us.apache.org/repos/asf/james-project/blob/472447d4/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java
index 59c1fbd..9d35294 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java
@@ -166,6 +166,23 @@ public class SetMailboxesMethodStepdefs {
         renamingMailbox(userStepdefs.getConnectedUser(), actualMailboxName, newMailboxName);
     }
 
+    @When("^\"([^\"]*)\" deletes the mailbox \"([^\"]*)\" owned by \"([^\"]*)\"$")
+    public void deletesMailbox(String user, String mailboxName, String owner) throws Throwable {
+        Mailbox mailbox = mainStepdefs.mailboxProbe.getMailbox("#private", owner, mailboxName);
+        String mailboxId = mailbox.getMailboxId().serialize();
+        userStepdefs.connectUser(user);
+        String requestBody =
+                "[" +
+                    "  [ \"setMailboxes\"," +
+                    "    {" +
+                    "      \"destroy\": [ \"" + mailboxId + "\" ]" +
+                    "    }," +
+                    "    \"#0\"" +
+                    "  ]" +
+                    "]";
+        httpClient.post(requestBody);
+    }
+
     @When("^moving mailbox \"([^\"]*)\" to \"([^\"]*)\"$")
     public void movingMailbox(String actualMailboxPath, String newParentMailboxPath) throws Throwable {
         String username = userStepdefs.getConnectedUser();
@@ -229,4 +246,11 @@ public class SetMailboxesMethodStepdefs {
         assertThat(httpClient.jsonPath.<Map<String, String>>read("[0][1].notUpdated"))
             .containsOnlyKeys(mailbox.getMailboxId().serialize());
     }
+
+    @Then("^mailbox \"([^\"]*)\" owned by \"([^\"]*)\" is not destroyed$")
+    public void assertNotDestroyed(String mailboxName, String owner) throws Exception {
+        Mailbox mailbox = mainStepdefs.mailboxProbe.getMailbox(MailboxConstants.USER_NAMESPACE, owner, mailboxName);
+        assertThat(httpClient.jsonPath.<Map<String, String>>read("[0][1].notDestroyed"))
+            .containsOnlyKeys(mailbox.getMailboxId().serialize());
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/472447d4/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature
index 34278c3..9ec81e9 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature
@@ -277,3 +277,12 @@ Feature: GetMailboxes method
   Scenario: A sharee should receive a not updated response when trying to rename a shared mailbox
     Given "bob@domain.tld" renames the mailbox, owned by "alice@domain.tld", "shared" to "mySharedMailbox"
     Then mailbox "shared" owned by "alice@domain.tld" is not updated
+
+  Scenario: A sharee should receive a not destroyed response when trying to destroy a shared mailbox
+    Given "bob@domain.tld" deletes the mailbox "shared" owned by "alice@domain.tld"
+    Then mailbox "shared" owned by "alice@domain.tld" is not destroyed
+
+  Scenario: A sharee should not be able to delete a shared mailbox
+    Given "bob@domain.tld" deletes the mailbox "shared" owned by "alice@domain.tld"
+    When "alice@domain.tld" lists mailboxes
+    Then the mailboxes should contain "shared" in "Personal" namespace


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


[6/8] james-project git commit: JAMES-2219 Introduce OptionalUtils::or

Posted by ad...@apache.org.
JAMES-2219 Introduce OptionalUtils::or


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

Branch: refs/heads/master
Commit: 9c14a96c478ed453c8faa23c867971975c89994a
Parents: 6a9f1f9
Author: benwa <bt...@linagora.com>
Authored: Thu Nov 16 10:18:05 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Nov 16 14:19:17 2017 +0100

----------------------------------------------------------------------
 .../org/apache/james/util/OptionalUtils.java    |  6 ++++
 .../apache/james/util/OptionalUtilsTest.java    | 36 ++++++++++++++++++++
 2 files changed, 42 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/9c14a96c/server/container/util-java8/src/main/java/org/apache/james/util/OptionalUtils.java
----------------------------------------------------------------------
diff --git a/server/container/util-java8/src/main/java/org/apache/james/util/OptionalUtils.java b/server/container/util-java8/src/main/java/org/apache/james/util/OptionalUtils.java
index 000feb8..fc20117 100644
--- a/server/container/util-java8/src/main/java/org/apache/james/util/OptionalUtils.java
+++ b/server/container/util-java8/src/main/java/org/apache/james/util/OptionalUtils.java
@@ -39,4 +39,10 @@ public class OptionalUtils {
         return optional.map(Stream::of)
             .orElse(Stream.of());
     }
+
+    public static <T> Optional<T> or(Optional<T> optional1, Optional<T> optional2) {
+        return optional1.map(Optional::of)
+            .filter(Optional::isPresent)
+            .orElse(optional2);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/9c14a96c/server/container/util-java8/src/test/java/org/apache/james/util/OptionalUtilsTest.java
----------------------------------------------------------------------
diff --git a/server/container/util-java8/src/test/java/org/apache/james/util/OptionalUtilsTest.java b/server/container/util-java8/src/test/java/org/apache/james/util/OptionalUtilsTest.java
index 80a8684..4af7b23 100644
--- a/server/container/util-java8/src/test/java/org/apache/james/util/OptionalUtilsTest.java
+++ b/server/container/util-java8/src/test/java/org/apache/james/util/OptionalUtilsTest.java
@@ -83,4 +83,40 @@ public class OptionalUtilsTest {
                 .collect(Guavate.toImmutableList()))
             .containsExactly(value);
     }
+
+    @Test
+    public void orShouldReturnEmptyWhenBothEmpty() {
+        assertThat(
+            OptionalUtils.or(
+                Optional.empty(),
+                Optional.empty()))
+            .isEmpty();
+    }
+
+    @Test
+    public void orShouldReturnFirstValueWhenOnlyFirstValue() {
+        assertThat(
+            OptionalUtils.or(
+                Optional.of(18),
+                Optional.empty()))
+            .contains(18);
+    }
+
+    @Test
+    public void orShouldReturnSecondValueWhenOnlySecondValue() {
+        assertThat(
+            OptionalUtils.or(
+                Optional.empty(),
+                Optional.of(18)))
+            .contains(18);
+    }
+
+    @Test
+    public void orShouldReturnFirstValueWhenBothValues() {
+        assertThat(
+            OptionalUtils.or(
+                Optional.of(1),
+                Optional.of(2)))
+            .contains(1);
+    }
 }


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


[7/8] james-project git commit: JAMES-2219 Do only one store read when resolving parent path

Posted by ad...@apache.org.
JAMES-2219 Do only one store read when resolving parent path


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

Branch: refs/heads/master
Commit: 35663c29b523babc1ad96639644df8235694f4bc
Parents: 9c14a96
Author: benwa <bt...@linagora.com>
Authored: Thu Nov 16 10:18:56 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Nov 16 14:19:17 2017 +0100

----------------------------------------------------------------------
 .../jmap/methods/SetMailboxesCreationProcessor.java      | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/35663c29/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
index 39695b1..4dfa901 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
@@ -51,6 +51,7 @@ import org.apache.james.mailbox.model.MailboxId.Factory;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.metrics.api.TimeMetric;
+import org.apache.james.util.OptionalUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -189,15 +190,15 @@ public class SetMailboxesCreationProcessor implements SetMailboxesProcessor {
     }
 
     private MailboxPath getMailboxPath(Map<MailboxCreationId, MailboxId> creationIdsToCreatedMailboxId, MailboxSession mailboxSession, MailboxCreationId parentId) throws MailboxException {
-        Optional<MailboxId> mailboxId = getMailboxIdFromCreationId(parentId);
-        Optional<MailboxId> mailboxIdFromCreationId = Optional.ofNullable(creationIdsToCreatedMailboxId.get(parentId));
+        Optional<MailboxId> mailboxId = OptionalUtils.or(
+            readCreationIdAsMailboxId(parentId),
+            Optional.ofNullable(creationIdsToCreatedMailboxId.get(parentId)));
 
         return getMailboxPathFromId(mailboxId, mailboxSession)
-            .orElseGet(() -> getMailboxPathFromId(mailboxIdFromCreationId, mailboxSession)
-                .orElseThrow(() -> new MailboxParentNotFoundException(parentId)));
+                .orElseThrow(() -> new MailboxParentNotFoundException(parentId));
     }
 
-    private Optional<MailboxId> getMailboxIdFromCreationId(MailboxCreationId creationId) {
+    private Optional<MailboxId> readCreationIdAsMailboxId(MailboxCreationId creationId) {
         try {
             return Optional.of(mailboxIdFactory.fromString(creationId.getCreationId()));
         } catch (Exception e) {


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


[8/8] james-project git commit: JAMES-2219 Moving mailboxes and delegation is not compatible

Posted by ad...@apache.org.
JAMES-2219 Moving mailboxes and delegation is not compatible


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

Branch: refs/heads/master
Commit: 51cc52ae3f91160a333ecac9afba1e8ff4e16884
Parents: 35663c2
Author: benwa <bt...@linagora.com>
Authored: Thu Nov 16 11:40:23 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Nov 16 14:19:17 2017 +0100

----------------------------------------------------------------------
 .../cucumber/GetMailboxesMethodStepdefs.java    | 34 +++++++++-
 .../cucumber/SetMailboxesMethodStepdefs.java    | 39 +++++++++++
 .../resources/cucumber/GetMailboxes.feature     | 69 ++++++++++++++++++++
 .../methods/SetMailboxesUpdateProcessor.java    | 39 ++++++++---
 4 files changed, 172 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/51cc52ae/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMailboxesMethodStepdefs.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMailboxesMethodStepdefs.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMailboxesMethodStepdefs.java
index 73272cf..677ebfa 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMailboxesMethodStepdefs.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMailboxesMethodStepdefs.java
@@ -23,10 +23,14 @@ import static com.jayway.jsonpath.Criteria.where;
 import static com.jayway.jsonpath.Filter.filter;
 import static org.assertj.core.api.Assertions.assertThat;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import javax.inject.Inject;
 
+import org.apache.james.mailbox.model.MailboxConstants;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+
 import cucumber.api.java.en.Then;
 import cucumber.api.java.en.When;
 import cucumber.runtime.java.guice.ScenarioScoped;
@@ -39,11 +43,13 @@ public class GetMailboxesMethodStepdefs {
 
     private final UserStepdefs userStepdefs;
     private final HttpClient httpClient;
+    private final MainStepdefs mainStepdefs;
 
     @Inject
-    private GetMailboxesMethodStepdefs(UserStepdefs userStepdefs, HttpClient httpClient) {
+    private GetMailboxesMethodStepdefs(UserStepdefs userStepdefs, HttpClient httpClient, MainStepdefs mainStepdefs) {
         this.userStepdefs = userStepdefs;
         this.httpClient = httpClient;
+        this.mainStepdefs = mainStepdefs;
     }
 
     @When("^\"([^\"]*)\" lists mailboxes$")
@@ -71,6 +77,32 @@ public class GetMailboxesMethodStepdefs {
             .containsOnly(namespace);
     }
 
+    @Then("^the mailboxes should contain \"([^\"]*)\" in \"([^\"]*)\" namespace, with parent mailbox \"([^\"]*)\" of user \"([^\"]*)\"$")
+    public void assertMailboxesNames(String mailboxName, String namespace, String parentName, String parentOwner) throws Exception {
+        Mailbox parentMailbox = mainStepdefs.mailboxProbe.getMailbox(MailboxConstants.USER_NAMESPACE, parentOwner, parentName);
+        assertThat(httpClient.jsonPath.<List<String>>read(ARGUMENTS + ".list[*].name")).contains(mailboxName);
+        assertThat(httpClient.jsonPath.<List<String>>read(ARGUMENTS + ".list[?].namespace.type",
+                filter(where("name").is(mailboxName))))
+            .containsOnly(namespace);
+        assertThat(httpClient.jsonPath.<List<String>>read(ARGUMENTS + ".list[?].parentId",
+                filter(where("name").is(mailboxName))))
+            .containsOnly(parentMailbox.getMailboxId().serialize());
+    }
+
+    @Then("^the mailboxes should contain \"([^\"]*)\" in \"([^\"]*)\" namespace, with no parent mailbox$")
+    public void assertMailboxesNamesNoParent(String mailboxName, String namespace) throws Exception {
+        ArrayList<Object> noParent = new ArrayList<>();
+        noParent.add(null); // Trick to allow collection with null element matching
+
+        assertThat(httpClient.jsonPath.<List<String>>read(ARGUMENTS + ".list[*].name")).contains(mailboxName);
+        assertThat(httpClient.jsonPath.<List<String>>read(ARGUMENTS + ".list[?].namespace.type",
+                filter(where("name").is(mailboxName))))
+            .containsOnly(namespace);
+        assertThat(httpClient.jsonPath.<List<String>>read(ARGUMENTS + ".list[?].parentId",
+                filter(where("name").is(mailboxName))))
+            .isEqualTo(noParent);
+    }
+
     @Then("^the mailboxes should not contain \"([^\"]*)\"$")
     public void assertNoMailboxesNames(String mailboxName) throws Exception {
         assertThat(httpClient.jsonPath.<List<String>>read(ARGUMENTS + ".list[*].name")).doesNotContain(mailboxName);

http://git-wip-us.apache.org/repos/asf/james-project/blob/51cc52ae/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java
index ef22490..96c1ad1 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMailboxesMethodStepdefs.java
@@ -137,6 +137,45 @@ public class SetMailboxesMethodStepdefs {
         renamingMailbox(mailbox, newMailboxName);
     }
 
+    @When("^\"([^\"]*)\" moves the mailbox \"([^\"]*)\" owned by \"([^\"]*)\", into mailbox \"([^\"]*)\" owned by \"([^\"]*)\"$")
+    public void movingMailbox(String user, String mailboxName, String mailboxOwner, String newParentName, String newParentOwner) throws Throwable {
+        Mailbox mailbox = mainStepdefs.mailboxProbe.getMailbox("#private", mailboxOwner, mailboxName);
+        Mailbox newParent = mainStepdefs.mailboxProbe.getMailbox("#private", newParentOwner, newParentName);
+        String requestBody =
+            "[" +
+                "  [ \"setMailboxes\"," +
+                "    {" +
+                "      \"update\": {" +
+                "        \"" + mailbox.getMailboxId().serialize() + "\" : {" +
+                "          \"parentId\" : \"" + newParent.getMailboxId().serialize() + "\"" +
+                "        }" +
+                "      }" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+        userStepdefs.execWithUser(user, () -> httpClient.post(requestBody));
+    }
+
+    @When("^\"([^\"]*)\" moves the mailbox \"([^\"]*)\" owned by \"([^\"]*)\" as top level mailbox$")
+    public void movingMailboxAsTopLevel(String user, String mailboxName, String mailboxOwner) throws Throwable {
+        Mailbox mailbox = mainStepdefs.mailboxProbe.getMailbox("#private", mailboxOwner, mailboxName);
+        String requestBody =
+            "[" +
+                "  [ \"setMailboxes\"," +
+                "    {" +
+                "      \"update\": {" +
+                "        \"" + mailbox.getMailboxId().serialize() + "\" : {" +
+                "          \"parentId\" : null" +
+                "        }" +
+                "      }" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+        userStepdefs.execWithUser(user, () -> httpClient.post(requestBody));
+    }
+
     @When("^\"([^\"]*)\" creates mailbox \"([^\"]*)\" with creationId \"([^\"]*)\" in mailbox \"([^\"]*)\" owned by \"([^\"]*)\"$")
     public void createChildMailbox(String user, String mailboxName, String creationId, String parentMailboxName, String parentOwner) throws Throwable {
         Mailbox parentMailbox = mainStepdefs.mailboxProbe.getMailbox(MailboxConstants.USER_NAMESPACE, parentOwner, parentMailboxName);

http://git-wip-us.apache.org/repos/asf/james-project/blob/51cc52ae/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature
index 9d5dbb0..36ff9b4 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/GetMailboxes.feature
@@ -295,3 +295,72 @@ Feature: GetMailboxes method
   Scenario: A sharee should receive a not created response when trying to create a shared mailbox child
     When "bob@domain.tld" creates mailbox "sharedChild" with creationId "c-01" in mailbox "shared" owned by "alice@domain.tld"
     Then mailbox with creationId "c-01" is not created
+
+  Scenario: A sharee moving a delegated mailbox as top level should be rejected
+    Given "alice@domain.tld" has a mailbox "shared.sharedChild"
+    And "alice@domain.tld" shares her mailbox "shared.sharedChild" with "bob@domain.tld" with "aeilrwt" rights
+    When "bob@domain.tld" moves the mailbox "shared.sharedChild" owned by "alice@domain.tld" as top level mailbox
+    Then mailbox "shared.sharedChild" owned by "alice@domain.tld" is not updated
+
+  Scenario: A sharee moving a delegated mailbox as top level should not move mailbox
+    Given "alice@domain.tld" has a mailbox "shared.sharedChild"
+    And "alice@domain.tld" shares her mailbox "shared.sharedChild" with "bob@domain.tld" with "aeilrwt" rights
+    When "bob@domain.tld" moves the mailbox "shared.sharedChild" owned by "alice@domain.tld" as top level mailbox
+    Then "alice@domain.tld" lists mailboxes
+    And the mailboxes should contain "sharedChild" in "Personal" namespace, with parent mailbox "shared" of user "alice@domain.tld"
+
+  Scenario: A sharee moving a delegated mailbox into sharer mailboxes should be rejected
+    Given "alice@domain.tld" has a mailbox "shared.sharedChild"
+    And "alice@domain.tld" has a mailbox "otherShared"
+    And "alice@domain.tld" shares her mailbox "shared.sharedChild" with "bob@domain.tld" with "aeilrwt" rights
+    And "alice@domain.tld" shares her mailbox "otherShared" with "bob@domain.tld" with "aeilrwt" rights
+    When "bob@domain.tld" moves the mailbox "shared.sharedChild" owned by "alice@domain.tld", into mailbox "otherShared" owned by "alice@domain.tld"
+    Then mailbox "shared.sharedChild" owned by "alice@domain.tld" is not updated
+
+  Scenario: A sharee moving a delegated mailbox into another delegated mailbox should not move mailbox
+    Given "alice@domain.tld" has a mailbox "shared.sharedChild"
+    And "alice@domain.tld" has a mailbox "otherShared"
+    And "alice@domain.tld" shares her mailbox "shared.sharedChild" with "bob@domain.tld" with "aeilrwt" rights
+    And "alice@domain.tld" shares her mailbox "otherShared" with "bob@domain.tld" with "aeilrwt" rights
+    When "bob@domain.tld" moves the mailbox "shared.sharedChild" owned by "alice@domain.tld", into mailbox "otherShared" owned by "alice@domain.tld"
+    Then "alice@domain.tld" lists mailboxes
+    And the mailboxes should contain "sharedChild" in "Personal" namespace, with parent mailbox "shared" of user "alice@domain.tld"
+
+  Scenario: A sharee moving a delegated mailbox to his mailboxes should be rejected
+    Given "alice@domain.tld" has a mailbox "shared.sharedChild"
+    And "bob@domain.tld" has a mailbox "other"
+    And "alice@domain.tld" shares her mailbox "shared.sharedChild" with "bob@domain.tld" with "aeilrwt" rights
+    When "bob@domain.tld" moves the mailbox "shared.sharedChild" owned by "alice@domain.tld", into mailbox "other" owned by "bob@domain.tld"
+    Then mailbox "shared.sharedChild" owned by "alice@domain.tld" is not updated
+
+  Scenario: A sharee moving a delegated mailbox into his mailbox should not move mailbox
+    Given "alice@domain.tld" has a mailbox "shared.sharedChild"
+    And "bob@domain.tld" has a mailbox "other"
+    And "alice@domain.tld" shares her mailbox "shared.sharedChild" with "bob@domain.tld" with "aeilrwt" rights
+    When "bob@domain.tld" moves the mailbox "shared.sharedChild" owned by "alice@domain.tld", into mailbox "other" owned by "bob@domain.tld"
+    Then "alice@domain.tld" lists mailboxes
+    And the mailboxes should contain "sharedChild" in "Personal" namespace, with parent mailbox "shared" of user "alice@domain.tld"
+
+  Scenario: A sharee should be able to retrieve a mailbox after sharer moved it as a top level mailbox
+    Given "alice@domain.tld" has a mailbox "shared.sharedChild"
+    And "alice@domain.tld" shares her mailbox "shared.sharedChild" with "bob@domain.tld" with "aeilrwt" rights
+    When "alice@domain.tld" moves the mailbox "shared.sharedChild" owned by "alice@domain.tld" as top level mailbox
+    Then "bob@domain.tld" lists mailboxes
+    And the mailboxes should contain "sharedChild" in "Delegated" namespace, with no parent mailbox
+
+  Scenario: A sharee should be able to retrieve a mailbox after sharer moved it into another mailbox
+    Given "alice@domain.tld" has a mailbox "shared.sharedChild"
+    And "alice@domain.tld" has a mailbox "other"
+    And "alice@domain.tld" shares her mailbox "shared.sharedChild" with "bob@domain.tld" with "aeilrwt" rights
+    When "alice@domain.tld" moves the mailbox "shared.sharedChild" owned by "alice@domain.tld", into mailbox "other" owned by "alice@domain.tld"
+    Then "bob@domain.tld" lists mailboxes
+    And the mailboxes should contain "sharedChild" in "Delegated" namespace, with parent mailbox "other" of user "alice@domain.tld"
+
+  Scenario: A sharer can not move its mailboxes to someone else delegated mailboxes
+    Given "alice@domain.tld" has a mailbox "shared.sharedChild"
+    And "bob@domain.tld" has a mailbox "other"
+    And "alice@domain.tld" shares her mailbox "shared.sharedChild" with "bob@domain.tld" with "aeilrwt" rights
+    And "bob@domain.tld" shares her mailbox "other" with "alice@domain.tld" with "aeilrwt" rights
+    When "alice@domain.tld" moves the mailbox "shared.sharedChild" owned by "alice@domain.tld", into mailbox "other" owned by "bob@domain.tld"
+    Then mailbox "shared.sharedChild" owned by "alice@domain.tld" is not updated
+

http://git-wip-us.apache.org/repos/asf/james-project/blob/51cc52ae/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesUpdateProcessor.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesUpdateProcessor.java
index 645182e..b9b554d 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesUpdateProcessor.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesUpdateProcessor.java
@@ -26,6 +26,7 @@ import java.util.Optional;
 import javax.inject.Inject;
 
 import org.apache.james.jmap.exceptions.MailboxHasChildException;
+import org.apache.james.jmap.exceptions.MailboxNotOwnedException;
 import org.apache.james.jmap.exceptions.MailboxParentNotFoundException;
 import org.apache.james.jmap.exceptions.SystemMailboxNotUpdatableException;
 import org.apache.james.jmap.model.MailboxFactory;
@@ -40,6 +41,7 @@ import org.apache.james.jmap.model.mailbox.Role;
 import org.apache.james.jmap.utils.MailboxUtils;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.SubscriptionManager;
 import org.apache.james.mailbox.exception.DifferentDomainException;
 import org.apache.james.mailbox.exception.MailboxException;
@@ -130,6 +132,11 @@ public class SetMailboxesUpdateProcessor implements SetMailboxesProcessor {
                     .type("invalidArguments")
                     .description("Cannot update a parent mailbox.")
                     .build());
+        } catch (MailboxNotOwnedException e) {
+            responseBuilder.notUpdated(mailboxId, SetError.builder()
+                    .type("invalidArguments")
+                    .description("Parent mailbox is not owned.")
+                    .build());
         } catch (MailboxExistsException e) {
             responseBuilder.notUpdated(mailboxId, SetError.builder()
                     .type("invalidArguments")
@@ -188,20 +195,36 @@ public class SetMailboxesUpdateProcessor implements SetMailboxesProcessor {
     }
 
     private void validateParent(Mailbox mailbox, MailboxUpdateRequest updateRequest, MailboxSession mailboxSession) throws MailboxException, MailboxHasChildException {
-
         if (isParentIdInRequest(updateRequest)) {
             MailboxId newParentId = updateRequest.getParentId().get();
-            try {
-                mailboxManager.getMailbox(newParentId, mailboxSession);
-            } catch (MailboxNotFoundException e) {
-                throw new MailboxParentNotFoundException(newParentId);
-            }
-            if (mustChangeParent(mailbox.getParentId(), newParentId) && mailboxUtils.hasChildren(mailbox.getId(), mailboxSession)) {
-                throw new MailboxHasChildException();
+            MessageManager parent = retrieveParent(mailboxSession, newParentId);
+            if (mustChangeParent(mailbox.getParentId(), newParentId)) {
+                assertNoChildren(mailbox, mailboxSession);
+                assertOwned(mailboxSession, parent);
             }
         }
     }
 
+    private void assertNoChildren(Mailbox mailbox, MailboxSession mailboxSession) throws MailboxException, MailboxHasChildException {
+        if (mailboxUtils.hasChildren(mailbox.getId(), mailboxSession)) {
+            throw new MailboxHasChildException();
+        }
+    }
+
+    private void assertOwned(MailboxSession mailboxSession, MessageManager parent) throws MailboxException {
+        if (!parent.getMailboxPath().belongsTo(mailboxSession)) {
+            throw new MailboxNotOwnedException();
+        }
+    }
+
+    private MessageManager retrieveParent(MailboxSession mailboxSession, MailboxId newParentId) throws MailboxException {
+        try {
+            return mailboxManager.getMailbox(newParentId, mailboxSession);
+        } catch (MailboxNotFoundException e) {
+            throw new MailboxParentNotFoundException(newParentId);
+        }
+    }
+
     private boolean isParentIdInRequest(MailboxUpdateRequest updateRequest) {
         return updateRequest.getParentId() != null
                 && updateRequest.getParentId().isPresent();


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


[2/8] james-project git commit: JAMES-2219 More functional style for getMailboxNameFromId

Posted by ad...@apache.org.
JAMES-2219 More functional style for getMailboxNameFromId


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

Branch: refs/heads/master
Commit: 23055a3ff2d836a961b12a6cfef9031ee35f48a0
Parents: 472447d
Author: benwa <bt...@linagora.com>
Authored: Thu Nov 16 09:25:45 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Nov 16 14:19:16 2017 +0100

----------------------------------------------------------------------
 .../methods/SetMailboxesCreationProcessor.java  | 30 ++++++++++----------
 1 file changed, 15 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/23055a3f/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
index d9e4f1f..74f4f02 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
@@ -54,7 +54,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.github.fge.lambdas.Throwing;
-import com.github.fge.lambdas.functions.ThrowingFunction;
+import com.github.fge.lambdas.functions.FunctionChainer;
 import com.google.common.annotations.VisibleForTesting;
 
 public class SetMailboxesCreationProcessor implements SetMailboxesProcessor {
@@ -168,7 +168,8 @@ public class SetMailboxesCreationProcessor implements SetMailboxesProcessor {
             MailboxCreationId parentId = mailboxRequest.getParentId().get();
             String parentName = getMailboxNameFromId(parentId, mailboxSession)
                     .orElseGet(Throwing.supplier(() ->
-                        getMailboxNameFromId(creationIdsToCreatedMailboxId.get(parentId), mailboxSession)
+                        getMailboxNameFromId(Optional.ofNullable(creationIdsToCreatedMailboxId.get(parentId)),
+                            mailboxSession)
                             .orElseThrow(() -> new MailboxParentNotFoundException(parentId))
                     ));
 
@@ -178,10 +179,8 @@ public class SetMailboxesCreationProcessor implements SetMailboxesProcessor {
         return MailboxPath.forUser(mailboxSession.getUser().getUserName(), mailboxRequest.getName());
     }
 
-    private Optional<String> getMailboxNameFromId(MailboxCreationId creationId, MailboxSession mailboxSession) {
-        ThrowingFunction<? super MailboxId, Optional<String>> toName = parentId -> getMailboxNameFromId(parentId, mailboxSession);
-        return getMailboxIdFromCreationId(creationId)
-                .flatMap(Throwing.function(toName).sneakyThrow());
+    private Optional<String> getMailboxNameFromId(MailboxCreationId creationId, MailboxSession mailboxSession) throws MailboxException {
+        return getMailboxNameFromId(getMailboxIdFromCreationId(creationId), mailboxSession);
     }
 
     private Optional<MailboxId> getMailboxIdFromCreationId(MailboxCreationId creationId) {
@@ -193,15 +192,16 @@ public class SetMailboxesCreationProcessor implements SetMailboxesProcessor {
     }
 
     @VisibleForTesting
-    Optional<String> getMailboxNameFromId(MailboxId mailboxId, MailboxSession mailboxSession) throws MailboxException {
-        if (mailboxId == null) {
-            return Optional.empty();
-        }
-        try {
-            return Optional.of(mailboxManager.getMailbox(mailboxId, mailboxSession).getMailboxPath().getName());
-        } catch (MailboxNotFoundException e) {
-            return Optional.empty();
-        }
+    Optional<String> getMailboxNameFromId(Optional<MailboxId> mailboxId, MailboxSession mailboxSession) throws MailboxException {
+        FunctionChainer<MailboxId, Optional<String>> fromMailboxIdToMailboxPath = Throwing.function(id -> {
+            try {
+                return Optional.of(mailboxManager.getMailbox(id, mailboxSession).getMailboxPath().getName());
+            } catch (MailboxNotFoundException e) {
+                return Optional.empty();
+            }
+        });
+        return mailboxId
+            .flatMap(fromMailboxIdToMailboxPath.sneakyThrow());
     }
 
 }


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


[4/8] james-project git commit: JAMES-2219 Refactor Parent handling while creating mailbox

Posted by ad...@apache.org.
JAMES-2219 Refactor Parent handling while creating mailbox

 - Avoid needless exception declaration (avoid function wrapping)
 - Makes finding functions returns MailboxPath (for future ownership enforcing)
 - Review function extraction logic, and rely more on variables


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

Branch: refs/heads/master
Commit: f656a9ec17fed9967169974aa0aa5adb2e95de79
Parents: 23055a3
Author: benwa <bt...@linagora.com>
Authored: Thu Nov 16 09:54:19 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Thu Nov 16 14:19:16 2017 +0100

----------------------------------------------------------------------
 .../methods/SetMailboxesCreationProcessor.java  | 28 ++++++++++----------
 1 file changed, 14 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/f656a9ec/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
index 74f4f02..0f71d2e 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMailboxesCreationProcessor.java
@@ -113,7 +113,7 @@ public class SetMailboxesCreationProcessor implements SetMailboxesProcessor {
             Map<MailboxCreationId, MailboxId> creationIdsToCreatedMailboxId, SetMailboxesResponse.Builder builder) {
         try {
             ensureValidMailboxName(mailboxRequest, mailboxSession);
-            MailboxPath mailboxPath = getMailboxPath(mailboxRequest, creationIdsToCreatedMailboxId, mailboxSession);
+            MailboxPath mailboxPath = computeMailboxPath(mailboxRequest, creationIdsToCreatedMailboxId, mailboxSession);
             Optional<MailboxId> mailboxId = mailboxManager.createMailbox(mailboxPath, mailboxSession);
             Optional<Mailbox> mailbox = mailboxId.flatMap(id -> mailboxFactory.builder()
                     .id(id)
@@ -163,24 +163,24 @@ public class SetMailboxesCreationProcessor implements SetMailboxesProcessor {
         }
     }
 
-    private MailboxPath getMailboxPath(MailboxCreateRequest mailboxRequest, Map<MailboxCreationId, MailboxId> creationIdsToCreatedMailboxId, MailboxSession mailboxSession) throws MailboxException {
+    private MailboxPath computeMailboxPath(MailboxCreateRequest mailboxRequest, Map<MailboxCreationId, MailboxId> creationIdsToCreatedMailboxId, MailboxSession mailboxSession) throws MailboxException {
         if (mailboxRequest.getParentId().isPresent()) {
             MailboxCreationId parentId = mailboxRequest.getParentId().get();
-            String parentName = getMailboxNameFromId(parentId, mailboxSession)
-                    .orElseGet(Throwing.supplier(() ->
-                        getMailboxNameFromId(Optional.ofNullable(creationIdsToCreatedMailboxId.get(parentId)),
-                            mailboxSession)
-                            .orElseThrow(() -> new MailboxParentNotFoundException(parentId))
-                    ));
+            MailboxPath parentPath = getMailboxPath(creationIdsToCreatedMailboxId, mailboxSession, parentId);
 
             return MailboxPath.forUser(mailboxSession.getUser().getUserName(),
-                    parentName + mailboxSession.getPathDelimiter() + mailboxRequest.getName());
+                parentPath.getName() + mailboxSession.getPathDelimiter() + mailboxRequest.getName());
         }
         return MailboxPath.forUser(mailboxSession.getUser().getUserName(), mailboxRequest.getName());
     }
 
-    private Optional<String> getMailboxNameFromId(MailboxCreationId creationId, MailboxSession mailboxSession) throws MailboxException {
-        return getMailboxNameFromId(getMailboxIdFromCreationId(creationId), mailboxSession);
+    private MailboxPath getMailboxPath(Map<MailboxCreationId, MailboxId> creationIdsToCreatedMailboxId, MailboxSession mailboxSession, MailboxCreationId parentId) throws MailboxException {
+        Optional<MailboxId> mailboxId = getMailboxIdFromCreationId(parentId);
+        Optional<MailboxId> mailboxIdFromCreationId = Optional.ofNullable(creationIdsToCreatedMailboxId.get(parentId));
+
+        return getMailboxPathFromId(mailboxId, mailboxSession)
+            .orElseGet(() -> getMailboxPathFromId(mailboxIdFromCreationId, mailboxSession)
+                .orElseThrow(() -> new MailboxParentNotFoundException(parentId)));
     }
 
     private Optional<MailboxId> getMailboxIdFromCreationId(MailboxCreationId creationId) {
@@ -192,10 +192,10 @@ public class SetMailboxesCreationProcessor implements SetMailboxesProcessor {
     }
 
     @VisibleForTesting
-    Optional<String> getMailboxNameFromId(Optional<MailboxId> mailboxId, MailboxSession mailboxSession) throws MailboxException {
-        FunctionChainer<MailboxId, Optional<String>> fromMailboxIdToMailboxPath = Throwing.function(id -> {
+    Optional<MailboxPath> getMailboxPathFromId(Optional<MailboxId> mailboxId, MailboxSession mailboxSession) {
+        FunctionChainer<MailboxId, Optional<MailboxPath>> fromMailboxIdToMailboxPath = Throwing.function(id -> {
             try {
-                return Optional.of(mailboxManager.getMailbox(id, mailboxSession).getMailboxPath().getName());
+                return Optional.of(mailboxManager.getMailbox(id, mailboxSession).getMailboxPath());
             } catch (MailboxNotFoundException e) {
                 return Optional.empty();
             }


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