Levijatanu
Levijatanu

Reputation: 418

PlayFramework migration 2.5.x to 2.6.x deprecated Action.async

Trying to migrate from 2.5.x to 2.6.x. I have trait Secured with old method IsAuthenticatedAsync, i'm trying to write new method IsAuthenticatedAsyncNew. Compiler says that Action.async is deprecated, so I tried to replace Action.asyinc block with ActionBuilder but I'm struggling as I can't find good 2.6.x examples how to do this.

trait Secured {
  private def username(request: RequestHeader) = request.session.get("username")
  private def onUnauthorized(request: RequestHeader) = Results.Redirect(routes.Application.login())
  def userService: UserService
  def cc: ControllerComponents

  /**
   * Async action for authenticated users.
   */
  def IsAuthenticatedAsync(f: => User => Request[AnyContent] => Future[Result]) = Security.Authenticated(username, onUnauthorized) { user =>
    Action.async{ implicit request =>
      val _user = userService.findByUsername(user)
      if(_user.nonEmpty)
        f(_user.get)(request)
      else
        Future.successful(Results.Redirect(routes.Application.login()))
    }
  }


  def IsAuthenticatedAsyncNew(f: => User => Request[AnyContent] => Future[Result]) = new ActionBuilder[Request, AnyContent] {
    override def invokeBlock[A](request: Request[A], block: Request[A] => Future[Result]) = {
      val username = request.session.get("username")
      val user = userService.findByUsername(username.get)
      user match {
        case Some(user) => f(user)(request)
        case None => Future.successful(Results.Redirect(routes.Application.login()))
      }
    }


    override protected def executionContext: ExecutionContext = cc.executionContext
    override def parser: BodyParser[AnyContent] = cc.parsers.defaultBodyParser
  }

}

Compiler returns error

Error:(40, 36) type mismatch;
 found   : play.api.mvc.Request[A]
 required: play.api.mvc.Request[play.api.mvc.AnyContent]
        case Some(user) => f(user)(request)

If i change footprint of method to

 override def invokeBlock(request: Request[AnyContent], block: Request[AnyContent] => Future[Result]) 

then it doesn't ovveride nothing ... Can it be done this way at all?

Upvotes: 1

Views: 356

Answers (1)

Łukasz
Łukasz

Reputation: 8663

Action in play 2.6 is defined in BaseController trait as

def Action: ActionBuilder[Request, AnyContent] = controllerComponents.actionBuilder

This means that you can simply replace Action.async with cc.actionBuilder.async(...)

or even copy that method

def Action = cc.actionBuilder

and use Action.async as previously.

Upvotes: 2

Related Questions