I'm trying to wrap my head around Play action composition. My primary reference is: https://www.playframework.com/documentation/2.3.6/ScalaActionsComposition
Here's what I want to achieve (to be able to declare a function in my Controller this way):
def sensitiveOperation() = Protected {request => ...}
So, my action-plan is:
/**
* Now I need to make an Action builder that wraps two things:
* UserAction (to make sure that request is transformed to UserRequest),
* and then... an Action that checks if userId has a value (it proceeds by invoking the actual action)
* , or otherwise return Unauthorized
*/
So... I have these three things:
class UserRequest[A](val userId: Option[String], request: Request[A]) extends WrappedRequest[A](request)
object UserAction extends ActionBuilder[UserRequest] with ActionTransformer[Request, UserRequest] {
def transform[A](request: Request[A]) = Future.successful {
new UserRequest(request.session.get("userId"), request)
}
}
object CheckUserId extends ActionFilter[UserRequest] {
def filter[A](userRequest: UserRequest[A]) = Future.successful {
userRequest.userId match {
case Some(userIdVal) => None
case None => Some(Results.Unauthorized("User is not logged in. Log in first."))
}
}
}
All those three things compile.
My question is: how to declare an Action that makes use of UserAction and CheckUserId ?
object Protected extends ActionBuilder[Request] {
def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]) = {
block(request)
}
override def composeAction[A](action: Action[A]) = ... ?? how ?? ....
}
I've tried this one below, but it gives compile error:
override def composeAction[A](action: Action[A]) = UserAction andThen CheckUserId
ADDITIONAL ADDITIONAL
For now I can work around it using this:
def sensitiveOperation() = (UserAction andThen CheckUserId) {request => ...}
But, still, I think it would have been prettier if I can define a companion object named "Protected" that practically does the same (and-ing UserAction and CheckUserId)..., so I can go back with the original idea:
def sensitiveOperation() = Protected {request => ...}
How to achieve it?
Thanks in advance, Raka