Skip to content

Instantly share code, notes, and snippets.

@plawler
Created November 18, 2014 19:09
Show Gist options
  • Save plawler/37d2acb48da1dc6fb173 to your computer and use it in GitHub Desktop.
Save plawler/37d2acb48da1dc6fb173 to your computer and use it in GitHub Desktop.
Stormpath API Support Request
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)
HttpRequests.method(HttpMethod.fromName(request.method)).headers(headers).build()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment