Skip to content

Instantly share code, notes, and snippets.

@excavador
Created March 22, 2013 21:40
Show Gist options
  • Save excavador/5224983 to your computer and use it in GitHub Desktop.
Save excavador/5224983 to your computer and use it in GitHub Desktop.
/*
* This file is part of Z-Reader (c) 2013
*
* Z-Reader is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Z-Reader is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Z-Reader. If not, see <http://www.gnu.org/licenses/>.
*/
package sh.oleg.zreader.auth.google.oauth2
import net.liftweb.common.{Empty, Logger}
import scala.Enumeration
import net.liftweb._
import util._
import Helpers._
import java.net.URL
package object Login {
/** Helper for build URL */
abstract class Param(val name : String) {
protected val value : Option[String]
def pair : Option[(String, String)] = value match {
case None => None
case Some(v) => Some((name, v))
}
}
/**
* scope - space delimited set of permissions the application requests
*
* Indicates the Google API access your application is requesting.
* The values passed in this parameter inform the consent page shown to the user.
* There is an inverse relationship between the number of permissions requested
* and the likelihood of obtaining user consent.
*
* Every item from list would be translated to
* https://www.googleapis.com/auth/item
*
*/
class Scope(userInfoEmail : Boolean = true,
userInfoProfile : Boolean = true)
extends Param("scope") {
val value : Option[String] = {
val result = List(
(userInfoEmail, "userinfo.email"),
(userInfoProfile, "userinfo.profile")
).filter(_._1).map("https://www.googleapis.com/auth/" + _._2).mkString(" ")
if (result.isEmpty) None else Some(result)
}
}
/**
* state - any string
*
* This optional parameter indicates any state which may be useful to your application upon receipt of the response.
* The Google Authorization Server roundtrips this parameter, so your application receives the same value it sent.
* Possible uses include redirecting the user to the correct resource in your site, nonces,
* and cross-site-request-forgery mitigations.
*/
class State private (val value : Option[String])
extends Param("state") {
def this() = this(None)
def this(v : String) = this(Some(v))
}
/**
* redirect_uri - one of your redirect_uris registered at the APIs Console at https://code.google.com/apis/console#access
*
* Determines where the response is sent.
* The value of this parameter must exactly match one of the values registered in the APIs Console
* (including the http or https schemes, case, and trailing '/').
*/
class RedirectUri private(val value : Option[String])
extends Param("redirect_uri") {
def this(v : String) = this(Some(v))
}
/**
* response_type - code or token
*
* Determines if the Google Authorization Server returns an authorization code, or an opaque access token.
*/
object ResponseType {
class Type protected (val value : Option[String]) extends Param("response_type")
object code extends Type(Some("code"))
object token extends Type(Some("code"))
object default extends Type(None)
}
/**
* client_id - the client_id obtained from the APIs Console
*
* Indicates the client that is making the request.
* The value passed in this parameter must exactly match the value shown in the APIs Console at https://code.google.com/apis/console#access
*/
class ClientId private(val value : Option[String])
extends Param("client_id") {
def this(v : String) = this(Some(v))
}
/**
* access_type - online or offline
*
* Indicates if your application needs to access a Google API when the user is not present at the browser.
* This parameter defaults to online.
* If your application needs to refresh access tokens when the user is not present at the browser, then use offline.
* This will result in your application obtaining a refresh token the first time your application exchanges an authorization code for a user.
*/
object AccessType {
class Type protected (val value : Option[String]) extends Param("response_type")
object online extends Type(Some("code"))
object offline extends Type(Some("code"))
object default extends Type(None)
}
/**
* approval_prompt - force or auto
*
* Indicates if the user should be re-prompted for consent.
* The default is auto, so a given user should only see the consent page for a given set of scopes the first time through the sequence.
* If the value is force, then the user sees a consent page even if they have previously given consent to your application for a given set of scopes.
*
*/
object ApprovalPrompt {
class Type protected (val value : Option[String]) extends Param("approval_prompt")
object force extends Type(Some("force"))
object auto extends Type(Some("auto"))
object default extends Type(None)
}
class Snippet(redirectUri : RedirectUri,
clientId : ClientId,
scope : Scope = new Scope(),
state : State = new State(),
responseType : ResponseType.Type = ResponseType.default,
accessType : AccessType.Type = AccessType.default,
approvalPrompt : ApprovalPrompt.Type = ApprovalPrompt.default)
extends Logger {
def render = {
val l = List[Param](scope,
state,
redirectUri,
responseType,
clientId,
accessType,
approvalPrompt)
"a [href]" #> appendParams("https://accounts.google.com/o/oauth2/auth",
l.map(_.pair).filter(_.isDefined).map(_.get))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment