This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git


The following commit(s) were added to refs/heads/master by this push:
     new 8f7838c9bf [FIX] MailboxManager::create should not propagate lookup 
only
8f7838c9bf is described below

commit 8f7838c9bfbfb3e6d4641d225866a64746d747ea
Author: Benoit TELLIER <[email protected]>
AuthorDate: Fri Mar 20 15:35:32 2026 +0100

    [FIX] MailboxManager::create should not propagate lookup only
---
 .../apache/james/mailbox/MailboxManagerTest.java   | 52 ++++++++++++++++++++++
 .../james/mailbox/store/StoreMailboxManager.java   | 11 +++++
 2 files changed, 63 insertions(+)

diff --git 
a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java 
b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
index 468f84105c..ad44a3b4ae 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
@@ -363,6 +363,58 @@ public abstract class MailboxManagerTest<T extends 
MailboxManager> {
                 .isInstanceOf(MailboxNotFoundException.class);
         }
 
+        @Test
+        void createMailboxShouldNotPropagateParentLookupOnlyRightsToSibling() 
throws Exception {
+            assumeTrue(mailboxManager.hasCapability(MailboxCapabilities.ACL));
+            session = mailboxManager.createSystemSession(USER_1);
+            // Create a.b - this also creates intermediate "a"
+            MailboxPath childPath1 = MailboxPath.forUser(USER_1, "a.b");
+            mailboxManager.createMailbox(childPath1, session);
+
+            // Give USER_2 only Lookup right on "a" (simulating the right 
derived from PropagateLookupRightListener)
+            MailboxPath parentPath = MailboxPath.forUser(USER_1, "a");
+            mailboxManager.applyRightsCommand(parentPath,
+                MailboxACL.command()
+                    .key(MailboxACL.EntryKey.createUserEntryKey(USER_2))
+                    .rights(MailboxACL.Right.Lookup)
+                    .asAddition(), session);
+
+            // Create a.c (sibling of a.b)
+            MailboxPath childPath2 = MailboxPath.forUser(USER_1, "a.c");
+            mailboxManager.createMailbox(childPath2, session);
+
+            // USER_2 should NOT have rights on a.c - Lookup-only from parent 
should not propagate to siblings
+            assertThat(mailboxManager.getMailbox(childPath2, session)
+                
.getMailboxEntity().getACL().getEntries().get(MailboxACL.EntryKey.createUserEntryKey(USER_2)))
+                .isNull();
+        }
+
+        @Test
+        void createMailboxShouldPropagateParentNonLookupOnlyRightsToSibling() 
throws Exception {
+            assumeTrue(mailboxManager.hasCapability(MailboxCapabilities.ACL));
+            session = mailboxManager.createSystemSession(USER_1);
+            // Create a.b - this also creates intermediate "a"
+            MailboxPath childPath1 = MailboxPath.forUser(USER_1, "a.b");
+            mailboxManager.createMailbox(childPath1, session);
+
+            // Give USER_2 Read+Lookup rights on "a" (substantive rights, not 
just derived lookup)
+            MailboxPath parentPath = MailboxPath.forUser(USER_1, "a");
+            mailboxManager.applyRightsCommand(parentPath,
+                MailboxACL.command()
+                    .key(MailboxACL.EntryKey.createUserEntryKey(USER_2))
+                    .rights(MailboxACL.Right.Lookup, MailboxACL.Right.Read)
+                    .asAddition(), session);
+
+            // Create a.c (sibling of a.b)
+            MailboxPath childPath2 = MailboxPath.forUser(USER_1, "a.c");
+            mailboxManager.createMailbox(childPath2, session);
+
+            // USER_2 SHOULD have rights on a.c (non-lookup-only rights from 
parent should still propagate)
+            assertThat(mailboxManager.getMailbox(childPath2, session)
+                
.getMailboxEntity().getACL().getEntries().get(MailboxACL.EntryKey.createUserEntryKey(USER_2)))
+                
.isEqualTo(MailboxACL.Rfc4314Rights.fromSerializedRfc4314Rights("lr"));
+        }
+
         @Test
         void creatingMixedCaseINBOXShouldCreateItAsINBOX() throws Exception {
             session = mailboxManager.createSystemSession(USER_1);
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 725b628807..475c1ba003 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
@@ -477,6 +477,7 @@ public class StoreMailboxManager implements MailboxManager {
     private Mono<Void> inheritRightsReactive(MailboxSession mailboxSession, 
MailboxPath path) {
         return nearestExistingParent(mailboxSession, path)
             .flatMap(parent -> Mono.from(listRightsReactive(parent, 
mailboxSession)))
+            .map(this::filterLookupOnlyEntries)
             .flatMap(acl -> {
                 if (acl.getEntries().isEmpty()) {
                     return Mono.empty();
@@ -485,6 +486,16 @@ public class StoreMailboxManager implements MailboxManager 
{
             });
     }
 
+    private MailboxACL filterLookupOnlyEntries(MailboxACL acl) {
+        return new MailboxACL(acl.getEntries().entrySet().stream()
+            .filter(entry -> !isLookupOnly(entry.getValue()))
+            .collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, 
Map.Entry::getValue)));
+    }
+
+    private boolean isLookupOnly(Rfc4314Rights rights) {
+        return rights.equals(new Rfc4314Rights(Right.Lookup));
+    }
+
     @Override
     public void deleteMailbox(final MailboxPath mailboxPath, final 
MailboxSession session) throws MailboxException {
         LOGGER.info("deleteMailbox {}", mailboxPath);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to