I ended up with this:
// This contains a white-list of allowed query parameters. This is useful to
// ensure people don't try to use &r=234234 to bust your caches.
def allowedParameters(params: String*): Directive0 = parameterSeq.flatMap {
case xs =>
val illegal = xs.collect {
case (k, _) if !params.contains(k) => k
}
if (illegal.nonEmpty)
reject(ValidationRejection("Illegal query parameters: " + illegal.mkString("", ", ", "\nAllowed ones are: ") + params.mkString(", ")))
else
pass
}
For usage, have a look at the unit tests:
val allowedRoute = {
allowedParameters("foo", "bar") {
complete("OK")
}
}
"Allowed Parameter Directive" should "reject parameters not in its whitelist" in {
Get("/?foo&bar&quux") ~> allowedRoute ~> check {
handled should equal(false)
rejection should be(ValidationRejection("Illegal query parameters: quux\nAllowed ones are: foo, bar"))
}
}
it should "allow properly sorted parameters through" in {
Get("/?bar&foo") ~> allowedRoute ~> check {
handled should equal(true)
responseAs[String] should equal("OK")
}
}