Skip to content

Commit

Permalink
Released v1.3.0 (see changelog for compatibility issues)
Browse files Browse the repository at this point in the history
  • Loading branch information
binarylogic committed Nov 21, 2008
1 parent a15093e commit 4c310ed
Show file tree
Hide file tree
Showing 15 changed files with 201 additions and 174 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.rdoc
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
== 1.3.0 released 2008-11-20

* BREAKS BACKWARDS COMPATIBILITY: changed the confirm_password field to password_confirmation for acts_as_authentic, since the rails validates_confirmation_of handles creating this attribute.
* BREAKS BACKWARDS COMPATIBILITY: Cleaned up all of the validation configuration for acts_as_authentic, as well as the documentation that goes with it, you can accomplish the same things as before, but this is much more flexible and much more organized.
* Got rid of simple delegator for the abstract controller, apparently this has performance issues.
* Cleaned up validations to assume ActiveRecord dirty attributes are present, I think this is a safe assumption.

== 1.2.2 released 2008-11-20

* Added allow_blank_login_and_password_field and allow_blank_email_field options to acts_as_authentic, which allows you to have alternative logins, such as OpenID
Expand Down
1 change: 0 additions & 1 deletion Manifest
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ lib/authlogic/session/callbacks.rb
lib/authlogic/session/config.rb
lib/authlogic/session/cookies.rb
lib/authlogic/session/errors.rb
lib/authlogic/session/openid.rb
lib/authlogic/session/params.rb
lib/authlogic/session/perishability.rb
lib/authlogic/session/scopes.rb
Expand Down
2 changes: 1 addition & 1 deletion README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Authlogic makes this a reality. This is just the tip of the ice berg. Keep readi
* <b>Tutorial: Authlogic basic setup:</b> http://www.binarylogic.com/2008/11/3/tutorial-authlogic-basic-setup
* <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 setup tutorial above (with source):</b> http://authlogic_example.binarylogic.com
* <b>Live example of the setup tutorial above (with source):</b> http://authlogicexample.binarylogic.com
* <b>Bugs / feature suggestions:</b> http://binarylogic.lighthouseapp.com/projects/18752-authlogic

== Install and use
Expand Down
32 changes: 30 additions & 2 deletions lib/authlogic/controller_adapters/abstract_adapter.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,48 @@
module Authlogic
module ControllerAdapters # :nodoc:
# = Abstract Adapter
#
# Allows you to use Authlogic in any framework you want, not just rails. See tha RailsAdapter for an example of how to adapter Authlogic to work with your framework.
class AbstractAdapter < SimpleDelegator
class AbstractAdapter
attr_accessor :controller

def initialize(controller)
self.controller = controller
end

def authenticate_with_http_basic(&block)
@auth = Rack::Auth::Basic::Request.new(__getobj__.request.env)
@auth = Rack::Auth::Basic::Request.new(controller.request.env)
if @auth.provided? and @auth.basic?
block.call(*@auth.credentials)
else
false
end
end

def cookies
controller.cookies
end

def params
controller.params
end

def request
controller.request
end

def request_content_type
request.content_type
end

def session
controller.session
end

private
def method_missing(id, *args, &block)
controller.send(id, *args, &block)
end
end
end
end
4 changes: 2 additions & 2 deletions lib/authlogic/controller_adapters/rails_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ module ControllerAdapters
# provides. Similar to how ActiveRecord has an adapter for MySQL, PostgreSQL, SQLite, etc.
class RailsAdapter < AbstractAdapter
def authenticate_with_http_basic(&block)
__getobj__.authenticate_with_http_basic(&block)
controller.authenticate_with_http_basic(&block)
end

def cookies
__getobj__.send(:cookies)
controller.send(:cookies)
end

def request_content_type
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,40 @@ def acts_as_authentic_with_credentials(options = {})
acts_as_authentic_without_credentials(options)

