Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

parse.json of authenticated play request

I've set up authentication in my application like this, always allow when a username is supplied and the API-key is 123:

object Auth  {
    def IsAuthenticated(block: => String => Request[AnyContent] => Result) = {
      Security.Authenticated(RetrieveUser, HandleUnauthorized) { user =>
        Action { request =>
          block(user)(request)
        }
      }
    }

    def RetrieveUser(request: RequestHeader) = {

      val auth = new String(base64Decode(request.headers.get("AUTHORIZATION").get.replaceFirst("Basic", "")))
      val split  = auth.split(":")
      val user = split(0)
      val pass = split(1)
      Option(user)
    }

    def HandleUnauthorized(request: RequestHeader) = {
      Results.Forbidden
    }

    def APIKey(apiKey: String)(f: => String => Request[AnyContent] => Result) = IsAuthenticated { user => request =>

      if(apiKey == "123")
        f(user)(request)
      else
        Results.Forbidden
    }

}

I want then to define a method in my controller (testOut in this case) that uses the request as application/json only. Now, before I added authentication, I'd say "def testOut = Action(parse.json) {...}", but now that I'm using authentication, how can I add parse.json in to the mix and make this work?

  def testOut = Auth.APIKey("123") { username => implicit request =>

    var props:Map[String, JsValue] = Map[String, JsValue]()
    request.body  match {
      case JsObject(fields) => { props = fields.toMap }
      case _ => {} // Ok("received something else: " + request.body + '\n')
    }

    if(!props.contains("UUID"))
      props.+("UUID" -> UniqueIdGenerator.uuid)

    if (!props.contains("entity"))
      props.+("entity" -> "unset")

    props.+("username" -> username)

    Ok(props.toString)
  }

As a bonus question, why is only UUID added to the props map, not entity and username?

Sorry about the noob factor, I'm trying to learn Scala and Play at the same time. :-)

Cheers

Nik

like image 970
niklassaers Avatar asked Apr 07 '12 12:04

niklassaers


1 Answers

It turns out that I don't need to use a bodyparser at all, request.body has a asJson function that I can use. So I exploited this to do the following. This work, and I can continue my work, but I still don't quite understand how to get a JSON body parser in here. Learning in progress… ;-)

def testOut = Auth.APIKey("123") { username => request =>

  var props:Map[String, JsValue] = Map[String, JsValue]()
  request.body.asJson  match {
    case None => {}
    case Some(x) => {
      x match {
        case JsObject(fields) => { props = fields.toMap }
        case _ => {} // Ok("received something else: " + request.body + '\n')
      }
    }
  }

  if(!props.contains("UUID"))
    props += "UUID" -> toJson(UniqueIdGenerator.uuid)

  if(!props.contains("entity"))
    props += "entity" -> toJson("unset")

  props += "should" -> toJson("appear")
  props += "username" -> toJson(username)

  Ok(props.toString)
}
like image 118
niklassaers Avatar answered Oct 10 '22 10:10

niklassaers