authlogic 1.2.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of authlogic might be problematic. Click here for more details.

data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,12 @@
1
+ == 1.2.2 released 2008-11-19
2
+
3
+ * 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
4
+ * In the session Authlogic now also stores the record id. We use this id to find the record and then check the token against the record, thus allowing for quicker database lookups, while getting the same security.
5
+ * Skip validation for reset_perishable_token!
6
+ * Added checks for uniqueness validations to only perform if the values have changed, this cuts down on DB queries
7
+ * Abstract controller adapter now uses ruby's simple delegator class
8
+ * Allow to save with a block: user_session.save { |result| }, result will either be false or self, this is useful when implementing OpenID and other methods
9
+
1
10
  == 1.2.1 released 2008-11-19
2
11
 
3
12
  * Added build method to authenticates_many association to act like AR association collections.
data/Manifest CHANGED
@@ -21,6 +21,7 @@ lib/authlogic/session/callbacks.rb
21
21
  lib/authlogic/session/config.rb
22
22
  lib/authlogic/session/cookies.rb
23
23
  lib/authlogic/session/errors.rb
24
+ lib/authlogic/session/openid.rb
24
25
  lib/authlogic/session/params.rb
25
26
  lib/authlogic/session/perishability.rb
26
27
  lib/authlogic/session/scopes.rb
data/README.rdoc CHANGED
@@ -71,8 +71,8 @@ Authlogic makes this a reality. This is just the tip of the ice berg. Keep readi
71
71
  == Helpful links
72
72
 
73
73
  * <b>Documentation:</b> http://authlogic.rubyforge.org
74
- * <b>Authlogic setup tutorial:</b> http://www.binarylogic.com/2008/11/3/tutorial-authlogic-basic-setup
75
- * <b>Authlogic reset passwords tutorial:</b> http://www.binarylogic.com/2008/11/16/tutorial-reset-passwords-with-authlogic
74
+ * <b>Tutorial: Authlogic basic setup:</b> http://www.binarylogic.com/2008/11/3/tutorial-authlogic-basic-setup
75
+ * <b>Tutorial: Reset passwords with Authlogic the RESTful way:</b> http://www.binarylogic.com/2008/11/16/tutorial-reset-passwords-with-authlogic
76
76
  * <b>Live example of the setup tutorial above (with source):</b> http://authlogic_example.binarylogic.com
77
77
  * <b>Bugs / feature suggestions:</b> http://binarylogic.lighthouseapp.com/projects/18752-authlogic
78
78
 
@@ -211,7 +211,7 @@ This token is used to persist the user's session. This is the token that is stor
211
211
 
212
212
  === Single access token
213
213
 
214
- 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.
214
+ 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. For added security, by default this token is *ONLY* allowed for RSS and ATOM requests. Also, this token does *NOT* change with the password. Meaning if the user changes their password, this token will remain the same. Lastly, this token uses a "friendly" toke (see the URL example below) so that it is easier to email / copy and paste. 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.
215
215
 
216
216
  This field is optional, if you want to use it just add the field to your database:
217
217
 
@@ -250,6 +250,8 @@ That's all you need to do to locate the record. Here is what it does for extra s
250
250
  1. Ignores blank tokens all together. If a blank token is passed nil will be returned.
251
251
  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.
252
252
 
253
+ Just like the single access token this uses a friendly token, so it is easier to email / copy and paste.
254
+
253
255
  For a detailed tutorial on how to reset password using this token see the helpful links section above.
254
256
 
255
257
  For more information see: Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::Perishability
data/Rakefile CHANGED
@@ -1,14 +1,19 @@
1
1
  require 'rubygems'
2
- require 'echoe'
3
-
4
2
  require File.dirname(__FILE__) << "/lib/authlogic/version"
5
3
 
