Skip to content
This repository was archived by the owner on Mar 8, 2024. It is now read-only.

Commit 9825a31

Browse files
committed
MultiAuthSrv: Fail fast in case of BadRequestError
1 parent 2c16590 commit 9825a31

File tree

1 file changed

+29
-10
lines changed

1 file changed

+29
-10
lines changed

core/src/main/scala/org/thp/scalligraph/auth/MultiAuthSrv.scala

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package org.thp.scalligraph.auth
33
import org.thp.scalligraph.controllers.AuthenticatedRequest
44
import org.thp.scalligraph.services.config.ApplicationConfig.configurationFormat
55
import org.thp.scalligraph.services.config.{ApplicationConfig, ConfigItem}
6-
import org.thp.scalligraph.{AuthenticationError, AuthorizationError, BadConfigurationError, EntityIdOrName, RichSeq, ScalligraphApplication}
6+
import org.thp.scalligraph.{AuthenticationError, AuthorizationError, BadConfigurationError, BadRequestError, EntityIdOrName, RichSeq, ScalligraphApplication}
77
import play.api.mvc.{ActionFunction, Request, RequestHeader, Result}
88
import play.api.{Configuration, Logger}
99

@@ -49,18 +49,22 @@ class MultiAuthSrv(configuration: Configuration, appConfig: ApplicationConfig, a
4949

5050
override def capabilities: Set[AuthCapability.Value] = authProviders.flatMap(_.capabilities).toSet
5151

52-
private def forAllAuthProviders[A](providers: Seq[AuthSrv])(body: AuthSrv => Try[A]): Try[A] =
53-
providers.foldLeft[Either[Seq[(String, Throwable)], A]](Left(Seq())) {
54-
case (right: Right[_, _], _) => right
55-
case (Left(errors), auth) =>
52+
private def forAllAuthProviders[A](providers: Seq[AuthSrv])(body: AuthSrv => Try[A]): Try[A] = {
53+
providers.foldLeft[MultiAuthProviderResponse[A]](MultiAuthProviderResponse.Errors(Seq.empty)) {
54+
case (ok: MultiAuthProviderResponse.Ok[_], _) => ok
55+
case (stopping: MultiAuthProviderResponse.StoppingError, _) => stopping
56+
case (MultiAuthProviderResponse.Errors(errors), auth) =>
5657
body(auth).fold(
57-
error => Left(errors :+ ((auth.name, error))),
58-
success => Right(success)
58+
{
59+
case bre: BadRequestError => MultiAuthProviderResponse.StoppingError(auth.name -> bre, errors)
60+
case error => MultiAuthProviderResponse.Errors(errors :+ (auth.name -> error))
61+
},
62+
success => MultiAuthProviderResponse.Ok(success)
5963
)
6064
} match {
61-
case Right(auth) => Success(auth)
62-
case Left(Seq()) => Failure(AuthorizationError("no authentication provider found"))
63-
case Left(errors) =>
65+
case MultiAuthProviderResponse.Ok(value) => Success(value)
66+
case MultiAuthProviderResponse.Errors(Seq()) => Failure(AuthorizationError("no authentication provider found"))
67+
case MultiAuthProviderResponse.Errors(errors) =>
6468
errors.foreach {
6569
case (authName, AuthenticationError(_, cause)) if cause != null => logAuthError(authName, cause)
6670
case (authName, AuthorizationError(_, cause)) if cause != null => logAuthError(authName, cause)
@@ -70,7 +74,15 @@ class MultiAuthSrv(configuration: Configuration, appConfig: ApplicationConfig, a
7074
Failure(AuthorizationError("Operation not permitted"))
7175
else
7276
Failure(AuthenticationError("Authentication failure"))
77+
case MultiAuthProviderResponse.StoppingError(error, previousErrors) =>
78+
(previousErrors :+ error).foreach {
79+
case (authName, AuthenticationError(_, cause)) if cause != null => logAuthError(authName, cause)
80+
case (authName, AuthorizationError(_, cause)) if cause != null => logAuthError(authName, cause)
81+
case (authName, error) => logAuthError(authName, error)
82+
}
83+
Failure(error._2)
7384
}
85+
}
7486

7587
private def logAuthError(authName: String, error: Throwable): Unit = {
7688
logger.warn(s"$authName fails: $error")
@@ -113,6 +125,13 @@ class MultiAuthSrv(configuration: Configuration, appConfig: ApplicationConfig, a
113125
forAllAuthProviders(authProviders)(_.removeKey(username))
114126
}
115127

128+
sealed trait MultiAuthProviderResponse[+A]
129+
object MultiAuthProviderResponse {
130+
case class Ok[A](value: A) extends MultiAuthProviderResponse[A]
131+
case class Errors(errors: Seq[(String, Throwable)]) extends MultiAuthProviderResponse[Nothing]
132+
case class StoppingError(error: (String, Throwable), previousErrors: Seq[(String, Throwable)]) extends MultiAuthProviderResponse[Nothing]
133+
}
134+
116135
class MultiAuthSrvProvider(appConfig: ApplicationConfig, authProviders: Seq[AuthSrvProvider]) extends AuthSrvProvider {
117136
def this(app: ScalligraphApplication) = this(app.applicationConfig, app.authSrvProviders)
118137

0 commit comments

Comments
 (0)