Package

com.lookout.borderpatrol

sessionx

Permalink

package sessionx

This introduces types and functions that enable identifying, fetching, and storing web session data. This is accomplished by a set of types that will be used by consumers of this library: Session, Store, and Secret.

A Secret is a cryptographically verifiable signing key used to sign a SignedId. Creating a Secret is simple. It defaults to expire at Secret.lifetime

val secret = Secret() // default secret expiry
val expiringSecret = Secret(Time.now)

val randomBytes = EntropyGenerator(16) // 16 bytes of randomness
val randomId = EntropyGenerator(1).head // 1 byte of randomness for an id
val expiry = Time.from(0) // very expired
val constructedSecret = Secret(randomId, randomBytes, expiry)
log(s"secret has expired: ${constructedSecret.expired == true}")

val signedMsg = secret.sign("message to by signed".getBytes)

A SignedId is a cryptographically signed identifier for a Session, it consists of entropy, expiry, secret,and signature of those items. This is meant to be used as the com.twitter.finagle.http.Cookie value, so we provide serializing to String.

val id: SignedId = Await.result(SignedId.next)
val cookieValue: String = id.asBase64
SignedId.from[String](cookieValue) == id

A Session is product type of a cryptographically verifiable identifier SignedId and an arbitrary data type A. The only requirement for a SessionStore[B,M] to store/fetch a Session[A] is that there be some implicit injective views from A => B and B => Try[A].

We have provided default encodings for: http.Request => Buf, String => Buf and their injective views.

// set up secret/session stores
implicit val secretStore = SecretStores.InMemorySecretStore(Secrets(Secret(), Secret()))
val sessionStore = SessionStore.InMemoryStore()

// create a Session[http.Request]
val newSessionFuture = Session(Request("http://localhost/api/stuff")) // entropy is blocking on the JVM
val newSession = Await.result(newSessionFuture)

// see if the session expired (checks the [[SignedId.expires]])
log(s"Session has expired? ${newSession.expired}")

// store the session and then fetch it
sessionStore.update(newSession).onFailure(log)
sessionStore.get(newSession.id).onSuccess(s => s match {
  case Some(s) => log(s"Same session?: ${newSession == s}")
  case None => log("hrm, where did the session go?")
})

Let's say you have a Session.data type that doesn't have the injective that you need, that's OK! Assuming you are storing it in memcached, which requires a type of Buf for the value:

trait Foo {
  val value: Int
}

implicit val enc = SessionDataEncoder[Foo](
  foo => Buf.U32BE(foo.value),
  buf => new Foo { override val value = Buf.U32BE.unapply(buf) }
)

val foo1 = new Foo { override val value = 1 }
val fooSession = Session(foo1)
sessionStore.update(fooSession)
Linear Supertypes
Types, AnyRef, Any
Ordering
  1. Alphabetic
  2. By inheritance
Inherited
  1. sessionx
  2. Types
  3. AnyRef
  4. Any
  1. Hide All
  2. Show all
Visibility
  1. Public
  2. All

Type Members

  1. implicit final class AnyOps[A] extends AnyVal

    Permalink

    Wraps any object with a toFuture method

  2. case class BpConsulError(msg: String) extends BpSessionError with Product with Serializable

    Permalink
  3. case class BpOriginalRequestNotFound(msg: String) extends BpSessionError with Product with Serializable

    Permalink
  4. case class BpSecretDecodeError(msg: String) extends BpSessionError with Product with Serializable

    Permalink
  5. case class BpSecretsDecodeError(msg: String) extends BpSessionError with Product with Serializable

    Permalink
  6. case class BpSessionCreateUnavailable(msg: String) extends BpSessionError with Product with Serializable

    Permalink
  7. case class BpSessionDataError(error: Throwable) extends BpSessionError with Product with Serializable

    Permalink
  8. class BpSessionError extends Exception

    Permalink
  9. case class BpSessionStoreError(msg: String) extends BpSessionError with Product with Serializable

    Permalink
  10. case class BpSignedIdError(error: String) extends BpSessionError with Product with Serializable

    Permalink
  11. case class ConsulResponse(createIndex: Int, flags: Int, key: String, lockIndex: Int, modifyIndex: Int, value: String) extends Product with Serializable

    Permalink

    Consul Response

  12. trait Encoder[A, B] extends AnyRef

    Permalink

    Typeclasses for Encoding data within sessions

  13. type Encrypted = Array[Byte]

    Permalink
    Definition Classes
    Types
  14. trait EncryptedDataEncoder[A] extends AnyRef

    Permalink

    This type uses the SessionDataEncoder to encode generic types to com.twitter.io.Buf, then the Encryptable and Decryptable types will unwrap the Buf encrypt/decrypt it, and then rewrap it.

  15. type Entropy = IndexedSeq[Byte]

    Permalink
    Definition Classes
    Types
  16. type Payload = IndexedSeq[Byte]

    Permalink
    Definition Classes
    Types
  17. type Seconds = Long

    Permalink
    Definition Classes
    Types
  18. case class Secret(id: sessionx.SecretId, expiry: Time, entropy: sessionx.Entropy) extends Signer with Product with Serializable

    Permalink

    Creates a new Secret that can be used to Signer.sign

    Creates a new Secret that can be used to Signer.sign

    id

    unique identifier for this secret

    expiry

    how long this signer is valid

    entropy

    the random bytes for this key

  19. trait SecretEncoder[A] extends Encoder[Secret, A]

    Permalink
  20. type SecretId = IndexedSeq[Byte]

    Permalink
    Definition Classes
    Types
  21. implicit final class SecretOps extends AnyVal

    Permalink
  22. trait SecretStoreApi extends AnyRef

    Permalink

    Two secrets must be in rotation at any given time: - Current: used for creating new sessions and validating incoming non-expired sessions - Previous: validating incoming non-expired sessions, e.g.

    Two secrets must be in rotation at any given time: - Current: used for creating new sessions and validating incoming non-expired sessions - Previous: validating incoming non-expired sessions, e.g. sessions signed by yesterday's key

    Since each Secret expires (default of 1 day), the window of a non-expired Session is somewhere between the expiry of the current Secret and the previous Secret

  23. case class Secrets(current: Secret, previous: Secret) extends Product with Serializable

    Permalink

    Place for current and previous valid Secret as they rotate

    Place for current and previous valid Secret as they rotate

    current

    the current Secret

    previous

    the previous (and potentially expired) Secret

  24. trait SecretsEncoder[A] extends Encoder[Secrets, A]

    Permalink
  25. trait Session[+A] extends AnyRef

    Permalink

    A container for some type A with a unique identifier of SignedId

  26. trait SessionDataEncoder[A] extends Encoder[A, Buf]

    Permalink
  27. implicit final class SessionOps[A] extends AnyVal

    Permalink

    Helpful value class for Session operations

  28. trait SessionStore extends AnyRef

    Permalink

    Session store that will store a Session[_] data into

  29. type Signature = IndexedSeq[Byte]

    Permalink
    Definition Classes
    Types
  30. case class SignedId(expires: Time, entropy: sessionx.Entropy, secret: Secret, tag: Tag, signature: sessionx.Signature) extends Product with Serializable

    Permalink

    This type represents the value of a user's Cookie The design of this is to act as a cryptographically verifiable identifier for a user

    This type represents the value of a user's Cookie The design of this is to act as a cryptographically verifiable identifier for a user

    In String form, is a Base64 encoded concatenation of the following transformation: expires: Time => Long => Array[Byte] entropy: Array[Byte] secret: Secret => SecretId tag: => Tag signature: Array[Byte]

    expires

    the time at which this id is expired

    entropy

    the random bytes unique to this session id

    secret

    the secret used to sign this session id

    signature

    the bytes of the signature(expires, entropy, secret.id)

  31. trait SignedIdEncoder[A] extends Encoder[SignedId, A]

    Permalink
  32. implicit final class SignedIdOps extends AnyVal

    Permalink

    More object-style accessors on SignedId, implementation defined in SignedId

  33. type Size = Int

    Permalink
    Definition Classes
    Types
  34. trait Tag extends AnyRef

    Permalink

    Tag is a byte that help us differentiate the set of SignedId from others.

  35. type TagId = Byte

    Permalink
    Definition Classes
    Types
  36. implicit final class ThrowableOps extends AnyVal

    Permalink

    Wraps any Throwable with a toFutureException method

  37. type TimeBytes = IndexedSeq[Byte]

    Permalink
    Definition Classes
    Types
  38. trait Types extends AnyRef

    Permalink

Value Members

  1. object AuthenticatedTag extends Tag with Product with Serializable

    Permalink
  2. implicit val ByteCodecJson: CodecJson[Byte]

    Permalink

    Helper for Byte -> Json

  3. object ConsulResponse extends Serializable

    Permalink
  4. object Encoder

    Permalink

    Create instances of Encoder

  5. object EncryptedDataEncoder

    Permalink

    Instances of EncryptedDataEncoder only need to contain a SessionDataEncoder TODO: remove this whole concept of an EncryptedDataEncoder type class, it's worthless.

    Instances of EncryptedDataEncoder only need to contain a SessionDataEncoder TODO: remove this whole concept of an EncryptedDataEncoder type class, it's worthless. We can treat Session as a Functor and apply the encryption/decryption via mixins to the base SessionStore

  6. object Secret extends Serializable

    Permalink

    Helper object for defining defaults for entropy, id size, and expiry

    Helper object for defining defaults for entropy, id size, and expiry

    val validSecret = Secret()
    val anotherSecret = Secret(Time.now + Duration(1, TimeUnit.HOURS)) // expires in an hour
  7. object SecretEncoder

    Permalink

    Instances of SecretEncoder for Secret => A

  8. object SecretStores

    Permalink

    Default implementations of SecretStoreApi

  9. object Secrets extends Serializable

    Permalink
  10. object SecretsEncoder

    Permalink
  11. object Session

    Permalink
  12. object SessionDataEncoder

    Permalink

    Instances of SessionDataEncoder for A => com.twitter.io.Buf

  13. object SessionStores

    Permalink

    Default implementations of SessionStore with memcached and an in-memory store for mocking

  14. object SignedId extends Serializable

    Permalink
  15. object SignedIdEncoder

    Permalink

    Instances of SignedIdEncoder for SignedId => A

  16. object Tag

    Permalink
  17. implicit val TimeCodecJson: CodecJson[Time]

    Permalink

    Time -> Long -> Json

  18. object Untagged extends Tag with Product with Serializable

    Permalink

Inherited from Types

Inherited from AnyRef

Inherited from Any

Ungrouped