if options[:validate_fields]
email_name_regex = '[\w\.%\+\-]+'
domain_head_regex = '(?:[A-Z0-9\-]+\.)+'
domain_tld_regex = '(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|jobs|museum)'
email_field_regex ||= /\A#{email_name_regex}@#{domain_head_regex}#{domain_tld_regex}\z/i

if options[:validate_login_field]
case options[:login_field_type]
when :email
validates_length_of options[:login_field], :within => 6..100, :allow_blank => options[:allow_blank_login_and_password_fields]
validates_format_of options[:login_field], :with => options[:login_field_regex], :message => options[:login_field_regex_failed_message], :allow_blank => options[:allow_blank_login_and_password_fields]
validates_length_of options[:login_field], {:within => 6..100}.merge(options[:login_field_validates_length_of_options])
validates_format_of options[:login_field], {:with => email_field_regex, :message => "should look like an email address."}.merge(options[:login_field_validates_length_of_options])
else
validates_length_of options[:login_field], :within => 2..100, :allow_blank => options[:allow_blank_login_and_password_fields]
validates_format_of options[:login_field], :with => options[:login_field_regex], :message => options[:login_field_regex_failed_message], :allow_blank => options[:allow_blank_login_and_password_fields]
validates_length_of options[:login_field], {:within => 2..100}.merge(options[:login_field_validates_length_of_options])
validates_format_of options[:login_field], {:with => /\A\w[\w\.\-_@ ]+\z/, :message => "should use only letters, numbers, spaces, and .-_@ please."}.merge(options[:login_field_validates_format_of_options])
end

validates_uniqueness_of options[:login_field], :scope => options[:scope], :allow_blank => options[:allow_blank_login_and_password_fields], :if => Proc.new { |record| (record.respond_to?("#{options[:login_field]}_changed?") && record.send("#{options[:login_field]}_changed?")) || !record.respond_to?("#{options[:login_field]}_changed?") }
validates_uniqueness_of options[:login_field], {:allow_blank => true}.merge(options[:login_field_validates_uniqueness_of_options].merge(:if => "#{options[:login_field]}_changed?".to_sym))
end

if options[:validate_email_field] && options[:email_field]
validates_length_of options[:email_field], :within => 6..100, :allow_blank => options[:allow_blank_email_field]
validates_format_of options[:email_field], :with => options[:email_field_regex], :message => options[:email_field_regex_failed_message], :allow_blank => options[:allow_blank_email_field]
validates_uniqueness_of options[:email_field], :scope => options[:scope], :allow_blank => options[:allow_blank_email_field], :if => Proc.new { |record| (record.respond_to?("#{options[:email_field]}_changed?") && record.send("#{options[:email_field]}_changed?")) || !record.respond_to?("#{options[:email_field]}_changed?") }
if options[:validate_password_field]
validates_presence_of options[:password_field], {:on => :create}.merge(options[:password_field_validates_presence_of_options])


validates_confirmation_of options[:password_field], options[:password_field_validates_confirmation_of_options].merge(:if => "#{options[:crypted_password_field]}_changed?".to_sym)
validates_presence_of "#{options[:password_field]}_confirmation", :if => "#{options[:crypted_password_field]}_changed?"
end

validate :validate_password if options[:validate_password_field]
if options[:validate_email_field] && options[:email_field]
validates_length_of options[:email_field], {:within => 6..100}.merge(options[:email_field_validates_length_of_options])
validates_format_of options[:email_field], {:with => email_field_regex, :message => "should look like an email address."}.merge(options[:email_field_validates_format_of_options])
validates_uniqueness_of options[:email_field], options[:email_field_validates_uniqueness_of_options].merge(:if => "#{options[:email_field]}_changed?".to_sym)
end
end

attr_writer "confirm_#{options[:password_field]}"
attr_accessor "tried_to_set_#{options[:password_field]}"
attr_reader options[:password_field]

