2014-11-05 1 views
0

Я пытаюсь обернуть голову вокруг композиции действия. Моя главная ссылка: https://www.playframework.com/documentation/2.3.6/ScalaActionsCompositionScala Play Action Состав: Объявите ActionBuilder, который производит действие, объединив несколько ActionFunction

Вот что я хочу достичь (чтобы иметь возможность объявить функцию в моем контроллере так):

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?

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 => ...} 

Но, все же, я тонкий К было бы красивее, если я могу определить объект-компаньон под названием «Protected», что практически делает то же самое (и-ки UserAction и CheckUserId) ..., так что я могу вернуться с оригинальной идеей:

def sensitiveOperation() = Protected {request => ...} 

Как это достичь?

Спасибо заранее, Raka

ответ

3

Вы не можете это сделать с объектом, поскольку объект не может быть результатом выражение. Но вы можете сделать это def или val, и вы можете поместить его в объект пакета, если хотите, например:

package object security { 
    val Protected = UserAction andThen CheckUserId 
} 
+0

Я думаю, что мне нравится ваше решение лучше, более кратким. Благодаря! –

0

Я думаю, что я нашел, как ....

object Protected extends ActionBuilder[UserRequest] { 
    def invokeBlock[A](request: Request[A], block: (UserRequest[A]) => Future[Result]) = { 
    (UserAction andThen CheckUserId).invokeBlock(request, block) 
    } 
}