我正在尝试学习在Scala的Play框架中使用Action组合。
我理解能够执行基本操作组合和WrappedRequests,但我的问题是:是否可以在组合Action中访问多个WrappedRequests的内容?
让我解释一下,我有以下代码:
class RequestWithUser[A](val user: models.User, request: Request[A]) extends WrappedRequest[A](request)
def UserAction(userId: Long) = new ActionBuilder[RequestWithUser] {
def invokeBlock[A](request: Request[A], block: (RequestWithUser[A]) => Future[SimpleResult]) = {
models.UsersDAO.findById(userId).map { user =>
block(new RequestWithUser(user, request))
} getOrElse {
Future.successful(NotFound)
}
}
}
case class AuthenticatedRequest[A](user: models.User, request: Request[A]) extends WrappedRequest[A](request)
object Authorized extends ActionBuilder[AuthenticatedRequest] {
def invokeBlock[A](request: Request[A], block: (AuthenticatedRequest[A]) => Future[SimpleResult]) = {
userTokenForm.bindFromRequest()(request).fold(
formWithErrors => {
resolve(Results.Unauthorized(formWithErrors.errorsAsJson))
},
userData => {
models.UsersDAO.findByToken(userData.token) map { user=>
block(AuthenticatedRequest(user, request))
} getOrElse {
resolve(Results.Unauthorized("Token matched no one."))
}
}
)
}
}
我希望能够将它们组成第三个可能称为“UserPermissionAction”的动作,它构成了Authorized和UserAction。 它应该检查授权用户是否与RequestWithUser中的用户相同(即只允许用户自己编辑)。
这可能吗?
答案 0 :(得分:0)
这是我最终做的事情。 它有效,但我希望看到反馈,如果有更多惯用的Scala方式:
/** Contains the security token, extracted from the RequestHeader */
case class AuthenticatedRequest[A](user: models.User, request: Request[A]) extends WrappedRequest[A](request)
case class AuthorizedAction[A](action: Action[A]) extends Action[A] {
lazy val parser = action.parser
def apply(request: Request[A]): Future[SimpleResult] = {
userTokenForm.bindFromRequest()(request).fold(
formWithErrors => {
resolve(Results.Unauthorized(formWithErrors.errorsAsJson))
},
userData => {
models.UsersDAO.findByToken(userData.token) map { user=>
action(AuthenticatedRequest(user, request))
} getOrElse {
resolve(Results.Unauthorized("Token matched no one."))
}
}
)
}
}
class RequestWithUser[A](val user: models.User, request: Request[A]) extends WrappedRequest[A](request)
case class UserAction[A](userId: Long, action: Action[A]) extends Action[A] {
lazy val parser = action.parser
def apply(request: Request[A]): Future[SimpleResult] = {
models.UsersDAO.findById(userId).map { user =>
action(new RequestWithUser(user, request))
} getOrElse {
Future.successful(NotFound)
}
}
}
def UserHasPermission[A](userId: Long) = new ActionBuilder[AuthenticatedRequest] {
def invokeBlock[A](request: Request[A], block: (AuthenticatedRequest[A]) => Future[SimpleResult]) = {
request match {
case req: AuthenticatedRequest[A] => {
{
for (
authUserId <- req.user.id
if authUserId == userId
) yield block(req)
} getOrElse Future.successful(Unauthorized)
}
case _ => Future.successful(BadRequest)
}
}
override def composeAction[A](action: Action[A]) = UserAction(userId, AuthorizedAction(action) )
}