JAMES-3933 BasicAuthenticationStrategy should throw a proper error message when invalid credentials
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/AuthenticationContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/AuthenticationContract.scala
index 86a3fbc..4369683 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/AuthenticationContract.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/AuthenticationContract.scala
@@ -166,7 +166,7 @@
         .statusCode(SC_UNAUTHORIZED)
         .body("status", equalTo(401))
         .body("type", equalTo("about:blank"))
-        .body("detail", equalTo("No valid authentication methods provided"))
+        .body("detail", equalTo("Wrong credentials provided"))
     }
   }
 
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/custom/authentication/strategy/ModularizeJmapRFC8621AuthenticationStrategyContract.java b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/custom/authentication/strategy/ModularizeJmapRFC8621AuthenticationStrategyContract.java
index 3937856..6b2687f 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/custom/authentication/strategy/ModularizeJmapRFC8621AuthenticationStrategyContract.java
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/custom/authentication/strategy/ModularizeJmapRFC8621AuthenticationStrategyContract.java
@@ -182,7 +182,7 @@
             .statusCode(SC_UNAUTHORIZED)
             .body("status", equalTo(401))
             .body("type", equalTo("about:blank"))
-            .body("detail", equalTo("No valid authentication methods provided"));
+            .body("detail", equalTo("Wrong credentials provided"));
     }
 
     @Test
@@ -199,7 +199,7 @@
     }
 
     @Test
-    public void givenDefaultStrategiesWhenEchoMethodWithValidUnknownUserJWTAuthenticationShouldSucceed(GuiceJamesServer server) throws Throwable {
+    public void givenDefaultStrategiesWhenEchoMethodWithValidUnknownUserJWTAuthenticationShouldFail(GuiceJamesServer server) throws Throwable {
         setupJamesServerWithCustomAuthenticationStrategy(server, DEFAULT_STRATEGIES);
 
         given()
@@ -215,7 +215,7 @@
     }
 
     @Test
-    public void givenDefaultStrategiesWhenEchoMethodWithInvalidJWTAuthenticationShouldSucceed(GuiceJamesServer server) throws Throwable {
+    public void givenDefaultStrategiesWhenEchoMethodWithInvalidJWTAuthenticationShouldFail(GuiceJamesServer server) throws Throwable {
         setupJamesServerWithCustomAuthenticationStrategy(server, DEFAULT_STRATEGIES);
 
         given()
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/BasicAuthenticationStrategy.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/BasicAuthenticationStrategy.scala
index 876a1b4..73029b5 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/BasicAuthenticationStrategy.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/http/BasicAuthenticationStrategy.scala
@@ -34,7 +34,7 @@
 import org.apache.james.util.ReactorUtils
 import org.slf4j.LoggerFactory
 import reactor.core.publisher.Mono
-import reactor.core.scala.publisher.SMono
+import reactor.core.scala.publisher.{SMono, scalaOption2JavaOptional}
 import reactor.netty.http.server.HttpServerRequest
 
 import scala.jdk.CollectionConverters._
@@ -118,8 +118,7 @@
       .map(parseUserCredentials)
       .handle(publishNext)
       .flatMap(getAuthenticatedUsername)
-      .filter(_.isDefined)
-      .map(loggedInUser => mailboxManager.authenticate(loggedInUser.get).withoutDelegation())
+      .map(loggedInUser => mailboxManager.authenticate(loggedInUser).withoutDelegation())
       .asJava()
 
 
@@ -129,7 +128,8 @@
   private def publishNext[T]: (Option[T], reactor.core.publisher.SynchronousSink[T]) => Unit =
     (maybeT, sink) => maybeT.foreach(t => sink.next(t))
 
-  private def getAuthenticatedUsername(userCredential: UserCredential): SMono[Option[Username]] =
-    SMono.fromCallable(() => usersRepository.test(userCredential.username, userCredential.password).toScala)
+  private def getAuthenticatedUsername(userCredential: UserCredential): SMono[Username] =
+    SMono.fromCallable(() => usersRepository.test(userCredential.username, userCredential.password)
+          .orElseThrow(() => new UnauthorizedException("Wrong credentials provided")))
       .subscribeOn(ReactorUtils.BLOCKING_CALL_WRAPPER)
 }