All Downloads are FREE. Search and download functionalities are using the official Maven repository.

securesocial.core.providers.utils.PasswordHasher.scala Maven / Gradle / Ivy

/**
 * Copyright 2012-2014 Jorge Aliss (jaliss at gmail dot com) - twitter: @jaliss
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package securesocial.core.providers.utils

import securesocial.core.PasswordInfo
import org.mindrot.jbcrypt._

/**
 * A trait that defines the password hasher interface
 */

abstract class PasswordHasher {
  /**
   * The password hasher id
   */
  val id: String

  /**
   * Hashes a password
   *
   * @param plainPassword the password to hash
   * @return a PasswordInfo containting the hashed password and optional salt
   */
  def hash(plainPassword: String): PasswordInfo

  /**
   * Checks whether a supplied password matches the hashed one
   *
   * @param passwordInfo the password retrieved from the backing store (by means of UserService)
   * @param suppliedPassword the password supplied by the user trying to log in
   * @return true if the password matches, false otherwise.
   */
  def matches(passwordInfo: PasswordInfo, suppliedPassword: String): Boolean
}

object PasswordHasher {
  val id = "bcrypt"

  /**
   * The default password hasher based on BCrypt.
   */
  class Default(logRounds: Int) extends PasswordHasher {
    /**
     * Creates an instance with logRounds set to the value specified in
     * securesocial.passwordHasher.bcrypt.rounds or to a default 10 if the property is not
     * defined.
     */
    def this() = this({
      val app = play.api.Play.current
      app.configuration.getInt(Default.RoundsProperty).getOrElse(Default.Rounds)
    })

    /**
     * The hasher id
     */
    override val id = PasswordHasher.id

    /**
     * Hashes a password. This implementation does not return the salt because it is not needed
     * to verify passwords later.  Other implementations might need to return it so it gets saved in the
     * backing store.
     *
     * @param plainPassword the password to hash
     * @return a PasswordInfo containing the hashed password.
     */
    def hash(plainPassword: String): PasswordInfo = {
      PasswordInfo(id, BCrypt.hashpw(plainPassword, BCrypt.gensalt(logRounds)))
    }

    /**
     * Checks if a password matches the hashed version
     *
     * @param passwordInfo the password retrieved from the backing store (by means of UserService)
     * @param suppliedPassword the password supplied by the user trying to log in
     * @return true if the password matches, false otherwise.
     */
    def matches(passwordInfo: PasswordInfo, suppliedPassword: String): Boolean = {
      BCrypt.checkpw(suppliedPassword, passwordInfo.password)
    }
  }

  object Default {
    val Rounds = 10
    val RoundsProperty = "securesocial.passwordHasher.bcrypt.rounds"
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy