First of all, I'm a newbie in Play Framework, so maybe this is very basic, but I couldn't find enough documentation to clarify.
Currently I have a project that use Oauth2 to identify and authorize the users. This is being done with an ActionBuilder and working well.
What I do want now is an aditional "layer", this means, after authorizing, check if the user has enough permissions (permission table is stored in DB).
I've read about Action Composition, but since I'm using ActionBuilder I think I should be able to do it with them. I've seen composeAction function, but I'm not pretty sure about how to implement this.
My code, currently looks like:
case class AuthenticatedRequest[A](user: User, request: Request[A]) extends WrappedRequest(request)
def authenticate[A](block: AuthenticatedRequest[A] => Future[Result])(implicit request: Request[A]) = {
authorize(new OauthDataHandler()) { authInfo =>
block(AuthenticatedRequest(authInfo.user, request))
}
}
object Authenticated extends api.mvc.ActionBuilder[AuthenticatedRequest] {
def invokeBlock[A](request: Request[A], block: AuthenticatedRequest[A] => Future[Result]) = {
authenticate(block)(request)
}
}
}
And my attempt right now is this:
case class PermissionAuthenticatedRequest[A](user: User, zone: String, request: Request[A]) extends WrappedRequest(request)
object PermissionAuthenticated extends api.mvc.ActionBuilder[PermissionAuthenticatedRequest] {
def invokeBlock[A](request: Request[A], block: PermissionAuthenticatedRequest[A] => Future[Result]) = {
checkPermissions(???/*user*/, ???/*zone*/,block)(request)
}
def checkPermissions[A](user: User, permission: String, block: PermissionAuthenticatedRequest[A] => Future[Result])(implicit request: Request[A]) = {
if(user._id == 1) //silly check
block(PermissionAuthenticatedRequest(user, permission, request))
else
Future.successful(Forbidden)
}
}
But I still don't know how to retrieve the user (from other AuthenticatedAction) or privilege (from the request).
Thank you in advance.
w, scala-oauth2-provider 0.13.1 has AuthorizedAction. so you can authenticate as follows
import scalaoauth2.provider.OAuth2ProviderActionBuilders._
object YourController extends Controller {
def index = AuthorizedAction(new OauthDataHandler()) { req =>
req.authInfo // you can take AuthInfo
...
}
}
And all you need is create a permission check ActionFilter
import scalaoauth2.provider._
object PermissionActionFilter extends ActionFilter[({type L[A] = AuthInfoRequest[User, A]})#L] {
protected def filter[A](request: AuthInfoRequest[User, A]): Future[Option[Result]] = Future.successful {
request.authInfo.user // you can take AuthInfo
if (user._id == 1) //silly check {
None
} else {
Some(Forbidden)
}
}
}
you can use PermissionActionFilter
as follows
object YourController extends Controller {
val MyAction = AuthorizedAction(new OauthDataHandler()) andThen PermissionActionFilter
def index = MyAction { req =>
req.authInfo // you can take AuthInfo
...
}
}