Skip to content

Instantly share code, notes, and snippets.

@Softsapiens
Created August 19, 2014 09:32
Show Gist options
  • Select an option

  • Save Softsapiens/bfb5f37f19aa95fe1456 to your computer and use it in GitHub Desktop.

Select an option

Save Softsapiens/bfb5f37f19aa95fe1456 to your computer and use it in GitHub Desktop.
package models
import play.api.libs.ws.WS
import play.core.parsers._
import scala.concurrent.Future
import play.api.libs.concurrent.Execution.Implicits._
case class OAuth2Settings(
clientId: String,
clientSecret: String,
signInUrl: String,
accessTokenUrl: String,
userInfoUrl: String
)
abstract class OAuth2[T](settings: OAuth2Settings){
def user(body: String): T
import settings._
lazy val signIn = signInUrl + "?client_id=" + clientId
def authenticate(code: String): Future[T] = {
val url = accessTokenUrl + "?client_id=" + clientId + "&client_secret=" + clientSecret + "&code=" + code
for {
accessToken <- WS.url(url).get()
userInfo <- WS.url(userInfoUrl + "?access_token=" + FormUrlEncodedParser.parse(accessToken.body).get("access_token").flatMap(_.headOption).get).get()
} yield {
user(userInfo.body)
}
}
}
package controllers
import lib._
import play.api.mvc._
import play.api.libs.json._
import play.api.libs.functional.syntax._
import scala.concurrent.{Future}
import scala.concurrent.ExecutionContext.Implicits.global
object OAuth2Github extends Controller {
val GITHUB = new OAuth2[GithubUser](OAuth2Settings(
"your_client_id",
"your_client_secret",
"https://github.com/login/oauth/authorize",
"https://github.com/login/oauth/access_token",
"https://api.github.com/user"
)){
def user(body: String): GithubUser = Json.parse(body).validate[GithubUser](githubUserReads).get
}
case class GithubUser(
login: String,
email: String,
avatar_url: String,
name: String
)
implicit val githubUserReads = (
(__ \ "login").read[String] and
(__ \ "email").read[String] and
(__ \ "avatar_url").read[String] and
(__ \ "name").read[String]
)(GithubUser.apply _)
def signin() = Action { Redirect(GITHUB.signIn) }
def signout() = Action { Redirect(routes.Application.index()).withSession() }
def callback(code: String) = Action.async { implicit request =>
GITHUB.authenticate(code).map { user =>
Redirect(routes.Application.index()).withSession("login" -> user.login)
}
}
}
# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~
GET / controllers.Application.index
# OAuth2
GET /signin controllers.OAuth2Github.signin
GET /callback controllers.OAuth2Github.callback(code: String)
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.at(path="/public", file)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment