@@ -7,6 +7,7 @@ import org.thp.scalligraph.{
77 AuthenticationError ,
88 AuthorizationError ,
99 BadConfigurationError ,
10+ BadRequestError ,
1011 EntityIdOrName ,
1112 NotSupportedError ,
1213 RichSeq ,
@@ -58,26 +59,34 @@ class MultiAuthSrv(configuration: Configuration, appConfig: ApplicationConfig, a
5859 override def capabilities : Set [AuthCapability .Value ] = authProviders.flatMap(_.capabilities).toSet
5960
6061 private def forAllAuthProviders [A ](providers : Seq [AuthSrv ])(body : AuthSrv => Try [A ]): Try [A ] =
61- providers.foldLeft[Either [Seq [(String , Throwable )], A ]](Left (Seq ())) {
62- case (right : Right [_, _], _) => right
63- case (Left (errors), auth) =>
62+ providers.foldLeft[MultiAuthProviderResponse [A ]](MultiAuthProviderResponse .Errors (Seq .empty)) {
63+ case (ok : MultiAuthProviderResponse .Ok [_], _) => ok
64+ case (stopping : MultiAuthProviderResponse .StoppingError , _) => stopping
65+ case (MultiAuthProviderResponse .Errors (errors), auth) =>
6466 body(auth).fold(
6567 {
66- case _ : NotSupportedError => Left (errors)
67- case error => Left (errors :+ ((auth.name, error)))
68+ case bre : BadRequestError => MultiAuthProviderResponse .StoppingError (auth.name -> bre, errors)
69+ case _ : NotSupportedError => MultiAuthProviderResponse .Errors (errors)
70+ case error => MultiAuthProviderResponse .Errors (errors :+ (auth.name -> error))
6871 },
69- success => Right (success)
72+ success => MultiAuthProviderResponse . Ok (success)
7073 )
7174 } match {
72- case Right (auth) => Success (auth)
73- case Left (errors) =>
74- errors
75- .foreach {
76- case (authName, AuthenticationError (_, cause)) if cause != null => logAuthError(authName, cause)
77- case (authName, AuthorizationError (_, cause)) if cause != null => logAuthError(authName, cause)
78- case (authName, error) => logAuthError(authName, error)
79- }
75+ case MultiAuthProviderResponse .Ok (value) => Success (value)
76+ case MultiAuthProviderResponse .Errors (errors) =>
77+ errors.foreach {
78+ case (authName, AuthenticationError (_, cause)) if cause != null => logAuthError(authName, cause)
79+ case (authName, AuthorizationError (_, cause)) if cause != null => logAuthError(authName, cause)
80+ case (authName, error) => logAuthError(authName, error)
81+ }
8082 errors.headOption.fold(Failure (AuthorizationError (" Operation not supported" )))(e => Failure (e._2))
83+ case MultiAuthProviderResponse .StoppingError (error, previousErrors) =>
84+ (previousErrors :+ error).foreach {
85+ case (authName, AuthenticationError (_, cause)) if cause != null => logAuthError(authName, cause)
86+ case (authName, AuthorizationError (_, cause)) if cause != null => logAuthError(authName, cause)
87+ case (authName, error) => logAuthError(authName, error)
88+ }
89+ Failure (error._2)
8190 }
8291
8392 private def logAuthError (authName : String , error : Throwable ): Unit = {
@@ -121,6 +130,13 @@ class MultiAuthSrv(configuration: Configuration, appConfig: ApplicationConfig, a
121130 forAllAuthProviders(authProviders)(_.removeKey(username))
122131}
123132
133+ sealed trait MultiAuthProviderResponse [+ A ]
134+ object MultiAuthProviderResponse {
135+ case class Ok [A ](value : A ) extends MultiAuthProviderResponse [A ]
136+ case class Errors (errors : Seq [(String , Throwable )]) extends MultiAuthProviderResponse [Nothing ]
137+ case class StoppingError (error : (String , Throwable ), previousErrors : Seq [(String , Throwable )]) extends MultiAuthProviderResponse [Nothing ]
138+ }
139+
124140class MultiAuthSrvProvider (appConfig : ApplicationConfig , authProviders : Seq [AuthSrvProvider ]) extends AuthSrvProvider {
125141 def this (app : ScalligraphApplication ) = this (app.applicationConfig, app.authSrvProviders)
126142
0 commit comments