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

commit 018cdba07c3d9317129f01fa03d1a428b3b77f6b
Author: Benoit TELLIER <btell...@linagora.com>
AuthorDate: Thu Oct 10 09:27:00 2024 +0200

    JAMES-2182 LSUB for delegated accounts
---
 .../james/mailbox/model/search/PrefixedRegex.java  | 22 ++++++-
 .../mailbox/model/search/PrefixedRegexTest.java    |  4 +-
 .../james/imap/scripts/ListWithSharedMailbox.test  | 73 +++++++++++++++++++++-
 .../james/imap/processor/DefaultProcessor.java     |  2 +-
 .../apache/james/imap/processor/LSubProcessor.java | 12 ++--
 .../james/imap/processor/LSubProcessorTest.java    |  3 +-
 6 files changed, 105 insertions(+), 11 deletions(-)

diff --git 
a/mailbox/api/src/main/java/org/apache/james/mailbox/model/search/PrefixedRegex.java
 
b/mailbox/api/src/main/java/org/apache/james/mailbox/model/search/PrefixedRegex.java
index 1040391c35..d9a65dd58e 100644
--- 
a/mailbox/api/src/main/java/org/apache/james/mailbox/model/search/PrefixedRegex.java
+++ 
b/mailbox/api/src/main/java/org/apache/james/mailbox/model/search/PrefixedRegex.java
@@ -41,8 +41,18 @@ public class PrefixedRegex implements MailboxNameExpression {
 
     @Override
     public boolean isExpressionMatch(String name) {
-        return name.startsWith(prefix)
-            && regexMatching(name.substring(prefix.length()));
+        if (name.startsWith(prefix)) {
+            String nameSubstring = 
sanitizeSubstring(name.substring(prefix.length()));
+            return regexMatching(nameSubstring);
+        }
+        return false;
+    }
+
+    private String sanitizeSubstring(String name) {
+        if (!name.isEmpty() && name.charAt(0) == pathDelimiter) {
+            return name.substring(1);
+        }
+        return name;
     }
 
     private boolean regexMatching(String name) {
@@ -133,4 +143,12 @@ public class PrefixedRegex implements 
MailboxNameExpression {
     public final int hashCode() {
         return Objects.hash(prefix, regex, pathDelimiter);
     }
+
+    @Override
+    public String toString() {
+        return "PrefixedRegex{" +
+            "prefix='" + prefix + '\'' +
+            ", regex='" + regex + '\'' +
+            '}';
+    }
 }
diff --git 
a/mailbox/api/src/test/java/org/apache/james/mailbox/model/search/PrefixedRegexTest.java
 
b/mailbox/api/src/test/java/org/apache/james/mailbox/model/search/PrefixedRegexTest.java
index 95a2681c58..03340f532f 100644
--- 
a/mailbox/api/src/test/java/org/apache/james/mailbox/model/search/PrefixedRegexTest.java
+++ 
b/mailbox/api/src/test/java/org/apache/james/mailbox/model/search/PrefixedRegexTest.java
@@ -224,12 +224,12 @@ class PrefixedRegexTest {
     }
 
     @Test
-    void isExpressionMatchShouldReturnFalseWhenNameBeginsWithDelimiter() {
+    void isExpressionMatchShouldReturnTrueWhenNameBeginsWithDelimiter() {
         PrefixedRegex testee = new PrefixedRegex(EMPTY_PREFIX, "mailbox", 
PATH_DELIMITER);
 
         boolean actual = testee.isExpressionMatch(".mailbox");
 
-        assertThat(actual).isFalse();
+        assertThat(actual).isTrue();
     }
 
     @Test
diff --git 
a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/ListWithSharedMailbox.test
 
b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/ListWithSharedMailbox.test
index b2c54b2911..ba08ab81ed 100644
--- 
a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/ListWithSharedMailbox.test
+++ 
b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/ListWithSharedMailbox.test
@@ -98,4 +98,75 @@ S: \* LIST \(\\HasChildren\) \".\" 
\"#user.boby.sharedMailbox\"
 S: \* LIST \(\\HasNoChildren\) \".\" \"#user.boby.sharedMailbox.child\"
 S: \* LIST \(\\HasNoChildren\) \".\" \"#user.boby.Sent\"
 }
-S: a12 OK LIST completed.
\ No newline at end of file
+S: a12 OK LIST completed.
+
+C: b01 SUBSCRIBE INBOX
+S: b01 OK SUBSCRIBE completed.
+C: b02 SUBSCRIBE #user.diana.sharedMailbox
+S: b02 OK SUBSCRIBE completed.
+C: b03 SUBSCRIBE #user.boby.sharedMailbox
+S: b03 OK SUBSCRIBE completed.
+C: b04 SUBSCRIBE #user.boby.sharedMailbox.child
+S: b04 OK SUBSCRIBE completed.
+C: b05 SUBSCRIBE #user.boby.Sent
+S: b05 OK SUBSCRIBE completed.
+
+C: b06 LSUB "" "*"
+SUB {
+S: \* LSUB \(\) \"\.\" \"INBOX\"
+S: \* LSUB \(\) \".\" \"#user.diana.sharedMailbox\"
+S: \* LSUB \(\) \".\" \"#user.boby.sharedMailbox\"
+S: \* LSUB \(\) \".\" \"#user.boby.sharedMailbox.child\"
+S: \* LSUB \(\) \".\" \"#user.boby.Sent\"
+}
+S: b06 OK LSUB completed.
+
+C: b07 LSUB "#user" "*"
+SUB {
+S: \* LSUB \(\) \".\" \"#user.diana.sharedMailbox\"
+S: \* LSUB \(\) \".\" \"#user.boby.sharedMailbox\"
+S: \* LSUB \(\) \".\" \"#user.boby.sharedMailbox.child\"
+S: \* LSUB \(\) \".\" \"#user.boby.Sent\"
+}
+S: b07 OK LSUB completed.
+
+C: b08 LSUB "#user.diana" "*"
+S: \* LSUB \(\) \".\" \"#user.diana.sharedMailbox\"
+S: b08 OK LSUB completed.
+
+C: b09 LSUB "" "#user.*"
+SUB {
+S: \* LSUB \(\) \".\" \"#user.diana.sharedMailbox\"
+S: \* LSUB \(\) \".\" \"#user.boby.sharedMailbox\"
+S: \* LSUB \(\) \".\" \"#user.boby.sharedMailbox.child\"
+S: \* LSUB \(\) \".\" \"#user.boby.Sent\"
+}
+S: b09 OK LSUB completed.
+
+C: b10 LSUB "" "#user.diana.*"
+S: \* LSUB \(\) \".\" \"#user.diana.sharedMailbox\"
+S: b10 OK LSUB completed.
+
+C: b11 LSUB "#user" "diana.*"
+S: \* LSUB \(\) \".\" \"#user.diana.sharedMailbox\"
+S: b11 OK LSUB completed.
+
+C: b12 LIST "" "*" RETURN (SUBSCRIBED)
+SUB {
+S: \* LIST \(\\HasNoChildren \\Subscribed\) \"\.\" \"INBOX\"
+S: \* LIST \(\\HasNoChildren \\Subscribed\) \".\" \"#user.diana.sharedMailbox\"
+S: \* LIST \(\\HasChildren \\Subscribed\) \".\" \"#user.boby.sharedMailbox\"
+S: \* LIST \(\\HasNoChildren \\Subscribed\) \".\" 
\"#user.boby.sharedMailbox.child\"
+S: \* LIST \(\\HasNoChildren \\Subscribed\) \".\" \"#user.boby.Sent\"
+}
+S: b12 OK LIST completed.
+
+C: b13 LIST (SUBSCRIBED) "" "*"RETURN (SUBSCRIBED)
+SUB {
+S: \* LIST \(\\HasNoChildren \\Subscribed\) \"\.\" \"INBOX\"
+S: \* LIST \(\\HasNoChildren \\Subscribed\) \".\" \"#user.diana.sharedMailbox\"
+S: \* LIST \(\\HasChildren \\Subscribed\) \".\" \"#user.boby.sharedMailbox\"
+S: \* LIST \(\\HasNoChildren \\Subscribed\) \".\" 
\"#user.boby.sharedMailbox.child\"
+S: \* LIST \(\\HasNoChildren \\Subscribed\) \".\" \"#user.boby.Sent\"
+}
+S: b13 OK LIST completed.
\ No newline at end of file
diff --git 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/DefaultProcessor.java
 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/DefaultProcessor.java
index f96689a2e4..a69c2133a3 100644
--- 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/DefaultProcessor.java
+++ 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/DefaultProcessor.java
@@ -83,7 +83,7 @@ public class DefaultProcessor implements ImapProcessor {
         builder.add(new IdleProcessor(mailboxManager, statusResponseFactory, 
metricFactory));
         StatusProcessor statusProcessor = new StatusProcessor(mailboxManager, 
statusResponseFactory, metricFactory, pathConverterFactory);
         builder.add(statusProcessor);
-        builder.add(new LSubProcessor(mailboxManager, subscriptionManager, 
statusResponseFactory, metricFactory));
+        builder.add(new LSubProcessor(mailboxManager, subscriptionManager, 
statusResponseFactory, metricFactory, pathConverterFactory));
         builder.add(new XListProcessor(mailboxManager, statusResponseFactory, 
mailboxTyper, metricFactory, subscriptionManager, pathConverterFactory));
         builder.add(new ListProcessor<>(mailboxManager, statusResponseFactory, 
metricFactory, subscriptionManager, statusProcessor, mailboxTyper, 
pathConverterFactory));
         builder.add(new SearchProcessor(mailboxManager, statusResponseFactory, 
metricFactory));
diff --git 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/LSubProcessor.java
 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/LSubProcessor.java
index a7f779f7c1..581b0472e0 100644
--- 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/LSubProcessor.java
+++ 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/LSubProcessor.java
@@ -29,6 +29,7 @@ import org.apache.james.imap.api.display.HumanReadableText;
 import org.apache.james.imap.api.display.ModifiedUtf7;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapSession;
+import org.apache.james.imap.main.PathConverter;
 import org.apache.james.imap.message.request.LsubRequest;
 import org.apache.james.imap.message.response.LSubResponse;
 import org.apache.james.mailbox.MailboxManager;
@@ -36,7 +37,6 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.SubscriptionManager;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.SubscriptionException;
-import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.search.MailboxNameExpression;
 import org.apache.james.mailbox.model.search.PrefixedRegex;
 import org.apache.james.metrics.api.MetricFactory;
@@ -50,14 +50,17 @@ import reactor.core.publisher.Mono;
 
 public class LSubProcessor extends AbstractMailboxProcessor<LsubRequest> {
     private static final Logger LOGGER = 
LoggerFactory.getLogger(LSubProcessor.class);
+    public static final boolean RELATIVE = true;
 
     private final SubscriptionManager subscriptionManager;
+    private final PathConverter.Factory pathConverterFactory;
 
     @Inject
     public LSubProcessor(MailboxManager mailboxManager, SubscriptionManager 
subscriptionManager, StatusResponseFactory factory,
-                         MetricFactory metricFactory) {
+                         MetricFactory metricFactory, PathConverter.Factory 
pathConverterFactory) {
         super(LsubRequest.class, mailboxManager, factory, metricFactory);
         this.subscriptionManager = subscriptionManager;
+        this.pathConverterFactory = pathConverterFactory;
     }
 
     @Override
@@ -76,8 +79,9 @@ public class LSubProcessor extends 
AbstractMailboxProcessor<LsubRequest> {
     private Mono<Void> listSubscriptions(ImapSession session, Responder 
responder, String referenceName, String mailboxName) {
         MailboxSession mailboxSession = session.getMailboxSession();
         try {
+            PathConverter pathConverter = 
pathConverterFactory.forSession(session);
             Mono<List<String>> mailboxesMono = 
Flux.from(subscriptionManager.subscriptionsReactive(mailboxSession))
-                .map(MailboxPath::getName)
+                .map(path -> pathConverter.mailboxName(RELATIVE, path, 
mailboxSession))
                 .collectList();
 
             String decodedMailName = 
ModifiedUtf7.decodeModifiedUTF7(referenceName);
@@ -90,7 +94,7 @@ public class LSubProcessor extends 
AbstractMailboxProcessor<LsubRequest> {
             return mailboxesMono.doOnNext(mailboxes -> {
                 Collection<String> mailboxResponses = new ArrayList<>();
                 for (String mailbox : mailboxes) {
-                    respond(responder, expression, mailbox, true, mailboxes, 
mailboxResponses, mailboxSession.getPathDelimiter());
+                    respond(responder, expression, mailbox, RELATIVE, 
mailboxes, mailboxResponses, mailboxSession.getPathDelimiter());
                 }
             }).then();
         } catch (SubscriptionException e) {
diff --git 
a/protocols/imap/src/test/java/org/apache/james/imap/processor/LSubProcessorTest.java
 
b/protocols/imap/src/test/java/org/apache/james/imap/processor/LSubProcessorTest.java
index d24da477ec..410ffe71b1 100644
--- 
a/protocols/imap/src/test/java/org/apache/james/imap/processor/LSubProcessorTest.java
+++ 
b/protocols/imap/src/test/java/org/apache/james/imap/processor/LSubProcessorTest.java
@@ -38,6 +38,7 @@ import 
org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.encode.FakeImapSession;
+import org.apache.james.imap.main.PathConverter;
 import org.apache.james.imap.message.request.LsubRequest;
 import org.apache.james.imap.message.response.LSubResponse;
 import org.apache.james.mailbox.MailboxManager;
@@ -101,7 +102,7 @@ class LSubProcessorTest {
             Object[] args = invocation.getArguments();
             return (Mono) args[0];
         });
-        processor = new LSubProcessor(mailboxManager, manager, 
serverResponseFactory, new RecordingMetricFactory());
+        processor = new LSubProcessor(mailboxManager, manager, 
serverResponseFactory, new RecordingMetricFactory(), 
PathConverter.Factory.DEFAULT);
         session.setMailboxSession(mailboxSession);
     }
 


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

Reply via email to