Skip to content

Instantly share code, notes, and snippets.

@amolbrid
Created February 27, 2015 16:44
Show Gist options
  • Save amolbrid/d29c63815ca7d47ca116 to your computer and use it in GitHub Desktop.
Save amolbrid/d29c63815ca7d47ca116 to your computer and use it in GitHub Desktop.
package com.example.test
import scala.slick.driver.PostgresDriver
object UserComponentRegistry extends UserRepositoryComponent {
val userRepository = new UserRepository(PostgresDriver)
}
package com.example.test
import java.nio.charset.StandardCharsets
import java.security.MessageDigest
import com.example.domain.JdbcProfileComponent
import scala.slick.driver.JdbcProfile
trait UserRepositoryComponent {
val userRepository:UserRepository
class UserRepository(val profile: JdbcProfile) extends UsersTable with JdbcProfileComponent {
import profile.simple._
private[this] val Sha256Algorithm = "SHA-256"
private[this] val UsAsciiEncoding = StandardCharsets.US_ASCII
/**
* Hashes the token with SHA-256.
*
* We could not use bcrypt since only the token is transmitted,
* and unlike the SHA functions there exist more than 1 hash per input,
* which would require us to table scan users.
*/
def hashToken(token: String): String = {
val messageDigest = MessageDigest.getInstance(Sha256Algorithm)
messageDigest.update(token.getBytes(UsAsciiEncoding))
messageDigest.digest().foldLeft("") { case (acc, byte) ⇒ f"${acc}%s${byte}%02x"}
}
private[this] val findByHashedToken = usersTable.findBy {
_.hashedToken
}
/**
* Returns the user with the corresponding authentication token.
*
* Authentication tokens are hashed in the database, but this method expects
* an unauthenticated token.
*/
def authenticateWithToken(token: String)
(implicit session: Session): Option[User] = {
findByHashedToken(hashToken(token)).firstOption
}
}
}
package com.example.test
import com.example.domain.JdbcProfileComponent
case class User(id: Int, email: String, hashed_token: String)
trait UsersTable { this: JdbcProfileComponent =>
import profile.simple._
class Users(tag: Tag) extends Table[User](tag, "USERS") {
def id = column[Long]("id", O.PrimaryKey, O.NotNull, O.AutoInc)
def emailAddress = column[String]("emailAddress", O.NotNull)
def hashedToken = column[String]("hashed_token", O.Nullable)
def * = (
id,
emailAddress,
hashedToken.?
) <> (User.tupled, User.unapply)
}
val usersTable = TableQuery[Users]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment