forked from t2v/play2-auth
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Changed that The Play Session might not be used
- Loading branch information
gakuzzzz
committed
Nov 22, 2012
1 parent
d170c00
commit 1dc399b
Showing
13 changed files
with
176 additions
and
149 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,3 +6,8 @@ tmp | |
.history | ||
.idea | ||
.idea_modules | ||
*.iml | ||
.project | ||
.settings/ | ||
.ivy2/ | ||
.classpath |
This file contains 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
This file contains 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
This file contains 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
57 changes: 57 additions & 0 deletions
57
module/src/main/scala/jp/t2v/lab/play20/auth/CacheIdContainer.scala
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package jp.t2v.lab.play20.auth | ||
|
||
import play.api.cache.Cache | ||
import play.api.Play._ | ||
import scala.annotation.tailrec | ||
import scala.util.Random | ||
import java.security.SecureRandom | ||
|
||
class CacheIdContainer[Id: ClassManifest] extends IdContainer[Id] { | ||
|
||
private[auth] val tokenSuffix = ":token" | ||
private[auth] val userIdSuffix = ":userId" | ||
private[auth] val random = new Random(new SecureRandom()) | ||
|
||
def startNewSession(userId: Id, timeoutInSeconds: Int): AuthenticityToken = { | ||
removeByUserId(userId) | ||
val token = generate | ||
store(token, userId, timeoutInSeconds) | ||
token | ||
} | ||
|
||
@tailrec | ||
private[auth] final def generate: AuthenticityToken = { | ||
val table = "abcdefghijklmnopqrstuvwxyz1234567890_.!~*'()" | ||
val token = Stream.continually(random.nextInt(table.size)).map(table).take(64).mkString | ||
if (get(token).isDefined) generate else token | ||
} | ||
|
||
private[auth] def removeByUserId(userId: Id) { | ||
Cache.getAs[String](userId.toString + userIdSuffix) foreach unsetToken | ||
unsetUserId(userId) | ||
} | ||
|
||
def remove(token: AuthenticityToken) { | ||
get(token) foreach unsetUserId | ||
unsetToken(token) | ||
} | ||
|
||
private[auth] def unsetToken(token: AuthenticityToken) { | ||
Cache.set(token + tokenSuffix, None, 1) | ||
} | ||
private[auth] def unsetUserId(userId: Id) { | ||
Cache.set(userId.toString + userIdSuffix, None, 1) | ||
} | ||
|
||
def get(token: AuthenticityToken) = Cache.get(token + tokenSuffix).map(_.asInstanceOf[Id]) | ||
|
||
private[auth] def store(token: AuthenticityToken, userId: Id, timeoutInSeconds: Int) { | ||
Cache.set(token + tokenSuffix, userId, timeoutInSeconds) | ||
Cache.set(userId.toString + userIdSuffix, token, timeoutInSeconds) | ||
} | ||
|
||
def prolongTimeout(token: AuthenticityToken, timeoutInSeconds: Int) { | ||
get(token).foreach(store(token, _, timeoutInSeconds)) | ||
} | ||
|
||
} |
45 changes: 0 additions & 45 deletions
45
module/src/main/scala/jp/t2v/lab/play20/auth/CacheRelationResolver.scala
This file was deleted.
Oops, something went wrong.
41 changes: 41 additions & 0 deletions
41
module/src/main/scala/jp/t2v/lab/play20/auth/CookieIdContainer.scala
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package jp.t2v.lab.play20.auth | ||
|
||
import scala.util.control.Exception._ | ||
|
||
class CookieIdContainer[Id: ToString: FromString] extends IdContainer[Id] { | ||
|
||
def startNewSession(userId: Id, timeoutInSeconds: Int) = implicitly[ToString[Id]].apply(userId) | ||
|
||
def remove(token: AuthenticityToken) { | ||
} | ||
|
||
def get(token: AuthenticityToken) = implicitly[FromString[Id]].apply(token) | ||
|
||
def prolongTimeout(token: AuthenticityToken, timeoutInSeconds: Int) { | ||
// Cookie Id Container does not support timeout. | ||
} | ||
|
||
} | ||
|
||
trait ToString[A] { | ||
def apply(id: A): String | ||
} | ||
object ToString { | ||
def apply[A](f: A => String) = new ToString[A] { | ||
def apply(id: A) = f(id) | ||
} | ||
implicit val string = ToString[String](identity) | ||
implicit val int = ToString[Int](_.toString) | ||
implicit val long = ToString[Long](_.toString) | ||
} | ||
trait FromString[A] { | ||
def apply(id: String): Option[A] | ||
} | ||
object FromString { | ||
def apply[A](f: String => A) = new FromString[A] { | ||
def apply(id: String) = allCatch opt f(id) | ||
} | ||
implicit val string = FromString[String](identity) | ||
implicit val int = FromString[Int](_.toInt) | ||
implicit val long = FromString[Long](_.toLong) | ||
} |
52 changes: 0 additions & 52 deletions
52
module/src/main/scala/jp/t2v/lab/play20/auth/CookieRelationResolver.scala
This file was deleted.
Oops, something went wrong.
13 changes: 13 additions & 0 deletions
13
module/src/main/scala/jp/t2v/lab/play20/auth/IdContainer.scala
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package jp.t2v.lab.play20.auth | ||
|
||
|
||
trait IdContainer[Id] { | ||
|
||
def startNewSession(userId: Id, timeoutInSeconds: Int): AuthenticityToken | ||
|
||
def remove(token: AuthenticityToken): Unit | ||
def get(token: AuthenticityToken): Option[Id] | ||
|
||
def prolongTimeout(token: AuthenticityToken, timeoutInSeconds: Int): Unit | ||
|
||
} |
40 changes: 23 additions & 17 deletions
40
module/src/main/scala/jp/t2v/lab/play20/auth/LoginLogout.scala
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,38 @@ | ||
package jp.t2v.lab.play20.auth | ||
|
||
import play.api.mvc.{Request, PlainResult, Controller} | ||
import play.api.mvc._ | ||
import play.api.mvc.AsyncResult | ||
import play.api.mvc.Cookie | ||
import scala.annotation.tailrec | ||
import scala.util.Random | ||
import java.security.SecureRandom | ||
|
||
trait LoginLogout { | ||
self: Controller with AuthConfig => | ||
|
||
def gotoLoginSucceeded[A](userId: Id)(implicit request: Request[A]): PlainResult = { | ||
resolver.removeByUserId(userId) | ||
val sessionId = generateSessionId(request) | ||
val session = resolver.store(sessionId, userId, sessionTimeoutInSeconds) | ||
loginSucceeded(request).withSession(session + ("sessionId" -> sessionId)) | ||
def gotoLoginSucceeded(userId: Id)(implicit request: RequestHeader): Result = { | ||
val token = idContainer.startNewSession(userId, sessionTimeoutInSeconds) | ||
setCookie(loginSucceeded(request), token) | ||
} | ||
|
||
def gotoLogoutSucceeded[A](implicit request: Request[A]): PlainResult = { | ||
request.session.get("sessionId") foreach resolver.removeBySessionId | ||
logoutSucceeded(request).withNewSession | ||
def gotoLogoutSucceeded(implicit request: RequestHeader): Result = { | ||
request.cookies.get(cookieName) map (_.value) foreach idContainer.remove | ||
unsetCookie(logoutSucceeded(request)) | ||
} | ||
|
||
@tailrec | ||
private def generateSessionId[A](implicit request: Request[A]): String = { | ||
val table = "abcdefghijklmnopqrstuvwxyz1234567890_.!~*'()" | ||
val token = Stream.continually(random.nextInt(table.size)).map(table).take(64).mkString | ||
if (resolver.exists(token)) generateSessionId(request) else token | ||
protected[auth] final def setCookie(result: Result, token: AuthenticityToken): Result = { | ||
setCookie_(result, Cookie(cookieName, token, -1, cookiePathOption, cookieDomainOption, cookieSecureOption, cookieHttpOnlyOption)) | ||
} | ||
|
||
protected[auth] final def unsetCookie(result: Result): Result = { | ||
setCookie_(result, Cookie(cookieName, "", 0)) | ||
} | ||
|
||
protected[auth] final def setCookie_(result: Result, cookie: Cookie): Result = { | ||
def set(r: Result): Result = r match { | ||
case p: PlainResult => p.withCookies(cookie) | ||
case a: AsyncResult => AsyncResult(a.result.map(set)) | ||
} | ||
set(result) | ||
} | ||
|
||
private val random = new Random(new SecureRandom()) | ||
|
||
} |
17 changes: 0 additions & 17 deletions
17
module/src/main/scala/jp/t2v/lab/play20/auth/RelationResolver.scala
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.