2016-01-06 45 views
1

將將請求轉換爲帶有附加類型參數的自定義WrappedRequest,然後將其與ActionFilter合併的ActionBuilder會導致自定義WrappedRequest的類型被刪除。爲什麼將自定義的WrappedRequest與額外的類型參數結合起來並且ActionFilter會導致類型丟失?

這是爲什麼,有沒有修復?

例如,假設我需要身份驗證ActionBuilder和可選的授權ActionFilter,其中我們需要的用戶類型可能因用途而異。

見本做作代碼:

case class AuthRequest[A, U](val request: Request[A], val user: U) extends WrappedRequest[A](request) 

case class TestUser(id: String) 

case class AuthenticationAction[A]() extends ActionBuilder[({type λ[B] = AuthRequest[B, TestUser]})#λ] { 

    override def invokeBlock[A](request: Request[A], block: (AuthRequest[A, TestUser]) => Future[Result]): Future[Result] = 
    block(AuthRequest(request, TestUser("test-id"))) 

} 

case class AuthorisedAction[A]() extends ActionFilter[({type λ[B] = AuthRequest[B, TestUser]})#λ] { 

    // does some additional authorisation checks for added security 
    def authorised(user: TestUser) = true 

    override def filter[A](request: AuthRequest[A, TestUser]) = Future.successful { 
    if(authorised(request.user)) None 
    else Some(Unauthorized) 
    } 

} 

請注意:在上述類型的功能是必需的按this answer因爲在AuthRequest附加類型的參數。這也是必需的,因爲這個API將與多種類型的用戶一起使用。

如果我再實現使用上述控制器:

class ExampleController extends Controller { 

    def secured = (AuthenticationAction() andThen AuthorisedAction()) { request => 
    Ok(request.user.id) 
    } 

} 

我得到一個編譯錯誤(value user is not a member of play.api.mvc.WrappedRequest[play.api.mvc.AnyContent])。換句話說,上面的變量request的類型是WrappedRequest而不是期望的類型AuthRequest[play.api.mvc.AnyContent, TestUser]

據我所知,大多數使用案例AuthenticationActionAuthorisedAction將被合併成一個單一的行動,但由於授權是可選的,我想保留這些作爲單獨的擔憂。

這可能嗎?這是Play Framework API中的錯誤嗎?還是斯卡拉的錯誤?還是人爲錯誤?使用

回答

1

你的榜樣,我能夠組成這樣的動作:

class ExampleController extends Controller { 
    def secured = AuthorisedAction().compose(AuthenticationAction()) { request => 
    Ok(request.user.id) 
    } 
} 

很有趣的是,在這兩種情況下的IntelliJ的型式檢驗認爲requestAuthRequest[AnyContent, TestUser]類型的 - 這是隻看到它scalac作爲WrappedRequest

相關問題