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]