diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc index 0bbd7838..fc6092d7 100644 --- a/CHANGELOG.rdoc +++ b/CHANGELOG.rdoc @@ -1,3 +1,11 @@ +* enhancements + * Move salt to encryptors + +* bug fix + * Bcrypt generator was not being loaded neither setting the proper salt + +== 0.8.0 + * enhancements * Warden 0.8.0 compatibility * Add an easy for map.connect "sign_in", :controller => "sessions", :action => "new" to work diff --git a/lib/devise.rb b/lib/devise.rb index a2ce0461..085209ae 100644 --- a/lib/devise.rb +++ b/lib/devise.rb @@ -11,12 +11,13 @@ module Devise end module Encryptors + autoload :Base, 'devise/encryptors/base' + autoload :Bcrypt, 'devise/encryptors/bcrypt' autoload :AuthlogicSha512, 'devise/encryptors/authlogic_sha512' autoload :AuthlogicSha1, 'devise/encryptors/authlogic_sha1' autoload :RestfulAuthenticationSha1, 'devise/encryptors/restful_authentication_sha1' autoload :Sha512, 'devise/encryptors/sha512' autoload :Sha1, 'devise/encryptors/sha1' - autoload :BCrypt, 'devise/encryptors/bcrypt' end module Orm @@ -48,7 +49,8 @@ module Devise :sha512 => 128, :clearance_sha1 => 40, :restful_authentication_sha1 => 40, - :authlogic_sha512 => 128 + :authlogic_sha512 => 128, + :bcrypt => 60 } # Email regex used to validate email formats. Retrieved from authlogic. diff --git a/lib/devise/encryptors/authlogic_sha512.rb b/lib/devise/encryptors/authlogic_sha512.rb index 024f327d..9c4be984 100644 --- a/lib/devise/encryptors/authlogic_sha512.rb +++ b/lib/devise/encryptors/authlogic_sha512.rb @@ -1,19 +1,12 @@ require "digest/sha2" module Devise - # Implements a way of adding different encryptions. - # The class should implement a self.digest method that taks the following params: - # - password - # - stretches: the number of times the encryption will be applied - # - salt: the password salt as defined by devise - # - pepper: Devise config option - # module Encryptors # = AuthlogicSha512 # Simulates Authlogic's default encryption mechanism. # Warning: it uses Devise's stretches configuration to port Authlogic's one. Should be set to 20 in the initializer to silumate # the default behavior. - class AuthlogicSha512 + class AuthlogicSha512 < Base # Gererates a default password digest based on salt, pepper and the # incoming password. diff --git a/lib/devise/encryptors/base.rb b/lib/devise/encryptors/base.rb new file mode 100644 index 00000000..7b25f312 --- /dev/null +++ b/lib/devise/encryptors/base.rb @@ -0,0 +1,20 @@ +module Devise + # Implements a way of adding different encryptions. + # The class should implement a self.digest method that taks the following params: + # - password + # - stretches: the number of times the encryption will be applied + # - salt: the password salt as defined by devise + # - pepper: Devise config option + # + module Encryptors + class Base + def self.digest + raise NotImplemented + end + + def self.salt + Devise.friendly_token + end + end + end +end \ No newline at end of file diff --git a/lib/devise/encryptors/bcrypt.rb b/lib/devise/encryptors/bcrypt.rb index 16525e0c..583d6ed6 100644 --- a/lib/devise/encryptors/bcrypt.rb +++ b/lib/devise/encryptors/bcrypt.rb @@ -1,22 +1,19 @@ require "bcrypt" module Devise - # Implements a way of adding different encryptions. - # The class should implement a self.digest method that taks the following params: - # - password - # - stretches: the number of times the encryption will be applied - # - salt: the password salt as defined by devise - # - pepper: Devise config option - # module Encryptors # = BCrypt # Uses the BCrypt hash algorithm to encrypt passwords. - class BCrypt + class Bcrypt < Base # Gererates a default password digest based on stretches, salt, pepper and the # incoming password. We don't strech it ourselves since BCrypt does so internally. def self.digest(password, stretches, salt, pepper) - ::BCrypt::Engine.hash_secret(password, [salt, pepper].flatten.join('xx'), stretches) + ::BCrypt::Engine.hash_secret([password, pepper].join, salt, stretches) + end + + def self.salt + ::BCrypt::Engine.generate_salt end end diff --git a/lib/devise/encryptors/clearance_sha1.rb b/lib/devise/encryptors/clearance_sha1.rb index f072ff26..dbe396b9 100644 --- a/lib/devise/encryptors/clearance_sha1.rb +++ b/lib/devise/encryptors/clearance_sha1.rb @@ -1,19 +1,12 @@ require "digest/sha1" module Devise - # Implements a way of adding different encryptions. - # The class should implement a self.digest method that taks the following params: - # - password - # - stretches: the number of times the encryption will be applied - # - salt: the password salt as defined by devise - # - pepper: Devise config option - # module Encryptors # = ClearanceSha1 # Simulates Clearance's default encryption mechanism. # Warning: it uses Devise's pepper to port the concept of REST_AUTH_SITE_KEY # Warning: it uses Devise's stretches configuration to port the concept of REST_AUTH_DIGEST_STRETCHES - class ClearanceSha1 + class ClearanceSha1 < Base # Gererates a default password digest based on salt, pepper and the # incoming password. diff --git a/lib/devise/encryptors/restful_authentication_sha1.rb b/lib/devise/encryptors/restful_authentication_sha1.rb index 29873164..38f9cd74 100644 --- a/lib/devise/encryptors/restful_authentication_sha1.rb +++ b/lib/devise/encryptors/restful_authentication_sha1.rb @@ -1,20 +1,13 @@ require "digest/sha1" module Devise - # Implements a way of adding different encryptions. - # The class should implement a self.digest method that taks the following params: - # - password - # - stretches: the number of times the encryption will be applied - # - salt: the password salt as defined by devise - # - pepper: Devise config option - # module Encryptors # = RestfulAuthenticationSha1 # Simulates Restful Authentication's default encryption mechanism. # Warning: it uses Devise's pepper to port the concept of REST_AUTH_SITE_KEY # Warning: it uses Devise's stretches configuration to port the concept of REST_AUTH_DIGEST_STRETCHES. Should be set to 10 in # the initializer to silumate the default behavior. - class RestfulAuthenticationSha1 + class RestfulAuthenticationSha1 < Base # Gererates a default password digest based on salt, pepper and the # incoming password. diff --git a/lib/devise/encryptors/sha1.rb b/lib/devise/encryptors/sha1.rb index 1b364c7b..ecc0968f 100644 --- a/lib/devise/encryptors/sha1.rb +++ b/lib/devise/encryptors/sha1.rb @@ -1,17 +1,10 @@ require "digest/sha1" module Devise - # Implements a way of adding different encryptions. - # The class should implement a self.digest method that taks the following params: - # - password - # - stretches: the number of times the encryption will be applied - # - salt: the password salt as defined by devise - # - pepper: Devise config option - # module Encryptors # = Sha1 # Uses the Sha1 hash algorithm to encrypt passwords. - class Sha1 + class Sha1 < Base # Gererates a default password digest based on stretches, salt, pepper and the # incoming password. diff --git a/lib/devise/encryptors/sha512.rb b/lib/devise/encryptors/sha512.rb index 1a917b42..769389b9 100644 --- a/lib/devise/encryptors/sha512.rb +++ b/lib/devise/encryptors/sha512.rb @@ -1,17 +1,10 @@ require "digest/sha2" module Devise - # Implements a way of adding different encryptions. - # The class should implement a self.digest method that taks the following params: - # - password - # - stretches: the number of times the encryption will be applied - # - salt: the password salt as defined by devise - # - pepper: Devise config option - # module Encryptors # = Sha512 # Uses the Sha512 hash algorithm to encrypt passwords. - class Sha512 + class Sha512 < Base # Gererates a default password digest based on salt, pepper and the # incoming password. diff --git a/lib/devise/models/authenticatable.rb b/lib/devise/models/authenticatable.rb index 227606d2..ca59e769 100644 --- a/lib/devise/models/authenticatable.rb +++ b/lib/devise/models/authenticatable.rb @@ -43,7 +43,7 @@ module Devise @password = new_password if @password.present? - self.password_salt = Devise.friendly_token + self.password_salt = self.class.encryptor_class.salt self.encrypted_password = password_digest(@password) end end diff --git a/test/encryptors_test.rb b/test/encryptors_test.rb index 52cb4a24..354dbca9 100644 --- a/test/encryptors_test.rb +++ b/test/encryptors_test.rb @@ -18,18 +18,11 @@ class Encryptors < ActiveSupport::TestCase assert_equal clearance, encryptor end - test 'should match a password created by bcrypt' do - bcrypt = "$2a$10$81UWRL4S01M6zxjMPyBame1He8EHYgdFm26rQh0qKzglf2ijtEyfa" - encryptor = Devise::Encryptors::BCrypt.digest('123mudar', 4, '$2a$10$81UWRL4S01M6zxjMPyBame', '') - assert_equal bcrypt, encryptor - end - - - Devise::ENCRYPTORS_LENGTH.each do |key, value| test "should have length #{value} for #{key.inspect}" do swap Devise, :encryptor => key do - assert_equal value, Devise::Encryptors.const_get(key.to_s.classify).digest('a', 2, 'b', 'c').size + encryptor = Devise::Encryptors.const_get(key.to_s.classify) + assert_equal value, encryptor.digest('a', 4, encryptor.salt, nil).size end end end