MAILBOX-310 Mapper should store the ACL by user/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/78f208c4
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/78f208c4
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/78f208c4

Branch: refs/heads/master
Commit: 78f208c4af9ba198e13eb8dd1f5a32772aa6c4ac
Parents: e55b371
Author: benwa <btell...@linagora.com>
Authored: Wed Oct 4 15:43:08 2017 +0700
Committer: Matthieu Baechler <matth...@apache.org>
Committed: Thu Oct 5 09:48:53 2017 +0200

----------------------------------------------------------------------
 .../mailbox/caching/CachingMailboxMapper.java   |   6 +
 .../CassandraMailboxSessionMapperFactory.java   |   6 +-
 .../cassandra/mail/CassandraACLMapper.java      |  39 +++--
 .../cassandra/mail/CassandraMailboxMapper.java  |  24 ++-
 .../CassandraSubscriptionManagerTest.java       |   3 +
 ...estCassandraMailboxSessionMapperFactory.java |   6 +-
 .../cassandra/mail/CassandraACLMapperTest.java  |   7 +-
 .../CassandraMailboxMapperConcurrencyTest.java  |   7 +-
 .../mail/CassandraMailboxMapperTest.java        |   7 +-
 .../mail/CassandraModSeqProviderTest.java       |   3 +
 .../mail/CassandraUidProviderTest.java          |   3 +
 .../mailbox/hbase/mail/HBaseMailboxMapper.java  |   8 +
 .../mailbox/jcr/mail/JCRMailboxMapper.java      |   8 +
 .../mailbox/jpa/mail/JPAMailboxMapper.java      |   7 +
 .../jpa/mail/TransactionalMailboxMapper.java    |   6 +
 .../maildir/mail/MaildirMailboxMapper.java      |   8 +
 .../inmemory/mail/InMemoryMailboxMapper.java    |  20 +++
 .../james/mailbox/store/mail/MailboxMapper.java |  10 ++
 .../store/TestMailboxSessionMapperFactory.java  |   6 +
 .../store/mail/model/MailboxMapperACLTest.java  | 153 +++++++++++++++++++
 .../modules/mailbox/CassandraMailboxModule.java |   2 +
 21 files changed, 319 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/caching/src/main/java/org/apache/james/mailbox/caching/CachingMailboxMapper.java
----------------------------------------------------------------------
diff --git 
a/mailbox/caching/src/main/java/org/apache/james/mailbox/caching/CachingMailboxMapper.java
 
b/mailbox/caching/src/main/java/org/apache/james/mailbox/caching/CachingMailboxMapper.java
index 8a6179a..fe67704 100644
--- 
a/mailbox/caching/src/main/java/org/apache/james/mailbox/caching/CachingMailboxMapper.java
+++ 
b/mailbox/caching/src/main/java/org/apache/james/mailbox/caching/CachingMailboxMapper.java
@@ -24,6 +24,7 @@ import java.util.List;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MailboxNotFoundException;
 import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MailboxACL.Right;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
@@ -120,4 +121,9 @@ public class CachingMailboxMapper implements MailboxMapper {
                cache.invalidate(mailbox);
        }
 
