aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel
diff options
context:
space:
mode:
authorUnathi Chonco <choncou@Unathis-MacBook-Pro.local>2016-10-12 09:01:57 +0800
committerUnathi Chonco <choncou@Unathis-MacBook-Pro.local>2016-10-12 09:01:57 +0800
commit9b63bf1dfda36c61802165b2683761d2bb0d2110 (patch)
tree0744ede2fb6aca01e23af43a7b17c96249ad79b2 /activemodel
parent86a48b4da3cbd925d30b0fbe472edbda7171ea9e (diff)
downloadrails-9b63bf1dfda36c61802165b2683761d2bb0d2110.tar.gz
rails-9b63bf1dfda36c61802165b2683761d2bb0d2110.tar.bz2
rails-9b63bf1dfda36c61802165b2683761d2bb0d2110.zip
Remove method for regenerating a token, and update `#authenticate`.
This change now creates a method `#authenticate_XXX` where XXX is the configured attribute name on `#has_secure_password`. `#authenticate` is now an alias to this method when the attribute name is the default 'password'
Diffstat (limited to 'activemodel')
-rw-r--r--activemodel/CHANGELOG.md17
-rw-r--r--activemodel/lib/active_model/secure_password.rb56
-rw-r--r--activemodel/test/cases/secure_password_test.rb13
3 files changed, 25 insertions, 61 deletions
diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md
index 0721655a9c..21ebe7e9ec 100644
--- a/activemodel/CHANGELOG.md
+++ b/activemodel/CHANGELOG.md
@@ -1,21 +1,18 @@
* Allows configurable attribute name for `#has_secure_password`. This
still defaults to an attribute named 'password', causing no breaking
- change. Also includes a convenience method `#regenerate_XXX` where
- +XXX+ is the name of the custom attribute name, eg:
+ change. There is a new method `#authenticate_XXX` where XXX is the
+ configured attribute name, making the existing `#authenticate` now an
+ alias for this when the attribute is the default 'password'.
+ Example:
class User < ActiveRecord::Base
has_secure_password :activation_token, validations: false
end
user = User.new()
- user.regenerate_activation_token
- user.activation_token # => "ME7abXFGvzZWJRVrD6Et0YqAS6Pg2eDo"
- user.activation_token_digest # => "$2a$10$0Budk0Fi/k2CDm2PEwa3Be..."
-
- The existing `#authenticate` method now allows specifying the attribute
- to be authenticated, but defaults to 'password', eg:
-
- user.authenticate('ME7abXFGvzZWJRVrD6Et0YqAS6Pg2eDo', :activation_token) # => user
+ user.activation_token = "a_new_token"
+ user.activation_token_digest # => "$2a$10$0Budk0Fi/k2CDm2PEwa3Be..."
+ user.authenticate_activation_token('a_new_token') # => user
*Unathi Chonco*
diff --git a/activemodel/lib/active_model/secure_password.rb b/activemodel/lib/active_model/secure_password.rb
index 5c7322698a..0172ddc97e 100644
--- a/activemodel/lib/active_model/secure_password.rb
+++ b/activemodel/lib/active_model/secure_password.rb
@@ -48,15 +48,14 @@ module ActiveModel
# user.save # => false, confirmation doesn't match
# user.password_confirmation = 'mUc3m00RsqyRe'
# user.save # => true
- # user.regenerate_activation_token
- # user.activation_token # => "ME7abXFGvzZWJRVrD6Et0YqAS6Pg2eDo"
+ # user.activation_token = "a_new_token"
# user.activation_token_digest # => "$2a$10$0Budk0Fi/k2CDm2PEwa3BeXO5tPOA85b6xazE9rp8nF2MIJlsUik."
# user.save # => true
# user.authenticate('notright') # => false
# user.authenticate('mUc3m00RsqyRe') # => user
+ # user.authenticate_activation_token('a_new_token') # => user
# User.find_by(name: 'david').try(:authenticate, 'notright') # => false
# User.find_by(name: 'david').try(:authenticate, 'mUc3m00RsqyRe') # => user
- # user.authenticate('ME7abXFGvzZWJRVrD6Et0YqAS6Pg2eDo', :activation_token) # => user
def has_secure_password(attribute = :password, validations: true)
# Load bcrypt gem only when has_secure_password is used.
# This is to avoid ActiveModel (and by extension the entire framework)
@@ -70,18 +69,6 @@ module ActiveModel
attr_reader attribute
- # Encrypts the password into the +password_digest+ attribute, only if the
- # new password is not empty.
- #
- # class User < ActiveRecord::Base
- # has_secure_password validations: false
- # end
- #
- # user = User.new
- # user.password = nil
- # user.password_digest # => nil
- # user.password = 'mUc3m00RsqyRe'
- # user.password_digest # => "$2a$10$4LEA7r4YmNHtvlAvHhsYAeZmk/xeUVtMTYqwIvYY76EW5GUqDiP4."
define_method("#{attribute}=") do |unencrypted_password|
if unencrypted_password.nil?
self.send("#{attribute}_digest=", nil)
@@ -96,11 +83,22 @@ module ActiveModel
instance_variable_set("@#{attribute}_confirmation", unencrypted_password)
end
- define_method("regenerate_#{attribute}") do
- self.send("#{attribute}=", self.class.generate_unique_secure_token)
+ # Returns +self+ if the password is correct, otherwise +false+.
+ #
+ # class User < ActiveRecord::Base
+ # has_secure_password validations: false
+ # end
+ #
+ # user = User.new(name: 'david', password: 'mUc3m00RsqyRe')
+ # user.save
+ # user.authenticate_password('notright') # => false
+ # user.authenticate_password('mUc3m00RsqyRe') # => user
+ define_method("authenticate_#{attribute}") do |unencrypted_password|
+ attribute_digest = send("#{attribute}_digest")
+ BCrypt::Password.new(attribute_digest).is_password?(unencrypted_password) && self
end
- include InstanceMethodsOnActivation
+ alias_method :authenticate, :authenticate_password if attribute == :password
if validations
include ActiveModel::Validations
@@ -117,28 +115,6 @@ module ActiveModel
validates_confirmation_of attribute, allow_blank: true
end
end
-
- # SecureRandom::base64 is used to generate a 24-character unique token, so collisions are highly unlikely.
- def generate_unique_secure_token
- SecureRandom.base64(24)
- end
- end
-
- module InstanceMethodsOnActivation
- # Returns +self+ if the password is correct, otherwise +false+.
- #
- # class User < ActiveRecord::Base
- # has_secure_password validations: false
- # end
- #
- # user = User.new(name: 'david', password: 'mUc3m00RsqyRe')
- # user.save
- # user.authenticate('notright') # => false
- # user.authenticate('mUc3m00RsqyRe') # => user
- def authenticate(unencrypted_password, attribute = :password)
- attribute_digest = send("#{attribute}_digest")
- BCrypt::Password.new(attribute_digest).is_password?(unencrypted_password) && self
- end
end
end
end
diff --git a/activemodel/test/cases/secure_password_test.rb b/activemodel/test/cases/secure_password_test.rb
index abbd182f66..279a908aeb 100644
--- a/activemodel/test/cases/secure_password_test.rb
+++ b/activemodel/test/cases/secure_password_test.rb
@@ -189,8 +189,8 @@ class SecurePasswordTest < ActiveModel::TestCase
assert !@user.authenticate("wrong")
assert @user.authenticate("secret")
- assert !@user.authenticate("wrong", :activation_token)
- assert @user.authenticate("new_token", :activation_token)
+ assert !@user.authenticate_activation_token("wrong")
+ assert @user.authenticate_activation_token("new_token")
end
test "Password digest cost defaults to bcrypt default cost when min_cost is false" do
@@ -219,13 +219,4 @@ class SecurePasswordTest < ActiveModel::TestCase
@user.password = "secret"
assert_equal BCrypt::Engine::MIN_COST, @user.password_digest.cost
end
-
- test "regenerate attribute method" do
- old_digest = @user.activation_token_digest
- @user.regenerate_activation_token
-
- assert_not_nil @user.activation_token
- assert_not_nil @user.activation_token_digest
- assert_not_equal old_digest, @user.activation_token_digest
- end
end