Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Released 1.2.1

  • Loading branch information...
commit 4caccd0bafa21f84f26b28510ac086b7e9a6c61d 1 parent 4ed1d7f
@binarylogic binarylogic authored
Showing with 259 additions and 224 deletions.
  1. +5 −3 CHANGELOG.rdoc
  2. +4 −4 Manifest
  3. +49 −20 README.rdoc
  4. +0 −1  Rakefile
  5. +3 −3 lib/authlogic.rb
  6. +13 −12 lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/config.rb
  7. +0 −73 lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/password_reset.rb
  8. +75 −0 lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/perishability.rb
  9. +7 −7 lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/persistence.rb
  10. +1 −1  lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/session_maintenance.rb
  11. +2 −2 lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/single_access.rb
  12. +4 −4 lib/authlogic/session/config.rb
  13. +2 −2 lib/authlogic/session/cookies.rb
  14. +2 −2 lib/authlogic/session/params.rb
  15. +0 −17 lib/authlogic/session/password_reset.rb
  16. +18 −0 lib/authlogic/session/perishability.rb
  17. +2 −2 lib/authlogic/session/session.rb
  18. +1 −1  lib/authlogic/version.rb
  19. +2 −2 test/fixtures/employees.yml
  20. +3 −3 test/fixtures/users.yml
  21. +3 −3 test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/config_test.rb
  22. +5 −5 test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/credentials_test.rb
  23. +0 −40 test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/password_reset_test.rb
  24. +41 −0 test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/perishability_test.rb
  25. +4 −4 test/session_tests/base_test.rb
  26. +1 −1  test/session_tests/cookies_test.rb
  27. +3 −3 test/session_tests/{password_reset_test.rb → perishability_test.rb}
  28. +4 −4 test/session_tests/session_test.rb
  29. +5 −5 test/test_helper.rb
View
8 CHANGELOG.rdoc
@@ -1,7 +1,9 @@
-== 1.2.1 released 2008-11-16
+== 1.2.1 released 2008-11-19
-* Added build method to authenticates_many association.
-* Added validation boolean configuration options for acts_as_authentic: validate_field, validate_login_field, validate_password_field, validate_email_field
+* Added build method to authenticates_many association to act like AR association collections.
+* Added validation boolean configuration options for acts_as_authentic: validate_field, validate_login_field, validate_password_field, validate_email_field. This turns on and off validations for their respective fields.
+* Renamed all password_reset_token terms to perishable_token, including configuration, etc. I still allow for the old configurations so this will not break compatibility, but perishable token is a better name and can be used for account confirmation as well as a password reset token, or anything else you want.
+* Renamed all remember_token instances to persistence_token, the term "remember token" doesn't really make sense. I still allow for the old configuration, so this will not break backwards compatibility: persistence_token fits better and makes more sense.
== 1.2.0 released 2008-11-16
View
8 Manifest
@@ -8,7 +8,7 @@ lib/authlogic/crypto_providers/sha512.rb
lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/config.rb
lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/credentials.rb
lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/logged_in.rb
-lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/password_reset.rb
+lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/perishability.rb
lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/persistence.rb
lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/session_maintenance.rb
lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/single_access.rb
@@ -22,7 +22,7 @@ lib/authlogic/session/config.rb
lib/authlogic/session/cookies.rb
lib/authlogic/session/errors.rb
lib/authlogic/session/params.rb
-lib/authlogic/session/password_reset.rb
+lib/authlogic/session/perishability.rb
lib/authlogic/session/scopes.rb
lib/authlogic/session/session.rb
lib/authlogic/version.rb
@@ -44,7 +44,7 @@ test/libs/ordered_hash.rb
test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/config_test.rb
test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/credentials_test.rb
test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/logged_in_test.rb
-test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/password_reset_test.rb
+test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/perishability_test.rb
test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/persistence_test.rb
test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/session_maintenance_test.rb
test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/single_access_test.rb
@@ -55,7 +55,7 @@ test/session_tests/base_test.rb
test/session_tests/config_test.rb
test/session_tests/cookies_test.rb
test/session_tests/params_test.rb
-test/session_tests/password_reset_test.rb
+test/session_tests/perishability_test.rb
test/session_tests/scopes_test.rb
test/session_tests/session_test.rb
test/test_helper.rb
View
69 README.rdoc
@@ -32,6 +32,7 @@ What if your user sessions controller could look just like your other controller
def destroy
current_user_session.destroy
+ redirect_to new_user_session_url
end
end
@@ -109,9 +110,9 @@ The user model needs to have the following columns. The names of these columns c
t.string :login, :null => false
t.string :crypted_password, :null => false
t.string :password_salt, :null => false # not needed if you are encrypting your pw instead of using a hash algorithm.
- t.string :remember_token, :null => false
- t.string :single_access_token, :null => false # optional, see the single access section below.
- t.string :password_reset_token, :null => false # optional, see the password reset section below.
+ t.string :persistence_token, :null => false
+ t.string :single_access_token, :null => false # optional, see the tokens section below.
+ t.string :perishable_token, :null => false # optional, see the tokens section below.
t.integer :login_count # optional, this is a "magic" column, see the magic columns section below
=== Set up your model
@@ -191,39 +192,67 @@ This will keep everything separate. The :secure session will store its info in a
For more information on ids checkout Authlogic::Session::Base#id
-== Resetting passwords
+== Tokens (persistence, resetting passwords, private feed access, etc.)
-You may have noticed in the helpful links section is a tutorial on resetting password with Authlogic. I'm not going to repeat myself here, but I will touch on the basics, if you want more information please see the tutorial.
+To start, let me define tokens as Authlogic sees it. A token is a form of credentials that grants some type of access to their account. Depending on the type of access, a different type of token may be needed. Put simply, it's a way for the user to say "I am this person, let me proceed". What types of different access you ask? Here are just a few:
-Just add the following field to your database:
+1. Regular account access
+2. Access to reset their password
+3. Access to a private feed
+4. Access to confirm their account
- t.string :password_reset_token, :null => false
+There could be many more depending on your application. What's great about Authlogic is that it doesn't care what you do or how you want to grant access to accounts. That's up to you and your application. Authlogic just cares about the type of tokens you need. Instead of giving you a token for each specific task, it gives you all of the necessary *types* of tokens, and you get to use them how you wish. It maintains the tokens and gives you all of the tools you need to use them. Just add the fields to your database and you are good to go.
-Authlogic will notice this field and take care of maintaining it for you. You should use the value of this field to verify your user before they reset their password. There is a finder method you can use to find users with this token, I highly recommend using this method, as it adds in extra security checks to verify the user. See Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::PasswordReset for more information.
+Here are the 3 tokens in more detail:
-== Single Access / Private Feeds Access
+=== Persistence token
-Need to provide a single / one time access to an account where the session does NOT get persisted? Take a private feed for example, if everyone followed standards, basic http auth should work just fine, but since we live in a world where following standards is not a standard (\*cough\* Microsoft \*cough\*), the feed url needs to have some sort of "credentials" to log the user in and get their user specific feed items. This is easy, Authlogic has a nifty little feature for doing just this. All that you need to do is add the following field in your table:
+This token is used to persist the user's session. This is the token that is stored in the session and the cookie, so that during each request the user stays logged in. What's unique about this token is that the first time it is used the value is stored in the session, thus persisting the session. This field is required and must be in your database.
+
+=== Single access token
+
+This token is used for single access only, it is not persisted. Meaning the user provides it, Authlogic grants them access, and that's it. If they want access again they need to provide the token again. Authlogic will *NEVER* store this value in the session or a cookie. Also, for added security, by default this token is *ONLY* allowed for RSS and ATOM requests. Lastly, this token does *NOT* change with the password. Meaning if the user changes their password, this token will remain the same. You can change all of this with configuration (see Authlogic::Session::config), so if you don't like how this works by default, just set some simple configuration in your session.
+
+This field is optional, if you want to use it just add the field to your database:
t.string :single_access_token, :null => false
# or call it feeds_token, feed_token, or whatever you want with configuration
-Authlogic will notice you have this and adjust accordingly. By default single_access_tokens can only be used to login for rss and atom request types.
+This is great for private feed access. So your URL to that user's private feed could look something like:
+
+ http://www.mydomain.com/account/feed.rss?single_access_token=4LiXF7FiGUppIPubBPey
+
+The single_access_token parameter name is configurable (see Authlogic::Session::Config), but if that parameter exists Authlogic will automatically use it to try and grant that user access. You don't have to do a thing: UserSession.find will take care of it just like it does for everything else.
+
+For more information see: Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::SingleAccess
+
+=== Perishable token
+
+This token is used for temporary account access, hence the term "perishable". This token is constantly changing, it changes...
+
+1. In a before_validation in your model, so basically every time the record is saved
+2. Any time a new session is successfully saved (aka logged in)
+
+This is perfect for <b>resetting passwords</b> or <b>confirming accounts</b>. You email them a url with this token in it, and then use this token to find the record and perform your action.
+
+This field is optional, if you want to use it just add the field to your database:
+
+ t.string :perishable_token, :null => false
+ # or call it password_reset_token, pw_reset_token, activation_token, or whatever you want with configuration
-To tailor how this works, you have the following configuration options:
+Finding the record with this token couldn't be easier, Authlogic provides a special finder method that you can use. I highly recommend using it as it adds extra security:
-Session configuration (Authlogic::Session::Config)
+ User.find_using_perishable_token(token)
+ User.find_using_perishable_token(token, 20.minutes)
-1. params_key
-2. single_access_allowed_request_types
-3. single_access_token_field
+That's all you need to do to locate the record. Here is what it does for extra security:
-Model configuration (Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::Config)
+1. Ignores blank tokens all together. If a blank token is passed nil will be returned.
+2. It checks the age of the token, by default the threshold is 10 minutes, meaning if the token is older than 10 minutes, it is not valid and no record will be returned. You can change the default or just override it by passing the threshold as the second parameter. If you don't want a threshold at all, pass 0.
-1. single_access_token_field:
-2. change_single_access_token_with_password
+For a detailed tutorial on how to reset password using this token see the helpful links section above.
-Please use this with care and make sure you warn your users that the URL you provide them is to remain private. Even if Billy 13 year old gets this URL and tries to log in, the only way he can login is through a GET or POST parameter with an rss or atom request. Billy can't create a cookie with this token and Billy wont have access to anything else on the site, unless you change the above configuration.
+For more information see: Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::Perishability
== Scoping
View
1  Rakefile
@@ -11,5 +11,4 @@ Echoe.new 'authlogic' do |p|
p.summary = "A clean, simple, and unobtrusive ruby authentication solution."
p.url = "http://github.com/binarylogic/authlogic"
p.dependencies = %w(activesupport)
- p.include_rakefile = true
end
View
6 lib/authlogic.rb
@@ -13,7 +13,7 @@
require File.dirname(__FILE__) + "/authlogic/orm_adapters/active_record_adapter/acts_as_authentic"
require File.dirname(__FILE__) + "/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/credentials"
require File.dirname(__FILE__) + "/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/logged_in"
- require File.dirname(__FILE__) + "/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/password_reset"
+ require File.dirname(__FILE__) + "/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/perishability"
require File.dirname(__FILE__) + "/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/persistence"
require File.dirname(__FILE__) + "/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/session_maintenance"
require File.dirname(__FILE__) + "/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/single_access"
@@ -28,7 +28,7 @@
require File.dirname(__FILE__) + "/authlogic/session/cookies"
require File.dirname(__FILE__) + "/authlogic/session/errors"
require File.dirname(__FILE__) + "/authlogic/session/params"
-require File.dirname(__FILE__) + "/authlogic/session/password_reset"
+require File.dirname(__FILE__) + "/authlogic/session/perishability"
require File.dirname(__FILE__) + "/authlogic/session/session"
require File.dirname(__FILE__) + "/authlogic/session/scopes"
require File.dirname(__FILE__) + "/authlogic/session/base"
@@ -40,7 +40,7 @@ class Base
include Callbacks
include Cookies
include Params
- include PasswordReset
+ include Perishability
include Session
include Scopes
end
View
25 lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/config.rb
@@ -77,17 +77,18 @@ module ActsAsAuthentic
# * <tt>password_salt_field</tt> - default: :password_salt, :pw_salt, or :salt, depending on which column is present, defaults to :password_salt if none are present,
# This is the name of the field in your database that stores your password salt.
#
- # * <tt>password_reset_token_field</tt> - default: :password_reset_token, :pw_reset_token, :reset_password_token, or :reset_pw_token, depending on which column is present, if none are present defaults to nil
- # This is the name of the field in your database that stores your password reset token. The token you should use to verify your users before you allow a password reset. Authlogic takes care
- # of maintaining this for you and making sure it changes when needed.
+ # * <tt>perishable_token_field</tt> - default: :perishable_token, :password_reset_token, :pw_reset_token, :reset_password_token, or :reset_pw_token, depending on which column is present, if none are present defaults to nil
+ # This is the name of the field in your database that stores your perishable token. The token you should use to confirm your users or allow a password reset. Authlogic takes care
+ # of maintaining this for you and making sure it changes when needed. Use this token for whatever you want, but keep in mind it is temporary, hence the term "perishable".
#
- # * <tt>password_reset_token_valid_for</tt> - default: 10.minutes,
- # Authlogic gives you a sepcial method for finding records by the password reset token (see Authlogic::ORMAdapters::ActiveRecordAdapter::ActcsAsAuthentic::PasswordReset). In this method
- # it checks for the age of the token. If the token is old than whatever you specify here, a user will NOT be returned. This way the tokens are perishable, thus making this system much
+ # * <tt>perishable_token_valid_for</tt> - default: 10.minutes,
+ # Authlogic gives you a sepcial method for finding records by the perishable token (see Authlogic::ORMAdapters::ActiveRecordAdapter::ActcsAsAuthentic::Perishability). In this method
+ # it checks for the age of the token. If the token is older than whatever you specify here, a record will NOT be returned. This way the tokens are perishable, thus making this system much
# more secure.
#
- # * <tt>remember_token_field</tt> - default: :remember_token, :remember_key, :cookie_tokien, or :cookie_key, depending on which column is present, defaults to :remember_token if none are present,
- # This is the name of the field your remember_token is stored. The remember token is a unique token that is stored in the users cookie and
+ # * <tt>persistence_field</tt> - default: :persistence_token, :remember_token, or :cookie_tokien, depending on which column is present,
+ # defaults to :persistence_token if none are present,
+ # This is the name of the field your persistence token is stored. The persistence token is a unique token that is stored in the users cookie and
# session. This way you have complete control of when sessions expire and you don't have to change passwords to expire sessions. This also
# ensures that stale sessions can not be persisted. By stale, I mean sessions that are logged in using an outdated password.
#
@@ -149,11 +150,11 @@ def acts_as_authentic_with_config(options = {})
options[:confirm_password_did_not_match_message] ||= "did not match"
options[:crypted_password_field] ||= first_column_to_exist(:crypted_password, :encrypted_password, :password_hash, :pw_hash)
options[:password_salt_field] ||= first_column_to_exist(:password_salt, :pw_salt, :salt)
- options[:remember_token_field] ||= first_column_to_exist(:remember_token, :remember_key, :cookie_token, :cookiey_key)
+ options[:persistence_token_field] ||= options[:remember_token_field] || first_column_to_exist(:persistence_token, :remember_token, :cookie_token)
options[:single_access_token_field] ||= first_column_to_exist(nil, :single_access_token, :feed_token, :feeds_token)
- options[:password_reset_token_field] ||= first_column_to_exist(nil, :password_reset_token, :pw_reset_token, :reset_password_token, :reset_pw_token)
- options[:password_reset_token_valid_for] ||= 10.minutes
- options[:password_reset_token_valid_for] = options[:password_reset_token_valid_for].to_i
+ options[:perishable_token_field] ||= options[:password_reset_token_field] || first_column_to_exist(nil, :perishable_token, :password_reset_token, :pw_reset_token, :reset_password_token, :reset_pw_token, :activation_token)
+ options[:perishable_token_valid_for] ||= 10.minutes
+ options[:perishable_token_valid_for] = options[:perishable_token_valid_for].to_i
options[:logged_in_timeout] ||= 10.minutes
options[:logged_in_timeout] = options[:logged_in_timeout].to_i
options[:session_ids] ||= [nil]
View
73 lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/password_reset.rb
@@ -1,73 +0,0 @@
-module Authlogic
- module ORMAdapters
- module ActiveRecordAdapter
- module ActsAsAuthentic
- # = Password Reset
- #
- # Handles all logic the deals with maintaining the password reset token. This token should be used to authenticate a user that is not logged in so that they
- # can change their password.
- #
- # === Class Methods
- #
- # * <tt>find_using_{options[:password_reset_token_field]}(token)</tt> - returns the record that matches the pased token. The record's updated at column must not be older than
- # {options[:password_reset_token_valid_for]} ago. Lastly, if a blank token is passed no record will be returned.
- #
- # === Instance Methods
- #
- # * <tt>reset_#{options[:password_reset_token_field]}</tt> - resets the password reset token field to a friendly unique token.
- # * <tt>reset_#{options[:password_reset_token_field]}!</tt> - same as above but saves the record afterwards.
- module PasswordReset
- def acts_as_authentic_with_password_reset(options = {})
- acts_as_authentic_without_password_reset(options)
-
- return if options[:password_reset_token_field].blank?
-
- class_eval <<-"end_eval", __FILE__, __LINE__
- validates_uniqueness_of :#{options[:password_reset_token_field]}
-
- before_validation :reset_#{options[:password_reset_token_field]}, :unless => :resetting_#{options[:password_reset_token_field]}?
-
- def self.find_using_#{options[:password_reset_token_field]}(token)
- return if token.blank?
-
- conditions_sql = "#{options[:password_reset_token_field]} = ?"
- conditions_subs = [token]
-
- if column_names.include?("updated_at") && #{options[:password_reset_token_valid_for]} > 0
- conditions_sql += " and updated_at > ?"
- conditions_subs << #{options[:password_reset_token_valid_for]}.seconds.ago
- end
-
- find(:first, :conditions => [conditions_sql, *conditions_subs])
- end
-
- def reset_#{options[:password_reset_token_field]}
- self.#{options[:password_reset_token_field]} = self.class.friendly_unique_token
- end
-
- def reset_#{options[:password_reset_token_field]}!
- reset_#{options[:password_reset_token_field]}
- @resetting_#{options[:password_reset_token_field]} = true
- result = save_without_session_maintenance
- @resetting_#{options[:password_reset_token_field]} = false
- result
- end
-
- private
- def resetting_#{options[:password_reset_token_field]}?
- @resetting_#{options[:password_reset_token_field]} == true
- end
- end_eval
- end
- end
- end
- end
- end
-end
-
-ActiveRecord::Base.class_eval do
- class << self
- include Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::PasswordReset
- alias_method_chain :acts_as_authentic, :password_reset
- end
-end
View
75 lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/perishability.rb
@@ -0,0 +1,75 @@
+module Authlogic
+ module ORMAdapters
+ module ActiveRecordAdapter
+ module ActsAsAuthentic
+ # = Perishable
+ #
+ # Handles all logic the deals with maintaining the perishable token. This token should be used to authenticate a user that is not logged in so that they
+ # can change their password, confirm their account, etc. Use it for whatever you want, but keep in mind this token is only temporary. Which
+ # is perfect for emailing, etc.
+ #
+ # === Class Methods
+ #
+ # * <tt>find_using_{options[:perishable_token_field]}(token, age = {options[:perishable_token_valid_for]})</tt> - returns the record that matches the pased token. The record's updated at column must not be older than
+ # {age} ago. Lastly, if a blank token is passed no record will be returned.
+ #
+ # === Instance Methods
+ #
+ # * <tt>reset_#{options[:perishable_token_field]}</tt> - resets the perishable token field to a friendly unique token.
+ # * <tt>reset_#{options[:perishable_token_field]}!</tt> - same as above but saves the record afterwards.
+ module Perishability
+ def acts_as_authentic_with_perishability(options = {})
+ acts_as_authentic_without_perishability(options)
+
+ return if options[:perishable_token_field].blank?
+
+ class_eval <<-"end_eval", __FILE__, __LINE__
+ validates_uniqueness_of :#{options[:perishable_token_field]}
+
+ before_validation :reset_#{options[:perishable_token_field]}, :unless => :resetting_#{options[:perishable_token_field]}?
+
+ def self.find_using_#{options[:perishable_token_field]}(token, age = #{options[:perishable_token_valid_for]})
+ return if token.blank?
+ age = age.to_i
+
+ conditions_sql = "#{options[:perishable_token_field]} = ?"
+ conditions_subs = [token]
+
+ if column_names.include?("updated_at") && age > 0
+ conditions_sql += " and updated_at > ?"
+ conditions_subs << age.seconds.ago
+ end
+
+ find(:first, :conditions => [conditions_sql, *conditions_subs])
+ end
+
+ def reset_#{options[:perishable_token_field]}
+ self.#{options[:perishable_token_field]} = self.class.friendly_unique_token
+ end
+
+ def reset_#{options[:perishable_token_field]}!
+ reset_#{options[:perishable_token_field]}
+ @resetting_#{options[:perishable_token_field]} = true
+ result = save_without_session_maintenance
+ @resetting_#{options[:perishable_token_field]} = false
+ result
+ end
+
+ private
+ def resetting_#{options[:perishable_token_field]}?
+ @resetting_#{options[:perishable_token_field]} == true
+ end
+ end_eval
+ end
+ end
+ end
+ end
+ end
+end
+
+ActiveRecord::Base.class_eval do
+ class << self
+ include Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::Perishability
+ alias_method_chain :acts_as_authentic, :perishability
+ end
+end
View
14 lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/persistence.rb
@@ -8,21 +8,21 @@ module ActsAsAuthentic
#
# === Class Methods
#
- # * <tt>forget_all!</tt> - resets ALL records remember_token to a unique value, requiring all users to re-login
+ # * <tt>forget_all!</tt> - resets ALL records persistence_token to a unique value, requiring all users to re-login
# * <tt>unique_token</tt> - returns a pretty hardcore random token that is finally encrypted with a hash algorithm
#
# === Instance Methods
#
- # * <tt>forget!</tt> - resets the record's remember_token which requires them to re-login
+ # * <tt>forget!</tt> - resets the record's persistence_token which requires them to re-login
#
# === Alias Method Chains
#
- # * <tt>#{options[:password_field]}</tt> - adds in functionality to reset the remember token when the password is changed
+ # * <tt>#{options[:password_field]}</tt> - adds in functionality to reset the persistence token when the password is changed
module Persistence
def acts_as_authentic_with_persistence(options = {})
acts_as_authentic_without_persistence(options)
- validates_uniqueness_of options[:remember_token_field]
+ validates_uniqueness_of options[:persistence_token_field]
def forget_all!
# Paginate these to save on memory
@@ -37,19 +37,19 @@ def forget_all!
class_eval <<-"end_eval", __FILE__, __LINE__
def self.unique_token
- # The remember token should be a unique string that is not reversible, which is what a hash is all about
+ # 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)
end
def forget!
- self.#{options[:remember_token_field]} = self.class.unique_token
+ self.#{options[:persistence_token_field]} = self.class.unique_token
save_without_session_maintenance(false)
end
def #{options[:password_field]}_with_persistence=(value)
- self.#{options[:remember_token_field]} = self.class.unique_token
+ self.#{options[:persistence_token_field]} = self.class.unique_token
self.#{options[:password_field]}_without_persistence = value
end
alias_method_chain :#{options[:password_field]}=, :persistence
View
2  lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/session_maintenance.rb
@@ -30,7 +30,7 @@ def save_without_session_maintenance(*args)
protected
def update_sessions?
- !@skip_session_maintenance && #{options[:session_class]}.activated? && !#{options[:session_ids].inspect}.blank? && #{options[:remember_token_field]}_changed?
+ !@skip_session_maintenance && #{options[:session_class]}.activated? && !#{options[:session_ids].inspect}.blank? && #{options[:persistence_token_field]}_changed?
end
def get_session_information
View
4 lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/single_access.rb
@@ -4,8 +4,8 @@ module ActiveRecordAdapter
module ActsAsAuthentic
# = Single Access
#
- # Instead of repeating myself here, checkout the README. There is a "Single Access" section in there that goes over this. Keep in mind none of this will be applied if there
- # is not a single_access_token field supplied in the database.
+ # Instead of repeating myself here, checkout the README. There is a "Tokens" section in there that goes over the single access token.
+ # Keep in mind none of this will be applied if there is not a single_access_token field supplied in the database.
#
# === Instance Methods
#
View
8 lib/authlogic/session/config.rb
@@ -389,8 +389,8 @@ def password_invalid_message
self.class.password_invalid_message
end
- def password_reset_token_field
- klass.acts_as_authentic_config[:password_reset_token_field]
+ def perishable_token_field
+ klass.acts_as_authentic_config[:perishable_token_field]
end
def remember_me_for
@@ -398,8 +398,8 @@ def remember_me_for
self.class.remember_me_for
end
- def remember_token_field
- klass.acts_as_authentic_config[:remember_token_field]
+ def persistence_token_field
+ klass.acts_as_authentic_config[:persistence_token_field]
end
def session_key
View
4 lib/authlogic/session/cookies.rb
@@ -12,7 +12,7 @@ def self.included(klass)
# Tries to validate the session from information in the cookie
def valid_cookie?
if cookie_credentials
- self.unauthorized_record = search_for_record("find_by_#{remember_token_field}", cookie_credentials)
+ self.unauthorized_record = search_for_record("find_by_#{persistence_token_field}", cookie_credentials)
return valid?
end
@@ -26,7 +26,7 @@ def cookie_credentials
def save_cookie
controller.cookies[cookie_key] = {
- :value => record.send(remember_token_field),
+ :value => record.send(persistence_token_field),
:expires => remember_me_until
}
end
View
4 lib/authlogic/session/params.rb
@@ -7,8 +7,8 @@ module Session
#
# https://www.domain.com?user_credentials=[insert single access token here]
#
- # Wait, what is a single access token? It is all explained in the README. Checkout the "Single Access" section in the README. For security reasons, this type of authentication
- # is ONLY available via single access tokens, you can NOT pass your remember token.
+ # Wait, what is a single access token? It is all explained in the README. Checkout the "Tokens" section in the README, there is section about
+ # single access tokens. For security reasons, this type of authentication is ONLY available via single access tokens, you can NOT pass your persistence token.
module Params
# Tries to validate the session from information in the params token
def valid_params?
View
17 lib/authlogic/session/password_reset.rb
@@ -1,17 +0,0 @@
-module Authlogic
- module Session
- # = Password Reset
- #
- # Provides utilities that assist in maintaining the password reset token. This module just resets the token after a session has been saved, just to keep changing it and add extra security.
- module PasswordReset
- def self.included(klass)
- klass.after_save :reset_password_reset_token!
- end
-
- private
- def reset_password_reset_token!
- record.send("reset_#{password_reset_token_field}!") if record.respond_to?("reset_#{password_reset_token_field}!")
- end
- end
- end
-end
View
18 lib/authlogic/session/perishability.rb
@@ -0,0 +1,18 @@
+module Authlogic
+ module Session
+ # = Perishability
+ #
+ # Maintains the perishable token, which is helpful for confirming records or authorizing records to reset their password. All that this
+ # module does is reset it after a session have been saved, just keep it changing. The more it changes, the tighter the security.
+ module Perishability
+ def self.included(klass)
+ klass.after_save :reset_perishable_token!
+ end
+
+ private
+ def reset_perishable_token!
+ record.send("reset_#{perishable_token_field}!") if record.respond_to?("reset_#{perishable_token_field}!")
+ end
+ end
+ end
+end
View
4 lib/authlogic/session/session.rb
@@ -13,7 +13,7 @@ def self.included(klass)
# Tries to validate the session from information in the session
def valid_session?
if session_credentials
- self.unauthorized_record = search_for_record("find_by_#{remember_token_field}", session_credentials)
+ self.unauthorized_record = search_for_record("find_by_#{persistence_token_field}", session_credentials)
return valid?
end
@@ -26,7 +26,7 @@ def session_credentials
end
def update_session!
- controller.session[session_key] = record && record.send(remember_token_field)
+ controller.session[session_key] = record && record.send(persistence_token_field)
end
end
end
View
2  lib/authlogic/version.rb
@@ -44,7 +44,7 @@ def to_a
MAJOR = 1
MINOR = 2
- TINY = 0
+ TINY = 1
# The current version as a Version instance
CURRENT = new(MAJOR, MINOR, TINY)
View
4 test/fixtures/employees.yml
@@ -3,7 +3,7 @@ drew:
email: dgainor@binarylogic.com
password_salt: <%= salt = Employee.unique_token %>
crypted_password: "<%= Employee.acts_as_authentic_config[:crypto_provider].encrypt("drewrocks" + salt) %>"
- remember_token: 5273d85ed156e9dbd6a7c1438d319ef8c8d41dd24368db6c222de11346c7b11e53ee08d45ecf619b1c1dc91233d22b372482b751b066d0a6f6f9bac42eacaabf
+ persistence_token: 5273d85ed156e9dbd6a7c1438d319ef8c8d41dd24368db6c222de11346c7b11e53ee08d45ecf619b1c1dc91233d22b372482b751b066d0a6f6f9bac42eacaabf
first_name: Drew
last_name: Gainor
@@ -12,6 +12,6 @@ jennifer:
email: jjohnson@logicoverdata.com
password_salt: <%= salt = Employee.unique_token %>
crypted_password: "<%= Employee.acts_as_authentic_config[:crypto_provider].encrypt("jenniferocks" + salt) %>"
- remember_token: 2be52a8f741ad00056e6f94eb6844d5316527206da7a3a5e3d0e14d19499ef9fe4c47c89b87febb59a2b41a69edfb4733b6b79302040f3de83f297c6991c75a2
+ persistence_token: 2be52a8f741ad00056e6f94eb6844d5316527206da7a3a5e3d0e14d19499ef9fe4c47c89b87febb59a2b41a69edfb4733b6b79302040f3de83f297c6991c75a2
first_name: Jennifer
last_name: Johnson
View
6 test/fixtures/users.yml
@@ -4,9 +4,9 @@ ben:
login: bjohnson
password_salt: <%= salt = User.unique_token %>
crypted_password: <%= Authlogic::CryptoProviders::Sha512.encrypt("benrocks" + salt) %>
- remember_token: 6cde0674657a8a313ce952df979de2830309aa4c11ca65805dd00bfdc65dbcc2f5e36718660a1d2e68c1a08c276d996763985d2f06fd3d076eb7bc4d97b1e317
+ persistence_token: 6cde0674657a8a313ce952df979de2830309aa4c11ca65805dd00bfdc65dbcc2f5e36718660a1d2e68c1a08c276d996763985d2f06fd3d076eb7bc4d97b1e317
single_access_token: <%= User.friendly_unique_token %>
- password_reset_token: <%= User.friendly_unique_token %>
+ perishable_token: <%= User.friendly_unique_token %>
email: bjohnson@binarylogic.com
first_name: Ben
last_name: Johnson
@@ -17,7 +17,7 @@ zack:
login: zham
password_salt: <%= salt = User.unique_token %>
crypted_password: <%= Authlogic::CryptoProviders::Sha512.encrypt("zackrocks" + salt) %>
- remember_token: fd3c2d5ce09ab98e7547d21f1b3dcf9158a9a19b5d3022c0402f32ae197019fce3fdbc6614d7ee57d719bae53bb089e30edc9e5d6153e5bc3afca0ac1d320342
+ persistence_token: fd3c2d5ce09ab98e7547d21f1b3dcf9158a9a19b5d3022c0402f32ae197019fce3fdbc6614d7ee57d719bae53bb089e30edc9e5d6153e5bc3afca0ac1d320342
single_access_token: <%= User.friendly_unique_token %>
email: zham@ziggityzack.com
first_name: Zack
View
6 test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/config_test.rb
@@ -17,12 +17,12 @@ def test_acts_as_authentic_config
:login_field_regex => /\A\w[\w\.\-_@ ]+\z/,
:session_ids => [nil],
:login_field_regex_failed_message => "use only letters, numbers, spaces, and .-_@ please.",
- :remember_token_field => :remember_token,
+ :persistence_token_field => :persistence_token,
:password_field => :password,
:logged_in_timeout => 600,
:password_salt_field => :password_salt,
- :password_reset_token_valid_for => 600,
- :password_reset_token_field => :password_reset_token,
+ :perishable_token_valid_for => 600,
+ :perishable_token_field => :perishable_token,
:login_field_type => :login,
:crypto_provider => Authlogic::CryptoProviders::Sha512,
:password_blank_message => "can not be blank",
View
10 test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/credentials_test.rb
@@ -94,14 +94,14 @@ def test_password
user.password = "sillywilly"
assert user.crypted_password
assert user.password_salt
- assert user.remember_token
+ assert user.persistence_token
assert_equal true, user.tried_to_set_password
assert_nil user.password
employee = Employee.new
employee.password = "awesome"
assert employee.crypted_password
- assert employee.remember_token
+ assert employee.persistence_token
assert_equal true, employee.tried_to_set_password
assert_nil employee.password
end
@@ -123,18 +123,18 @@ def test_reset_password
old_password = ben.crypted_password
old_salt = ben.password_salt
- old_remember_token = ben.remember_token
+ old_persistence_token = ben.persistence_token
ben.reset_password
assert_not_equal old_password, ben.crypted_password
assert_not_equal old_salt, ben.password_salt
- assert_not_equal old_remember_token, ben.remember_token
+ assert_not_equal old_persistence_token, ben.persistence_token
assert UserSession.find
ben.reset_password!
ben.reload
assert_not_equal old_password, ben.crypted_password
assert_not_equal old_salt, ben.password_salt
- assert_not_equal old_remember_token, ben.remember_token
+ assert_not_equal old_persistence_token, ben.persistence_token
assert !UserSession.find
end
end
View
40 test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/password_reset_test.rb
@@ -1,40 +0,0 @@
-require File.dirname(__FILE__) + '/../../../test_helper.rb'
-
-module ORMAdaptersTests
- module ActiveRecordAdapterTests
- module ActsAsAuthenticTests
- class PasswordResetTest < ActiveSupport::TestCase
- def test_before_validation
- ben = users(:ben)
- old_password_reset_token = ben.password_reset_token
- assert ben.valid?
- assert_not_equal old_password_reset_token, ben.password_reset_token
- ben.reload
- assert_equal old_password_reset_token, ben.password_reset_token
- assert ben.save
- assert_not_equal old_password_reset_token, ben.password_reset_token
- end
-
- def test_find_using_password_reset_token
- ben = users(:ben)
- assert_nil User.find_using_password_reset_token("")
- assert_equal ben, User.find_using_password_reset_token(ben.password_reset_token)
- assert ben.class.connection.execute("update users set updated_at = '#{10.minutes.ago.to_s(:db)}' where id = '#{ben.id}';")
- assert_nil User.find_using_password_reset_token(ben.password_reset_token)
- end
-
- def test_reset_password_reset_token
- ben = users(:ben)
- old_password_reset_token = ben.password_reset_token
- ben.reset_password_reset_token
- assert_not_equal old_password_reset_token, ben.password_reset_token
- ben.reload
- assert_equal old_password_reset_token, ben.password_reset_token
- ben.reset_password_reset_token!
- ben.reload
- assert_not_equal old_password_reset_token, ben.password_reset_token
- end
- end
- end
- end
-end
View
41 test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/perishability_test.rb
@@ -0,0 +1,41 @@
+require File.dirname(__FILE__) + '/../../../test_helper.rb'
+
+module ORMAdaptersTests
+ module ActiveRecordAdapterTests
+ module ActsAsAuthenticTests
+ class PerishabilityTest < ActiveSupport::TestCase
+ def test_before_validation
+ ben = users(:ben)
+ old_perishable_token = ben.perishable_token
+ assert ben.valid?
+ assert_not_equal old_perishable_token, ben.perishable_token
+ ben.reload
+ assert_equal old_perishable_token, ben.perishable_token
+ assert ben.save
+ assert_not_equal old_perishable_token, ben.perishable_token
+ end
+
+ def test_find_using_perishable_token
+ ben = users(:ben)
+ assert_nil User.find_using_perishable_token("")
+ assert_equal ben, User.find_using_perishable_token(ben.perishable_token)
+ assert ben.class.connection.execute("update users set updated_at = '#{10.minutes.ago.to_s(:db)}' where id = '#{ben.id}';")
+ assert_nil User.find_using_perishable_token(ben.perishable_token)
+ assert_equal ben, User.find_using_perishable_token(ben.perishable_token, 20.minutes)
+ end
+
+ def test_reset_perishable_token
+ ben = users(:ben)
+ old_perishable_token = ben.perishable_token
+ ben.reset_perishable_token
+ assert_not_equal old_perishable_token, ben.perishable_token
+ ben.reload
+ assert_equal old_perishable_token, ben.perishable_token
+ ben.reset_perishable_token!
+ ben.reload
+ assert_not_equal old_perishable_token, ben.perishable_token
+ end
+ end
+ end
+ end
+end
View
8 test/session_tests/base_test.rb
@@ -55,10 +55,10 @@ def test_find
assert UserSession.find
last_request_at = ben.reload.last_request_at
- sleep(1)
+ sleep(1.1)
assert UserSession.find
assert_equal last_request_at, ben.reload.last_request_at
- sleep(1)
+ sleep(1.1)
assert UserSession.find
assert_not_equal last_request_at, ben.reload.last_request_at
@@ -157,10 +157,10 @@ def test_id
def test_inspect
session = UserSession.new
- assert_equal "#<UserSession {:login=>nil, :password=>\"<protected>\"}>", session.inspect
+ assert_equal "#<UserSession #{{:login=>nil, :password=>"<protected>"}.inspect}>", session.inspect
session.login = "login"
session.password = "pass"
- assert "#<UserSession {:login=>\"login\", :password=>\"<protected>\"}>" == session.inspect || "#<UserSession {:password=>\"<protected>\", :login=>\"login\"}>" == session.inspect
+ assert "#<UserSession #{{:login=>"login", :password=>"<protected>"}.inspect}>" == session.inspect
end
def test_new_session
View
2  test/session_tests/cookies_test.rb
@@ -17,7 +17,7 @@ def test_save
ben = users(:ben)
session = UserSession.new(ben)
assert session.save
- assert_equal ben.remember_token, @controller.cookies["user_credentials"]
+ assert_equal ben.persistence_token, @controller.cookies["user_credentials"]
end
def test_destroy
View
6 test/session_tests/password_reset_test.rb → test/session_tests/perishability_test.rb
@@ -1,12 +1,12 @@
require File.dirname(__FILE__) + '/../test_helper.rb'
module SessionTests
- class PasswordResetTest < ActiveSupport::TestCase
+ class PerishabilityTest < ActiveSupport::TestCase
def test_after_save
ben = users(:ben)
- old_password_reset_token = ben.password_reset_token
+ old_perishable_token = ben.perishable_token
session = UserSession.create(ben)
- assert_not_equal old_password_reset_token, ben.password_reset_token
+ assert_not_equal old_perishable_token, ben.perishable_token
drew = employees(:drew)
assert UserSession.create(drew)
View
8 test/session_tests/session_test.rb
@@ -12,7 +12,7 @@ def test_valid_session
assert session.valid_session?
assert session.find_record
assert_equal ben, session.record
- assert_equal ben.remember_token, @controller.session["user_credentials"]
+ assert_equal ben.persistence_token, @controller.session["user_credentials"]
assert_equal ben, session.unauthorized_record
assert !session.new_session?
end
@@ -22,13 +22,13 @@ def test_save
session = UserSession.new(ben)
assert @controller.session["user_credentials"].blank?
assert session.save
- assert_equal ben.remember_token, @controller.session["user_credentials"]
+ assert_equal ben.persistence_token, @controller.session["user_credentials"]
end
def test_destroy
ben = users(:ben)
set_session_for(ben)
- assert_equal ben.remember_token, @controller.session["user_credentials"]
+ assert_equal ben.persistence_token, @controller.session["user_credentials"]
session = UserSession.find
assert session.destroy
assert @controller.session["user_credentials"].blank?
@@ -39,7 +39,7 @@ def test_find
set_cookie_for(ben)
assert @controller.session["user_credentials"].blank?
assert UserSession.find
- assert_equal ben.remember_token, @controller.session["user_credentials"]
+ assert_equal ben.persistence_token, @controller.session["user_credentials"]
end
end
end
View
10 test/test_helper.rb
@@ -38,9 +38,9 @@
t.string :login
t.string :crypted_password
t.string :password_salt
- t.string :remember_token
+ t.string :persistence_token
t.string :single_access_token
- t.string :password_reset_token
+ t.string :perishable_token
t.string :email
t.string :first_name
t.string :last_name
@@ -59,7 +59,7 @@
t.string :email
t.string :crypted_password
t.string :password_salt
- t.string :remember_token
+ t.string :persistence_token
t.string :first_name
t.string :last_name
t.integer :login_count
@@ -132,7 +132,7 @@ def http_basic_auth_for(user = nil, &block)
end
def set_cookie_for(user, id = nil)
- @controller.cookies["user_credentials"] = {:value => user.remember_token, :expires => nil}
+ @controller.cookies["user_credentials"] = {:value => user.persistence_token, :expires => nil}
end
def unset_cookie
@@ -156,7 +156,7 @@ def unset_request_content_type
end
def set_session_for(user, id = nil)
- @controller.session["user_credentials"] = user.remember_token
+ @controller.session["user_credentials"] = user.persistence_token
end
def unset_session
Please sign in to comment.
Something went wrong with that request. Please try again.