6
- Echoe.new 'authlogic' do |p|
7
- p.version = Authlogic::Version::STRING
8
- p.author = "Ben Johnson of Binary Logic"
9
- p.email = 'bjohnson@binarylogic.com'
10
- p.project = 'authlogic'
11
- p.summary = "A clean, simple, and unobtrusive ruby authentication solution."
12
- p.url = "http://github.com/binarylogic/authlogic"
13
- p.dependencies = %w(activesupport)
4
+ begin
5
+ require 'echoe'
6
+
7
+ Echoe.new 'authlogic' do |p|
8
+ p.version = Authlogic::Version::STRING
9
+ p.author = "Ben Johnson of Binary Logic"
10
+ p.email = 'bjohnson@binarylogic.com'
11
+ p.project = 'authlogic'
12
+ p.summary = "A clean, simple, and unobtrusive ruby authentication solution."
13
+ p.url = "http://github.com/binarylogic/authlogic"
14
+ p.dependencies = %w(activesupport)
15
+ end
16
+ rescue LoadError => boom
17
+ puts "You are missing a dependency required for meta-operations on this gem."
18
+ puts "#{boom.to_s.capitalize}."
14
19
  end
data/authlogic.gemspec CHANGED
@@ -2,15 +2,15 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{authlogic}
5
- s.version = "1.2.1"
5
+ s.version = "1.2.2"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Ben Johnson of Binary Logic"]
9
- s.date = %q{2008-11-19}
9
+ s.date = %q{2008-11-20}
10
10
  s.description = %q{A clean, simple, and unobtrusive ruby authentication solution.}
11
11
  s.email = %q{bjohnson@binarylogic.com}
