vumaasha
vumaasha

Reputation: 2845

overloaded method value apply with alternatives with ActionFunction andThen

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

Answers (1)

vumaasha
vumaasha

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

Related Questions