From 236df9bfaa712359e4dfe401accaa73658de785c Mon Sep 17 00:00:00 2001 From: Tristan McHardie Date: Thu, 10 Sep 2015 18:40:48 +1200 Subject: [PATCH 1/2] Set stretches back to the Devise default of 10. Any higher makes tests intolerably slow when using bcrypt. --- config/initializers/devise.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 9ef2a1002..146829448 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -37,7 +37,7 @@ # ==> Configuration for :database_authenticatable # For bcrypt, this is the cost for hashing the password and defaults to 10. If # using other encryptors, it sets how many times you want the password re-encrypted. - config.stretches = 20 + config.stretches = 10 # Setup a pepper to generate the encrypted password. config.pepper = Rails.configuration.secret_token From cd1e881f9ffc2f1ed128710e9f9fa8e9f06cb598 Mon Sep 17 00:00:00 2001 From: Tristan McHardie Date: Thu, 10 Sep 2015 18:54:33 +1200 Subject: [PATCH 2/2] Allow other encryptors other than authlogic_sha512. - Creates an encryptor preference. - Only includes Devise::Models::Encryptable if bcrypt is not used. --- README.md | 21 +++++++++++++++++ app/models/spree/auth_configuration.rb | 1 + app/models/spree/user.rb | 8 ++++++- spec/models/user_spec.rb | 32 ++++++++++++++++++++++++++ spec/support/config_helpers.rb | 18 +++++++++++++++ 5 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 spec/support/config_helpers.rb diff --git a/README.md b/README.md index 68b073cce..77362d69c 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,27 @@ Devise.setup do |config| end ``` +### Encryptable + +**Warning:** Changing the encryptor will invalidate all existing passwords in your users table! + +Spree Auth (Devise) by default uses the `authlogic_sha512` encryptor provided by the [Devise Encryptable](https://github.com/plataformatec/devise-encryptable) gem. New projects (or older projects migrating to Spree) may require the more the secure `bcrypt` (Devise's default) or some other encryptor provided by Devise Encryptable. + +To change the encryptor: + +* Add this line to an initializer in your Rails project (typically `config/initializers/spree.rb`): +```ruby +Spree::Auth::Config[:encryptor] = 'bcrypt' +``` + +* Add a Devise initializer to your Rails project (typically `config/initializers/devise.rb`): +```ruby +Devise.setup do |config| + # Set stretches to at least 10 (the default) + config.stretches = 10 +end +``` + ## Using in an existing Rails application If you are installing Spree inside of a host application in which you want your own permission setup, you can do this using spree_auth_devise's register_ability method. diff --git a/app/models/spree/auth_configuration.rb b/app/models/spree/auth_configuration.rb index cef022f86..aa241ccf7 100644 --- a/app/models/spree/auth_configuration.rb +++ b/app/models/spree/auth_configuration.rb @@ -3,5 +3,6 @@ class AuthConfiguration < Preferences::Configuration preference :registration_step, :boolean, :default => true preference :signout_after_password_change, :boolean, :default => true preference :confirmable, :boolean, :default => false + preference :encryptor, :string, :default => 'authlogic_sha512' end end diff --git a/app/models/spree/user.rb b/app/models/spree/user.rb index cbfbe34d4..192c67d8b 100644 --- a/app/models/spree/user.rb +++ b/app/models/spree/user.rb @@ -4,9 +4,15 @@ class User < ActiveRecord::Base include UserPaymentSource devise :database_authenticatable, :registerable, :recoverable, - :rememberable, :trackable, :validatable, :encryptable, :encryptor => 'authlogic_sha512' + :rememberable, :trackable, :validatable devise :confirmable if Spree::Auth::Config[:confirmable] + # Devise's default encryptor is bcrypt and does not require the encryptable + # module to be loaded. + if Spree::Auth::Config[:encryptor] != 'bcrypt' + devise :encryptable, :encryptor => Spree::Auth::Config[:encryptor] + end + acts_as_paranoid after_destroy :scramble_email_and_password diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index eeb19ac14..7e8e9ef8b 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -55,4 +55,36 @@ expect(Spree::User.devise_modules).to_not include(:confirmable) end end + + describe 'encryptable' do + context 'when encryptor option is set to authlogic_sha512' do + around do |example| + with_config_option(:encryptor, 'authlogic_sha512') { example.run } + end + + it 'includes encryptable module' do + expect(Spree::User.devise_modules).to include(:encryptable) + end + + describe '.encryptor' do + it 'returns authlogic_sha512' do + expect(Spree::User.encryptor).to eq('authlogic_sha512') + end + end + end + + context 'when encryptor option is set to bcrypt' do + around do |example| + with_config_option(:encryptor, 'bcrypt') { example.run } + end + + it 'does not include encryptable module' do + expect(Spree::User.devise_modules).to_not include(:encryptable) + end + + it 'does not respond to .encryptor' do + expect(Spree::User).to_not respond_to(:encryptor) + end + end + end end diff --git a/spec/support/config_helpers.rb b/spec/support/config_helpers.rb new file mode 100644 index 000000000..7381c6ac7 --- /dev/null +++ b/spec/support/config_helpers.rb @@ -0,0 +1,18 @@ +module ConfigHelpers + def with_config_option(key, value) + option_was = Spree::Auth::Config[key] + set_config_option(key, value) + yield + set_config_option(key, option_was) + end + + def set_config_option(key, value) + Spree::Auth::Config[key] = value + Spree.send(:remove_const, 'User') + load File.expand_path("../../../app/models/spree/user.rb", __FILE__) + end +end + +RSpec.configure do |c| + c.include ConfigHelpers +end