j3d
j3d

Reputation: 9734

Play Framework: How to pass the current request to a body parser

I've implemented a SecureAction for my controller like this:

class SecureRequest[A](
  val token: Token,
  request: Request[A]) extends WrappedRequest[A](request) {
  ...
}

class SecureAction[T <: Controller : TypeTag] private(
  private val methodName: String,
  private val tokenTypes: Seq[TokenType]) extends ActionBuilder[SecureRequest] {

  def invokeBlock[A](request: Request[A], block: SecureRequest[A] => Future[Result]) = {
    ...
  }
}

def saveFile = SecureAction.async(fsBodyParser) { implicit request =>

  // code here not executed if current user has not required privileges
  ...
}

Everything works fine... except that even if the request is NOT authorized fsBodyParser gets still invoked and the multipart file saved in the database.

The implicit request object contains security rules... so would it be possible to pass somehow the request to the body parser?

EDIT

This is my body parser...

fsBodyParser()(
  implicit fsService: FsServiceComponent#FsService
): BodyParser[MultipartFormData[Future[MetaFile]]] = {
  import BodyParsers.parse._

  multipartFormData(
    Multipart.handleFilePart {
      case Multipart.FileInfo(partName, filename, contentType) =>
        fsService.iteratee(filename, contentType)
    }
  ) 
}

I probably need a method that can be invoked from the body of the action so that security is not by-passed. It's not clear to me who the body signature should look like:

def saveFile = SecureAction.async(fsBodyParser) { implicit request =>

  // how should the signature of this method look like???
  parseMultpart(request.body  ???)

  ...
}

Upvotes: 0

Views: 742

Answers (1)

Arne Claassen
Arne Claassen

Reputation: 14404

BodyParser[T] is a function from RequestHeader to Iteratee[Array[Byte], Either[Result, A]], so it does have access to the request header when being executed.

Although I would say that the intent of the Request => Future[Result] pipeline in Play! is for the BodyParser to just transform the incoming body, not take action on the body. I would suggest that you do not store the file at the bodyParser stage, but only once your SecureAction is invoked and retrieves the body from the request.

Upvotes: 2

Related Questions