Adding pepper and stretches configuration per model, and globaly setup through Devise.pepper and Devise.stretches

This commit is contained in:
Carlos A. da Silva
2009-10-20 11:08:40 -02:00
parent 4d45672298
commit 342f948bc8
9 changed files with 169 additions and 61 deletions

View File

@@ -16,6 +16,16 @@ module Devise
}.freeze
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'].freeze
# Default pepper and stretches used in authenticable to create password hash.
# You can setup it inside each model or globaly using this attributes.
# Example:
# Devise.pepper = 'my_pepper_123'
# Devise.stretches = 20
mattr_accessor :pepper, :stretches
# Default stretches configuration
self.stretches = 10
end
require 'devise/warden'

View File

@@ -1,6 +1,23 @@
module Devise
module ActiveRecord
# Shortcut method for including all devise modules inside your model
# Shortcut method for including all devise modules inside your model.
# You can give some extra options while declaring devise in your model:
#
# * except: let's you add all devise modules, except the ones you setup here:
#
# devise :all, :except => :rememberable
#
# * pepper: setup a pepper to generate de encrypted password. By default no
# pepper is used:
#
# devise :all, :pepper => 'my_pepper'
#
# * stretches: configure how many times you want the password is reencrypted.
#
# devise :all, :stretches => 20
#
# You can refer to Authenticable for more information about writing your own
# method to setup pepper and stretches
#
# Examples:
#
@@ -30,6 +47,7 @@ module Devise
#
def devise(*modules)
options = modules.extract_options!
options.assert_valid_keys(:except, :stretches, :pepper)
modules = Devise::ALL if modules.include?(:all)
modules -= Array(options[:except]) if options.key?(:except)
@@ -39,6 +57,13 @@ module Devise
devise_modules << m.to_sym
include Devise::Models.const_get(m.to_s.classify)
end
if options.key?(:stretches) || options.key?(:pepper)
class_eval <<-END_EVAL, __FILE__, __LINE__
def stretches; #{options[:stretches]}; end if options.key?(:stretches)
def pepper; '#{options[:pepper]}'; end if options.key?(:pepper)
END_EVAL
end
end
# Stores all modules included inside the model, so we are able to verify

View File

@@ -10,8 +10,10 @@ module Devise
# pepper: encryption key used for creating encrypted password. Each time
# password changes, it's gonna be encrypted again, and this key
# is added to the password and salt to create a secure hash.
# def pepper; '1234567890987654321'; end
#
# stretches: defines how many times the password will be encrypted.
# def stretches; 20; end
#
# Examples:
#
@@ -20,12 +22,6 @@ module Devise
module Authenticable
mattr_accessor :pepper, :stretches
# Pepper for encrypting password
self.pepper = '23c64df433d9b08e464db5c05d1e6202dd2823f0'
# Encrypt password as many times as possible
self.stretches = 10
def self.included(base)
base.class_eval do
extend ClassMethods
@@ -36,21 +32,41 @@ module Devise
end
end
# Regenerates password salt and encrypted password each time password is
# setted.
def password=(new_password)
@password = new_password
self.password_salt = friendly_token
self.encrypted_password = password_digest(@password)
end
# Verifies whether an incoming_password (ie from login) is the user password
# Verifies whether an incoming_password (ie from login) is the user
# password.
def valid_password?(incoming_password)
password_digest(incoming_password) == encrypted_password
end
private
protected
# Pepper for encrypting password. Fallback to default configuration if
# no one exists for this specific model. Overwrite inside your model
# to provide specific pepper configuration:
#
# def pepper; 'my_pepper_123'; end
def pepper
@pepper ||= Devise.pepper
end
# Encrypt password as many times as possible. Fallback to default
# configuration if no one exists for this specific model.
#
# def stretches; 20; end
def stretches
@stretches ||= Devise.stretches
end
# Gererates a default password digest based on salt, pepper and the
# incoming password
# incoming password.
def password_digest(password_to_digest)
digest = pepper
stretches.times { digest = secure_digest(password_salt, digest, password_to_digest, pepper) }
@@ -64,7 +80,7 @@ module Devise
::Digest::SHA1.hexdigest('--' << tokens.flatten.join('--') << '--')
end
# Generate a friendly string randomically to be used as token
# Generate a friendly string randomically to be used as token.
def friendly_token
ActiveSupport::SecureRandom.base64(15).tr('+/=', '-_ ').strip.delete("\n")
end

View File

@@ -56,7 +56,7 @@ module Devise
end
end
private
protected
# Remove confirmation date from the user, ensuring after a user update
# it's email, it won't be able to sign in without confirming it.

View File

@@ -23,7 +23,7 @@ module Devise
end
end
private
protected
# Checks whether a password is needed or not. For validations only.
# Passwords are always required if it's a new record, or if the password