Reputation: 2845
I am following the action composition documentation of play framework and I am trying to mimic the user authentication and permissions through action composition. I get a compilation error when I am trying to use andThen to pipeline authentication and permission check as described in the documentation.
My wrapped request:
type UserRequest[A] = AuthenticatedRequest[A,User]
Request to UserRequest transformation:
case object AuthAction extends ActionBuilder[UserRequest] with ActionRefiner[Request,UserRequest]{
override def refine[A](request: Request[A]): Future[Either[Result,UserRequest[A]]] = {
getUser(request) match {
case Some(user) => Future.successful(Right(new UserRequest(user,request)))
case _ => Future.successful(Left(oauthLogin(request)))
}
}
}
ActionFilter to manage permissions:
object PermissionHandler extends ActionFilter[UserRequest]{
override def filter[A](req:UserRequest[A]) = Future.successful{
if (!req.user.hasPermission(Employee)) {
Some(Unauthorized(views.html.defaultpages.unauthorized()))
} else None
}
}
My Index page:
def index = (AuthAction andThen PermissionHandler) {
Future.successful(Redirect(routes.Application.requestLeave))
}
compilation error:
[error] /home/venki/play/lrs/app/controllers/Application.scala:119: overloaded method value apply with alternatives:
[error] (block: => play.api.mvc.Result)play.api.mvc.Action[play.api.mvc.AnyContent] <and>
[error] (block: controllers.Application.UserRequest[play.api.mvc.AnyContent] => play.api.mvc.Result)play.api.mvc.Action[play.api.mvc.AnyContent] <and>
[error] [A](bodyParser: play.api.mvc.BodyParser[A])(block: controllers.Application.UserRequest[A] => play.api.mvc.Result)play.api.mvc.Action[A]
[error] cannot be applied to (scala.concurrent.Future[play.api.mvc.Result])
[error] def index = (AuthAction andThen PermissionHandler) {
[error] ^
[error] one error found
[error] (compile:compile) Compilation failed
Documentation used: https://www.playframework.com/documentation/2.3.x/ScalaActionsComposition
Upvotes: 1
Views: 1117
Reputation: 2845
Just posting to SO helped me solve this problem. modifying my index page like shown below fixed the problem, I should not wrap the result with Future.succesful while using normal version of the actions.
def index = (AuthAction andThen PermissionHandler) {
Redirect(routes.Application.requestLeave)
}
If I want to use the async version of the actions, I should mention it like below
def index = (AuthAction andThen PermissionHandler).async {
Future.successful(Redirect(routes.Application.requestLeave))
}
Upvotes: 1