diff --git a/module/src/main/scala/jp/t2v/lab/play2/auth/AsyncAuth.scala b/module/src/main/scala/jp/t2v/lab/play2/auth/AsyncAuth.scala index 35b77ec..da1f073 100644 --- a/module/src/main/scala/jp/t2v/lab/play2/auth/AsyncAuth.scala +++ b/module/src/main/scala/jp/t2v/lab/play2/auth/AsyncAuth.scala @@ -16,7 +16,7 @@ trait AsyncAuth { case Right((user, resultUpdater)) => authorize(user, authority) collect { case true => Right(user -> resultUpdater) } recoverWith { - case _ => authorizationFailed(request).map(Left.apply) + case _ => authorizationFailed(request, user, Some(authority)).map(Left.apply) } case Left(result) => Future.successful(Left(result)) } diff --git a/module/src/main/scala/jp/t2v/lab/play2/auth/AuthActionBuilders.scala b/module/src/main/scala/jp/t2v/lab/play2/auth/AuthActionBuilders.scala index dd56a0a..53f1560 100644 --- a/module/src/main/scala/jp/t2v/lab/play2/auth/AuthActionBuilders.scala +++ b/module/src/main/scala/jp/t2v/lab/play2/auth/AuthActionBuilders.scala @@ -41,7 +41,7 @@ trait AuthActionBuilders extends AsyncAuth { self: AuthConfig with Controller => authorize(request.user, authority) collect { case true => None } recoverWith { - case _ => authorizationFailed(request).map(Some.apply) + case _ => authorizationFailed(request, request.user, Some(authority)).map(Some.apply) } } } diff --git a/module/src/main/scala/jp/t2v/lab/play2/auth/AuthConfig.scala b/module/src/main/scala/jp/t2v/lab/play2/auth/AuthConfig.scala index 1d36f9f..27e3a28 100644 --- a/module/src/main/scala/jp/t2v/lab/play2/auth/AuthConfig.scala +++ b/module/src/main/scala/jp/t2v/lab/play2/auth/AuthConfig.scala @@ -24,8 +24,13 @@ trait AuthConfig { def authenticationFailed(request: RequestHeader)(implicit context: ExecutionContext): Future[Result] + @deprecated("it will be deleted since 0.14.x. use authorizationFailed(RequestHeader, User, Option[Authority])", since = "0.13.1") def authorizationFailed(request: RequestHeader)(implicit context: ExecutionContext): Future[Result] + def authorizationFailed(request: RequestHeader, user: User, authority: Option[Authority])(implicit context: ExecutionContext): Future[Result] = { + authorizationFailed(request) + } + def authorize(user: User, authority: Authority)(implicit context: ExecutionContext): Future[Boolean] lazy val idContainer: AsyncIdContainer[Id] = AsyncIdContainer(new CacheIdContainer[Id]) diff --git a/module/src/main/scala/jp/t2v/lab/play2/auth/AuthElement.scala b/module/src/main/scala/jp/t2v/lab/play2/auth/AuthElement.scala index 3187065..5362a60 100644 --- a/module/src/main/scala/jp/t2v/lab/play2/auth/AuthElement.scala +++ b/module/src/main/scala/jp/t2v/lab/play2/auth/AuthElement.scala @@ -14,11 +14,17 @@ trait AuthElement extends StackableController with AsyncAuth { implicit val (r, ctx) = (req, StackActionExecutionContext(req)) req.get(AuthorityKey) map { authority => authorized(authority) flatMap { - case Right((user, cookieUpdater)) => super.proceed(req.set(AuthKey, user))(f).map(cookieUpdater) + case Right((user, resultUpdater)) => super.proceed(req.set(AuthKey, user))(f).map(resultUpdater) case Left(result) => Future.successful(result) } } getOrElse { - authorizationFailed(req) + restoreUser collect { + case (Some(user), _) => user + } flatMap { + authorizationFailed(req, _, None) + } recoverWith { + case _ => authenticationFailed(req) + } } } diff --git a/sample/app/controllers/BaseAuthConfig.scala b/sample/app/controllers/BaseAuthConfig.scala index d990dc3..76ec9a2 100644 --- a/sample/app/controllers/BaseAuthConfig.scala +++ b/sample/app/controllers/BaseAuthConfig.scala @@ -8,6 +8,7 @@ import play.api.mvc.Results._ import scala.concurrent.{Future, ExecutionContext} import scala.reflect._ +import play.Logger trait BaseAuthConfig extends AuthConfig { @@ -19,7 +20,11 @@ trait BaseAuthConfig extends AuthConfig { val sessionTimeoutInSeconds = 3600 def resolveUser(id: Id)(implicit ctx: ExecutionContext) = Future.successful(Account.findById(id)) - def authorizationFailed(request: RequestHeader)(implicit ctx: ExecutionContext) = Future.successful(Forbidden("no permission")) + def authorizationFailed(request: RequestHeader)(implicit ctx: ExecutionContext) = throw new AssertionError("don't use") + override def authorizationFailed(request: RequestHeader, user: User, authority: Option[Authority])(implicit ctx: ExecutionContext) = { + Logger.info(s"authorizationFailed. userId: ${user.id}, userName: ${user.name}, authority: $authority") + Future.successful(Forbidden("no permission")) + } def authorize(user: User, authority: Authority)(implicit ctx: ExecutionContext) = Future.successful((user.role, authority) match { case (Administrator, _) => true case (NormalUser, NormalUser) => true