authlogic 1.1.0 → 1.1.1
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 +11 -2
- data/Manifest +9 -3
- data/README.rdoc +32 -7
- data/Rakefile +1 -1
- data/authlogic.gemspec +4 -7
- data/lib/authlogic.rb +2 -4
- data/lib/authlogic/controller_adapters/abstract_adapter.rb +4 -0
- data/lib/authlogic/controller_adapters/rails_adapter.rb +4 -0
- data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic.rb +2 -76
- data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/config.rb +132 -0
- data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/credentials.rb +77 -116
- data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/logged_in.rb +35 -24
- data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/persistence.rb +51 -44
- data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/session_maintenance.rb +64 -54
- data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/single_access.rb +61 -0
- data/lib/authlogic/session/base.rb +20 -9
- data/lib/authlogic/session/config.rb +54 -63
- data/lib/authlogic/session/cookies.rb +2 -2
- data/lib/authlogic/session/params.rb +9 -6
- data/lib/authlogic/session/session.rb +3 -3
- data/lib/authlogic/version.rb +1 -1
- data/shoulda_macros/authlogic.rb +13 -0
- data/test/fixtures/employees.yml +2 -2
- data/test/fixtures/users.yml +2 -0
- data/test/libs/mock_controller.rb +5 -0
- data/test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/config_test.rb +36 -0
- data/test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/credentials_test.rb +129 -0
- data/test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/logged_in_test.rb +24 -0
- data/test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/persistence_test.rb +45 -0
- data/test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/session_maintenance_test.rb +62 -0
- data/test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_tests/single_access_test.rb +41 -0
- data/test/session_tests/base_test.rb +15 -0
- data/test/session_tests/config_test.rb +31 -14
- data/test/session_tests/params_test.rb +17 -1
- data/test/test_helper.rb +10 -2
- metadata +18 -17
- data/lib/authlogic/session/openid.rb +0 -106
- data/lib/authlogic/testing/shoulda_macros.rb +0 -17
- data/test/orm_adapters_tests/active_record_adapter_tests/acts_as_authentic_test.rb +0 -217
@@ -1,135 +1,96 @@
|
|
1
1
|
module Authlogic
|
2
2
|
module ORMAdapters
|
3
3
|
module ActiveRecordAdapter
|
4
|
-
module
|
5
|
-
|
6
|
-
|
4
|
+
module ActsAsAuthentic
|
5
|
+
# = Credentials
|
6
|
+
#
|
7
|
+
# Handles any credential specific code, such as validating the login, encrpyting the password, etc.
|
8
|
+
#
|
9
|
+
# === Class Methods
|
10
|
+
#
|
11
|
+
# * <tt>friendly_unique_token</tt> - returns a random string of 20 alphanumeric characters. Used when resetting the password. This is a more user friendly token then a long Sha512 hash.
|
12
|
+
#
|
13
|
+
# === Instance Methods
|
14
|
+
#
|
15
|
+
# * <tt>{options[:password_field]}=(value)</tt> - encrypts a raw password and sets it to your crypted_password_field. Also sets the password_salt to a random token.
|
16
|
+
# * <tt>valid_{options[:password_field]}?(password_to_check)</tt> - checks is the password is valid. The password passed can be the raw password or the encrypted password.
|
17
|
+
# * <tt>reset_{options[:password_field]}</tt> - resets the password using the friendly_unique_token class method
|
18
|
+
# * <tt>reset_{options[:password_field]}!</tt> - calls reset_password and then saves the record
|
19
|
+
module Credentials
|
20
|
+
def acts_as_authentic_with_credentials(options = {})
|
21
|
+
acts_as_authentic_without_credentials(options)
|
7
22
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
:
|
23
|
+
# Validations
|
24
|
+
case options[:login_field_type]
|
25
|
+
when :email
|
26
|
+
validates_length_of options[:login_field], :within => 6..100
|
27
|
+
validates_format_of options[:login_field], :with => options[:login_field_regex], :message => options[:login_field_regex_failed_message]
|
28
|
+
else
|
29
|
+
validates_length_of options[:login_field], :within => 2..100, :allow_blank => true
|
30
|
+
validates_format_of options[:login_field], :with => options[:login_field_regex], :message => options[:login_field_regex_failed_message]
|
16
31
|
end
|
17
|
-
|
18
|
-
def self.password_field
|
19
|
-
@password_field ||= #{options[:password_field].inspect} ||
|
20
|
-
(column_names.include?("password") && :password) ||
|
21
|
-
(column_names.include?("pass") && :pass) ||
|
22
|
-
:password
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.crypted_password_field
|
26
|
-
@crypted_password_field ||= #{options[:crypted_password_field].inspect} ||
|
27
|
-
(column_names.include?("crypted_password") && :crypted_password) ||
|
28
|
-
(column_names.include?("encrypted_password") && :encrypted_password) ||
|
29
|
-
(column_names.include?("password_hash") && :password_hash) ||
|
30
|
-
(column_names.include?("pw_hash") && :pw_hash) ||
|
31
|
-
:crypted_password
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.password_salt_field
|
35
|
-
@password_salt_field ||= #{options[:password_salt_field].inspect} ||
|
36
|
-
(column_names.include?("password_salt") && :password_salt) ||
|
37
|
-
(column_names.include?("pw_salt") && :pw_salt) ||
|
38
|
-
(column_names.include?("salt") && :salt) ||
|
39
|
-
:password_salt
|
40
|
-
end
|
41
|
-
end_eval
|
42
|
-
|
43
|
-
# The following methods allow other focused modules to alter validation behavior, such as openid as an alternate login
|
44
|
-
unless respond_to?(:allow_blank_for_login_validations?)
|
45
|
-
def self.allow_blank_for_login_validations?
|
46
|
-
false
|
47
|
-
end
|
48
|
-
end
|
49
32
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
# Validations
|
54
|
-
case options[:login_field_type]
|
55
|
-
when :email
|
56
|
-
validates_length_of login_field, :within => 6..100
|
57
|
-
email_name_regex = '[\w\.%\+\-]+'
|
58
|
-
domain_head_regex = '(?:[A-Z0-9\-]+\.)+'
|
59
|
-
domain_tld_regex = '(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|jobs|museum)'
|
60
|
-
options[:login_field_regex] ||= /\A#{email_name_regex}@#{domain_head_regex}#{domain_tld_regex}\z/i
|
61
|
-
options[:login_field_regex_message] ||= "should look like an email address."
|
62
|
-
validates_format_of login_field, :with => options[:login_field_regex], :message => options[:login_field_regex_message]
|
63
|
-
else
|
64
|
-
validates_length_of login_field, :within => 2..100, :allow_blank => true
|
65
|
-
options[:login_field_regex] ||= /\A\w[\w\.\-_@ ]+\z/
|
66
|
-
options[:login_field_regex_message] ||= "use only letters, numbers, spaces, and .-_@ please."
|
67
|
-
validates_format_of login_field, :with => options[:login_field_regex], :message => options[:login_field_regex_message]
|
68
|
-
end
|
33
|
+
validates_uniqueness_of options[:login_field], :scope => options[:scope]
|
34
|
+
validate :validate_password
|
69
35
|
|
70
|
-
|
71
|
-
|
36
|
+
attr_writer "confirm_#{options[:password_field]}"
|
37
|
+
attr_accessor "tried_to_set_#{options[:password_field]}"
|
72
38
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
def crypto_provider
|
82
|
-
self.class.crypto_provider
|
83
|
-
end
|
84
|
-
|
85
|
-
def #{password_field}=(pass)
|
86
|
-
return if pass.blank?
|
87
|
-
self.tried_to_set_#{password_field} = true
|
88
|
-
@#{password_field} = pass
|
89
|
-
self.#{password_salt_field} = self.class.unique_token
|
90
|
-
self.#{crypted_password_field} = crypto_provider.encrypt(@#{password_field} + #{password_salt_field})
|
91
|
-
end
|
39
|
+
class_eval <<-"end_eval", __FILE__, __LINE__
|
40
|
+
def self.friendly_unique_token
|
41
|
+
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
|
42
|
+
newpass = ""
|
43
|
+
1.upto(20) { |i| newpass << chars[rand(chars.size-1)] }
|
44
|
+
newpass
|
45
|
+
end
|
92
46
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
47
|
+
def #{options[:password_field]}=(pass)
|
48
|
+
return if pass.blank?
|
49
|
+
self.tried_to_set_#{options[:password_field]} = true
|
50
|
+
@#{options[:password_field]} = pass
|
51
|
+
self.#{options[:password_salt_field]} = self.class.unique_token
|
52
|
+
self.#{options[:crypted_password_field]} = #{options[:crypto_provider]}.encrypt(@#{options[:password_field]} + #{options[:password_salt_field]})
|
53
|
+
end
|
99
54
|
|
100
|
-
|
101
|
-
|
55
|
+
def valid_#{options[:password_field]}?(attempted_password)
|
56
|
+
return false if attempted_password.blank? || #{options[:crypted_password_field]}.blank? || #{options[:password_salt_field]}.blank?
|
57
|
+
attempted_password == #{options[:crypted_password_field]} ||
|
58
|
+
(#{options[:crypto_provider]}.respond_to?(:decrypt) && #{options[:crypto_provider]}.decrypt(#{options[:crypted_password_field]}) == attempted_password + #{options[:password_salt_field]}) ||
|
59
|
+
(!#{options[:crypto_provider]}.respond_to?(:decrypt) && #{options[:crypto_provider]}.encrypt(attempted_password + #{options[:password_salt_field]}) == #{options[:crypted_password_field]})
|
60
|
+
end
|
102
61
|
|
103
|
-
|
104
|
-
|
105
|
-
newpass = ""
|
106
|
-
1.upto(10) { |i| newpass << chars[rand(chars.size-1)] }
|
107
|
-
self.#{password_field} = newpass
|
108
|
-
self.confirm_#{password_field} = newpass
|
109
|
-
end
|
110
|
-
alias_method :randomize_password, :reset_password
|
62
|
+
def #{options[:password_field]}; end
|
63
|
+
def confirm_#{options[:password_field]}; end
|
111
64
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
65
|
+
def reset_#{options[:password_field]}
|
66
|
+
friendly_token = self.class.friendly_unique_token
|
67
|
+
self.#{options[:password_field]} = friendly_token
|
68
|
+
self.confirm_#{options[:password_field]} = friendly_token
|
69
|
+
end
|
70
|
+
alias_method :randomize_password, :reset_password
|
117
71
|
|
118
|
-
|
119
|
-
|
120
|
-
|
72
|
+
def reset_#{options[:password_field]}!
|
73
|
+
reset_#{options[:password_field]}
|
74
|
+
save_without_session_maintenance(false)
|
121
75
|
end
|
76
|
+
alias_method :randomize_password!, :reset_password!
|
77
|
+
|
78
|
+
protected
|
79
|
+
def tried_to_set_password?
|
80
|
+
tried_to_set_password == true
|
81
|
+
end
|
122
82
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
83
|
+
def validate_password
|
84
|
+
if new_record? || tried_to_set_#{options[:password_field]}?
|
85
|
+
if @#{options[:password_field]}.blank?
|
86
|
+
errors.add(:#{options[:password_field]}, #{options[:password_blank_message].inspect})
|
87
|
+
else
|
88
|
+
errors.add(:confirm_#{options[:password_field]}, #{options[:confirm_password_did_not_match_message].inspect}) if @confirm_#{options[:password_field]} != @#{options[:password_field]}
|
89
|
+
end
|
129
90
|
end
|
130
91
|
end
|
131
|
-
|
132
|
-
|
92
|
+
end_eval
|
93
|
+
end
|
133
94
|
end
|
134
95
|
end
|
135
96
|
end
|
@@ -138,7 +99,7 @@ end
|
|
138
99
|
|
139
100
|
ActiveRecord::Base.class_eval do
|
140
101
|
class << self
|
141
|
-
include Authlogic::ORMAdapters::ActiveRecordAdapter::Credentials
|
102
|
+
include Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::Credentials
|
142
103
|
alias_method_chain :acts_as_authentic, :credentials
|
143
104
|
end
|
144
105
|
end
|
@@ -1,31 +1,42 @@
|
|
1
1
|
module Authlogic
|
2
2
|
module ORMAdapters
|
3
3
|
module ActiveRecordAdapter
|
4
|
-
module
|
5
|
-
|
6
|
-
|
4
|
+
module ActsAsAuthentic
|
5
|
+
# = Logged In
|
6
|
+
#
|
7
|
+
# Handles all logic determining if a record is logged in or not. This uses the "last_request_at" field, if this field is not present none of this will be available.
|
8
|
+
#
|
9
|
+
# === Named Scopes
|
10
|
+
#
|
11
|
+
# * <tt>logged_in</tt> - returns all records that have a last_request_at value that is > your :logged_in_timeout.ago
|
12
|
+
# * <tt>logged_out</tt> - same as logged in but returns users that are logged out, be careful with using this, this can return a lot of users
|
13
|
+
#
|
14
|
+
# === Instance Methods
|
15
|
+
#
|
16
|
+
# * <tt>logged_in?</tt> - same as the logged_in named scope, but returns true if the record is logged in
|
17
|
+
# * <tt>logged_out?</tt> - opposite of logged_in?
|
18
|
+
module LoggedIn
|
19
|
+
def acts_as_authentic_with_logged_in(options = {})
|
20
|
+
acts_as_authentic_without_logged_in(options)
|
7
21
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
22
|
+
validates_numericality_of :login_count, :only_integer => :true, :greater_than_or_equal_to => 0, :allow_nil => true if column_names.include?("login_count")
|
23
|
+
|
24
|
+
if column_names.include?("last_request_at")
|
25
|
+
named_scope :logged_in, lambda { {:conditions => ["last_request_at > ?", options[:logged_in_timeout].ago]} }
|
26
|
+
named_scope :logged_out, lambda { {:conditions => ["last_request_at is NULL or last_request_at <= ?", options[:logged_in_timeout].ago]} }
|
27
|
+
end
|
28
|
+
|
29
|
+
if column_names.include?("last_request_at")
|
30
|
+
class_eval <<-"end_eval", __FILE__, __LINE__
|
31
|
+
def logged_in?
|
32
|
+
!last_request_at.nil? && last_request_at > #{options[:logged_in_timeout]}.seconds.ago
|
33
|
+
end
|
34
|
+
|
35
|
+
def logged_out?
|
36
|
+
!logged_in?
|
37
|
+
end
|
38
|
+
end_eval
|
20
39
|
end
|
21
|
-
end_eval
|
22
|
-
|
23
|
-
if column_names.include?("last_request_at")
|
24
|
-
class_eval <<-"end_eval", __FILE__, __LINE__
|
25
|
-
def logged_in?
|
26
|
-
!last_request_at.nil? && last_request_at > self.class.logged_in_timeout.ago
|
27
|
-
end
|
28
|
-
end_eval
|
29
40
|
end
|
30
41
|
end
|
31
42
|
end
|
@@ -35,7 +46,7 @@ end
|
|
35
46
|
|
36
47
|
ActiveRecord::Base.class_eval do
|
37
48
|
class << self
|
38
|
-
include Authlogic::ORMAdapters::ActiveRecordAdapter::LoggedIn
|
49
|
+
include Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::LoggedIn
|
39
50
|
alias_method_chain :acts_as_authentic, :logged_in
|
40
51
|
end
|
41
52
|
end
|
@@ -1,53 +1,60 @@
|
|
1
1
|
module Authlogic
|
2
2
|
module ORMAdapters
|
3
3
|
module ActiveRecordAdapter
|
4
|
-
module
|
5
|
-
|
6
|
-
|
4
|
+
module ActsAsAuthentic
|
5
|
+
# = Persistence
|
6
|
+
#
|
7
|
+
# This is responsible for all record persistence. Basically what your Authlogic session needs to persist the record's session.
|
8
|
+
#
|
9
|
+
# === Class Methods
|
10
|
+
#
|
11
|
+
# * <tt>forget_all!</tt> - resets ALL records remember_token to a unique value, requiring all users to re-login
|
12
|
+
# * <tt>unique_token</tt> - returns a pretty hardcore random token that is finally encrypted with a hash algorithm
|
13
|
+
#
|
14
|
+
# === Instance Methods
|
15
|
+
#
|
16
|
+
# * <tt>forget!</tt> - resets the record's remember_token which requires them to re-login
|
17
|
+
#
|
18
|
+
# === Alias Method Chains
|
19
|
+
#
|
20
|
+
# * <tt>#{options[:password_field]}</tt> - adds in functionality to reset the remember token when the password is changed
|
21
|
+
module Persistence
|
22
|
+
def acts_as_authentic_with_persistence(options = {})
|
23
|
+
acts_as_authentic_without_persistence(options)
|
7
24
|
|
8
|
-
|
9
|
-
def self.remember_token_field
|
10
|
-
@remember_token_field ||= #{options[:remember_token_field].inspect} ||
|
11
|
-
(column_names.include?("remember_token") && :remember_token) ||
|
12
|
-
(column_names.include?("remember_key") && :remember_key) ||
|
13
|
-
(column_names.include?("cookie_token") && :cookie_token) ||
|
14
|
-
(column_names.include?("cookie_key") && :cookie_key) ||
|
15
|
-
:remember_token
|
16
|
-
end
|
17
|
-
end_eval
|
18
|
-
|
19
|
-
validates_uniqueness_of remember_token_field
|
20
|
-
|
21
|
-
def unique_token
|
22
|
-
# The remember token should be a unique string that is not reversible, which is what a hash is all about
|
23
|
-
# if you using encryption this defaults to Sha512.
|
24
|
-
token_class = crypto_provider.respond_to?(:decrypt) ? Authlogic::CryptoProviders::Sha512 : crypto_provider
|
25
|
-
token_class.encrypt(Time.now.to_s + (1..10).collect{ rand.to_s }.join)
|
26
|
-
end
|
27
|
-
|
28
|
-
def forget_all!
|
29
|
-
# Paginate these to save on memory
|
30
|
-
records = nil
|
31
|
-
i = 0
|
32
|
-
begin
|
33
|
-
records = find(:all, :limit => 50, :offset => i)
|
34
|
-
records.each { |record| record.forget! }
|
35
|
-
i += 50
|
36
|
-
end while !records.blank?
|
37
|
-
end
|
25
|
+
validates_uniqueness_of options[:remember_token_field]
|
38
26
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
27
|
+
def forget_all!
|
28
|
+
# Paginate these to save on memory
|
29
|
+
records = nil
|
30
|
+
i = 0
|
31
|
+
begin
|
32
|
+
records = find(:all, :limit => 50, :offset => i)
|
33
|
+
records.each { |record| record.forget! }
|
34
|
+
i += 50
|
35
|
+
end while !records.blank?
|
43
36
|
end
|
37
|
+
|
38
|
+
class_eval <<-"end_eval", __FILE__, __LINE__
|
39
|
+
def self.unique_token
|
40
|
+
# The remember token should be a unique string that is not reversible, which is what a hash is all about
|
41
|
+
# if you using encryption this defaults to Sha512.
|
42
|
+
token_class = #{options[:crypto_provider].respond_to?(:decrypt) ? Authlogic::CryptoProviders::Sha512 : options[:crypto_provider]}
|
43
|
+
token_class.encrypt(Time.now.to_s + (1..10).collect{ rand.to_s }.join)
|
44
|
+
end
|
44
45
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
46
|
+
def forget!
|
47
|
+
self.#{options[:remember_token_field]} = self.class.unique_token
|
48
|
+
save_without_session_maintenance(false)
|
49
|
+
end
|
50
|
+
|
51
|
+
def #{options[:password_field]}_with_persistence=(value)
|
52
|
+
self.#{options[:remember_token_field]} = self.class.unique_token
|
53
|
+
self.#{options[:password_field]}_without_persistence = value
|
54
|
+
end
|
55
|
+
alias_method_chain :#{options[:password_field]}=, :persistence
|
56
|
+
end_eval
|
57
|
+
end
|
51
58
|
end
|
52
59
|
end
|
53
60
|
end
|
@@ -56,7 +63,7 @@ end
|
|
56
63
|
|
57
64
|
ActiveRecord::Base.class_eval do
|
58
65
|
class << self
|
59
|
-
include Authlogic::ORMAdapters::ActiveRecordAdapter::Persistence
|
66
|
+
include Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::Persistence
|
60
67
|
alias_method_chain :acts_as_authentic, :persistence
|
61
68
|
end
|
62
69
|
end
|
data/lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/session_maintenance.rb
CHANGED
@@ -1,74 +1,84 @@
|
|
1
1
|
module Authlogic
|
2
2
|
module ORMAdapters
|
3
3
|
module ActiveRecordAdapter
|
4
|
-
module
|
5
|
-
|
6
|
-
|
4
|
+
module ActsAsAuthentic
|
5
|
+
# = Session Maintenance
|
6
|
+
#
|
7
|
+
# Responsible for maintaining the related session as the record changes. Here is what it does:
|
8
|
+
#
|
9
|
+
# 1. If the user is logged out and creates a new record, they will be logged in as that record
|
10
|
+
# 2. If the user is logged out and changes a record's password, they will be logged in as that record
|
11
|
+
# 3. If a user is logged in and changes his own password, their session will be updated accordingly. This can be done *anywhere*: the my account section, admin area, etc.
|
12
|
+
#
|
13
|
+
# === Instance Methods
|
14
|
+
#
|
15
|
+
# * <tt>save_without_session_maintenance</tt> - allows you to save the record and skip all of the session maintenance completely
|
16
|
+
module SessionMaintenance
|
17
|
+
def acts_as_authentic_with_session_maintenance(options = {})
|
18
|
+
acts_as_authentic_without_session_maintenance(options)
|
7
19
|
|
8
|
-
|
9
|
-
|
20
|
+
before_save :get_session_information, :if => :update_sessions?
|
21
|
+
after_save :maintain_sessions!, :if => :update_sessions?
|
10
22
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
result = save(*args)
|
18
|
-
@skip_session_maintenance = false
|
19
|
-
result
|
20
|
-
end
|
21
|
-
|
22
|
-
protected
|
23
|
-
def update_sessions?
|
24
|
-
!@skip_session_maintenance && #{options[:session_class]}.activated? && !#{options[:session_ids].inspect}.blank? && #{remember_token_field}_changed?
|
23
|
+
class_eval <<-"end_eval", __FILE__, __LINE__
|
24
|
+
def save_without_session_maintenance(*args)
|
25
|
+
@skip_session_maintenance = true
|
26
|
+
result = save(*args)
|
27
|
+
@skip_session_maintenance = false
|
28
|
+
result
|
25
29
|
end
|
26
30
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
+
protected
|
32
|
+
def update_sessions?
|
33
|
+
!@skip_session_maintenance && #{options[:session_class]}.activated? && !#{options[:session_ids].inspect}.blank? && #{options[:remember_token_field]}_changed?
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_session_information
|
37
|
+
# Need to determine if we are completely logged out, or logged in as another user
|
38
|
+
@_sessions = []
|
39
|
+
@_logged_out = true
|
31
40
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
41
|
+
#{options[:session_ids].inspect}.each do |session_id|
|
42
|
+
session = #{options[:session_class]}.find(*[session_id].compact)
|
43
|
+
if session
|
44
|
+
if !session.record.blank?
|
45
|
+
@_logged_out = false
|
46
|
+
@_sessions << session if session.record == self
|
47
|
+
end
|
38
48
|
end
|
39
49
|
end
|
40
50
|
end
|
41
|
-
end
|
42
51
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
52
|
+
def maintain_sessions!
|
53
|
+
if @_logged_out
|
54
|
+
create_session!
|
55
|
+
elsif !@_sessions.blank?
|
56
|
+
update_sessions!
|
57
|
+
end
|
48
58
|
end
|
49
|
-
end
|
50
59
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
60
|
+
def create_session!
|
61
|
+
# We only want to automatically login into the first session, since this is the main session. The other sessions are sessions
|
62
|
+
# that need to be created after logging into the main session.
|
63
|
+
session_id = #{options[:session_ids].inspect}.first
|
55
64
|
|
56
|
-
|
57
|
-
|
65
|
+
# If we are already logged in, ignore this completely. All that we care about is updating ourself.
|
66
|
+
next if #{options[:session_class]}.find(*[session_id].compact)
|
58
67
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
68
|
+
# Log me in
|
69
|
+
args = [self, session_id].compact
|
70
|
+
#{options[:session_class]}.create(*args)
|
71
|
+
end
|
63
72
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
73
|
+
def update_sessions!
|
74
|
+
# We found sessions above, let's update them with the new info
|
75
|
+
@_sessions.each do |stale_session|
|
76
|
+
stale_session.unauthorized_record = self
|
77
|
+
stale_session.save
|
78
|
+
end
|
69
79
|
end
|
70
|
-
|
71
|
-
|
80
|
+
end_eval
|
81
|
+
end
|
72
82
|
end
|
73
83
|
end
|
74
84
|
end
|
@@ -77,7 +87,7 @@ end
|
|
77
87
|
|
78
88
|
ActiveRecord::Base.class_eval do
|
79
89
|
class << self
|
80
|
-
include Authlogic::ORMAdapters::ActiveRecordAdapter::SessionMaintenance
|
90
|
+
include Authlogic::ORMAdapters::ActiveRecordAdapter::ActsAsAuthentic::SessionMaintenance
|
81
91
|
alias_method_chain :acts_as_authentic, :session_maintenance
|
82
92
|
end
|
83
93
|
end
|