Skip to content

Instantly share code, notes, and snippets.

@dungvn3000
Created May 13, 2014 14:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dungvn3000/ed117473bb1297d84783 to your computer and use it in GitHub Desktop.
Save dungvn3000/ed117473bb1297d84783 to your computer and use it in GitHub Desktop.
package controllers
import play.api.mvc._
import jp.t2v.lab.play2.stackc.StackableController
import jp.t2v.lab.play2.auth.LoginLogout
import play.api.Play
import play.api.Play.current
import com.google.api.client.googleapis.auth.oauth2.{GoogleAuthorizationCodeTokenRequest, GoogleBrowserClientRequestUrl, GoogleTokenResponse, GoogleCredential}
import scala.collection.JavaConverters._
import com.google.api.client.http.javanet.NetHttpTransport
import com.google.api.client.json.jackson2.JacksonFactory
import scala.concurrent.{Promise, ExecutionContext, Future}
import models.{Users, User}
import org.apache.commons.lang3.{RandomStringUtils, StringUtils}
import com.google.api.services.oauth2.Oauth2
import ExecutionContext.Implicits.global
import controllers.element.{TransactionElement, AuthConfigImpl}
import scala.util.{Failure, Success}
import utils.HttpUtil
/**
* The Class GoogleCtr.
*
* @author Nguyen Duc Dung
* @since 1/12/14 9:37 PM
*
*/
class GoogleCtr extends Controller with StackableController with LoginLogout with AuthConfigImpl with TransactionElement {
lazy val app_id = Play.configuration.getString("google.app.id").getOrElse(throw new Exception("Please add google.app.id to application.conf"))
lazy val app_secret = Play.configuration.getString("google.app.secret").getOrElse(throw new Exception("Please add google.app.secret to application.conf"))
val redirect_url = Play.configuration.getString("application.google.redirect.url").getOrElse(throw new Exception("Please add application.google.redirect.url to application.conf"))
def login = Action {
val url = new GoogleBrowserClientRequestUrl(app_id, redirect_url,
List(
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/userinfo.profile"
).asJava
).setState("/profile").setResponseTypes(List("code").asJava).build()
Redirect(url)
}
def auth = AsyncStack(implicit request => request.getQueryString("code").map(code => {
val promise = Promise[SimpleResult]()
def getUserProfile = Future {
val transport = new NetHttpTransport()
val jsonFactory = new JacksonFactory()
val tokenResponse = new GoogleAuthorizationCodeTokenRequest(transport, jsonFactory, app_id, app_secret, code, redirect_url).execute()
val token = tokenResponse.toString
val credential = new GoogleCredential.Builder()
.setJsonFactory(jsonFactory)
.setTransport(transport)
.setClientSecrets(app_id, app_secret).build()
.setFromTokenResponse(jsonFactory.fromString(token, classOf[GoogleTokenResponse]))
val userInfoService = new Oauth2.Builder(transport, jsonFactory, credential).build()
val userInfo = userInfoService.userinfo.get.execute()
userInfo
}
def getUserAvatar(url: Option[String]) = url.fold(Future.successful(Option.empty[Array[Byte]]))(HttpUtil.safeDownload)
getUserProfile.onComplete {
case Success(userInfo) =>
if (userInfo != null && StringUtils.isNotBlank(userInfo.getEmail)) {
Users.findByEmail(userInfo.getEmail)
.map(user => promise.completeWith(gotoLoginSucceeded(user.email)))
.getOrElse {
val newPassword = RandomStringUtils.randomAlphanumeric(6)
val fullName = if (StringUtils.isNotBlank(userInfo.getName)) Some(userInfo.getName) else None
val language = if (StringUtils.isNotBlank(userInfo.getLocale)) userInfo.getLocale else "en"
val avatarUrl = if (StringUtils.isNotBlank(userInfo.getPicture)) Some(userInfo.getPicture) else None
getUserAvatar(avatarUrl).onComplete {
case Success(avatar) =>
val newUser = User(
email = userInfo.getEmail,
fullName = fullName,
password = newPassword,
avatar = avatar.getOrElse(Array.empty)
)
Users.save(newUser)
promise.completeWith(gotoLoginSucceeded(newUser.email))
case Failure(ex) => promise.failure(ex)
}
}
} else {
promise.success(BadRequest)
}
case Failure(ex) => promise.failure(ex)
}
promise.future
}).getOrElse(Future.successful(BadRequest)))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment