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