class_eval <<-"end_eval", __FILE__, __LINE__
def self.friendly_unique_token
Expand All @@ -56,7 +66,6 @@ def self.friendly_unique_token
def #{options[:password_field]}=(pass)
return if pass.blank?
self.tried_to_set_#{options[:password_field]} = true
@#{options[:password_field]} = pass
self.#{options[:password_salt_field]} = self.class.unique_token
self.#{options[:crypted_password_field]} = #{options[:crypto_provider]}.encrypt(@#{options[:password_field]} + #{options[:password_salt_field]})
Expand All @@ -68,13 +77,10 @@ def valid_#{options[:password_field]}?(attempted_password)
(!#{options[:crypto_provider]}.respond_to?(:decrypt) && #{options[:crypto_provider]}.encrypt(attempted_password + #{options[:password_salt_field]}) == #{options[:crypted_password_field]})
end
def #{options[:password_field]}; end
def confirm_#{options[:password_field]}; end
def reset_#{options[:password_field]}
friendly_token = self.class.friendly_unique_token
self.#{options[:password_field]} = friendly_token
self.confirm_#{options[:password_field]} = friendly_token
self.#{options[:password_field]}_confirmation = friendly_token
end
alias_method :randomize_password, :reset_password
Expand All @@ -83,23 +89,6 @@ def reset_#{options[:password_field]}!
save_without_session_maintenance(false)
end
alias_method :randomize_password!, :reset_password!
protected
def tried_to_set_password?
tried_to_set_password == true
end
def validate_password
return if #{options[:allow_blank_login_and_password_fields].inspect} && @#{options[:password_field]}.blank? && @confirm_#{options[:password_field]}.blank?
if new_record? || tried_to_set_#{options[:password_field]}?
if @#{options[:password_field]}.blank?
errors.add(:#{options[:password_field]}, #{options[:password_blank_message].inspect})
else
errors.add(:confirm_#{options[:password_field]}, #{options[:confirm_password_did_not_match_message].inspect}) if @confirm_#{options[:password_field]} != @#{options[:password_field]}
end
end
end
end_eval
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def acts_as_authentic_with_perishability(options = {})
return if options[:perishable_token_field].blank?

class_eval <<-"end_eval", __FILE__, __LINE__
validates_uniqueness_of :#{options[:perishable_token_field]}, :if => Proc.new { |record| (record.respond_to?("#{options[:perishable_token_field]}_changed?") && record.send("#{options[:perishable_token_field]}_changed?")) || !record.respond_to?("#{options[:perishable_token_field]}_changed?") }
validates_uniqueness_of :#{options[:perishable_token_field]}, :if => :#{options[:perishable_token_field]}_changed?
before_validation :reset_#{options[:perishable_token_field]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ module Persistence
def acts_as_authentic_with_persistence(options = {})
acts_as_authentic_without_persistence(options)

validates_uniqueness_of options[:persistence_token_field], :if => Proc.new { |record| (record.respond_to?("#{options[:persistence_token_field]}_changed?") && record.send("#{options[:persistence_token_field]}_changed?")) || !record.respond_to?("#{options[:persistence_token_field]}_changed?") }
validates_uniqueness_of options[:persistence_token_field], :if => "#{options[:persistence_token_field]}_changed?".to_sym

def forget_all!
# Paginate these to save on memory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def acts_as_authentic_with_single_access(options = {})
return if options[:single_access_token_field].blank?

class_eval <<-"end_eval", __FILE__, __LINE__
validates_uniqueness_of :#{options[:single_access_token_field]}, :if => Proc.new { |record| (record.respond_to?("#{options[:single_access_token_field]}_changed?") && record.send("#{options[:single_access_token_field]}_changed?")) || !record.respond_to?("#{options[:single_access_token_field]}_changed?") }
validates_uniqueness_of :#{options[:single_access_token_field]}, :if => :#{options[:single_access_token_field]}_changed?
before_validation :set_#{options[:single_access_token_field]}_field
Expand Down
17 changes: 0 additions & 17 deletions lib/authlogic/session/openid.rb

This file was deleted.

4 changes: 2 additions & 2 deletions lib/authlogic/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ def to_a
end

MAJOR = 1
MINOR = 2
TINY = 2
MINOR = 3
TINY = 0

# The current version as a Version instance
CURRENT = new(MAJOR, MINOR, TINY)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,37 @@ def test_first_column_to_exist

def test_acts_as_authentic_config
default_config = {
:confirm_password_did_not_match_message => "did not match",
:single_access_token_field => :single_access_token,
:login_field_regex => /\A\w[\w\.\-_@ ]+\z/,
:session_ids => [nil],
:login_field_regex_failed_message => "should use only letters, numbers, spaces, and .-_@ please.",
:persistence_token_field => :persistence_token,
:password_field => :password,
:logged_in_timeout => 600,
:password_salt_field => :password_salt,
: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",
:crypted_password_field => :crypted_password,
:session_class => "UserSession",
:login_field => :login,
:email_field => :email,
:email_field_regex => /\A[\w\.%\+\-]+@(?:[A-Z0-9\-]+\.)+(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|jobs|museum)\z/i,
:email_field_regex_failed_message=>"should look like an email address.",
:validate_fields => true,
:validate_login_field => true,
:validate_email_field => true,
:validate_password_field => true
}
:email_field_validates_length_of_options => {},
:logged_in_timeout => 600,
:validate_password_field => true,
:login_field_validates_length_of_options => {},
:password_field_validation_options => {},
:login_field_type => :login,
:email_field_validates_format_of_options => {},
:crypted_password_field => :crypted_password,
:password_salt_field => :password_salt,
:login_field_validates_format_of_options => {},
:email_field_validation_options => {},
:crypto_provider => Authlogic::CryptoProviders::Sha512,
:persistence_token_field => :persistence_token,
:email_field_validates_uniqueness_of_options => {},
:session_class => "UserSession",
:single_access_token_field => :single_access_token,
:login_field_validates_uniqueness_of_options => {},
:validate_fields => true,
:login_field => :login,
:perishable_token_valid_for => 600,
:password_field_validates_presence_of_options => {},
:password_field => :password,
:validate_login_field => true,
:email_field => :email,
:perishable_token_field => :perishable_token,
:password_field_validates_confirmation_of_options => {},
:validate_email_field => true,
:validation_options => {},
:login_field_validation_options => {}
}
assert_equal default_config, User.acts_as_authentic_config
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,14 @@ def test_user_validations
user.password = "my pass"
assert !user.valid?
assert !user.errors.on(:password)
assert user.errors.on(:confirm_password)
assert user.errors.on(:password_confirmation)

user.confirm_password = "my pizass"
user.password_confirmation = "my pizass"
assert !user.valid?
assert !user.errors.on(:password)
assert user.errors.on(:confirm_password)
assert user.errors.on(:password)
assert user.errors.on(:email)

user.confirm_password = "my pass"
user.password_confirmation = "my pass"
assert !user.valid?
assert user.errors.on(:email)

Expand All @@ -61,7 +60,7 @@ def test_user_validations
def test_employee_validations
employee = Employee.new
employee.password = "pass"
employee.confirm_password = "pass"
employee.password_confirmation = "pass"

assert !employee.valid?
assert employee.errors.on(:email)
Expand Down Expand Up @@ -95,15 +94,13 @@ def test_password
assert user.crypted_password
assert user.password_salt
assert user.persistence_token
assert_equal true, user.tried_to_set_password
assert_nil user.password
assert_equal "sillywilly", user.password

employee = Employee.new
employee.password = "awesome"
assert employee.crypted_password
assert employee.persistence_token
assert_equal true, employee.tried_to_set_password
assert_nil employee.password
assert_equal "awesome", employee.password
end

def test_valid_password
Expand Down
Loading

0 comments on commit 4c310ed

Please sign in to comment.