Skip to content

Instantly share code, notes, and snippets.

@dbousamra
Created July 1, 2016 04:43
Show Gist options
  • Select an option

  • Save dbousamra/aa05549a3538f0dad5e10182c2cc0e03 to your computer and use it in GitHub Desktop.

Select an option

Save dbousamra/aa05549a3538f0dad5e10182c2cc0e03 to your computer and use it in GitHub Desktop.
class AuthedRequest(a: AuthedAccount) extends Request {
def account: AuthedAccount = this.a
}
object AuthedHttpService {
type AuthedHttpService = Service[AuthedRequest, Response]
/** Alternative application which lifts a partial function to an `AuthedHttpService`,
* answering with a [[Response]] with status [[Status.NotFound]] for any requests
* where the function is undefined.
*/
def apply(pf: PartialFunction[AuthedRequest, Task[Response]], default: AuthedHttpService = empty): AuthedHttpService =
Service.lift(req => pf.applyOrElse(req, default))
/** Alternative application which lifts a partial function to an `AuthedHttpService`,
* answering with a [[Response]] as supplied by the default argument.
*/
def apply(pf: PartialFunction[AuthedRequest, Task[Response]], default: Task[Response]): AuthedHttpService =
Service.lift(req => pf.applyOrElse(req, (_: AuthedRequest) => default))
/**
* Lifts a (total) function to an `AuthedHttpService`. The function is expected to handle
* ALL requests it is given.
*/
def lift(f: AuthedRequest => Task[Response]): AuthedHttpService = Service.lift(f)
/** The default 'Not Found' response used when lifting a partial function
* to a [[AuthedHttpService]] or general 'not handled' results.
*
* This particular instance is tagged with an so that it interacts appropriately
* attribute to play well with the default [[Fallthrough]] behavior.
*/
val notFound: Task[Response] = Task.now(Response(Status.NotFound)
.withAttribute(Fallthrough.fallthroughKey, ())
.withBody("404 Not Found.").run)
val empty : AuthedHttpService = Service.const(notFound)
}
object CammyAuth {
def apply(auth: CammyAuthentication)(service: AuthedHttpService): HttpService = {
Service.lift[Request, Response] { req =>
auth.checkAuth(req).flatMap {
case \/-(account) =>
service(new AuthedRequest(account))
case -\/(error) =>
Task.now(Response(Status.Unauthorized).putHeaders(`WWW-Authenticate`(Challenge("Bearer", "Cammy", Nil.toMap))))
}
}
}
}
object Tester {
val ec = scala.concurrent.ExecutionContext.Implicits.global
val config = Config()
val authClient = AccountAuthClient(config.authConfig.config)(ec)
val auth = CammyAuth(CammyAuthentication(authClient)(ec))(_)
val authedService: AuthedHttpService = AuthedHttpService {
/*
* See how we have access to the account
*/
case req @ GET -> Root => {
println(req.account)
Ok(req.account.toString)
}
}
val backend = Router(
"/" -> auth(authedService)
)
def main(args: Array[String]) {
val builder = BlazeBuilder.mountService(backend)
val server = builder.run
server.awaitShutdown()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment