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

btellier 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 a190bf8555 JAMES-2128 IMAP list should skip mailboxes not handled by 
the naming schema (#2506)
a190bf8555 is described below

commit a190bf855565225696b76f66b1ef0834078b7cfb
Author: Benoit TELLIER <btell...@linagora.com>
AuthorDate: Tue Nov 19 15:07:57 2024 +0700

    JAMES-2128 IMAP list should skip mailboxes not handled by the naming schema 
(#2506)
---
 .../org/apache/james/imap/main/PathConverter.java  |  9 +++--
 .../apache/james/imap/processor/LSubProcessor.java |  2 +-
 .../apache/james/imap/processor/ListProcessor.java | 46 ++++++++++++----------
 .../james/imap/processor/StatusProcessor.java      |  5 ++-
 .../apache/james/imap/main/PathConverterTest.java  | 28 ++++++-------
 5 files changed, 49 insertions(+), 41 deletions(-)

diff --git 
a/protocols/imap/src/main/java/org/apache/james/imap/main/PathConverter.java 
b/protocols/imap/src/main/java/org/apache/james/imap/main/PathConverter.java
index 5164f14602..7987eafd24 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/main/PathConverter.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/main/PathConverter.java
@@ -20,6 +20,7 @@
 package org.apache.james.imap.main;
 
 import java.util.List;
+import java.util.Optional;
 
 import org.apache.james.core.Domain;
 import org.apache.james.core.Username;
@@ -160,11 +161,11 @@ public interface PathConverter {
             return sb.toString();
         }
 
-        public String mailboxName(boolean relative, MailboxPath path, 
MailboxSession session) {
+        public Optional<String> mailboxName(boolean relative, MailboxPath 
path, MailboxSession session) {
             if (relative && path.belongsTo(session)) {
-                return path.getName();
+                return Optional.of(path.getName());
             } else {
-                return joinMailboxPath(path, session);
+                return Optional.of(joinMailboxPath(path, session));
             }
         }
 
@@ -250,7 +251,7 @@ public interface PathConverter {
 
     MailboxPath buildFullPath(String mailboxName);
 
-    String mailboxName(boolean relative, MailboxPath path, MailboxSession 
session);
+    Optional<String> mailboxName(boolean relative, MailboxPath path, 
MailboxSession session);
 
     MailboxQuery mailboxQuery(String finalReferencename, String mailboxName, 
ImapSession session);
 }
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 581b0472e0..1ba7850434 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
@@ -81,7 +81,7 @@ public class LSubProcessor extends 
AbstractMailboxProcessor<LsubRequest> {
         try {
             PathConverter pathConverter = 
pathConverterFactory.forSession(session);
             Mono<List<String>> mailboxesMono = 
Flux.from(subscriptionManager.subscriptionsReactive(mailboxSession))
-                .map(path -> pathConverter.mailboxName(RELATIVE, path, 
mailboxSession))
+                .<String>handle((path, sink) -> 
pathConverter.mailboxName(RELATIVE, path, mailboxSession).ifPresent(sink::next))
                 .collectList();
 
             String decodedMailName = 
ModifiedUtf7.decodeModifiedUTF7(referenceName);
diff --git 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/ListProcessor.java
 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/ListProcessor.java
index ee3cce3edc..17c92b022a 100644
--- 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/ListProcessor.java
+++ 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/ListProcessor.java
@@ -213,13 +213,14 @@ public class ListProcessor<T extends ListRequest> extends 
AbstractMailboxProcess
             .doOnNext(metaData -> {
                 MailboxType mailboxType = getMailboxType(request, session, 
metaData.getPath());
                 if (!request.getSelectOptions().contains(SPECIAL_USE) || 
mailboxType.getRfc6154attributeName() != null) {
-                    responder.respond(
-                        createResponse(metaData.inferiors(),
-                            metaData.getSelectability(),
-                            
pathConverterFactory.forSession(session).mailboxName(isRelative, 
metaData.getPath(), mailboxSession),
-                            metaData.getHierarchyDelimiter(),
-                            mailboxType,
-                            isSubscribed.test(metaData.getPath())));
+                    
pathConverterFactory.forSession(session).mailboxName(isRelative, 
metaData.getPath(), mailboxSession)
+                            .ifPresent(mailboxName -> responder.respond(
+                                createResponse(metaData.inferiors(),
+                                    metaData.getSelectability(),
+                                    mailboxName,
+                                    metaData.getHierarchyDelimiter(),
+                                    mailboxType,
+                                    isSubscribed.test(metaData.getPath()))));
                 }
             })
             .doOnNext(metaData -> respondMyRights(request, responder, 
mailboxSession, metaData, isRelative))
@@ -267,23 +268,24 @@ public class ListProcessor<T extends ListRequest> extends 
AbstractMailboxProcess
         allSubscribedSearch.stream()
             .filter(subscribed -> !listRecursiveMatchPath.contains(subscribed))
             .filter(mailboxQuery::isPathMatch)
-            .map(subscribed -> buildListResponse(listRequest, 
searchedResultMap, session, relative, subscribed))
+            .flatMap(subscribed -> buildListResponse(listRequest, 
searchedResultMap, session, relative, subscribed).stream())
             .filter(pair -> 
!listRequest.getSelectOptions().contains(SPECIAL_USE) || 
mailboxTyper.getMailboxType(session, pair.getKey()).getRfc6154attributeName() 
!= null)
             .forEach(pair -> responseBuilders.add(Triple.of(pair.getLeft(), 
pair.getRight(), Optional.ofNullable(searchedResultMap.get(pair.getLeft())))));
 
         return responseBuilders.build();
     }
 
-    private Pair<MailboxPath, ListResponse> buildListResponse(ListRequest 
listRequest, Map<MailboxPath, MailboxMetaData> searchedResultMap, ImapSession 
session, boolean relative, MailboxPath subscribed) {
-        return Pair.of(subscribed, 
Optional.ofNullable(searchedResultMap.get(subscribed))
+    private Optional<Pair<MailboxPath, ListResponse>> 
buildListResponse(ListRequest listRequest, Map<MailboxPath, MailboxMetaData> 
searchedResultMap, ImapSession session, boolean relative, MailboxPath 
subscribed) {
+        return pathConverterFactory.forSession(session).mailboxName(relative, 
subscribed, session.getMailboxSession())
+            .map(name -> Pair.of(subscribed, 
Optional.ofNullable(searchedResultMap.get(subscribed))
             .map(mailboxMetaData -> ListResponse.builder()
                 .returnSubscribed(RETURN_SUBSCRIBED)
                 .forMetaData(mailboxMetaData)
-                
.name(pathConverterFactory.forSession(session).mailboxName(relative, 
subscribed, session.getMailboxSession()))
+                .name(name)
                 .returnNonExistent(!RETURN_NON_EXISTENT)
                 .mailboxType(getMailboxType(listRequest, session, 
mailboxMetaData.getPath())))
             .orElseGet(() -> 
ListResponse.builder().nonExitingSubscribedMailbox(subscribed))
-            .build());
+            .build()));
     }
 
     private List<Pair<MailboxPath, ListResponse>> 
listRecursiveMatch(ImapSession session, Map<MailboxPath, MailboxMetaData> 
searchedResultMap,
@@ -299,26 +301,28 @@ public class ListProcessor<T extends ListRequest> extends 
AbstractMailboxProcess
 
         return searchedResultMap.entrySet().stream()
             .filter(pair -> allSubscribedSearchParent.contains(pair.getKey()))
-            .map(pair -> {
+            .flatMap(pair -> {
                 MailboxMetaData metaData = pair.getValue();
-                ListResponse listResponse = ListResponse.builder()
+                Optional<String> maybeMailboxName = 
pathConverterFactory.forSession(session).mailboxName(relative, 
metaData.getPath(), mailboxSession);
+                return maybeMailboxName.map(mailboxName -> 
Pair.of(pair.getKey(), ListResponse.builder()
                     .forMetaData(metaData)
-                    
.name(pathConverterFactory.forSession(session).mailboxName(relative, 
metaData.getPath(), mailboxSession))
+                    .name(mailboxName)
                     .childInfos(ListResponse.ChildInfo.SUBSCRIBED)
                     
.returnSubscribed(allSubscribedSearch.contains(pair.getKey()))
                     .mailboxType(getMailboxType(listRequest, session, 
metaData.getPath()))
-                    .build();
-                return Pair.of(pair.getKey(), listResponse);
+                    .build()))
+                    .stream();
             })
             .collect(Collectors.toList());
     }
 
     private void respondMyRights(T request, Responder responder, 
MailboxSession mailboxSession, MailboxMetaData metaData, boolean isRelative) {
         if 
(request.getReturnOptions().contains(ListRequest.ListReturnOption.MYRIGHTS)) {
-            MailboxName mailboxName = new 
MailboxName(pathConverterFactory.forSession(mailboxSession)
-                .mailboxName(isRelative, metaData.getPath(), mailboxSession));
-            MyRightsResponse myRightsResponse = new 
MyRightsResponse(mailboxName, getRfc4314Rights(mailboxSession, metaData));
-            responder.respond(myRightsResponse);
+            pathConverterFactory.forSession(mailboxSession)
+                .mailboxName(isRelative, metaData.getPath(), mailboxSession)
+                .map(MailboxName::new)
+                .map(mailboxName -> new MyRightsResponse(mailboxName, 
getRfc4314Rights(mailboxSession, metaData)))
+                .ifPresent(responder::respond);
         }
     }
 
diff --git 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java
 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java
index bade56b99b..2c8d0ac79c 100644
--- 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java
+++ 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java
@@ -186,12 +186,15 @@ public class StatusProcessor extends 
AbstractMailboxProcessor<StatusRequest> imp
                 Long unseen = unseen(statusDataItems, metaData);
                 ModSeq highestModSeq = highestModSeq(statusDataItems, 
metaData);
                 MailboxId mailboxId = mailboxId(statusDataItems, mailbox);
+                String mailboxName = 
pathConverterFactory.forSession(mailboxSession)
+                    .mailboxName(RELATIVE, mailbox.getMailboxPath(), 
mailboxSession)
+                    .orElseThrow(() -> new RuntimeException("Not exposed 
mailbox"));
                 return new MailboxStatusResponse(
                     appendLimit,
                     maybeIterationResult.flatMap(result -> 
result.getSize(statusDataItems)).orElse(null),
                     maybeIterationResult.flatMap(result -> 
result.getDeleted(statusDataItems)).orElse(null),
                     maybeIterationResult.flatMap(result -> 
result.getDeletedStorage(statusDataItems)).orElse(null),
-                    messages, recent, uidNext, highestModSeq, uidValidity, 
unseen, pathConverterFactory.forSession(mailboxSession).mailboxName(RELATIVE, 
mailbox.getMailboxPath(), mailboxSession), mailboxId);
+                    messages, recent, uidNext, highestModSeq, uidValidity, 
unseen, mailboxName, mailboxId);
             });
     }
 
diff --git 
a/protocols/imap/src/test/java/org/apache/james/imap/main/PathConverterTest.java
 
b/protocols/imap/src/test/java/org/apache/james/imap/main/PathConverterTest.java
index 02a9a12807..3541ad53e3 100644
--- 
a/protocols/imap/src/test/java/org/apache/james/imap/main/PathConverterTest.java
+++ 
b/protocols/imap/src/test/java/org/apache/james/imap/main/PathConverterTest.java
@@ -137,49 +137,49 @@ class PathConverterTest {
     @Test
     void mailboxNameShouldReturnNameOnlyWhenRelativeAndUserMailbox() {
         assertThat(pathConverter.mailboxName(RELATIVE, 
MailboxPath.forUser(USERNAME, "abc"), mailboxSession))
-            .isEqualTo("abc");
+            .contains("abc");
     }
 
     @Test
     void mailboxNameShouldReturnFQDNWhenRelativeAndOtherUserMailbox() {
         assertThat(pathConverter.mailboxName(RELATIVE, 
MailboxPath.forUser(USERNAME2, "abc"), mailboxSession))
-            .isEqualTo("#user.username2.abc");
+            .contains("#user.username2.abc");
     }
 
     @Test
     void mailboxNameShouldEscapeDotInUsername() {
         assertThat(pathConverter.mailboxName(RELATIVE, 
MailboxPath.forUser(USERNAME_WITH_DOT, "abc"), mailboxSession))
-            .isEqualTo("#user.username__with__dot.abc");
+            .contains("#user.username__with__dot.abc");
     }
 
     @Test
     void mailboxNameShouldEscapeUnderscoreInUsername() {
         assertThat(pathConverter.mailboxName(RELATIVE, 
MailboxPath.forUser(USERNAME_WITH_UNDERSCORE, "abc"), mailboxSession))
-            .isEqualTo("#user.username_-with_-underscore.abc");
+            .contains("#user.username_-with_-underscore.abc");
     }
 
     @Test
     void mailboxNameShouldReturnFQDNWhenRelativeAndSharedMailbox() {
         assertThat(pathConverter.mailboxName(RELATIVE, new 
MailboxPath("#Shared", Username.of("marketing"), "abc"), mailboxSession))
-            .isEqualTo("#Shared.marketing.abc");
+            .contains("#Shared.marketing.abc");
     }
 
     @Test
     void mailboxNameShouldReturnFQDNWhenNotRelativeAndUserMailbox() {
         assertThat(pathConverter.mailboxName(!RELATIVE, 
MailboxPath.forUser(USERNAME, "abc"), mailboxSession))
-            .isEqualTo("#private.abc");
+            .contains("#private.abc");
     }
 
     @Test
     void mailboxNameShouldReturnFQDNWhenNotRelativeAndOtherUserMailbox() {
         assertThat(pathConverter.mailboxName(!RELATIVE, 
MailboxPath.forUser(USERNAME2, "abc"), mailboxSession))
-            .isEqualTo("#user.username2.abc");
+            .contains("#user.username2.abc");
     }
 
     @Test
     void mailboxNameShouldReturnFQDNWhenNotRelativeAndSharedMailbox() {
         assertThat(pathConverter.mailboxName(!RELATIVE, new 
MailboxPath("#Shared", Username.of("marketing"), "abc"), mailboxSession))
-            .isEqualTo("#Shared.marketing.abc");
+            .contains("#Shared.marketing.abc");
     }
     
     @Nested
@@ -257,37 +257,37 @@ class PathConverterTest {
         @Test
         void mailboxNameShouldReturnNameOnlyWhenRelativeAndUserMailbox() {
             assertThat(pathConverter.mailboxName(RELATIVE, 
MailboxPath.forUser(USERNAME_WITH_MAIL, "abc"), mailboxSession))
-                .isEqualTo("abc");
+                .contains("abc");
         }
 
         @Test
         void mailboxNameShouldReturnFQDNWhenRelativeAndOtherUserMailbox() {
             assertThat(pathConverter.mailboxName(RELATIVE, 
MailboxPath.forUser(USERNAME2_WITH_MAIL, "abc"), mailboxSession))
-                .isEqualTo("#user.username2.abc");
+                .contains("#user.username2.abc");
         }
 
         @Test
         void mailboxNameShouldReturnFQDNWhenRelativeAndSharedMailbox() {
             assertThat(pathConverter.mailboxName(RELATIVE, new 
MailboxPath("#Shared", Username.of("market...@apache.org"), "abc"), 
mailboxSession))
-                .isEqualTo("#Shared.marketing.abc");
+                .contains("#Shared.marketing.abc");
         }
 
         @Test
         void mailboxNameShouldReturnFQDNWhenNotRelativeAndUserMailbox() {
             assertThat(pathConverter.mailboxName(!RELATIVE, 
MailboxPath.forUser(USERNAME_WITH_MAIL, "abc"), mailboxSession))
-                .isEqualTo("#private.abc");
+                .contains("#private.abc");
         }
 
         @Test
         void mailboxNameShouldReturnFQDNWhenNotRelativeAndOtherUserMailbox() {
             assertThat(pathConverter.mailboxName(!RELATIVE, 
MailboxPath.forUser(USERNAME2_WITH_MAIL, "abc"), mailboxSession))
-                .isEqualTo("#user.username2.abc");
+                .contains("#user.username2.abc");
         }
 
         @Test
         void mailboxNameShouldReturnFQDNWhenNotRelativeAndSharedMailbox() {
             assertThat(pathConverter.mailboxName(!RELATIVE, new 
MailboxPath("#Shared", Username.of("market...@apache.org"), "abc"), 
mailboxSession))
-                .isEqualTo("#Shared.marketing.abc");
+                .contains("#Shared.marketing.abc");
         }
     }
 }


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

Reply via email to