12
- s.extra_rdoc_files = ["CHANGELOG.rdoc", "lib/authlogic/controller_adapters/abstract_adapter.rb", "lib/authlogic/controller_adapters/merb_adapter.rb", "lib/authlogic/controller_adapters/rails_adapter.rb", "lib/authlogic/crypto_providers/sha1.rb", "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/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", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic.rb", "lib/authlogic/orm_adapters/active_record_adapter/authenticates_many.rb", "lib/authlogic/session/active_record_trickery.rb", "lib/authlogic/session/authenticates_many_association.rb", "lib/authlogic/session/base.rb", "lib/authlogic/session/callbacks.rb", "lib/authlogic/session/config.rb", "lib/authlogic/session/cookies.rb", "lib/authlogic/session/errors.rb", "lib/authlogic/session/params.rb", "lib/authlogic/session/perishability.rb", "lib/authlogic/session/scopes.rb", "lib/authlogic/session/session.rb", "lib/authlogic/version.rb", "lib/authlogic.rb", "README.rdoc"]
13
- s.files = ["CHANGELOG.rdoc", "init.rb", "lib/authlogic/controller_adapters/abstract_adapter.rb", "lib/authlogic/controller_adapters/merb_adapter.rb", "lib/authlogic/controller_adapters/rails_adapter.rb", "lib/authlogic/crypto_providers/sha1.rb", "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/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", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic.rb", "lib/authlogic/orm_adapters/active_record_adapter/authenticates_many.rb", "lib/authlogic/session/active_record_trickery.rb", "lib/authlogic/session/authenticates_many_association.rb", "lib/authlogic/session/base.rb", "lib/authlogic/session/callbacks.rb", "lib/authlogic/session/config.rb", "lib/authlogic/session/cookies.rb", "lib/authlogic/session/errors.rb", "lib/authlogic/session/params.rb", "lib/authlogic/session/perishability.rb", "lib/authlogic/session/scopes.rb", "lib/authlogic/session/session.rb", "lib/authlogic/version.rb", "lib/authlogic.rb", "Manifest", "MIT-LICENSE", "Rakefile", "README.rdoc", "shoulda_macros/authlogic.rb", "test/fixtures/companies.yml", "test/fixtures/employees.yml", "test/fixtures/projects.yml", "test/fixtures/users.yml", "test/libs/aes128_crypto_provider.rb", "test/libs/mock_controller.rb", "test/libs/mock_cookie_jar.rb", "test/libs/mock_request.rb", "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/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", "test/orm_adapters_tests/active_record_adapter_tests/authenticates_many_test.rb", "test/session_tests/active_record_trickery_test.rb", "test/session_tests/authenticates_many_association_test.rb", "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/perishability_test.rb", "test/session_tests/scopes_test.rb", "test/session_tests/session_test.rb", "test/test_helper.rb", "authlogic.gemspec"]
12
+ s.extra_rdoc_files = ["CHANGELOG.rdoc", "lib/authlogic/controller_adapters/abstract_adapter.rb", "lib/authlogic/controller_adapters/merb_adapter.rb", "lib/authlogic/controller_adapters/rails_adapter.rb", "lib/authlogic/crypto_providers/sha1.rb", "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/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", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic.rb", "lib/authlogic/orm_adapters/active_record_adapter/authenticates_many.rb", "lib/authlogic/session/active_record_trickery.rb", "lib/authlogic/session/authenticates_many_association.rb", "lib/authlogic/session/base.rb", "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", "lib/authlogic/session/session.rb", "lib/authlogic/version.rb", "lib/authlogic.rb", "README.rdoc"]
13
+ s.files = ["CHANGELOG.rdoc", "init.rb", "lib/authlogic/controller_adapters/abstract_adapter.rb", "lib/authlogic/controller_adapters/merb_adapter.rb", "lib/authlogic/controller_adapters/rails_adapter.rb", "lib/authlogic/crypto_providers/sha1.rb", "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/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", "lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic.rb", "lib/authlogic/orm_adapters/active_record_adapter/authenticates_many.rb", "lib/authlogic/session/active_record_trickery.rb", "lib/authlogic/session/authenticates_many_association.rb", "lib/authlogic/session/base.rb", "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", "lib/authlogic/session/session.rb", "lib/authlogic/version.rb", "lib/authlogic.rb", "Manifest", "MIT-LICENSE", "Rakefile", "README.rdoc", "shoulda_macros/authlogic.rb", "test/fixtures/companies.yml", "test/fixtures/employees.yml", "test/fixtures/projects.yml", "test/fixtures/users.yml", "test/libs/aes128_crypto_provider.rb", "test/libs/mock_controller.rb", "test/libs/mock_cookie_jar.rb", "test/libs/mock_request.rb", "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/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", "test/orm_adapters_tests/active_record_adapter_tests/authenticates_many_test.rb", "test/session_tests/active_record_trickery_test.rb", "test/session_tests/authenticates_many_association_test.rb", "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/perishability_test.rb", "test/session_tests/scopes_test.rb", "test/session_tests/session_test.rb", "test/test_helper.rb", "authlogic.gemspec"]
14
14
  s.has_rdoc = true
15
15
  s.homepage = %q{http://github.com/binarylogic/authlogic}
16
16
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Authlogic", "--main", "README.rdoc"]
@@ -2,15 +2,9 @@ module Authlogic
2
2
  module ControllerAdapters # :nodoc:
3
3
  # = Abstract Adapter
4
4
  # 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.
5
- class AbstractAdapter
6
- attr_accessor :controller
7
-
8
- def initialize(controller)
9
- self.controller = controller
10
- end
11
-
5
+ class AbstractAdapter < SimpleDelegator
12
6
  def authenticate_with_http_basic(&block)
13
- @auth = Rack::Auth::Basic::Request.new(controller.request.env)
7
+ @auth = Rack::Auth::Basic::Request.new(__getobj__.request.env)
14
8
  if @auth.provided? and @auth.basic?
15
9
  block.call(*@auth.credentials)
16
10
  else
@@ -18,25 +12,9 @@ module Authlogic
18
12
  end
19
13
  end
20
14
 
21
- def cookies
22
- controller.cookies
23
- end
24
-
25
- def params
26
- controller.params
27
- end
28
-
29
- def request
30
- controller.request
31
- end
32
-
33
15
  def request_content_type
34
16
  request.content_type
35
17
  end
36
-
37
- def session
38
- controller.session
39
- end
40
18
  end
41
19
  end
42
20
  end
@@ -5,11 +5,11 @@ module Authlogic
5
5
  # provides. Similar to how ActiveRecord has an adapter for MySQL, PostgreSQL, SQLite, etc.
6
6
  class RailsAdapter < AbstractAdapter
7
7
  def authenticate_with_http_basic(&block)
8
- controller.authenticate_with_http_basic(&block)
8
+ __getobj__.authenticate_with_http_basic(&block)
9
9
  end
10
10
 
11
11
  def cookies
12
- controller.send(:cookies)
12
+ __getobj__.send(:cookies)
13
13
  end
14
14
 
15
15
  def request_content_type
@@ -41,6 +41,9 @@ module Authlogic
41
41
  # * <tt>login_field_regex_failed_message</tt> - the message to use when the validates_format_of for the login field fails. This depends on if you are
42
42
  # performing :email or :login regex.
43
43
  #
44
+ # * <tt>allow_blank_login_and_password_fields</tt> - default: false,
45
+ # Tells authlogic if it should allow blank values for the login and password. This is useful is you provide alternate authentication methods, such as OpenID.
46
+ #
44
47
  # * <tt>email_field</tt> - default: :email, depending on if it is present, if :email is not present defaults to nil
45
48
  # The name of the field used to store the email address. Only specify this if you arent using this as your :login_field.
46
49
  #
@@ -51,6 +54,9 @@ module Authlogic
51
54
  # This is used in validates_format_of for the :email_field.
52
55
  #
53
56
  # * <tt>email_field_regex_failed_message</tt> - the message to use when the validates_format_of for the email field fails.
57
+ #
58
+ # * <tt>allow_blank_email_field</tt> - default: false,
59
+ # Tells Authlogic if it should allow blank values for the email address.
54
60
  #
55
61
  # * <tt>change_single_access_token_with_password</tt> - default: false,
56
62
  # When a user changes their password do you want the single access token to change as well? That's what this configuration option is all about.
@@ -127,6 +133,7 @@ module Authlogic
127
133
  options[:email_field] = first_column_to_exist(nil, :email) unless options.key?(:email_field)
128
134
  options[:email_field] = nil if options[:email_field] == options[:login_field]
129
135
  options[:validate_email_field] = true unless options.key?(:validate_email_field)
136
+ options[:allow_blank_login_and_password]
130
137
 
131
138
  email_name_regex = '[\w\.%\+\-]+'
132
139
  domain_head_regex = '(?:[A-Z0-9\-]+\.)+'
@@ -140,7 +147,7 @@ module Authlogic
140
147
  options[:login_field_regex_failed_message] ||= options[:email_field_regex_failed_message]
141
148
  else
142
149
  options[:login_field_regex] ||= /\A\w[\w\.\-_@ ]+\z/
143
- options[:login_field_regex_failed_message] ||= "use only letters, numbers, spaces, and .-_@ please."
150
+ options[:login_field_regex_failed_message] ||= "should use only letters, numbers, spaces, and .-_@ please."
144
151
  end
145
152
 
146
153
  options[:password_field] ||= :password
@@ -24,28 +24,28 @@ module Authlogic
24
24
  if options[:validate_login_field]
25
25
  case options[:login_field_type]
26
26
  when :email
27
- validates_length_of options[:login_field], :within => 6..100
28
- validates_format_of options[:login_field], :with => options[:login_field_regex], :message => options[:login_field_regex_failed_message]
27
+ validates_length_of options[:login_field], :within => 6..100, :allow_blank => options[:allow_blank_login_and_password_fields]
28
+ 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]
29
29
  else
30
- validates_length_of options[:login_field], :within => 2..100, :allow_blank => true
31
- validates_format_of options[:login_field], :with => options[:login_field_regex], :message => options[:login_field_regex_failed_message]
30
+ validates_length_of options[:login_field], :within => 2..100, :allow_blank => options[:allow_blank_login_and_password_fields]
31
+ 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]
32
32
  end
33
-
34
- validates_uniqueness_of options[:login_field], :scope => options[:scope]
33
+
34
+ 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?") }
35
35
  end
36
-
36
+
37
37
  if options[:validate_email_field] && options[:email_field]
38
- validates_length_of options[:email_field], :within => 6..100
39
- validates_format_of options[:email_field], :with => options[:email_field_regex], :message => options[:email_field_regex_failed_message]
40
- validates_uniqueness_of options[:email_field], :scope => options[:scope]
38
+ validates_length_of options[:email_field], :within => 6..100, :allow_blank => options[:allow_blank_email_field]
39
+ 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]
40
+ 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?") }
41
41
  end
42
-
42
+
43
43
  validate :validate_password if options[:validate_password_field]
44
44
  end
45
-
45
+
46
46
  attr_writer "confirm_#{options[:password_field]}"
47
47
  attr_accessor "tried_to_set_#{options[:password_field]}"
48
-
48
+
49
49
  class_eval <<-"end_eval", __FILE__, __LINE__
50
50
  def self.friendly_unique_token
51
51
  chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
@@ -53,7 +53,7 @@ module Authlogic
53
53
  1.upto(20) { |i| newpass << chars[rand(chars.size-1)] }
54
54
  newpass
55
55
  end
56
-
56
+
57
57
  def #{options[:password_field]}=(pass)
58
58
  return if pass.blank?
59
59
  self.tried_to_set_#{options[:password_field]} = true
@@ -61,35 +61,37 @@ module Authlogic
61
61
  self.#{options[:password_salt_field]} = self.class.unique_token
62
62
  self.#{options[:crypted_password_field]} = #{options[:crypto_provider]}.encrypt(@#{options[:password_field]} + #{options[:password_salt_field]})
63
63
  end
64
-
64
+
65
65
  def valid_#{options[:password_field]}?(attempted_password)
66
66
  return false if attempted_password.blank? || #{options[:crypted_password_field]}.blank? || #{options[:password_salt_field]}.blank?
67
67
  (#{options[:crypto_provider]}.respond_to?(:decrypt) && #{options[:crypto_provider]}.decrypt(#{options[:crypted_password_field]}) == attempted_password + #{options[:password_salt_field]}) ||
68
68
  (!#{options[:crypto_provider]}.respond_to?(:decrypt) && #{options[:crypto_provider]}.encrypt(attempted_password + #{options[:password_salt_field]}) == #{options[:crypted_password_field]})
69
69
  end
70
-
70
+
71
71
  def #{options[:password_field]}; end
72
72
  def confirm_#{options[:password_field]}; end
73
-
73
+
74
74
  def reset_#{options[:password_field]}
75
75
  friendly_token = self.class.friendly_unique_token
76
76
  self.#{options[:password_field]} = friendly_token
77
77
  self.confirm_#{options[:password_field]} = friendly_token
78
78
  end
79
79
  alias_method :randomize_password, :reset_password
80
-
80
+
81
81
  def reset_#{options[:password_field]}!
82
82
  reset_#{options[:password_field]}
83
83
  save_without_session_maintenance(false)
84
84
  end
85
85
  alias_method :randomize_password!, :reset_password!
86
-
86
+
87
87
  protected
88
88
  def tried_to_set_password?
89
89
  tried_to_set_password == true
90
90
  end
91
-
91
+
92
92
  def validate_password
93
+ return if #{options[:allow_blank_login_and_password_fields].inspect} && @#{options[:password_field]}.blank? && @confirm_#{options[:password_field]}.blank?
94
+
93
95
  if new_record? || tried_to_set_#{options[:password_field]}?
94
96
  if @#{options[:password_field]}.blank?
95
97
  errors.add(:#{options[:password_field]}, #{options[:password_blank_message].inspect})
@@ -24,9 +24,9 @@ module Authlogic
24
24
  return if options[:perishable_token_field].blank?
25
25
 
26
26
  class_eval <<-"end_eval", __FILE__, __LINE__
27
- validates_uniqueness_of :#{options[:perishable_token_field]}
27
+ 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?") }
28
28
 
29
- before_validation :reset_#{options[:perishable_token_field]}, :unless => :resetting_#{options[:perishable_token_field]}?
29
+ before_validation :reset_#{options[:perishable_token_field]}
30
30
 
31
31
  def self.find_using_#{options[:perishable_token_field]}(token, age = #{options[:perishable_token_valid_for]})
32
32
  return if token.blank?
@@ -49,16 +49,8 @@ module Authlogic
49
49
 
50
50
  def reset_#{options[:perishable_token_field]}!
51
51
  reset_#{options[:perishable_token_field]}
52
- @resetting_#{options[:perishable_token_field]} = true
53
- result = save_without_session_maintenance
54
- @resetting_#{options[:perishable_token_field]} = false
55
- result
52
+ save_without_session_maintenance(false)
56
53
  end
57
-
58
- private
59
- def resetting_#{options[:perishable_token_field]}?
60
- @resetting_#{options[:perishable_token_field]} == true
61
- end
62
54
  end_eval
63
55
  end
64
56
  end
@@ -22,7 +22,7 @@ module Authlogic
22
22
  def acts_as_authentic_with_persistence(options = {})
23
23
  acts_as_authentic_without_persistence(options)
24
24
 
25
- validates_uniqueness_of options[:persistence_token_field]
25
+ 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?") }
26
26
 
27
27
  def forget_all!
28
28
  # Paginate these to save on memory
@@ -22,7 +22,7 @@ module Authlogic
22
22
  return if options[:single_access_token_field].blank?
23
23
 
24
24
  class_eval <<-"end_eval", __FILE__, __LINE__
25
- validates_uniqueness_of :#{options[:single_access_token_field]}
25
+ 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?") }
26
26
 
27
27
  before_validation :set_#{options[:single_access_token_field]}_field
28
28
 
@@ -26,9 +26,9 @@ module Authlogic
26
26
  #
27
27
  # session = UserSession.new
28
28
  # session.create
29
- def create(*args)
29
+ def create(*args, &block)
30
30
  session = new(*args)
31
- session.save
31
+ session.save(&block)
32
32
  end
33
33
 
34
34
  # Same as create but calls create!, which raises an exception when authentication fails
@@ -150,9 +150,9 @@ module Authlogic
150
150
  def credentials=(values)
151
151
  return if values.blank? || !values.is_a?(Hash)
152
152
  values.symbolize_keys!
153
- [login_field.to_sym, password_field.to_sym, :remember_me].each do |field|
154
- next if values[field].blank?
155
- send("#{field}=", values[field])
153
+ values.each do |field, value|
154
+ next if value.blank?
155
+ send("#{field}=", value)
156
156
  end
157
157
  end
158
158
 
@@ -272,7 +272,8 @@ module Authlogic
272
272
  # 2. sets session
273
273
  # 3. sets cookie
274
274
  # 4. updates magic fields
275
- def save
275
+ def save(&block)
276
+ result = nil
276
277
  if valid?
277
278
  record.login_count = (record.login_count.blank? ? 1 : record.login_count + 1) if record.respond_to?(:login_count)
278
279
 
@@ -289,8 +290,13 @@ module Authlogic
289
290
  record.save_without_session_maintenance(false)
290
291
 
291
292
  self.new_session = false
292
- self
293
+ result = self
294
+ else
295
+ result = false
293
296
  end
297
+
298
+ yield result if block_given?
299
+ result
294
300
  end
295
301
 
296
302
  # Same as save but raises an exception when authentication fails
@@ -411,6 +417,8 @@ module Authlogic
411
417
  errors.add(password_field, password_invalid_message)
412
418
  return false
413
419
  end
420
+
421
+ self.record = unchecked_record
414
422
  when :unauthorized_record
415
423
  unchecked_record = unauthorized_record
416
424
 
@@ -423,9 +431,10 @@ module Authlogic
423
431
  errors.add_to_base("You can not login with a new record.")
424
432
  return false
425
433
  end
434
+
435
+ self.record = unchecked_record
426
436
  end
427
437
 
428
- self.record = unchecked_record
429
438
  true
430
439
  end
431
440
 
@@ -49,14 +49,14 @@ module Authlogic
49
49
  # after_save
50
50
  # before_update # only if new_session? == false
51
51
  # before_create # only if new_session? == true
52
- def save_with_callbacks
52
+ def save_with_callbacks(&block)
53
53
  run_callbacks(:before_save)
54
54
  if new_session?
55
55
  run_callbacks(:before_create)
56
56
  else
57
57
  run_callbacks(:before_update)
58
58
  end
59
- result = save_without_callbacks
59
+ result = save_without_callbacks(&block)
60
60
  if result
61
61
  run_callbacks(:after_save)
62
62
 
@@ -45,6 +45,19 @@ module Authlogic
45
45
  yield self
46
46
  end
47
47
 
48
+ # This works just like ActiveRecord's attr_accessible, except by default this ONLY allows the login, password, and remember me option.
49
+ #
50
+ # * <tt>Default:</tt> {:login_field}, {:password_field}, :remember_me, set to nil to disable
51
+ # * <tt>Accepts:</tt> String
52
+ def attr_accessible(*values)
53
+ if values.blank?
54
+ read_inheritable_attribute(:attr_accessible) || attr_accessible(login_field, password_field, :remember_me)
55
+ else
56
+ write_inheritable_attribute(:attr_accessible, value)
57
+ end
58
+ end
59
+ alias_method :attr_accessible=, :attr_accessible
60
+
48
61
  # 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.
49
62
  # Also, if a id is set it will be inserted into the beginning of the string. Exmaple:
50
63
  #
@@ -0,0 +1,17 @@
1
+ module Authlogic
2
+ module Session
3
+ # = Session
4
+ #
5
+ # Handles all parts of authentication that deal with sessions. Such as persisting a session and saving / destroy a session.
6
+ module OpenID
7
+ def self.included(klass)
8
+ klass.class_eval do
9
+ attr_accessor :
10
+ alias_method_chain :credentials=, :openid
11
+ end
12
+ end
13
+
14
+ # Tries to validate the session from information in the session
15
+ def credentials_with_openid=(value)
16
+ self.credentials_without_openid
17
+ end
@@ -12,8 +12,19 @@ module Authlogic
12
12
 
13
13
  # Tries to validate the session from information in the session
14
14
  def valid_session?
15
- if session_credentials
16
- self.unauthorized_record = search_for_record("find_by_#{persistence_token_field}", session_credentials)
15
+ persistence_token, record_id = session_credentials
16
+ if !persistence_token.blank?
17
+ if record_id
18
+ record = search_for_record("find_by_id", record_id)
19
+ self.unauthorized_record = record if record && record.send(persistence_token_field) == persistence_token
20
+ else
21
+ # For backwards compatibility, will eventually be removed, just need to let the sessions update theirself
22
+ record = search_for_record("find_by_#{persistence_token_field}", persistence_token)
23
+ if record
24
+ controller.session["#{session_key}_id"] = record.send(record.class.primary_key)
25
+ self.unauthorized_record = record
26
+ end
27
+ end
17
28
  return valid?
18
29
  end
19
30
 
@@ -22,11 +33,12 @@ module Authlogic
22
33
 
23
34
  private
24
35
  def session_credentials
25
- controller.session[session_key]
36
+ [controller.session[session_key], controller.session["#{session_key}_id"]].compact
26
37
  end
27
38
 
28
39
  def update_session!
29
40
  controller.session[session_key] = record && record.send(persistence_token_field)
41
+ controller.session["#{session_key}_id"] = record && record.send(record.class.primary_key)
30
42
  end
31
43
  end
32
44
  end
@@ -44,7 +44,7 @@ module Authlogic # :nodoc:
44
44
 
45
45
  MAJOR = 1
46
46
  MINOR = 2
47
- TINY = 1
47
+ TINY = 2
48
48
 
49
49
  # The current version as a Version instance
50
50
  CURRENT = new(MAJOR, MINOR, TINY)
@@ -16,7 +16,7 @@ module ORMAdaptersTests
16
16
  :single_access_token_field => :single_access_token,
17
17
  :login_field_regex => /\A\w[\w\.\-_@ ]+\z/,
18
18
  :session_ids => [nil],
19
- :login_field_regex_failed_message => "use only letters, numbers, spaces, and .-_@ please.",
19
+ :login_field_regex_failed_message => "should use only letters, numbers, spaces, and .-_@ please.",
20
20
  :persistence_token_field => :persistence_token,
21
21
  :password_field => :password,
22
22
  :logged_in_timeout => 600,
@@ -55,10 +55,10 @@ module SessionTests
55
55
 
56
56
  assert UserSession.find
57
57
  last_request_at = ben.reload.last_request_at
58
- sleep(1.1)
58
+ sleep(0.5)
59
59
  assert UserSession.find
60
60
  assert_equal last_request_at, ben.reload.last_request_at
61
- sleep(1.1)
61
+ sleep(2)
62
62
  assert UserSession.find
63
63
  assert_not_equal last_request_at, ben.reload.last_request_at
64
64
 
@@ -212,7 +212,7 @@ module SessionTests
212
212
  assert session.new_session?
213
213
  end
214
214
 
215
- def test_save_with_record
215
+ def test_save_with_credentials
216
216
  ben = users(:ben)
217
217
  session = UserSession.new(:login => ben.login, :password => "benrocks")
218
218
  assert session.save
@@ -220,11 +220,9 @@ module SessionTests
220
220
  assert_equal 1, session.record.login_count
221
221
  assert Time.now >= session.record.current_login_at
222
222
  assert_equal "1.1.1.1", session.record.current_login_ip
223
- unset_cookie
224
- unset_session
225
223
  end
226
224
 
227
- def test_save_with_credentials
225
+ def test_save_with_record
228
226
  ben = users(:ben)
229
227
  session = UserSession.new(ben)
230
228
  assert session.save
@@ -234,6 +232,19 @@ module SessionTests
234
232
  assert_equal "1.1.1.1", session.record.current_login_ip
235
233
  end
236
234
 
235
+ def test_save_with_block
236
+ ben = users(:ben)
237
+ session = UserSession.new(:login => ben.login, :password => "benrocks")
238
+ block_result = session.save do |result|
239
+ assert result
240
+ end
241
+ assert_equal session, block_result
242
+ assert !session.new_session?
243
+ assert_equal 1, session.record.login_count
244
+ assert Time.now >= session.record.current_login_at
245
+ assert_equal "1.1.1.1", session.record.current_login_ip
246
+ end
247
+
237
248
  def test_save_with_bang
238
249
  session = UserSession.new
239
250
  assert_raise(Authlogic::Session::SessionInvalid) { session.save! }
data/test/test_helper.rb CHANGED
@@ -157,9 +157,10 @@ class Test::Unit::TestCase
157
157
 
158
158
  def set_session_for(user, id = nil)
159
159
  @controller.session["user_credentials"] = user.persistence_token
160
+ @controller.session["user_credentials_id"] = user.id
160
161
  end
161
162
 
162
163
  def unset_session
163
- @controller.session["user_credentials"] = nil
164
+ @controller.session["user_credentials"] = @controller.session["user_credentials_id"] = nil
164
165
  end
165
166
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authlogic
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Johnson of Binary Logic
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-11-19 00:00:00 -05:00
12
+ date: 2008-11-20 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -61,6 +61,7 @@ extra_rdoc_files:
61
61
  - lib/authlogic/session/config.rb
62
62
  - lib/authlogic/session/cookies.rb
63
63
  - lib/authlogic/session/errors.rb
64
+ - lib/authlogic/session/openid.rb
64
65
  - lib/authlogic/session/params.rb
65
66
  - lib/authlogic/session/perishability.rb
66
67
  - lib/authlogic/session/scopes.rb
@@ -92,6 +93,7 @@ files:
92
93
  - lib/authlogic/session/config.rb
93
94
  - lib/authlogic/session/cookies.rb
94
95
  - lib/authlogic/session/errors.rb
96
+ - lib/authlogic/session/openid.rb
95
97
  - lib/authlogic/session/params.rb
96
98
  - lib/authlogic/session/perishability.rb
97
99
  - lib/authlogic/session/scopes.rb