+    @Override
+    public List<Mailbox> findMailboxes(String userName, Right right) throws 
MailboxException {
+        return underlying.findMailboxes(userName, right);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
index d23d46c..78e2daf 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMailboxSessionMapperFactory.java
@@ -48,6 +48,7 @@ import 
org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageMapper;
 import org.apache.james.mailbox.cassandra.mail.CassandraModSeqProvider;
 import org.apache.james.mailbox.cassandra.mail.CassandraUidProvider;
+import org.apache.james.mailbox.cassandra.mail.CassandraUserMailboxRightsDAO;
 import org.apache.james.mailbox.cassandra.user.CassandraSubscriptionMapper;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
@@ -88,6 +89,7 @@ public class CassandraMailboxSessionMapperFactory extends 
MailboxSessionMapperFa
     private final CassandraAttachmentMessageIdDAO attachmentMessageIdDAO;
     private final CassandraAttachmentOwnerDAO ownerDAO;
     private final CassandraACLMapper aclMapper;
+    private final CassandraUserMailboxRightsDAO userMailboxRightsDAO;
     private final CassandraUtils cassandraUtils;
     private final CassandraConfiguration cassandraConfiguration;
 
@@ -100,6 +102,7 @@ public class CassandraMailboxSessionMapperFactory extends 
MailboxSessionMapperFa
                                                 CassandraAttachmentDAO 
attachmentDAO, CassandraAttachmentDAOV2 attachmentDAOV2, 
CassandraDeletedMessageDAO deletedMessageDAO,
                                                 CassandraBlobsDAO blobsDAO, 
CassandraAttachmentMessageIdDAO attachmentMessageIdDAO,
                                                 CassandraAttachmentOwnerDAO 
ownerDAO, CassandraACLMapper aclMapper,
+                                                CassandraUserMailboxRightsDAO 
userMailboxRightsDAO,
                                                 CassandraUtils cassandraUtils, 
CassandraConfiguration cassandraConfiguration) {
         this.uidProvider = uidProvider;
         this.modSeqProvider = modSeqProvider;
@@ -119,6 +122,7 @@ public class CassandraMailboxSessionMapperFactory extends 
MailboxSessionMapperFa
         this.blobsDAO = blobsDAO;
         this.attachmentMessageIdDAO = attachmentMessageIdDAO;
         this.aclMapper = aclMapper;
+        this.userMailboxRightsDAO = userMailboxRightsDAO;
         this.cassandraUtils = cassandraUtils;
         this.ownerDAO = ownerDAO;
         this.cassandraConfiguration = cassandraConfiguration;
@@ -159,7 +163,7 @@ public class CassandraMailboxSessionMapperFactory extends 
MailboxSessionMapperFa
 
     @Override
     public MailboxMapper createMailboxMapper(MailboxSession mailboxSession) {
-        return new CassandraMailboxMapper(mailboxDAO, mailboxPathDAO, 
aclMapper, cassandraConfiguration);
+        return new CassandraMailboxMapper(mailboxDAO, mailboxPathDAO, 
userMailboxRightsDAO, aclMapper, cassandraConfiguration);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java
index 32a2c5d..cd92520 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapper.java
@@ -37,6 +37,7 @@ import 
org.apache.james.backends.cassandra.init.CassandraConfiguration;
 import org.apache.james.backends.cassandra.utils.CassandraAsyncExecutor;
 import org.apache.james.backends.cassandra.utils.FunctionRunnerWithRetry;
 import 
org.apache.james.backends.cassandra.utils.LightweightTransactionException;
+import org.apache.james.mailbox.acl.PositiveUserACLChanged;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.table.CassandraACLTable;
 import org.apache.james.mailbox.cassandra.table.CassandraMailboxTable;
@@ -67,22 +68,24 @@ public class CassandraACLMapper {
     private final CassandraAsyncExecutor executor;
     private final int maxRetry;
     private final CodeInjector codeInjector;
+    private final CassandraUserMailboxRightsDAO userMailboxRightsDAO;
     private final PreparedStatement conditionalInsertStatement;
     private final PreparedStatement conditionalUpdateStatement;
     private final PreparedStatement readStatement;
 
     @Inject
-    public CassandraACLMapper(Session session, CassandraConfiguration 
cassandraConfiguration) {
-        this(session, cassandraConfiguration, () -> {});
+    public CassandraACLMapper(Session session, CassandraUserMailboxRightsDAO 
userMailboxRightsDAO, CassandraConfiguration cassandraConfiguration) {
+        this(session, userMailboxRightsDAO, cassandraConfiguration, () -> {});
     }
 
-    public CassandraACLMapper(Session session, CassandraConfiguration 
cassandraConfiguration, CodeInjector codeInjector) {
+    public CassandraACLMapper(Session session, CassandraUserMailboxRightsDAO 
userMailboxRightsDAO, CassandraConfiguration cassandraConfiguration, 
CodeInjector codeInjector) {
         this.executor = new CassandraAsyncExecutor(session);
         this.maxRetry = cassandraConfiguration.getAclMaxRetry();
         this.codeInjector = codeInjector;
         this.conditionalInsertStatement = prepareConditionalInsert(session);
         this.conditionalUpdateStatement = prepareConditionalUpdate(session);
         this.readStatement = prepareReadStatement(session);
+        this.userMailboxRightsDAO = userMailboxRightsDAO;
     }
 
     private PreparedStatement prepareConditionalInsert(Session session) {
@@ -126,25 +129,31 @@ public class CassandraACLMapper {
     public void updateACL(CassandraId cassandraId, MailboxACL.ACLCommand 
command) throws MailboxException {
         MailboxACL replacement = MailboxACL.EMPTY.apply(command);
 
-        updateAcl(cassandraId, aclWithVersion -> 
aclWithVersion.apply(command), replacement);
+        PositiveUserACLChanged positiveUserAclChanged = updateAcl(cassandraId, 
aclWithVersion -> aclWithVersion.apply(command), replacement);
+
+        userMailboxRightsDAO.update(cassandraId, 
positiveUserAclChanged).join();
     }
 
     public void setACL(CassandraId cassandraId, MailboxACL mailboxACL) throws 
MailboxException {
-        updateAcl(cassandraId,
+        PositiveUserACLChanged positiveUserAclChanged = updateAcl(cassandraId,
             acl -> new ACLWithVersion(acl.version, mailboxACL),
             mailboxACL);
+
+        userMailboxRightsDAO.update(cassandraId, 
positiveUserAclChanged).join();
     }
 
-    private void updateAcl(CassandraId cassandraId, Function<ACLWithVersion, 
ACLWithVersion> aclTransformation, MailboxACL replacement) throws 
MailboxException {
+    private PositiveUserACLChanged updateAcl(CassandraId cassandraId, 
Function<ACLWithVersion, ACLWithVersion> aclTransformation, MailboxACL 
replacement) throws MailboxException {
         try {
-            new FunctionRunnerWithRetry(maxRetry)
-                .execute(
+            return new FunctionRunnerWithRetry(maxRetry)
+                .executeAndRetrieveObject(
                     () -> {
                         codeInjector.inject();
                         return getAclWithVersion(cassandraId)
-                            .map(aclTransformation)
-                            .map(aclWithVersion -> 
updateStoredACL(cassandraId, aclWithVersion))
-                            .orElseGet(() -> insertACL(cassandraId, 
replacement));
+                            .map(aclWithVersion ->
+                                updateStoredACL(cassandraId, 
aclTransformation.apply(aclWithVersion))
+                                    .map(newACL -> new 
PositiveUserACLChanged(aclWithVersion.mailboxACL, newACL)))
+                            .orElseGet(() -> insertACL(cassandraId, 
replacement)
+                                .map(newACL -> new 
PositiveUserACLChanged(MailboxACL.EMPTY, newACL)));
                     });
         } catch (LightweightTransactionException e) {
             throw new MailboxException("Exception during lightweight 
transaction", e);
@@ -157,7 +166,7 @@ public class CassandraACLMapper {
                 .setUUID(CassandraACLTable.ID, cassandraId.asUuid()));
     }
 
-    private boolean updateStoredACL(CassandraId cassandraId, ACLWithVersion 
aclWithVersion) {
+    private Optional<MailboxACL> updateStoredACL(CassandraId cassandraId, 
ACLWithVersion aclWithVersion) {
         try {
             return executor.executeReturnApplied(
                 conditionalUpdateStatement.bind()
@@ -165,18 +174,22 @@ public class CassandraACLMapper {
                     .setString(CassandraACLTable.ACL,  
MailboxACLJsonConverter.toJson(aclWithVersion.mailboxACL))
                     .setLong(CassandraACLTable.VERSION, aclWithVersion.version 
+ 1)
                     .setLong(OLD_VERSION, aclWithVersion.version))
+                .thenApply(Optional::of)
+                .thenApply(optional -> optional.filter(b -> b).map(any -> 
aclWithVersion.mailboxACL))
                 .join();
         } catch (JsonProcessingException exception) {
             throw Throwables.propagate(exception);
         }
     }
 
-    private boolean insertACL(CassandraId cassandraId, MailboxACL acl) {
+    private Optional<MailboxACL> insertACL(CassandraId cassandraId, MailboxACL 
acl) {
         try {
             return executor.executeReturnApplied(
                 conditionalInsertStatement.bind()
                     .setUUID(CassandraACLTable.ID, cassandraId.asUuid())
                     .setString(CassandraACLTable.ACL, 
MailboxACLJsonConverter.toJson(acl)))
+                .thenApply(Optional::of)
+                .thenApply(optional -> optional.filter(b -> b).map(any -> acl))
                 .join();
         } catch (JsonProcessingException exception) {
             throw Throwables.propagate(exception);

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
index f76c308..498524b 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapper.java
@@ -21,12 +21,14 @@ package org.apache.james.mailbox.cassandra.mail;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.StringTokenizer;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionException;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import javax.inject.Inject;
 
@@ -38,6 +40,7 @@ import 
org.apache.james.mailbox.exception.MailboxExistsException;
 import org.apache.james.mailbox.exception.MailboxNotFoundException;
 import org.apache.james.mailbox.exception.TooLongMailboxNameException;
 import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MailboxACL.Right;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
@@ -50,6 +53,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.datastax.driver.core.exceptions.InvalidQueryException;
+import com.github.fge.lambdas.Throwing;
 import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Preconditions;
 
@@ -63,11 +67,13 @@ public class CassandraMailboxMapper implements 
MailboxMapper {
     private final CassandraMailboxPathDAO mailboxPathDAO;
     private final CassandraMailboxDAO mailboxDAO;
     private final CassandraACLMapper cassandraACLMapper;
+    private final CassandraUserMailboxRightsDAO userMailboxRightsDAO;
 
     @Inject
-    public CassandraMailboxMapper(CassandraMailboxDAO mailboxDAO, 
CassandraMailboxPathDAO mailboxPathDAO, CassandraACLMapper aclMapper, 
CassandraConfiguration cassandraConfiguration) {
+    public CassandraMailboxMapper(CassandraMailboxDAO mailboxDAO, 
CassandraMailboxPathDAO mailboxPathDAO, CassandraUserMailboxRightsDAO 
userMailboxRightsDAO, CassandraACLMapper aclMapper, CassandraConfiguration 
cassandraConfiguration) {
         this.mailboxDAO = mailboxDAO;
         this.mailboxPathDAO = mailboxPathDAO;
+        this.userMailboxRightsDAO = userMailboxRightsDAO;
         this.cassandraACLMapper = aclMapper;
     }
 
@@ -256,4 +262,20 @@ public class CassandraMailboxMapper implements 
MailboxMapper {
             });
     }
 
+    @Override
+    public List<Mailbox> findMailboxes(String userName, Right right) throws 
MailboxException {
+        return 
FluentFutureStream.of(userMailboxRightsDAO.listRightsForUser(userName)
+            .thenApply(map -> toAuthorizedMailboxIds(map, right)))
+            .thenFlatComposeOnOptional(this::retrieveMailbox)
+            .join()
+            .collect(Guavate.toImmutableList());
+    }
+
+    private Stream<CassandraId> toAuthorizedMailboxIds(Map<CassandraId, 
MailboxACL.Rfc4314Rights> map, Right right) {
+        return map.entrySet()
+            .stream()
+            .filter(Throwing.predicate(entry -> 
entry.getValue().contains(right)))
+            .map(Map.Entry::getKey);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManagerTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManagerTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManagerTest.java
index c1286f8..3736666 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManagerTest.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/CassandraSubscriptionManagerTest.java
@@ -44,6 +44,7 @@ import 
org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraModSeqProvider;
 import org.apache.james.mailbox.cassandra.mail.CassandraUidProvider;
+import org.apache.james.mailbox.cassandra.mail.CassandraUserMailboxRightsDAO;
 import 
org.apache.james.mailbox.cassandra.modules.CassandraMailboxCounterModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraModSeqModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraSubscriptionModule;
@@ -97,6 +98,7 @@ public class CassandraSubscriptionManagerTest extends 
AbstractSubscriptionManage
         CassandraAttachmentMessageIdDAO attachmentMessageIdDAO = null;
         CassandraAttachmentOwnerDAO ownerDAO = null;
         CassandraACLMapper aclMapper = null;
+        CassandraUserMailboxRightsDAO userMailboxRightsDAO = null;
         return new CassandraSubscriptionManager(
             new CassandraMailboxSessionMapperFactory(
                 new CassandraUidProvider(cassandra.getConf()),
@@ -118,6 +120,7 @@ public class CassandraSubscriptionManagerTest extends 
AbstractSubscriptionManage
                 attachmentMessageIdDAO,
                 ownerDAO,
                 aclMapper,
+                userMailboxRightsDAO,
                 CassandraUtils.WITH_DEFAULT_CONFIGURATION,
                 CassandraConfiguration.DEFAULT_CONFIGURATION));
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
index 6896d63..cbf4d0f 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/TestCassandraMailboxSessionMapperFactory.java
@@ -41,6 +41,7 @@ import 
org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraModSeqProvider;
 import org.apache.james.mailbox.cassandra.mail.CassandraUidProvider;
+import org.apache.james.mailbox.cassandra.mail.CassandraUserMailboxRightsDAO;
 
 import com.datastax.driver.core.Session;
 
@@ -67,7 +68,10 @@ public class TestCassandraMailboxSessionMapperFactory {
             cassandraBlobsDAO,
             new CassandraAttachmentMessageIdDAO(session, factory, 
CassandraUtils.WITH_DEFAULT_CONFIGURATION),
             new CassandraAttachmentOwnerDAO(session, 
CassandraUtils.WITH_DEFAULT_CONFIGURATION),
-            new CassandraACLMapper(session, 
CassandraConfiguration.DEFAULT_CONFIGURATION),
+            new CassandraACLMapper(session,
+                new CassandraUserMailboxRightsDAO(session, 
CassandraUtils.WITH_DEFAULT_CONFIGURATION),
+                CassandraConfiguration.DEFAULT_CONFIGURATION),
+            new CassandraUserMailboxRightsDAO(session, 
CassandraUtils.WITH_DEFAULT_CONFIGURATION),
             CassandraUtils.WITH_DEFAULT_CONFIGURATION,
             CassandraConfiguration.DEFAULT_CONFIGURATION);
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperTest.java
index bc5a7e7..b241980 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperTest.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraACLMapperTest.java
@@ -33,12 +33,12 @@ import java.util.concurrent.TimeoutException;
 import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.DockerCassandraRule;
 import org.apache.james.backends.cassandra.init.CassandraConfiguration;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
 import org.apache.james.mailbox.cassandra.ids.CassandraId;
 import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.table.CassandraACLTable;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MailboxACL;
-import org.apache.james.mailbox.store.mail.model.Mailbox;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.ClassRule;
@@ -58,7 +58,9 @@ public class CassandraACLMapperTest {
     @Before
     public void setUp() {
         cassandra = CassandraCluster.create(new CassandraAclModule(), 
cassandraServer.getIp(), cassandraServer.getBindingPort());
-        cassandraACLMapper = new CassandraACLMapper(cassandra.getConf(), 
CassandraConfiguration.DEFAULT_CONFIGURATION);
+        cassandraACLMapper = new CassandraACLMapper(cassandra.getConf(),
+            new CassandraUserMailboxRightsDAO(cassandra.getConf(), 
CassandraUtils.WITH_DEFAULT_CONFIGURATION),
+            CassandraConfiguration.DEFAULT_CONFIGURATION);
         executor = Executors.newFixedThreadPool(2);
     }
 
@@ -198,6 +200,7 @@ public class CassandraACLMapperTest {
         return executor.submit(() -> {
             CassandraACLMapper aclMapper = new CassandraACLMapper(
                 cassandra.getConf(),
+                new CassandraUserMailboxRightsDAO(cassandra.getConf(), 
CassandraUtils.WITH_DEFAULT_CONFIGURATION),
                 CassandraConfiguration.DEFAULT_CONFIGURATION,
                 runnable);
             try {

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperConcurrencyTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperConcurrencyTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperConcurrencyTest.java
index 42ed3a9..6d7822b 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperConcurrencyTest.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperConcurrencyTest.java
@@ -28,6 +28,7 @@ import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.DockerCassandraRule;
 import org.apache.james.backends.cassandra.init.CassandraConfiguration;
 import org.apache.james.backends.cassandra.init.CassandraModuleComposite;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
 import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraMailboxModule;
 import org.apache.james.mailbox.model.MailboxPath;
@@ -57,10 +58,14 @@ public class CassandraMailboxMapperConcurrencyTest {
         cassandra = CassandraCluster.create(modules, cassandraServer.getIp(), 
cassandraServer.getBindingPort());
         CassandraMailboxDAO mailboxDAO = new 
CassandraMailboxDAO(cassandra.getConf(), cassandra.getTypesProvider());
         CassandraMailboxPathDAO mailboxPathDAO = new 
CassandraMailboxPathDAO(cassandra.getConf(), cassandra.getTypesProvider());
+        CassandraUserMailboxRightsDAO userMailboxRightsDAO = new 
CassandraUserMailboxRightsDAO(cassandra.getConf(), 
CassandraUtils.WITH_DEFAULT_CONFIGURATION);
         testee = new CassandraMailboxMapper(
             mailboxDAO,
             mailboxPathDAO,
-            new CassandraACLMapper(cassandra.getConf(), 
CassandraConfiguration.DEFAULT_CONFIGURATION),
+            userMailboxRightsDAO,
+            new CassandraACLMapper(cassandra.getConf(),
+                userMailboxRightsDAO,
+                CassandraConfiguration.DEFAULT_CONFIGURATION),
             CassandraConfiguration.DEFAULT_CONFIGURATION);
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
index 1c7d9ea..2827bf9 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraMailboxMapperTest.java
@@ -29,6 +29,7 @@ import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.DockerCassandraRule;
 import org.apache.james.backends.cassandra.init.CassandraConfiguration;
 import org.apache.james.backends.cassandra.init.CassandraModuleComposite;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
 import 
org.apache.james.mailbox.cassandra.mail.CassandraMailboxPathDAO.CassandraIdAndPath;
 import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraMailboxModule;
@@ -61,10 +62,14 @@ public class CassandraMailboxMapperTest {
         cassandra = CassandraCluster.create(modules, cassandraServer.getIp(), 
cassandraServer.getBindingPort());
         CassandraMailboxDAO mailboxDAO = new 
CassandraMailboxDAO(cassandra.getConf(), cassandra.getTypesProvider());
         mailboxPathDAO = new CassandraMailboxPathDAO(cassandra.getConf(), 
cassandra.getTypesProvider());
+        CassandraUserMailboxRightsDAO userMailboxRightsDAO = new 
CassandraUserMailboxRightsDAO(cassandra.getConf(), 
CassandraUtils.WITH_DEFAULT_CONFIGURATION);
         testee = new CassandraMailboxMapper(
             mailboxDAO,
             mailboxPathDAO,
-            new CassandraACLMapper(cassandra.getConf(), 
CassandraConfiguration.DEFAULT_CONFIGURATION),
+            userMailboxRightsDAO,
+            new CassandraACLMapper(cassandra.getConf(),
+                new CassandraUserMailboxRightsDAO(cassandra.getConf(), 
CassandraUtils.WITH_DEFAULT_CONFIGURATION),
+                CassandraConfiguration.DEFAULT_CONFIGURATION),
             CassandraConfiguration.DEFAULT_CONFIGURATION);
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProviderTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProviderTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProviderTest.java
index 2d4e4c9..f3d6ed2 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProviderTest.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraModSeqProviderTest.java
@@ -27,6 +27,7 @@ import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.DockerCassandraRule;
 import org.apache.james.backends.cassandra.init.CassandraConfiguration;
 import org.apache.james.backends.cassandra.init.CassandraModuleComposite;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
 import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraMailboxModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraModSeqModule;
@@ -60,9 +61,11 @@ public class CassandraModSeqProviderTest {
         modSeqProvider = new CassandraModSeqProvider(cassandra.getConf());
         CassandraMailboxDAO mailboxDAO = new 
CassandraMailboxDAO(cassandra.getConf(), cassandra.getTypesProvider());
         CassandraMailboxPathDAO mailboxPathDAO = new 
CassandraMailboxPathDAO(cassandra.getConf(), cassandra.getTypesProvider());
+        CassandraUserMailboxRightsDAO userMailboxRightsDAO = new 
CassandraUserMailboxRightsDAO(cassandra.getConf(), 
CassandraUtils.WITH_DEFAULT_CONFIGURATION);
         mapper = new CassandraMailboxMapper(
             mailboxDAO,
             mailboxPathDAO,
+            userMailboxRightsDAO,
             new CassandraACLMapper(cassandra.getConf(), 
CassandraConfiguration.DEFAULT_CONFIGURATION),
             CassandraConfiguration.DEFAULT_CONFIGURATION);
         MailboxPath path = new MailboxPath("gsoc", "ieugen", "Trash");

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProviderTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProviderTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProviderTest.java
index 9380ba5..b9f22d8 100644
--- 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProviderTest.java
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/CassandraUidProviderTest.java
@@ -27,6 +27,7 @@ import org.apache.james.backends.cassandra.CassandraCluster;
 import org.apache.james.backends.cassandra.DockerCassandraRule;
 import org.apache.james.backends.cassandra.init.CassandraConfiguration;
 import org.apache.james.backends.cassandra.init.CassandraModuleComposite;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.cassandra.modules.CassandraAclModule;
 import org.apache.james.mailbox.cassandra.modules.CassandraMailboxModule;
@@ -61,9 +62,11 @@ public class CassandraUidProviderTest {
         uidProvider = new CassandraUidProvider(cassandra.getConf());
         CassandraMailboxDAO mailboxDAO = new 
CassandraMailboxDAO(cassandra.getConf(), cassandra.getTypesProvider());
         CassandraMailboxPathDAO mailboxPathDAO = new 
CassandraMailboxPathDAO(cassandra.getConf(), cassandra.getTypesProvider());
+        CassandraUserMailboxRightsDAO userMailboxRightsDAO = new 
CassandraUserMailboxRightsDAO(cassandra.getConf(), 
CassandraUtils.WITH_DEFAULT_CONFIGURATION);
         mapper = new CassandraMailboxMapper(
             mailboxDAO,
             mailboxPathDAO,
+            userMailboxRightsDAO,
             new CassandraACLMapper(cassandra.getConf(), 
CassandraConfiguration.DEFAULT_CONFIGURATION),
             CassandraConfiguration.DEFAULT_CONFIGURATION);
         MailboxPath path = new MailboxPath("gsoc", "ieugen", "Trash");

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMapper.java
----------------------------------------------------------------------
diff --git 
a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMapper.java
 
b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMapper.java
index 326bf77..bbf46b8 100644
--- 
a/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMapper.java
+++ 
b/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMailboxMapper.java
@@ -55,11 +55,14 @@ import org.apache.james.mailbox.hbase.HBaseId;
 import org.apache.james.mailbox.hbase.HBaseNonTransactionalMapper;
 import org.apache.james.mailbox.hbase.mail.model.HBaseMailbox;
 import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MailboxACL.Right;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
 
+import com.google.common.collect.ImmutableList;
+
 /**
  * Data access management for mailbox.
  *
@@ -422,4 +425,9 @@ public class HBaseMailboxMapper extends 
HBaseNonTransactionalMapper implements M
     public void setACL(Mailbox mailbox, MailboxACL mailboxACL) throws 
MailboxException {
         mailbox.setACL(mailboxACL);
     }
+
+    @Override
+    public List<Mailbox> findMailboxes(String userName, Right right) throws 
MailboxException {
+        return ImmutableList.of();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMailboxMapper.java
----------------------------------------------------------------------
diff --git 
a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMailboxMapper.java
 
b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMailboxMapper.java
index 3bf7cfe..8d51e0e 100644
--- 
a/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMailboxMapper.java
+++ 
b/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/mail/JCRMailboxMapper.java
@@ -40,11 +40,14 @@ import 
org.apache.james.mailbox.jcr.AbstractJCRScalingMapper;
 import org.apache.james.mailbox.jcr.MailboxSessionJCRRepository;
 import org.apache.james.mailbox.jcr.mail.model.JCRMailbox;
 import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MailboxACL.Right;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
 
+import com.google.common.collect.ImmutableList;
+
 /**
  * JCR implementation of a MailboxMapper
  * 
@@ -259,4 +262,9 @@ public class JCRMailboxMapper extends 
AbstractJCRScalingMapper implements Mailbo
     public void setACL(Mailbox mailbox, MailboxACL mailboxACL) throws 
MailboxException {
         mailbox.setACL(mailboxACL);
     }
+
+    @Override
+    public List<Mailbox> findMailboxes(String userName, Right right) throws 
MailboxException {
+        return ImmutableList.of();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMailboxMapper.java
----------------------------------------------------------------------
diff --git 
a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMailboxMapper.java
 
b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMailboxMapper.java
index 30826ca..8cd8761 100644
--- 
a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMailboxMapper.java
+++ 
b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/JPAMailboxMapper.java
@@ -34,12 +34,14 @@ import org.apache.james.mailbox.jpa.JPAId;
 import org.apache.james.mailbox.jpa.JPATransactionalMapper;
 import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
 import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MailboxACL.Right;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
 
 import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
 
 /**
  * Data access management for mailbox.
@@ -229,4 +231,9 @@ public class JPAMailboxMapper extends 
JPATransactionalMapper implements MailboxM
     public void setACL(Mailbox mailbox, MailboxACL mailboxACL) throws 
MailboxException {
         mailbox.setACL(mailboxACL);
     }
+
+    @Override
+    public List<Mailbox> findMailboxes(String userName, Right right) throws 
MailboxException {
+        return ImmutableList.of();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/TransactionalMailboxMapper.java
----------------------------------------------------------------------
diff --git 
a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/TransactionalMailboxMapper.java
 
b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/TransactionalMailboxMapper.java
index e88c0a9..f0fdc56 100644
--- 
a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/TransactionalMailboxMapper.java
+++ 
b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/TransactionalMailboxMapper.java
@@ -25,6 +25,7 @@ import org.apache.commons.lang.NotImplementedException;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MailboxNotFoundException;
 import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MailboxACL.Right;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
@@ -93,4 +94,9 @@ public class TransactionalMailboxMapper implements 
MailboxMapper {
         return wrapped.list();
     }
 
+    @Override
+    public List<Mailbox> findMailboxes(String userName, Right right) throws 
MailboxException {
+        return wrapped.findMailboxes(userName, right);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java
----------------------------------------------------------------------
diff --git 
a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java
 
b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java
index 4ccc892..c4506e7 100644
--- 
a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java
+++ 
b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMailboxMapper.java
@@ -35,6 +35,7 @@ import org.apache.james.mailbox.maildir.MaildirId;
 import org.apache.james.mailbox.maildir.MaildirMessageName;
 import org.apache.james.mailbox.maildir.MaildirStore;
 import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MailboxACL.Right;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
@@ -45,6 +46,8 @@ import 
org.apache.james.mailbox.store.transaction.NonTransactionalMapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.ImmutableList;
+
 public class MaildirMailboxMapper extends NonTransactionalMapper implements 
MailboxMapper {
 
     private static final Logger LOGGER = 
LoggerFactory.getLogger(MaildirMailboxMapper.class);
@@ -346,4 +349,9 @@ public class MaildirMailboxMapper extends 
NonTransactionalMapper implements Mail
         folder.setACL(session, mailboxACL);
         mailbox.setACL(mailboxACL);
     }
+
+    @Override
+    public List<Mailbox> findMailboxes(String userName, Right right) throws 
MailboxException {
+        return ImmutableList.of();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxMapper.java
----------------------------------------------------------------------
diff --git 
a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxMapper.java
 
b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxMapper.java
index c65b66c..dde0962 100644
--- 
a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxMapper.java
+++ 
b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryMailboxMapper.java
@@ -20,6 +20,7 @@ package org.apache.james.mailbox.inmemory.mail;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicLong;
 
@@ -28,6 +29,8 @@ import 
org.apache.james.mailbox.exception.MailboxExistsException;
 import org.apache.james.mailbox.exception.MailboxNotFoundException;
 import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MailboxACL.NameType;
+import org.apache.james.mailbox.model.MailboxACL.Right;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
@@ -163,4 +166,21 @@ public class InMemoryMailboxMapper implements 
MailboxMapper {
     public void setACL(Mailbox mailbox, MailboxACL mailboxACL) throws 
MailboxException {
         
mailboxesByPath.get(mailbox.generateAssociatedPath()).setACL(mailboxACL);
     }
+
+    @Override
+    public List<Mailbox> findMailboxes(String userName, Right right) throws 
MailboxException {
+        return mailboxesByPath.values()
+            .stream()
+            .filter(mailbox -> hasRightOn(mailbox, userName, right))
+            .collect(Guavate.toImmutableList());
+    }
+
+    private Boolean hasRightOn(Mailbox mailbox, String userName, Right right) {
+        return Optional.ofNullable(
+            mailbox.getACL()
+                .ofPositiveNameType(NameType.user)
+                .get(MailboxACL.EntryKey.createUserEntryKey(userName)))
+            .map(rights -> rights.contains(right))
+            .orElse(false);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MailboxMapper.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MailboxMapper.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MailboxMapper.java
index da96db2..efeb42b 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MailboxMapper.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/MailboxMapper.java
@@ -23,6 +23,7 @@ import java.util.List;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MailboxNotFoundException;
 import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MailboxACL.Right;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
@@ -75,6 +76,15 @@ public interface MailboxMapper extends Mapper {
             throws MailboxException, MailboxNotFoundException;
 
     /**
+     * Return a List of {@link Mailbox} for the given userName and matching 
the right
+     * 
+     * @param userName
+     * @return right
+     * @throws MailboxException
+     */
+    List<Mailbox> findMailboxes(String userName, Right right) throws 
MailboxException;
+
+    /**
      * Return a List of {@link Mailbox} which name is like the given name
      * 
      * @param mailboxPath

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/store/src/test/java/org/apache/james/mailbox/store/TestMailboxSessionMapperFactory.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/test/java/org/apache/james/mailbox/store/TestMailboxSessionMapperFactory.java
 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/TestMailboxSessionMapperFactory.java
index 4a001be..cf47c1d 100644
--- 
a/mailbox/store/src/test/java/org/apache/james/mailbox/store/TestMailboxSessionMapperFactory.java
+++ 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/TestMailboxSessionMapperFactory.java
@@ -42,6 +42,7 @@ import 
org.apache.james.mailbox.exception.MailboxNotFoundException;
 import org.apache.james.mailbox.exception.SubscriptionException;
 import org.apache.james.mailbox.fixture.MailboxFixture;
 import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MailboxACL.Right;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageId;
@@ -162,6 +163,11 @@ public class TestMailboxSessionMapperFactory extends 
MailboxSessionMapperFactory
             public <T> T execute(Transaction<T> transaction) throws 
MailboxException {
                 throw new NotImplementedException();
             }
+
+            @Override
+            public List<Mailbox> findMailboxes(String userName, Right right) 
throws MailboxException {
+                throw new NotImplementedException();
+            }
         };
         messageIdMapper = new MessageIdMapper() {
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MailboxMapperACLTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MailboxMapperACLTest.java
 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MailboxMapperACLTest.java
index e4bf959..836db5d 100644
--- 
a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MailboxMapperACLTest.java
+++ 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/MailboxMapperACLTest.java
@@ -242,4 +242,157 @@ public abstract class MailboxMapperACLTest {
         return mailbox;
     }
 
+    @Test
+    public void findMailboxesShouldReturnEmptyWhenNone() throws 
MailboxException {
+        assertThat(mailboxMapper.findMailboxes("user", 
Right.Administer)).isEmpty();
+    }
+
+    @Test
+    public void findMailboxesShouldReturnEmptyWhenRightDoesntMatch() throws 
MailboxException {
+        EntryKey key = EntryKey.createUserEntryKey("user");
+        Rfc4314Rights rights = new Rfc4314Rights(Right.Administer);
+        mailboxMapper.updateACL(benwaInboxMailbox,
+            MailboxACL.command()
+                .key(key)
+                .rights(rights)
+                .asReplacement());
+
+        assertThat(mailboxMapper.findMailboxes("user", Right.Read)).isEmpty();
+    }
+
+    @Test
+    public void updateACLShouldInsertUsersRights() throws MailboxException {
+        Rfc4314Rights rights = new Rfc4314Rights(Right.Administer, 
Right.PerformExpunge);
+        mailboxMapper.updateACL(benwaInboxMailbox,
+            MailboxACL.command()
+                .key(EntryKey.createUserEntryKey("user"))
+                .rights(rights)
+                .asAddition());
+
+        assertThat(mailboxMapper.findMailboxes("user", Right.Administer))
+            .containsOnly(benwaInboxMailbox);
+    }
+
+    @Test
+    public void updateACLShouldOverwriteUsersRights() throws MailboxException {
+        EntryKey key = EntryKey.createUserEntryKey("user");
+        Rfc4314Rights initialRights = new Rfc4314Rights(Right.Administer);
+        mailboxMapper.updateACL(benwaInboxMailbox,
+            MailboxACL.command()
+                .key(key)
+                .rights(initialRights)
+                .asReplacement());
+        Rfc4314Rights newRights = new Rfc4314Rights(Right.Read);
+        mailboxMapper.updateACL(benwaInboxMailbox,
+            MailboxACL.command()
+                .key(key)
+                .rights(newRights)
+                .asReplacement());
+
+        assertThat(mailboxMapper.findMailboxes("user", Right.Read))
+            .containsOnly(benwaInboxMailbox);
+    }
+
+    @Test
+    public void findMailboxesShouldNotReportDeletedACLViaReplace() throws 
MailboxException {
+        EntryKey key = EntryKey.createUserEntryKey("user");
+        Rfc4314Rights initialRights = new Rfc4314Rights(Right.Administer);
+        mailboxMapper.updateACL(benwaInboxMailbox,
+            MailboxACL.command()
+                .key(key)
+                .mode(MailboxACL.EditMode.REPLACE)
+                .rights(initialRights)
+                .build());
+        mailboxMapper.updateACL(benwaInboxMailbox,
+            MailboxACL.command()
+                .key(key)
+                .mode(MailboxACL.EditMode.REPLACE)
+                .rights(new Rfc4314Rights())
+                .build());
+
+        assertThat(mailboxMapper.findMailboxes("user", Right.Administer))
+            .isEmpty();
+    }
+
+    @Test
+    public void findMailboxesShouldNotReportDeletedACLViaRemove() throws 
MailboxException {
+        EntryKey key = EntryKey.createUserEntryKey("user");
+        Rfc4314Rights initialRights = new Rfc4314Rights(Right.Administer);
+        mailboxMapper.updateACL(benwaInboxMailbox,
+            MailboxACL.command()
+                .key(key)
+                .rights(initialRights)
+                .asReplacement());
+        mailboxMapper.updateACL(benwaInboxMailbox,
+            MailboxACL.command()
+                .key(key)
+                .rights(initialRights)
+                .asRemoval());
+
+        assertThat(mailboxMapper.findMailboxes("user", Right.Administer))
+            .isEmpty();
+    }
+
+    @Test
+    public void findMailboxesShouldNotReportDeletedMailboxes() throws 
MailboxException {
+        EntryKey key = EntryKey.createUserEntryKey("user");
+        Rfc4314Rights initialRights = new Rfc4314Rights(Right.Administer);
+        mailboxMapper.updateACL(benwaInboxMailbox,
+            MailboxACL.command()
+                .key(key)
+                .rights(initialRights)
+                .asReplacement());
+        mailboxMapper.delete(benwaInboxMailbox);
+
+        assertThat(mailboxMapper.findMailboxes("user", Right.Administer))
+            .isEmpty();
+    }
+
+    @Test
+    public void setACLShouldStoreMultipleUsersRights() throws MailboxException 
{
+        EntryKey user1 = EntryKey.createUserEntryKey("user1");
+        EntryKey user2 = EntryKey.createUserEntryKey("user2");
+
+        mailboxMapper.setACL(benwaInboxMailbox, new MailboxACL(
+            new MailboxACL.Entry(user1, new Rfc4314Rights(Right.Administer)),
+            new MailboxACL.Entry(user2, new Rfc4314Rights(Right.Read))));
+
+        assertThat(mailboxMapper.findMailboxes("user1", Right.Administer))
+            .containsOnly(benwaInboxMailbox);
+        assertThat(mailboxMapper.findMailboxes("user2", Right.Read))
+            .containsOnly(benwaInboxMailbox);
+    }
+
+    @Test
+    public void findMailboxesShouldNotReportRightsRemovedViaSetAcl() throws 
MailboxException {
+        EntryKey user1 = EntryKey.createUserEntryKey("user1");
+        EntryKey user2 = EntryKey.createUserEntryKey("user2");
+
+        mailboxMapper.setACL(benwaInboxMailbox, new MailboxACL(
+            new MailboxACL.Entry(user1, new Rfc4314Rights(Right.Administer)),
+            new MailboxACL.Entry(user2, new Rfc4314Rights(Right.Read))));
+
+        mailboxMapper.setACL(benwaInboxMailbox, new MailboxACL(
+            new MailboxACL.Entry(user2, new Rfc4314Rights(Right.Read))));
+
+        assertThat(mailboxMapper.findMailboxes("user1", Right.Administer))
+            .isEmpty();
+    }
+
+    @Test
+    public void findMailboxesShouldReportRightsUpdatedViaSetAcl() throws 
MailboxException {
+        EntryKey user1 = EntryKey.createUserEntryKey("user1");
+        EntryKey user2 = EntryKey.createUserEntryKey("user2");
+
+        mailboxMapper.setACL(benwaInboxMailbox, new MailboxACL(
+            new MailboxACL.Entry(user1, new Rfc4314Rights(Right.Administer)),
+            new MailboxACL.Entry(user2, new Rfc4314Rights(Right.Read))));
+
+        mailboxMapper.setACL(benwaInboxMailbox, new MailboxACL(
+            new MailboxACL.Entry(user2, new Rfc4314Rights(Right.Write))));
+
+        assertThat(mailboxMapper.findMailboxes("user2", Right.Write))
+            .containsOnly(benwaInboxMailbox);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/78f208c4/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
index 278ba4b..19b4c68 100644
--- 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
+++ 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraMailboxModule.java
@@ -44,6 +44,7 @@ import 
org.apache.james.mailbox.cassandra.mail.CassandraMessageIdDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraMessageIdToImapUidDAO;
 import org.apache.james.mailbox.cassandra.mail.CassandraModSeqProvider;
 import org.apache.james.mailbox.cassandra.mail.CassandraUidProvider;
+import org.apache.james.mailbox.cassandra.mail.CassandraUserMailboxRightsDAO;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageId;
@@ -102,6 +103,7 @@ public class CassandraMailboxModule extends AbstractModule {
         bind(CassandraAttachmentDAO.class).in(Scopes.SINGLETON);
         bind(CassandraAttachmentMessageIdDAO.class).in(Scopes.SINGLETON);
         bind(CassandraAttachmentDAOV2.class).in(Scopes.SINGLETON);
+        bind(CassandraUserMailboxRightsDAO.class).in(Scopes.SINGLETON);
         bind(StoreBlobManager.class).in(Scopes.SINGLETON);
 
         bind(BlobManager.class).to(StoreBlobManager.class);


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

Reply via email to