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/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 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