Question

I have a table User(id, password_hash, ....) in db and a model for it:

case class User(
  id: Pk[Long] = NotAssigned,
  email: String,
  password: Option[String] = None,
  passwordHash: Option[String] = None
)


object User {

  def create(newUser: User): Option[Long] = //.....

  //on("password_hash" -> generatePasswordHash(newUser.password)

  def generatePasswordHash(p: String) = //....
 }

The point is Password field exists only the model User and is filled up only I register a new user:

val newUser = User(email = emailFromForm, password = Some(passwordFromForm))

I send to db only a hash of the password. Obviously, when I retrieve it from db, Password field in None but PasswordHash has a value.

I made Password and PasswordHash to be Option because I think they should be Options, shouldn't they? I'm not sure, though, whether it's right or wrong.

The question is my is this a good approach?

Was it helpful?

Solution

Why do you want to have User.password at all?

case class User(
  id: Pk[Long] = NotAssigned,
  email: String,
  passwordHash: String 
)

object User {
  // or maybe Option[User] or Try[User]
  def create(email: String, password: String): Option[Long] = {
    val passwordHash = hashPassword(hash)
    val newUser = User(email, passwordHash)
    // save newUser to DB
  }

  // you may want to distinguish between "no such email" and "wrong password"
  // in which case you'd have something like Either[PasswordCheckFailure, User]
  def checkPassword(email: String, password: String): Option[User] = {
    val possibleUser: Option[User] = // get user by email
    possibleUser.filter(_.passwordHash = hashPassword(password))
  }

  private def hashPassword(password: String): String = ...
}

You may want to have a salt as well, see e.g. https://crackstation.net/hashing-security.htm. In this case you either store it in the same field as password or add another field:

case class User(
  id: Pk[Long] = NotAssigned,
  email: String,
  passwordHash: String,
  passwordSalt: String = // generate random string
)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top