mirror of
https://github.com/heartcombo/devise.git
synced 2026-04-28 03:00:29 -04:00
Extract encryptors into their own module for better bcrypt support.
This commit is contained in:
@@ -2,55 +2,17 @@ require 'test_helper'
|
||||
require 'digest/sha1'
|
||||
|
||||
class DatabaseAuthenticatableTest < ActiveSupport::TestCase
|
||||
|
||||
def encrypt_password(user, pepper=User.pepper, stretches=User.stretches, encryptor=User.encryptor_class)
|
||||
encryptor.digest('123456', stretches, user.password_salt, pepper)
|
||||
end
|
||||
|
||||
def swap_with_encryptor(klass, encryptor, options={})
|
||||
klass.instance_variable_set(:@encryptor_class, nil)
|
||||
|
||||
swap klass, options.merge(:encryptor => encryptor) do
|
||||
begin
|
||||
yield
|
||||
ensure
|
||||
klass.instance_variable_set(:@encryptor_class, nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test 'should respond to password and password confirmation' do
|
||||
user = new_user
|
||||
assert user.respond_to?(:password)
|
||||
assert user.respond_to?(:password_confirmation)
|
||||
end
|
||||
|
||||
test 'should generate encrypted password and salt while setting password' do
|
||||
test 'should generate encrypted password while setting password' do
|
||||
user = new_user
|
||||
assert_present user.password_salt
|
||||
assert_present user.encrypted_password
|
||||
end
|
||||
|
||||
test 'should not change password salt when updating' do
|
||||
user = create_user
|
||||
salt = user.password_salt
|
||||
user.expects(:password_salt=).never
|
||||
user.save!
|
||||
assert_equal salt, user.password_salt
|
||||
end
|
||||
|
||||
test 'should generate a base64 hash using SecureRandom for password salt' do
|
||||
swap_with_encryptor User, :sha1 do
|
||||
ActiveSupport::SecureRandom.expects(:base64).with(44).returns('friendly_token')
|
||||
assert_equal 'friendly_token', new_user.password_salt
|
||||
end
|
||||
end
|
||||
|
||||
test 'should not generate salt if password is blank' do
|
||||
assert_blank new_user(:password => nil).password_salt
|
||||
assert_blank new_user(:password => '').password_salt
|
||||
end
|
||||
|
||||
test 'should not generate encrypted password if password is blank' do
|
||||
assert_blank new_user(:password => nil).encrypted_password
|
||||
assert_blank new_user(:password => '').encrypted_password
|
||||
@@ -64,47 +26,12 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
|
||||
assert_not_equal encrypted_password, user.encrypted_password
|
||||
end
|
||||
|
||||
test 'should fallback to sha1 as default encryption' do
|
||||
user = new_user
|
||||
assert_equal encrypt_password(user), user.encrypted_password
|
||||
end
|
||||
|
||||
test 'should fallback to devise pepper default configuration' do
|
||||
begin
|
||||
Devise.pepper = ''
|
||||
user = new_user
|
||||
assert_equal encrypt_password(user), user.encrypted_password
|
||||
assert_not_equal encrypt_password(user, 'another_pepper'), user.encrypted_password
|
||||
|
||||
Devise.pepper = 'new_pepper'
|
||||
user = new_user
|
||||
assert_equal encrypt_password(user, 'new_pepper'), user.encrypted_password
|
||||
assert_not_equal encrypt_password(user, 'another_pepper'), user.encrypted_password
|
||||
ensure
|
||||
Devise.pepper = nil
|
||||
end
|
||||
end
|
||||
|
||||
test 'should respect encryptor configuration' do
|
||||
swap_with_encryptor User, :sha512 do
|
||||
user = create_user
|
||||
assert_equal user.encrypted_password, encrypt_password(user, User.pepper, User.stretches, ::Devise::Encryptors::Sha512)
|
||||
end
|
||||
end
|
||||
|
||||
test 'should test for a valid password' do
|
||||
user = create_user
|
||||
assert user.valid_password?('123456')
|
||||
assert_not user.valid_password?('654321')
|
||||
end
|
||||
|
||||
test 'should not validate password when salt is nil' do
|
||||
admin = create_admin
|
||||
admin.password_salt = nil
|
||||
admin.save
|
||||
assert_not admin.valid_password?('123456')
|
||||
end
|
||||
|
||||
test 'should respond to current password' do
|
||||
assert new_user.respond_to?(:current_password)
|
||||
end
|
||||
|
||||
65
test/models/encryptable_test.rb
Normal file
65
test/models/encryptable_test.rb
Normal file
@@ -0,0 +1,65 @@
|
||||
require 'test_helper'
|
||||
|
||||
class EncryptableTest < ActiveSupport::TestCase
|
||||
def encrypt_password(admin, pepper=Admin.pepper, stretches=Admin.stretches, encryptor=Admin.encryptor_class)
|
||||
encryptor.digest('123456', stretches, admin.password_salt, pepper)
|
||||
end
|
||||
|
||||
def swap_with_encryptor(klass, encryptor, options={})
|
||||
klass.instance_variable_set(:@encryptor_class, nil)
|
||||
|
||||
swap klass, options.merge(:encryptor => encryptor) do
|
||||
begin
|
||||
yield
|
||||
ensure
|
||||
klass.instance_variable_set(:@encryptor_class, nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test 'should generate salt while setting password' do
|
||||
assert_present create_admin.password_salt
|
||||
end
|
||||
|
||||
test 'should not change password salt when updating' do
|
||||
admin = create_admin
|
||||
salt = admin.password_salt
|
||||
admin.expects(:password_salt=).never
|
||||
admin.save!
|
||||
assert_equal salt, admin.password_salt
|
||||
end
|
||||
|
||||
test 'should generate a base64 hash using SecureRandom for password salt' do
|
||||
swap_with_encryptor Admin, :sha1 do
|
||||
ActiveSupport::SecureRandom.expects(:base64).with(44).returns('friendly_token')
|
||||
assert_equal 'friendly_token', create_admin.password_salt
|
||||
end
|
||||
end
|
||||
|
||||
test 'should not generate salt if password is blank' do
|
||||
assert_blank create_admin(:password => nil).password_salt
|
||||
assert_blank create_admin(:password => '').password_salt
|
||||
end
|
||||
|
||||
test 'should encrypt password again if password has changed' do
|
||||
admin = create_admin
|
||||
encrypted_password = admin.encrypted_password
|
||||
admin.password = admin.password_confirmation = 'new_password'
|
||||
admin.save!
|
||||
assert_not_equal encrypted_password, admin.encrypted_password
|
||||
end
|
||||
|
||||
test 'should respect encryptor configuration' do
|
||||
swap_with_encryptor Admin, :sha512 do
|
||||
admin = create_admin
|
||||
assert_equal admin.encrypted_password, encrypt_password(admin, Admin.pepper, Admin.stretches, ::Devise::Encryptors::Sha512)
|
||||
end
|
||||
end
|
||||
|
||||
test 'should not validate password when salt is nil' do
|
||||
admin = create_admin
|
||||
admin.password_salt = nil
|
||||
admin.save
|
||||
assert_not admin.valid_password?('123456')
|
||||
end
|
||||
end
|
||||
@@ -260,12 +260,12 @@ class WithSaltRememberableTest < ActiveSupport::TestCase
|
||||
test 'serialize into cookie' do
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
assert_equal [user.id, user.password_salt], User.serialize_into_cookie(user)
|
||||
assert_equal [user.id, user.authenticatable_salt], User.serialize_into_cookie(user)
|
||||
end
|
||||
|
||||
test 'serialize from cookie' do
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
assert_equal user, User.serialize_from_cookie(user.id, user.password_salt)
|
||||
assert_equal user, User.serialize_from_cookie(user.id, user.authenticatable_salt)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
require 'test_helper'
|
||||
|
||||
class Configurable < User
|
||||
devise :database_authenticatable, :confirmable, :rememberable, :timeoutable, :lockable,
|
||||
devise :database_authenticatable, :encryptable, :confirmable, :rememberable, :timeoutable, :lockable,
|
||||
:stretches => 15, :pepper => 'abcdef', :confirm_within => 5.days,
|
||||
:remember_for => 7.days, :timeout_in => 15.minutes, :unlock_in => 10.days
|
||||
end
|
||||
@@ -26,16 +26,16 @@ class ActiveRecordTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test 'can cherry pick modules' do
|
||||
assert_include_modules Admin, :database_authenticatable, :registerable, :timeoutable, :recoverable, :lockable, :rememberable
|
||||
assert_include_modules Admin, :database_authenticatable, :registerable, :timeoutable, :recoverable, :lockable, :rememberable, :encryptable
|
||||
end
|
||||
|
||||
test 'chosen modules are inheritable' do
|
||||
assert_include_modules Inheritable, :database_authenticatable, :registerable, :timeoutable, :recoverable, :lockable, :rememberable
|
||||
assert_include_modules Inheritable, :database_authenticatable, :registerable, :timeoutable, :recoverable, :lockable, :rememberable, :encryptable
|
||||
end
|
||||
|
||||
test 'order of module inclusion' do
|
||||
correct_module_order = [:database_authenticatable, :rememberable, :recoverable, :registerable, :lockable, :timeoutable]
|
||||
incorrect_module_order = [:database_authenticatable, :timeoutable, :registerable, :recoverable, :lockable, :rememberable]
|
||||
correct_module_order = [:database_authenticatable, :rememberable, :encryptable, :recoverable, :registerable, :lockable, :timeoutable]
|
||||
incorrect_module_order = [:database_authenticatable, :timeoutable, :registerable, :recoverable, :lockable, :encryptable, :rememberable]
|
||||
|
||||
assert_include_modules Admin, *incorrect_module_order
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ Devise.setup do |config|
|
||||
# from others authentication tools as :clearance_sha1, :authlogic_sha512 (then
|
||||
# you should set stretches above to 20 for default behavior) and :restful_authentication_sha1
|
||||
# (then you should set stretches to 10, and copy REST_AUTH_SITE_KEY to pepper)
|
||||
config.encryptor = :bcrypt
|
||||
config.encryptor = :sha512
|
||||
|
||||
# Setup a pepper to generate the encrypted password.
|
||||
config.pepper = "d142367154e5beacca404b1a6a4f8bc52c6fdcfa3ccc3cf8eb49f3458a688ee6ac3b9fae488432a3bfca863b8a90008368a9f3a3dfbe5a962e64b6ab8f3a3a1a"
|
||||
|
||||
@@ -15,7 +15,8 @@ class CreateTables < ActiveRecord::Migration
|
||||
end
|
||||
|
||||
create_table :admins do |t|
|
||||
t.database_authenticatable :null => true, :encryptor => :bcrypt
|
||||
t.database_authenticatable :null => true
|
||||
t.encryptable
|
||||
t.rememberable
|
||||
t.recoverable
|
||||
t.lockable
|
||||
|
||||
@@ -15,7 +15,7 @@ ActiveRecord::Schema.define(:version => 20100401102949) do
|
||||
create_table "admins", :force => true do |t|
|
||||
t.string "email", :default => ""
|
||||
t.string "encrypted_password", :limit => 128, :default => ""
|
||||
t.string "password_salt", :default => ""
|
||||
t.string "password_salt"
|
||||
t.string "reset_password_token"
|
||||
t.integer "failed_attempts", :default => 0
|
||||
t.string "unlock_token"
|
||||
@@ -29,7 +29,6 @@ ActiveRecord::Schema.define(:version => 20100401102949) do
|
||||
t.string "facebook_token"
|
||||
t.string "email", :default => "", :null => false
|
||||
t.string "encrypted_password", :limit => 128, :default => "", :null => false
|
||||
t.string "password_salt", :default => "", :null => false
|
||||
t.string "confirmation_token"
|
||||
t.datetime "confirmed_at"
|
||||
t.datetime "confirmation_sent_at"
|
||||
|
||||
@@ -2,6 +2,6 @@ module SharedAdmin
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
devise :database_authenticatable, :registerable, :timeoutable, :recoverable, :rememberable, :lockable, :unlock_strategy => :time
|
||||
devise :database_authenticatable, :encryptable, :registerable, :timeoutable, :recoverable, :rememberable, :lockable, :unlock_strategy => :time
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user