我试图围绕Play动作组合。我的主要参考是:https://www.playframework.com/documentation/2.3.6/ScalaActionsComposition
这是我想要实现的目标(能够以这种方式在我的Controller中声明一个函数):
def sensitiveOperation() = Protected {request => ...}
所以,我的行动计划是:
/**
* 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
*/
所以......我有这三件事:
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."))
}
}
}
所有这三件事都在编译。
我的问题是:如何声明一个使用UserAction和CheckUserId的Action?
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 ?? ....
}
我在下面尝试过这个,但它会出现编译错误:
override def composeAction[A](action: Action[A]) = UserAction andThen CheckUserId
其他附加
现在我可以使用它解决这个问题:
def sensitiveOperation() = (UserAction andThen CheckUserId) {request => ...}
但是,如果我能定义一个名为"受保护的"的伴侣对象,我认为它会更漂亮。实际上也是如此(和UserAction和CheckUserId)......所以我可以回到最初的想法:
def sensitiveOperation() = Protected {request => ...}
如何实现它?
提前致谢, 拉嘎
答案 0 :(得分:3)
您无法使用对象执行此操作,因为对象不能是表达式的结果。但是你可以把它变成def或val,你可以把它放在一个包对象中,如果你想要的话,例如:
package object security {
val Protected = UserAction andThen CheckUserId
}
答案 1 :(得分:0)
我想我已经找到了......
object Protected extends ActionBuilder[UserRequest] {
def invokeBlock[A](request: Request[A], block: (UserRequest[A]) => Future[Result]) = {
(UserAction andThen CheckUserId).invokeBlock(request, block)
}
}