Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Release v1.3.3

  • Loading branch information...
commit a623f67e1d17a6392f08bea13ae4aa358974b409 1 parent d10f713
@binarylogic binarylogic authored
View
8 CHANGELOG.rdoc
@@ -1,7 +1,13 @@
+== 1.3.3 released 2008-11-23
+
+* Updated :act_like_restful_authentication for those using the older version where no site wide key is preset (REST_AUTH_SITE_KEY), Authlogic will adjust automatically based on the presence of this constant.
+* Added :transition_from_crypto_provider option for acts_as_authentic to transition your user's passwords to a new algorithm.
+* Added :transition_from_restful_authentication for acts_as_authentic to transition your users from restful_authentication to the Authlogic password system. Now you can choose to keep your passwords the same by using :act_like_restful_authentication, which will *NOT* do any transitioning, or you can use :transition_from_crypto_provider which will update your users passwords as they login or new accounts are created, while still allowing users with the old password system to log in.
+* Modified the "interface" for the crypto providers to only provide a class level encrypt and matches? method, instead of a class level encrypt and decrypt method.
+
== 1.3.2 released 2008-11-22
* Updated code to work better with BCrypt, using root level class now.
-* Added :act_like_old_restful_authentication option for acts_as_authentic, for those using the older version where no site wide key is preset (REST_AUTH_SITE_KEY)
== 1.3.1 released 2008-11-22
View
26 README.rdoc
@@ -75,6 +75,8 @@ Authlogic makes this a reality. This is just the tip of the ice berg. Keep readi
* <b>Tutorial: Reset passwords with Authlogic the RESTful way:</b> http://www.binarylogic.com/2008/11/16/tutorial-reset-passwords-with-authlogic
* <b>Tutorial: Using OpenID with Authlogic:</b> http://www.binarylogic.com/2008/11/21/tutorial-using-openid-with-authlogic
* <b>Live example of the tutorials above (with source):</b> http://authlogicexample.binarylogic.com
+* <b>Tutorial: Easily migrate from restful_authentication:</b> http://www.binarylogic.com/2008/11/23/tutorial-easily-migrate-from-restful_authentication-to-authlogic
+* <b>Tutorial: Upgrade passwords easily with Authlogic:</b> http://www.binarylogic.com/2008/11/23/tutorial-upgrade-passwords-easily-with-authlogic
* <b>Bugs / feature suggestions:</b> http://binarylogic.lighthouseapp.com/projects/18752-authlogic
== Install and use
@@ -197,11 +199,22 @@ For more information on ids checkout Authlogic::Session::Base#id
== Encryption methods
-Authlogic is designed so you can use *any* encryption method you want. By default Authlogic uses salted Sha512 with 20 stretches. It also comes preloaded with some other common encryption algorithms so that you can choose. For example, if you wanted to use the BCrypt algorithm just do the following:
+Authlogic is designed so you can use *any* encryption method you want. It delegates this task to a class of your choice. By default Authlogic uses salted Sha512 with 20 stretches. It also comes preloaded with some other common encryption algorithms so that you can choose. For example, if you wanted to use the BCrypt algorithm just do the following:
acts_as_authentic :crypto_provider => Authlogic::CryptoProviders::BCrypt
-Check out the Authlogic::CryptoProviders module and sublcasses to get an idea of how to write your own crypto provider. It's extremely easy, all that you have to do is make a class with a class level encrypt and optional decrypt method. That's it, the sky is the limit.
+For more information on BCrypt checkout my blog post on it: http://www.binarylogic.com/2008/11/22/storing-nuclear-launch-codes-in-your-app-enter-bcrypt-for-authlogic
+
+Also, check out the Authlogic::CryptoProviders module and sublcasses to get an idea of how to write your own crypto provider. It's extremely easy, all that you have to do is make a class with a class level encrypt and matches? method. That's it, the sky is the limit.
+
+== Switching to a new encryption method
+
+Switching to a new encryption method used to be a pain in the ass. Authlogic has an option that makes this dead simple. Let's say you want to migrate to the BCrypt encryption method from Sha512:
+
+ acts_as_authentic :crypto_provider => Authlogic::CryptoProviders::BCrypt,
+ :transition_from_crypto_provider => Authlogic::CryptoProviders::Sha512
+
+That's it. When a user successfully logs in and is using the old method their password will be updated with the new method and all new registrations will use the new method as well. Your users won't know anything changed.
== Tokens (persistence, resetting passwords, private feed access, etc.)
@@ -382,9 +395,14 @@ Migrating from the restful_authentication plugin? I made an option especially fo
acts_as_authentic :act_like_restful_authentication => true
end
-**What's the difference?**
+Or you can transition your users to the Authlogic password system:
+
+ # app/models/user.rb
+ class User < ActiveRecord::Base
+ acts_as_authentic :transition_from_restful_authentication => true
+ end
-restful\_authentication uses Sha1 with 10 stretches to encrypt the password. Authlogic uses Sha512 with 20 stretches. Sha512 is stronger and more secure.
+For more information checkout my blog post on this: http://www.binarylogic.com/2008/11/23/tutorial-easily-migrate-from-restful_authentication-to-authlogic
== Framework agnostic (Rails, Merb, etc.)
View
37 lib/authlogic/crypto_providers/bcrypt.rb
@@ -22,7 +22,7 @@ module CryptoProviders
# x.report("Sha512:") { 100.times { Digest::SHA512.hexdigest("mypass") } }
# x.report("Sha1:") { 100.times { Digest::SHA1.hexdigest("mypass") } }
# end
-
+ #
# user system total real
# BCrypt (cost = 10): 10.780000 0.060000 10.840000 ( 11.100289)
# BCrypt (cost = 2): 0.180000 0.000000 0.180000 ( 0.181914)
@@ -50,14 +50,39 @@ def cost
attr_writer :cost
# Creates a BCrypt hash for the password passed.
- def encrypt(pass)
- ::BCrypt::Password.create(pass, :cost => cost)
+ def encrypt(*tokens)
+ ::BCrypt::Password.create(join_tokens(tokens), :cost => cost)
end
- # This does not actually decrypt the password, BCrypt is *not* reversible. The way the bcrypt library is set up requires us to do it this way, which is actually pretty convenient.
- def decrypt(crypted_pass)
- ::BCrypt::Password.new(crypted_pass)
+ # Does the hash match the tokens? Uses the same tokens that were used to encrypt.
+ def matches?(hash, *tokens)
+ hash = new_from_hash(hash)
+ return false if hash.blank?
+ hash == join_tokens(tokens)
end
+
+ # This method is used as a flag to tell Authlogic to "resave" the password upon a successful login, using the new cost
+ def cost_matches?(hash)
+ hash = new_from_hash(hash)
+ if hash.blank?
+ false
+ else
+ hash.cost == cost
+ end
+ end
+
+ private
+ def join_tokens(tokens)
+ tokens.flatten.join
+ end
+
+ def new_from_hash(hash)
+ begin
+ ::BCrypt::Password.new(hash)
+ rescue ::BCrypt::Errors::InvalidHash
+ return nil
+ end
+ end
end
end
end
View
22 lib/authlogic/crypto_providers/sha1.rb
@@ -4,10 +4,15 @@ module Authlogic
module CryptoProviders
# = Sha1
#
- # Uses the Sha1 hash algorithm to encrypt passwords. This class is useful if you are migrating from restful_authentication. This uses the
- # exact same excryption algorithm with 10 stretches, just like restful_authentication.
+ # This class was made for the users transitioning from restful_authentication. I highly discourage using this crypto provider as it inferior to your other options.
+ # Please use the Sha512 crypto provider or the BCrypt provider.
class Sha1
class << self
+ def join_token
+ @join_token ||= "--"
+ end
+ attr_writer :join_token
+
# The number of times to loop through the encryption. This is ten because that is what restful_authentication defaults to.
def stretches
@stretches ||= 10
@@ -15,10 +20,15 @@ def stretches
attr_writer :stretches
# Turns your raw password into a Sha1 hash.
- def encrypt(pass)
- digest = pass
- stretches.times { digest = Digest::SHA1.hexdigest(digest) }
- digest
+ def encrypt(*tokens)
+ tokens = tokens.flatten
+ digest = tokens.shift
+ stretches.times { digest = Digest::SHA1.hexdigest([digest, *tokens].compact.join(join_token)) }
+ end
+
+ # Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
+ def matches?(crypted, *tokens)
+ encrypt(*tokens) == crypted
end
end
end
View
30 lib/authlogic/crypto_providers/sha512.rb
@@ -4,22 +4,21 @@ module Authlogic
# = Crypto Providers
#
# The acts_as_authentic method allows you to pass a :crypto_provider option. This allows you to use any type of encryption you like.
- # Just create a class with a class level encrypt and decrypt method. The password will be passed as the single parameter to each of these
- # methods so you can do your magic.
- #
- # If you are encrypting via a hash just don't include a decrypt method, since hashes can't be decrypted. Authlogic will notice this adjust accordingly.
+ # Just create a class with a class level encrypt and matches? method. See example below.
#
# === Example
#
# class MyAwesomeEncryptionMethod
- # def self.encrypt(pass)
- # # encrypt the pass here
+ # def self.encrypt(*tokens)
+ # # the tokens passed wil be an array of objects, what type of object is irrelevant
+ # # just do what you need to do with them and return a single encrypted string.
+ # # for example, you will most likely join all of the objects into a single string and then encrypt that string
# end
#
- # def self.decrypt(crypted_pass)
- # # decrypt the pass here, this is an optional method
- # # don't even include this method if you are using a hash algorithm
- # # this is irreverisble
+ # def self.matches?(crypted, *tokens)
+ # # return true if the crypted string matches the tokens.
+ # # depending on your algorithm you might decrypt the string then compare it to the token, or you might
+ # # encrypt the tokens and make sure it matches the crypted string, its up to you
# end
# end
module CryptoProviders
@@ -28,6 +27,8 @@ module CryptoProviders
# Uses the Sha512 hash algorithm to encrypt passwords.
class Sha512
class << self
+ attr_accessor :join_token
+
# The number of times to loop through the encryption. This is ten because that is what restful_authentication defaults to.
def stretches
@stretches ||= 20
@@ -35,11 +36,16 @@ def stretches
attr_writer :stretches
# Turns your raw password into a Sha512 hash.
- def encrypt(pass)
- digest = pass
+ def encrypt(*tokens)
+ digest = tokens.flatten.join(join_token)
stretches.times { digest = Digest::SHA512.hexdigest(digest) }
digest
end
+
+ # Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
+ def matches?(crypted, *tokens)
+ encrypt(*tokens) == crypted
+ end
end
end
end
View
22 lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/config.rb
@@ -22,15 +22,20 @@ module ActsAsAuthentic
# * <tt>crypto_provider</tt> - default: Authlogic::CryptoProviders::Sha512,
# This is the class that provides your encryption. By default Authlogic provides its own crypto provider that uses Sha512 encrypton.
#
+ # * <tt>transition_from_crypto_provider</tt> - default: nil,
+ # This will transition your users to a new encryption algorithm. Let's say you are using Sha1 and you want to transition to Sha512. Just set the
+ # :crypto_provider option to Authlogic::CryptoProviders::Sha512 and then set this option to Authlogic::CryptoProviders::Sha1. Every time a user
+ # logs in their password will be resaved with the new algorithm and all new registrations will use the new algorithm as well.
+ #
# * <tt>act_like_restful_authentication</tt> - default: false,
# If you are migrating from restful_authentication you will want to set this to true, this way your users will still be able to log in and it will seems as
# if nothing has changed. If you don't do this none of your users will be able to log in. If you are starting a new project I do not recommend enabling this
# as the password encryption algorithm used in restful_authentication (Sha1) is not as secure as the one used in authlogic (Sha512). IF you REALLY want to be secure
# checkout Authlogic::CryptoProviders::BCrypt.
#
- # * <tt>act_like_old_restful_authentication</tt> - default: false,
- # This is the same thing as :act_like_restful_authentication, but it is for the older versions. How can you tell if you are using an older version? The new version
- # requires that you supply a site wide key called REST_AUTH_SITE_KEY. If you do not have that in your project then you are using the older version.
+ # * <tt>transition_from_restful_authentication</tt> - default: false,
+ # This works just like :transition_from_crypto_provider, but it makes some special exceptions so that your users will transition from restful_authentication, since
+ # restful_authentication does things a little different than Authlogic.
#
# * <tt>login_field</tt> - default: :login, :username, or :email, depending on which column is present, if none are present defaults to :login
# The name of the field used for logging in. Only specify if you aren't using any of the defaults.
@@ -194,11 +199,12 @@ def acts_as_authentic_with_config(options = {})
options[:email_field_validates_uniqueness_of_options][:scope] ||= options[:scope]
end
- if options[:act_like_restful_authentication] || options[:act_like_old_restful_authentication]
- options[:crypto_provider] = CryptoProviders::Sha1
- if options[:act_like_old_restful_authentication]
- const_set("::REST_AUTH_SITE_KEY", nil) unless defined?(REST_AUTH_SITE_KEY)
- options[:crypto_provider].stretches = 1
+ if options[:act_like_restful_authentication] || options[:transition_from_restful_authentication]
+ crypto_provider_key = options[:act_like_restful_authentication] ? :crypto_provider : :transition_from_crypto_provider
+ options[crypto_provider_key] = CryptoProviders::Sha1
+ if !defined?(REST_AUTH_SITE_KEY) || REST_AUTH_SITE_KEY.nil?
+ class_eval("::REST_AUTH_SITE_KEY = nil") unless defined?(REST_AUTH_SITE_KEY)
+ options[crypto_provider_key].stretches = 1
end
end
View
45 lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/credentials.rb
@@ -53,6 +53,7 @@ def acts_as_authentic_with_credentials(options = {})
end
attr_reader options[:password_field]
+ attr_accessor :crypto_provider
class_eval <<-"end_eval", __FILE__, __LINE__
def self.friendly_unique_token
@@ -66,13 +67,37 @@ def #{options[:password_field]}=(pass)
return if pass.blank?
@#{options[:password_field]} = pass
self.#{options[:password_salt_field]} = self.class.unique_token
- self.#{options[:crypted_password_field]} = #{options[:crypto_provider]}.encrypt(obfuscate_password(@#{options[:password_field]}))
+ self.#{options[:crypted_password_field]} = #{options[:crypto_provider]}.encrypt(*encrypt_arguments(@#{options[:password_field]}, #{options[:act_like_restful_authentication].inspect} ? :restful_authentication : nil))
end
+ alias_method :update_#{options[:password_field]}, :#{options[:password_field]}= # this is to avoids the method chain, so we are ONLY changing the password
def valid_#{options[:password_field]}?(attempted_password)
return false if attempted_password.blank? || #{options[:crypted_password_field]}.blank? || #{options[:password_salt_field]}.blank?
- (#{options[:crypto_provider]}.respond_to?(:decrypt) && #{options[:crypto_provider]}.decrypt(#{options[:crypted_password_field]}) == attempted_password + #{options[:password_salt_field]}) ||
- (!#{options[:crypto_provider]}.respond_to?(:decrypt) && #{options[:crypto_provider]}.encrypt(obfuscate_password(attempted_password)) == #{options[:crypted_password_field]})
+
+ [#{options[:crypto_provider]}, #{options[:transition_from_crypto_provider].inspect}].compact.each do |encryptor|
+ # The arguments_type of for the transitioning from restful_authentication
+ arguments_type = nil
+ case encryptor
+ when #{options[:crypto_provider]}
+ arguments_type = :restful_authentication if #{options[:act_like_restful_authentication].inspect}
+ when #{options[:transition_from_crypto_provider].inspect}
+ arguments_type = :restful_authentication if #{options[:transition_from_restful_authentication].inspect}
+ end
+
+ if encryptor.matches?(#{options[:crypted_password_field]}, *encrypt_arguments(attempted_password, arguments_type))
+ # If we are transitioning from an older encryption algorithm and the password is still using the old algorithm
+ # then let's reset the password using the new algorithm. If the algorithm has a cost (BCrypt) and the cost has changed, update the password with
+ # the new cost.
+ if encryptor == #{options[:transition_from_crypto_provider].inspect} || (encryptor.respond_to?(:cost_matches?) && !encryptor.cost_matches?(#{options[:crypted_password_field]}))
+ update_#{options[:password_field]}(attempted_password)
+ save(false)
+ end
+
+ return true
+ end
+ end
+
+ false
end
def reset_#{options[:password_field]}
@@ -82,6 +107,11 @@ def reset_#{options[:password_field]}
end
alias_method :randomize_password, :reset_password
+ def confirm_#{options[:password_field]}
+ raise "confirm_#{options[:password_field]} has been removed, please use #{options[:password_field]}_confirmation. " +
+ "As this is the field that ActiveRecord automatically creates with validates_confirmation_of."
+ end
+
def reset_#{options[:password_field]}!
reset_#{options[:password_field]}
save_without_session_maintenance(false)
@@ -89,11 +119,12 @@ def reset_#{options[:password_field]}!
alias_method :randomize_password!, :reset_password!
private
- def obfuscate_password(raw_password)
- if #{options[:act_like_restful_authentication].inspect} || #{options[:act_like_old_restful_authentication].inspect}
- [REST_AUTH_SITE_KEY, raw_password, #{options[:password_salt_field]}, REST_AUTH_SITE_KEY].compact.join("--")
+ def encrypt_arguments(raw_password, arguments_type = nil)
+ case arguments_type
+ when :restful_authentication
+ [REST_AUTH_SITE_KEY, raw_password, #{options[:password_salt_field]}, REST_AUTH_SITE_KEY]
else
- raw_password + #{options[:password_salt_field]}
+ [raw_password, #{options[:password_salt_field]}]
end
end
end_eval
View
5 lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/persistence.rb
@@ -37,10 +37,7 @@ def forget_all!
class_eval <<-"end_eval", __FILE__, __LINE__
def self.unique_token
- # The persistence token should be a unique string that is not reversible, which is what a hash is all about
- # if you using encryption this defaults to Sha512.
- token_class = #{options[:crypto_provider].respond_to?(:decrypt) ? Authlogic::CryptoProviders::Sha512 : options[:crypto_provider]}
- token_class.encrypt(Time.now.to_s + (1..10).collect{ rand.to_s }.join)
+ Authlogic::CryptoProviders::Sha512.encrypt(Time.now.to_s + (1..10).collect{ rand.to_s }.join)
end
def forget!
View
19 lib/authlogic/session/config.rb
@@ -45,19 +45,6 @@ def configure
yield self
end
- # This works just like ActiveRecord's attr_accessible, except by default this ONLY allows the login, password, and remember me option.
- #
- # * <tt>Default:</tt> {:login_field}, {:password_field}, :remember_me, set to nil to disable
- # * <tt>Accepts:</tt> String
- def attr_accessible(*values)
- if values.blank?
- read_inheritable_attribute(:attr_accessible) || attr_accessible(login_field, password_field, :remember_me)
- else
- write_inheritable_attribute(:attr_accessible, value)
- end
- end
- alias_method :attr_accessible=, :attr_accessible
-
# The name of the cookie or the key in the cookies hash. Be sure and use a unique name. If you have multiple sessions and they use the same cookie it will cause problems.
# Also, if a id is set it will be inserted into the beginning of the string. Exmaple:
#
@@ -193,7 +180,7 @@ def not_active_message(value = nil)
# * <tt>Accepts:</tt> String
def not_approved_message(value = nil)
if value.nil?
- read_inheritable_attribute(:not_approved_message) || not_active_message("Your account is not approved")
+ read_inheritable_attribute(:not_approved_message) || not_approved_message("Your account is not approved")
else
write_inheritable_attribute(:not_approved_message, value)
end
@@ -206,7 +193,7 @@ def not_approved_message(value = nil)
# * <tt>Accepts:</tt> String
def not_confirmed_message(value = nil)
if value.nil?
- read_inheritable_attribute(:not_confirmed_message) || not_active_message("Your account is not confirmed")
+ read_inheritable_attribute(:not_confirmed_message) || not_confirmed_message("Your account is not confirmed")
else
write_inheritable_attribute(:not_confirmed_message, value)
end
@@ -263,7 +250,7 @@ def password_field(value = nil)
# * <tt>Accepts:</tt> String
def password_invalid_message(value = nil)
if value.nil?
- read_inheritable_attribute(:password_invalid_message) || login_not_found_message("is invalid")
+ read_inheritable_attribute(:password_invalid_message) || password_invalid_message("is invalid")
else
write_inheritable_attribute(:password_invalid_message, value)
end
View
2  lib/authlogic/version.rb
@@ -44,7 +44,7 @@ def to_a
MAJOR = 1
MINOR = 3
- TINY = 2
+ TINY = 3
# The current version as a Version instance
CURRENT = new(MAJOR, MINOR, TINY)
View
4 test/crypto_provider_tests/bcrypt_test.rb
@@ -6,9 +6,9 @@ def test_encrypt
assert Authlogic::CryptoProviders::BCrypt.encrypt("mypass")
end
- def test_decrypt
+ def test_matches
hash = Authlogic::CryptoProviders::BCrypt.encrypt("mypass")
- assert Authlogic::CryptoProviders::BCrypt.decrypt(hash) == "mypass"
+ assert Authlogic::CryptoProviders::BCrypt.matches?(hash, "mypass")
end
end
end
View
5 test/crypto_provider_tests/sha1_test.rb
@@ -5,5 +5,10 @@ class Sha1Test < ActiveSupport::TestCase
def test_encrypt
assert Authlogic::CryptoProviders::Sha1.encrypt("mypass")
end
+
+ def test_matches
+ hash = Authlogic::CryptoProviders::Sha1.encrypt("mypass")
+ assert Authlogic::CryptoProviders::Sha1.matches?(hash, "mypass")
+ end
end
end
View
5 test/crypto_provider_tests/sha512_test.rb
@@ -5,5 +5,10 @@ class Sha512Test < ActiveSupport::TestCase
def test_encrypt
assert Authlogic::CryptoProviders::Sha512.encrypt("mypass")
end
+
+ def test_matches
+ hash = Authlogic::CryptoProviders::Sha512.encrypt("mypass")
+ assert Authlogic::CryptoProviders::Sha512.matches?(hash, "mypass")
+ end
end
end
View
8 test/libs/aes128_crypto_provider.rb
@@ -2,12 +2,12 @@
class AES128CryptoProvider
class << self
- def encrypt(term)
- [key.encrypt(term)].pack("m").chomp
+ def encrypt(*tokens)
+ [key.encrypt(tokens.join)].pack("m").chomp
end
- def decrypt(term)
- key.decrypt(term.unpack("m").first)
+ def matches?(crypted, *tokens)
+ key.decrypt(crypted.unpack("m").first) == tokens.join
end
def key
View
65 test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/config_test.rb
@@ -4,6 +4,9 @@ module ORMAdaptersTests
module ActiveRecordAdapterTests
module ActsAsAuthenticTests
class ConfigTest < ActiveSupport::TestCase
+ setup :get_default_configuration
+ teardown :restore_default_configuration
+
def test_first_column_to_exist
assert_equal :login, User.first_column_to_exist(:login, :crypted_password)
assert_equal nil, User.first_column_to_exist(nil, :unknown)
@@ -45,6 +48,68 @@ def test_acts_as_authentic_config
}
assert_equal default_config, User.acts_as_authentic_config
end
+
+ def test_session_class
+ EmployeeSession.authenticate_with User
+ User.acts_as_authentic(:session_class => EmployeeSession)
+ assert_equal EmployeeSession, User.acts_as_authentic_config[:session_class]
+
+ ben = users(:ben)
+ assert !EmployeeSession.find
+ ben.password = "benrocks"
+ ben.password_confirmation = "benrocks"
+ assert ben.save
+ assert EmployeeSession.find
+ EmployeeSession.authenticate_with Employee
+ end
+
+ def test_crypto_provider
+ User.acts_as_authentic(:crypto_provider => Authlogic::CryptoProviders::BCrypt)
+ ben = users(:ben)
+ assert !ben.valid_password?("benrocks")
+ ben.password = "benrocks"
+ ben.password_confirmation = "benrocks"
+ assert ben.save
+ assert ben.valid_password?("benrocks")
+ end
+
+ def test_transition_from_crypto_provider
+ ben = users(:ben)
+ convert_password_to(Authlogic::CryptoProviders::BCrypt, ben)
+ end
+
+ def test_act_like_restful_authentication
+ ben = users(:ben)
+ convert_password_to(Authlogic::CryptoProviders::Sha1, ben)
+ User.acts_as_authentic(:act_like_restful_authentication => true)
+ set_session_for(ben)
+ assert UserSession.find
+ end
+
+ def test_transition_from_restful_authentication
+ User.acts_as_authentic(:transition_from_restful_authentication => true)
+ assert_equal Authlogic::CryptoProviders::Sha512, User.acts_as_authentic_config[:crypto_provider]
+ assert_equal Authlogic::CryptoProviders::Sha1, User.acts_as_authentic_config[:transition_from_crypto_provider]
+ end
+
+ private
+ def get_default_configuration
+ @default_configuration = User.acts_as_authentic_config
+ end
+
+ def restore_default_configuration
+ User.acts_as_authentic @default_configuration
+ end
+
+ def convert_password_to(crypto_provider, *records)
+ User.acts_as_authentic(:crypto_provider => crypto_provider, :transition_from_crypto_provider => Authlogic::CryptoProviders::Sha512)
+ records.each do |record|
+ old_hash = record.crypted_password
+ assert record.valid_password?(password_for(record))
+ assert_not_equal old_hash, record.crypted_password
+ assert record.valid_password?(password_for(record))
+ end
+ end
end
end
end
View
20 test/test_helper.rb
@@ -113,19 +113,19 @@ def activate_authlogic
Authlogic::Session::Base.controller = @controller
end
+ def password_for(user)
+ case user
+ when users(:ben)
+ "benrocks"
+ when users(:zack)
+ "zackrocks"
+ end
+ end
+
def http_basic_auth_for(user = nil, &block)
unless user.blank?
@controller.http_user = user.login
-
- password = nil
- case user
- when users(:ben)
- password = "benrocks"
- when users(:zack)
- password = "zackrocks"
- end
-
- @controller.http_password = password
+ @controller.http_password = password_for(user)
end
yield
@controller.http_user = @controller.http_password = nil
Please sign in to comment.
Something went wrong with that request. Please try again.