Skip to content

Instantly share code, notes, and snippets.

@alexanderjarvis
Created January 12, 2015 09:52
Show Gist options
  • Save alexanderjarvis/9f5c578b54cc535bacce to your computer and use it in GitHub Desktop.
Save alexanderjarvis/9f5c578b54cc535bacce to your computer and use it in GitHub Desktop.
AccessToken
package security
import scala.concurrent._
object AccessToken {
/**
* The "b64token" syntax allows the 66 unreserved URI characters
* ([RFC3986]), plus a few others, so that it can hold a base64,
* base64url (URL and filename safe alphabet), base32, or base16 (hex)
* encoding, with or without padding, but excluding whitespace
* ([RFC4648]).
*
* http://tools.ietf.org/html/draft-ietf-httpbis-p7-auth-19#section-2.1
*
* Section 2.3. Unreserved Characters
* http://www.ietf.org/rfc/rfc2396.txt
*
* The additional characters to the unreserved characters of rfc2396 are:
* "+", "/"
*/
private val Chars = ('a' to 'z') ++ ('A' to 'Z') ++ ('0' to '9') ++ ("-_.!~*'()+/")
private val Length = 32
private val random = new scala.util.Random(new java.security.SecureRandom())
private def uniqueRandomToken(chars: String, length: Int, uniqueFunc: String => Future[Boolean])(implicit ec: ExecutionContext): Future[String] = {
val newKey = (1 to length).map(x => chars(random.nextInt(chars.length))).mkString
uniqueFunc(newKey).flatMap(unique => if (unique) Future(newKey) else uniqueRandomToken(chars, length, uniqueFunc)(ec))
}
def generate(isUnique: String => Future[Boolean])(implicit ec: ExecutionContext) = uniqueRandomToken(Chars.mkString, Length, isUnique)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment