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

commit 53b40cdffc5826a94c9a16593e72ad98f49019d3
Author: Benoit TELLIER <[email protected]>
AuthorDate: Thu Mar 12 16:32:18 2026 +0100

    JAMES-4189 Handle UsersRepository::listUsersOfADomainReactive without 
virtualHosting
---
 .../org/apache/james/user/api/UsersRepository.java   |  9 +--------
 .../apache/james/user/ldap/ReadOnlyLDAPUsersDAO.java |  6 +++---
 .../java/org/apache/james/user/lib/UsersDAO.java     |  4 ++--
 .../apache/james/user/lib/UsersRepositoryImpl.java   |  6 +-----
 .../james/user/lib/UsersRepositoryContract.java      | 20 +++++++++++---------
 .../apache/james/user/postgres/PostgresUsersDAO.java |  5 ++++-
 .../apache/james/webadmin/routes/DomainsRoutes.java  | 16 +++++-----------
 .../james/webadmin/routes/DomainsRoutesTest.java     | 11 ++++++-----
 8 files changed, 33 insertions(+), 44 deletions(-)

diff --git 
a/server/data/data-api/src/main/java/org/apache/james/user/api/UsersRepository.java
 
b/server/data/data-api/src/main/java/org/apache/james/user/api/UsersRepository.java
index 0ee3817ccf..b730b3e6c3 100644
--- 
a/server/data/data-api/src/main/java/org/apache/james/user/api/UsersRepository.java
+++ 
b/server/data/data-api/src/main/java/org/apache/james/user/api/UsersRepository.java
@@ -188,16 +188,9 @@ public interface UsersRepository {
     }
 
     default Publisher<Username> listUsersOfADomainReactive(Domain domain) {
-        try {
-            if (!supportVirtualHosting()) {
-                return Flux.error(new 
IllegalStateException("listUsersOfADomainReactive is not supported when virtual 
hosting is disabled"));
-            }
-        } catch (UsersRepositoryException e) {
-            return Flux.error(e);
-        }
         return Flux.from(listReactive())
             .filter(username -> username.getDomainPart()
                 .map(domain::equals)
-                .orElse(false));
+                .orElse(!supportVirtualHosting()));
     }
 }
diff --git 
a/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyLDAPUsersDAO.java
 
b/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyLDAPUsersDAO.java
index 70bb67f675..473b862431 100644
--- 
a/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyLDAPUsersDAO.java
+++ 
b/server/data/data-ldap/src/main/java/org/apache/james/user/ldap/ReadOnlyLDAPUsersDAO.java
@@ -342,7 +342,7 @@ public class ReadOnlyLDAPUsersDAO implements UsersDAO, 
Configurable {
 
 
     @Override
-    public Flux<Username> listUsersOfADomainReactive(Domain domain) {
+    public Flux<Username> listUsersOfADomainReactive(Domain domain, boolean 
supportsVirtualHosting) {
         return Flux.fromStream(() -> {
                 try {
                     return getUsernamesForDomain(domain);
@@ -359,7 +359,7 @@ public class ReadOnlyLDAPUsersDAO implements UsersDAO, 
Configurable {
         }
         return buildUserCollection(getValidUserDNs()).stream()
             .map(ReadOnlyLDAPUser::getUserName)
-            .filter(username -> 
username.getDomainPart().map(domain::equals).orElse(false))
+            .filter(username -> 
username.getDomainPart().map(domain::equals).orElse(!ldapConfiguration.supportsVirtualHosting()))
             .distinct();
     }
 
@@ -380,7 +380,7 @@ public class ReadOnlyLDAPUsersDAO implements UsersDAO, 
Configurable {
                     return Stream.empty();
                 }
             })
-            .filter(username -> 
username.getDomainPart().map(domain::equals).orElse(false))
+            .filter(username -> 
username.getDomainPart().map(domain::equals).orElse(!ldapConfiguration.supportsVirtualHosting()))
             .distinct();
     }
 
diff --git 
a/server/data/data-library/src/main/java/org/apache/james/user/lib/UsersDAO.java
 
b/server/data/data-library/src/main/java/org/apache/james/user/lib/UsersDAO.java
index c333f3af76..38b818e5a2 100644
--- 
a/server/data/data-library/src/main/java/org/apache/james/user/lib/UsersDAO.java
+++ 
b/server/data/data-library/src/main/java/org/apache/james/user/lib/UsersDAO.java
@@ -65,11 +65,11 @@ public interface UsersDAO {
         }).subscribeOn(Schedulers.boundedElastic());
     }
 
-    default Publisher<Username> listUsersOfADomainReactive(Domain domain) {
+    default Publisher<Username> listUsersOfADomainReactive(Domain domain, 
boolean supportsVirtualHosting) {
         return Flux.from(listReactive())
             .filter(username -> username.getDomainPart()
                 .map(domain::equals)
-                .orElse(false));
+                .orElse(!supportsVirtualHosting));
     }
 
     void addUser(Username username, String password) throws 
UsersRepositoryException;
diff --git 
a/server/data/data-library/src/main/java/org/apache/james/user/lib/UsersRepositoryImpl.java
 
b/server/data/data-library/src/main/java/org/apache/james/user/lib/UsersRepositoryImpl.java
index cf0beacad3..b8cbbdba8c 100644
--- 
a/server/data/data-library/src/main/java/org/apache/james/user/lib/UsersRepositoryImpl.java
+++ 
b/server/data/data-library/src/main/java/org/apache/james/user/lib/UsersRepositoryImpl.java
@@ -52,7 +52,6 @@ import com.github.fge.lambdas.Throwing;
 import com.google.common.base.CharMatcher;
 import com.google.common.collect.ImmutableSet;
 
-import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 
 public class UsersRepositoryImpl<T extends UsersDAO> implements 
UsersRepository, Configurable {
@@ -265,10 +264,7 @@ public class UsersRepositoryImpl<T extends UsersDAO> 
implements UsersRepository,
 
     @Override
     public Publisher<Username> listUsersOfADomainReactive(Domain domain) {
-        if (!virtualHosting) {
-            return Flux.error(new 
IllegalStateException("listUsersOfADomainReactive is not supported when virtual 
hosting is disabled"));
-        }
-        return usersDAO.listUsersOfADomainReactive(domain);
+        return usersDAO.listUsersOfADomainReactive(domain, 
supportVirtualHosting());
     }
 
     @Override
diff --git 
a/server/data/data-library/src/test/java/org/apache/james/user/lib/UsersRepositoryContract.java
 
b/server/data/data-library/src/test/java/org/apache/james/user/lib/UsersRepositoryContract.java
index fbad8b98eb..22c64045ad 100644
--- 
a/server/data/data-library/src/test/java/org/apache/james/user/lib/UsersRepositoryContract.java
+++ 
b/server/data/data-library/src/test/java/org/apache/james/user/lib/UsersRepositoryContract.java
@@ -782,20 +782,22 @@ public interface UsersRepositoryContract {
             assertThatCode(() -> testee().assertValid(withOutDomainPart))
                 .doesNotThrowAnyException();
         }
-
-        @Test
-        default void 
listUsersOfADomainShouldFailWhenVirtualHostingIsDisabled(TestSystem testSystem) 
{
-            assertThatThrownBy(() -> 
Flux.from(testee().listUsersOfADomainReactive(TestSystem.DOMAIN))
-                .collectList()
-                .block())
-                .isInstanceOf(IllegalStateException.class)
-                .hasMessageContaining("listUsersOfADomainReactive is not 
supported when virtual hosting is disabled");
-        }
     }
 
     interface WithVirtualHostingContract extends 
WithVirtualHostingReadOnlyContract, WithVirtualHostingReadWriteContract {
     }
 
     interface WithOutVirtualHostingContract extends 
WithOutVirtualHostingReadOnlyContract, ReadWriteContract {
+        @Test
+        default void listUsersOfADomainShouldReturnAllUsers(TestSystem 
testSystem) throws Exception {
+            testSystem.domainList.addDomain(Domain.of("domain1.tld"));
+            testee().addUser(Username.of("user1"), "password");
+            testee().addUser(Username.of("user2"), "password");
+
+            
assertThat(Flux.from(testee().listUsersOfADomainReactive(Domain.of("domain1.tld")))
+                .collectList()
+                .block())
+                .containsOnly(Username.of("user1"), Username.of("user2"));
+        }
     }
 }
diff --git 
a/server/data/data-postgres/src/main/java/org/apache/james/user/postgres/PostgresUsersDAO.java
 
b/server/data/data-postgres/src/main/java/org/apache/james/user/postgres/PostgresUsersDAO.java
index ba7c49e631..908f086462 100644
--- 
a/server/data/data-postgres/src/main/java/org/apache/james/user/postgres/PostgresUsersDAO.java
+++ 
b/server/data/data-postgres/src/main/java/org/apache/james/user/postgres/PostgresUsersDAO.java
@@ -148,7 +148,10 @@ public class PostgresUsersDAO implements UsersDAO {
     }
 
     @Override
-    public Flux<Username> listUsersOfADomainReactive(Domain domain) {
+    public Flux<Username> listUsersOfADomainReactive(Domain domain, boolean 
supportsVirtualHosting) {
+        if (!supportsVirtualHosting) {
+            return listReactive();
+        }
         String domainPattern = "%@" + domain.asString();
         return postgresExecutor.executeRows(dslContext -> Flux.from(
                 dslContext.select(USERNAME)
diff --git 
a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DomainsRoutes.java
 
b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DomainsRoutes.java
index a1108e5926..ee4362f1fa 100644
--- 
a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DomainsRoutes.java
+++ 
b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DomainsRoutes.java
@@ -35,7 +35,6 @@ import 
org.apache.james.rrt.api.RecipientRewriteTableException;
 import org.apache.james.rrt.api.SameSourceAndDestinationException;
 import org.apache.james.task.TaskManager;
 import org.apache.james.user.api.UsersRepository;
-import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.webadmin.Routes;
 import org.apache.james.webadmin.dto.DomainAliasResponse;
 import org.apache.james.webadmin.service.DeleteUserDataService;
@@ -146,8 +145,10 @@ public class DomainsRoutes implements Routes {
 
     public void defineGetDomains() {
         service.get(DOMAINS,
-            (request, response) ->
-                
domainList.getDomains().stream().map(Domain::name).collect(Collectors.toList()),
+            (request, response) -> domainList.getDomains()
+                .stream()
+                .map(Domain::name)
+                .collect(Collectors.toList()),
             jsonTransformer);
     }
 
@@ -159,14 +160,7 @@ public class DomainsRoutes implements Routes {
         service.get(DOMAIN_USERS, this::listUsersOfDomain, jsonTransformer);
     }
 
-    private List<String> listUsersOfDomain(Request request, Response response) 
throws UsersRepositoryException, DomainListException {
-        if (!usersRepository.supportVirtualHosting()) {
-            throw ErrorResponder.builder()
-                .statusCode(HttpStatus.METHOD_NOT_ALLOWED_405)
-                .type(ErrorType.WRONG_STATE)
-                .message("Virtual hosting must be enabled to list users by 
domain")
-                .haltError();
-        }
+    private List<String> listUsersOfDomain(Request request, Response response) 
throws DomainListException {
         Domain domain = checkValidDomain(request.params(DOMAIN_NAME));
         if (!domainList.containsDomain(domain)) {
             throw domainNotFound(domain);
diff --git 
a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DomainsRoutesTest.java
 
b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DomainsRoutesTest.java
index f7b583165f..0d8486acf9 100644
--- 
a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DomainsRoutesTest.java
+++ 
b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DomainsRoutesTest.java
@@ -944,15 +944,16 @@ class DomainsRoutesTest {
         }
 
         @Test
-        void getUsersOfDomainShouldReturn405WhenVirtualHostingDisabled() {
+        void getUsersOfDomainShouldReturnAllUsers() throws Exception {
+            usersRepository.addUser(Username.of("user1"), "password");
+            usersRepository.addUser(Username.of("user2"), "password");
+
             when()
                 .get(DOMAIN + "/users")
             .then()
                 .contentType(ContentType.JSON)
-                .statusCode(HttpStatus.METHOD_NOT_ALLOWED_405)
-                .body("statusCode", is(HttpStatus.METHOD_NOT_ALLOWED_405))
-                .body("type", is("WrongState"))
-                .body("message", is("Virtual hosting must be enabled to list 
users by domain"));
+                .statusCode(HttpStatus.OK_200)
+                .body(".", containsInAnyOrder("user1", "user2"));
         }
     }
 


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

Reply via email to