-
Notifications
You must be signed in to change notification settings - Fork 142
/
CacheIdContainer.scala
63 lines (49 loc) · 2.03 KB
/
CacheIdContainer.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package jp.t2v.lab.play2.auth
import play.api.cache.{ Cache, CacheApi }
import play.api.Play._
import scala.annotation.tailrec
import scala.util.Random
import java.security.SecureRandom
import java.util.concurrent.TimeUnit
import scala.concurrent.duration.Duration
import scala.reflect.ClassTag
class CacheIdContainer[Id: ClassTag] (cacheApi: CacheApi) 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 = Iterator.continually(random.nextInt(table.size)).map(table).take(64).mkString
if (get(token).isDefined) generate else token
}
private[auth] def removeByUserId(userId: Id) {
cacheApi.get[String](userId.toString + userIdSuffix) foreach unsetToken
unsetUserId(userId)
}
def remove(token: AuthenticityToken) {
get(token) foreach unsetUserId
unsetToken(token)
}
private[auth] def unsetToken(token: AuthenticityToken) {
cacheApi.remove(token + tokenSuffix)
}
private[auth] def unsetUserId(userId: Id) {
cacheApi.remove(userId.toString + userIdSuffix)
}
def get(token: AuthenticityToken) = cacheApi.get(token + tokenSuffix).map(_.asInstanceOf[Id])
private[auth] def store(token: AuthenticityToken, userId: Id, timeoutInSeconds: Int) {
def intToDuration(seconds: Int): Duration = if (seconds == 0) Duration.Inf else Duration(seconds, TimeUnit.SECONDS)
cacheApi.set(token + tokenSuffix, userId, intToDuration(timeoutInSeconds))
cacheApi.set(userId.toString + userIdSuffix, token, intToDuration(timeoutInSeconds))
}
def prolongTimeout(token: AuthenticityToken, timeoutInSeconds: Int) {
get(token).foreach(store(token, _, timeoutInSeconds))
}
}