Created
November 18, 2014 20:33
-
-
Save plawler/dcf362e546d82cda8adc to your computer and use it in GitHub Desktop.
Stormpath with grant_type query string included
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package services | |
import java.util.NoSuchElementException | |
import java.util.concurrent.TimeUnit | |
import com.google.inject.Singleton | |
import com.stormpath.sdk.account.Account | |
import com.stormpath.sdk.api.{ApiAuthenticationResult, ApiKeys} | |
import com.stormpath.sdk.application.Application | |
import com.stormpath.sdk.client.{Clients, Client} | |
import com.stormpath.sdk.cache.Caches._ | |
import com.stormpath.sdk.directory.CustomData | |
import com.stormpath.sdk.http.{HttpMethod, HttpRequests, HttpRequest} | |
import com.stormpath.sdk.oauth.{TokenResponse, AccessTokenResult} | |
import com.stormpath.sdk.resource.ResourceException | |
import play.api.Logger | |
import play.api.mvc.{AnyContent, Request} | |
import scala.collection.JavaConversions._ | |
/** | |
* Created by paullawler on 11/17/14. | |
*/ | |
case class AppAccount(appName: String, contactFullName: String, contactEmail: String, partnerId: String) { | |
def asUserName : String = appName.replace(" ", "").toLowerCase | |
} | |
case class ApiKey(id: String, secret: String, status: String) | |
trait AuthenticationService { | |
def createAccount(account: AppAccount): AppAccount | |
def fetchAccount(email: String): Option[AppAccount] | |
def deleteAccount(account: AppAccount) | |
def fetchApiKey(account: AppAccount): Option[ApiKey] | |
def retrieveToken(request: Request[AnyContent]): TokenResponse // todo: wrap this class with our own interface | |
} | |
@Singleton | |
class StormpathAuthenticationService extends AuthenticationService { | |
lazy val client: Client = { | |
val path = System.getProperty("user.home") + "/.stormpath/apiKey.properties" | |
val apiKey = ApiKeys.builder().setFileLocation(path).build() | |
Clients.builder() | |
.setApiKey(apiKey) | |
.setCacheManager(newCacheManager() | |
.withDefaultTimeToLive(1, TimeUnit.DAYS) | |
.withDefaultTimeToIdle(2, TimeUnit.HOURS) | |
.withCache(forResource(classOf[Account]) | |
.withTimeToLive(1, TimeUnit.HOURS) | |
.withTimeToIdle(30, TimeUnit.MINUTES)) | |
.build() | |
).build() | |
} | |
lazy val application = | |
client.getResource("https://api.stormpath.com/v1/applications/7Ew6jBE7mRo6kXAkrAfivL", classOf[Application]) | |
override def createAccount(pa: AppAccount): AppAccount = { | |
val account = client.instantiate(classOf[Account]) | |
account.setUsername(pa.asUserName) | |
account.setGivenName(pa.appName) | |
account.setSurname(pa.contactFullName) | |
account.setEmail(pa.contactEmail) | |
account.setPassword("chang3Me!") | |
val customData = account.getCustomData | |
customData.put("partnerId", pa.partnerId) | |
try { | |
val spAcct = application.createAccount(account) | |
spAcct.createApiKey() | |
AppAccount(spAcct.getGivenName, spAcct.getSurname, spAcct.getEmail, spAcct.getCustomData.get("partnerId").asInstanceOf[String]) | |
} catch { | |
case e: ResourceException => throw new ResourceException(e) | |
} | |
} | |
override def fetchAccount(email: String): Option[AppAccount] = { | |
try { | |
val account = application.getAccounts(Map("email" -> email)).head | |
Some(AppAccount(account.getGivenName, account.getSurname, account.getEmail, account.getCustomData.get("partnerId").asInstanceOf[String])) | |
} catch { | |
case e: NoSuchElementException => None | |
} | |
} | |
override def deleteAccount(account: AppAccount): Unit = { | |
try { | |
application.getAccounts(Map("email" -> account.contactEmail)).head.delete() | |
} catch { | |
case e: NoSuchElementException => Logger.info(s"Nothing to delete. No account with [$account.contactEmail] found.") | |
} | |
} | |
override def fetchApiKey(account: AppAccount): Option[ApiKey] = { | |
try { | |
val spAcct = application.getAccounts(Map("email" -> account.contactEmail)).head | |
val spKey = spAcct.getApiKeys.head | |
Some(ApiKey(spKey.getId, spKey.getSecret, spKey.getStatus.toString)) | |
} catch { | |
case e: NoSuchElementException => None | |
} | |
} | |
override def retrieveToken(request: Request[AnyContent]): TokenResponse = { | |
val result: AccessTokenResult = application.authenticateApiRequest(buildRequest(request)).asInstanceOf[AccessTokenResult] | |
result.getTokenResponse | |
} | |
private def buildRequest(request: Request[AnyContent]): HttpRequest = { | |
val headers = request.headers.toMap.mapValues(v => v.toArray) | |
val params = request.queryString.toMap.mapValues(v => v.toArray) | |
HttpRequests.method(HttpMethod.fromName(request.method)) | |
.headers(headers) | |
.queryParameters(request.rawQueryString) | |
.build() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment