photomix/vendor/plugins/authlogic/lib/authlogic/acts_as_authentic/perishable_token.rb

106 lines
4.6 KiB
Ruby

module Authlogic
module ActsAsAuthentic
# This provides a handy token that is "perishable". Meaning the token is only good for a certain amount of time. This is perfect for
# resetting password, confirming accounts, etc. Typically during these actions you send them this token in via their email. Once they
# use the token and do what they need to do, that token should expire. Don't worry about maintaining this, changing it, or expiring it
# yourself. Authlogic does all of this for you. See the sub modules for all of the tools Authlogic provides to you.
module PerishableToken
def self.included(klass)
klass.class_eval do
extend Config
add_acts_as_authentic_module(Methods)
end
end
# Change how the perishable token works.
module Config
# When using the find_using_perishable_token method the token can expire. If the token is expired, no
# record will be returned. Use this option to specify how long the token is valid for.
#
# * <tt>Default:</tt> 10.minutes
# * <tt>Accepts:</tt> Fixnum
def perishable_token_valid_for(value = nil)
rw_config(:perishable_token_valid_for, (!value.nil? && value.to_i) || value, 10.minutes.to_i)
end
alias_method :perishable_token_valid_for=, :perishable_token_valid_for
# Authlogic tries to expire and change the perishable token as much as possible, without comprising
# it's purpose. This is for security reasons. If you want to manage it yourself, you can stop
# Authlogic from getting your in way by setting this to true.
#
# * <tt>Default:</tt> false
# * <tt>Accepts:</tt> Boolean
def disable_perishable_token_maintenance(value = nil)
rw_config(:disable_perishable_token_maintenance, value, false)
end
alias_method :disable_perishable_token_maintenance=, :disable_perishable_token_maintenance
end
# All methods relating to the perishable token.
module Methods
def self.included(klass)
return if !klass.column_names.include?("perishable_token")
klass.class_eval do
extend ClassMethods
include InstanceMethods
validates_uniqueness_of :perishable_token, :if => :perishable_token_changed?
before_save :reset_perishable_token, :unless => :disable_perishable_token_maintenance?
end
end
# Class level methods for the perishable token
module ClassMethods
# Use this methdo to find a record with a perishable token. This method does 2 things for you:
#
# 1. It ignores blank tokens
# 2. It enforces the perishable_token_valid_for configuration option.
#
# If you want to use a different timeout value, just pass it as the second parameter:
#
# User.find_using_perishable_token(token, 1.hour)
def find_using_perishable_token(token, age = self.perishable_token_valid_for)
return if token.blank?
age = age.to_i
conditions_sql = "perishable_token = ?"
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
# This method will raise ActiveRecord::NotFound if no record is found.
def find_using_perishable_token!(token, age = perishable_token_valid_for)
find_using_perishable_token(token, age) || raise(ActiveRecord::RecordNotFound)
end
end
# Instance level methods for the perishable token.
module InstanceMethods
# Resets the perishable token to a random friendly token.
def reset_perishable_token
self.perishable_token = Random.friendly_token
end
# Same as reset_perishable_token, but then saves the record afterwards.
def reset_perishable_token!
reset_perishable_token
save_without_session_maintenance(:validate => false)
end
# A convenience method based on the disable_perishable_token_maintenance configuration option.
def disable_perishable_token_maintenance?
self.class.disable_perishable_token_maintenance == true
end
end
end
end
end
end