[Play] [Scala]我可以获得多个链接动作的内容吗?

时间:2014-03-02 02:29:39

标签: scala playframework playframework-2.0

我正在尝试学习在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中的用户相同(即只允许用户自己编辑)。

这可能吗?

1 个答案:

答案 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) )
    }