authlogic 3.4.6 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +33 -0
  4. data/.rubocop_todo.yml +427 -0
  5. data/.travis.yml +24 -3
  6. data/CHANGELOG.md +9 -2
  7. data/CONTRIBUTING.md +40 -1
  8. data/Gemfile +1 -1
  9. data/README.md +295 -0
  10. data/Rakefile +10 -2
  11. data/authlogic.gemspec +6 -5
  12. data/lib/authlogic.rb +2 -2
  13. data/lib/authlogic/acts_as_authentic/base.rb +2 -2
  14. data/lib/authlogic/acts_as_authentic/email.rb +59 -14
  15. data/lib/authlogic/acts_as_authentic/logged_in_status.rb +4 -3
  16. data/lib/authlogic/acts_as_authentic/login.rb +62 -12
  17. data/lib/authlogic/acts_as_authentic/magic_columns.rb +17 -6
  18. data/lib/authlogic/acts_as_authentic/password.rb +107 -53
  19. data/lib/authlogic/acts_as_authentic/persistence_token.rb +10 -9
  20. data/lib/authlogic/acts_as_authentic/restful_authentication.rb +2 -0
  21. data/lib/authlogic/acts_as_authentic/session_maintenance.rb +48 -35
  22. data/lib/authlogic/acts_as_authentic/single_access_token.rb +19 -15
  23. data/lib/authlogic/acts_as_authentic/validations_scope.rb +2 -2
  24. data/lib/authlogic/authenticates_many/association.rb +6 -5
  25. data/lib/authlogic/authenticates_many/base.rb +22 -12
  26. data/lib/authlogic/config.rb +2 -1
  27. data/lib/authlogic/controller_adapters/abstract_adapter.rb +2 -1
  28. data/lib/authlogic/controller_adapters/rack_adapter.rb +3 -4
  29. data/lib/authlogic/controller_adapters/rails_adapter.rb +26 -14
  30. data/lib/authlogic/controller_adapters/sinatra_adapter.rb +1 -1
  31. data/lib/authlogic/crypto_providers/aes256.rb +16 -12
  32. data/lib/authlogic/crypto_providers/bcrypt.rb +10 -4
  33. data/lib/authlogic/crypto_providers/md5.rb +7 -7
  34. data/lib/authlogic/crypto_providers/scrypt.rb +10 -2
  35. data/lib/authlogic/crypto_providers/sha1.rb +3 -3
  36. data/lib/authlogic/crypto_providers/sha256.rb +3 -3
  37. data/lib/authlogic/crypto_providers/sha512.rb +4 -4
  38. data/lib/authlogic/crypto_providers/wordpress.rb +13 -13
  39. data/lib/authlogic/i18n.rb +22 -16
  40. data/lib/authlogic/i18n/translator.rb +1 -1
  41. data/lib/authlogic/random.rb +13 -12
  42. data/lib/authlogic/regex.rb +3 -3
  43. data/lib/authlogic/session/activation.rb +7 -6
  44. data/lib/authlogic/session/active_record_trickery.rb +1 -2
  45. data/lib/authlogic/session/base.rb +7 -6
  46. data/lib/authlogic/session/brute_force_protection.rb +58 -34
  47. data/lib/authlogic/session/callbacks.rb +16 -12
  48. data/lib/authlogic/session/cookies.rb +29 -14
  49. data/lib/authlogic/session/existence.rb +10 -10
  50. data/lib/authlogic/session/foundation.rb +11 -7
  51. data/lib/authlogic/session/http_auth.rb +6 -5
  52. data/lib/authlogic/session/id.rb +5 -4
  53. data/lib/authlogic/session/klass.rb +2 -1
  54. data/lib/authlogic/session/magic_columns.rb +21 -14
  55. data/lib/authlogic/session/magic_states.rb +25 -14
  56. data/lib/authlogic/session/params.rb +41 -26
  57. data/lib/authlogic/session/password.rb +62 -40
  58. data/lib/authlogic/session/perishable_token.rb +3 -2
  59. data/lib/authlogic/session/persistence.rb +3 -3
  60. data/lib/authlogic/session/priority_record.rb +5 -4
  61. data/lib/authlogic/session/scopes.rb +20 -9
  62. data/lib/authlogic/session/session.rb +9 -4
  63. data/lib/authlogic/session/timeout.rb +40 -23
  64. data/lib/authlogic/session/unauthorized_record.rb +6 -5
  65. data/lib/authlogic/session/validation.rb +18 -9
  66. data/lib/authlogic/test_case.rb +2 -2
  67. data/lib/authlogic/test_case/mock_controller.rb +9 -9
  68. data/lib/authlogic/test_case/mock_cookie_jar.rb +2 -2
  69. data/lib/authlogic/test_case/mock_logger.rb +1 -1
  70. data/lib/authlogic/test_case/mock_request.rb +2 -1
  71. data/lib/authlogic/test_case/rails_request_adapter.rb +5 -5
  72. data/test/acts_as_authentic_test/email_test.rb +29 -17
  73. data/test/acts_as_authentic_test/logged_in_status_test.rb +9 -3
  74. data/test/acts_as_authentic_test/login_test.rb +47 -13
  75. data/test/acts_as_authentic_test/magic_columns_test.rb +4 -4
  76. data/test/acts_as_authentic_test/password_test.rb +31 -21
  77. data/test/acts_as_authentic_test/perishable_token_test.rb +15 -15
  78. data/test/acts_as_authentic_test/session_maintenance_test.rb +20 -13
  79. data/test/acts_as_authentic_test/single_access_test.rb +8 -8
  80. data/test/authenticates_many_test.rb +4 -4
  81. data/test/crypto_provider_test/aes256_test.rb +2 -2
  82. data/test/crypto_provider_test/scrypt_test.rb +1 -1
  83. data/test/crypto_provider_test/sha1_test.rb +3 -3
  84. data/test/crypto_provider_test/sha256_test.rb +1 -1
  85. data/test/crypto_provider_test/sha512_test.rb +2 -2
  86. data/test/gemfiles/Gemfile.rails-3.2.x +2 -2
  87. data/test/gemfiles/Gemfile.rails-5.0.x +6 -0
  88. data/test/i18n_test.rb +5 -5
  89. data/test/libs/affiliate.rb +2 -2
  90. data/test/libs/company.rb +1 -1
  91. data/test/libs/employee.rb +2 -2
  92. data/test/libs/employee_session.rb +1 -1
  93. data/test/libs/ldaper.rb +1 -1
  94. data/test/libs/project.rb +1 -1
  95. data/test/random_test.rb +5 -4
  96. data/test/session_test/activation_test.rb +5 -5
  97. data/test/session_test/active_record_trickery_test.rb +7 -5
  98. data/test/session_test/cookies_test.rb +8 -6
  99. data/test/session_test/existence_test.rb +19 -13
  100. data/test/session_test/http_auth_test.rb +0 -3
  101. data/test/session_test/id_test.rb +2 -2
  102. data/test/session_test/klass_test.rb +1 -1
  103. data/test/session_test/magic_columns_test.rb +0 -3
  104. data/test/session_test/magic_states_test.rb +11 -11
  105. data/test/session_test/params_test.rb +10 -10
  106. data/test/session_test/password_test.rb +4 -5
  107. data/test/session_test/perishability_test.rb +3 -3
  108. data/test/session_test/scopes_test.rb +8 -8
  109. data/test/session_test/session_test.rb +5 -4
  110. data/test/session_test/timeout_test.rb +8 -8
  111. data/test/session_test/unauthorized_record_test.rb +2 -2
  112. data/test/session_test/validation_test.rb +3 -3
  113. data/test/test_helper.rb +9 -5
  114. metadata +54 -24
  115. data/README.rdoc +0 -232
@@ -7,13 +7,13 @@ module Authlogic
7
7
  extend Config
8
8
  include InstanceMethods
9
9
  validate :validate_by_password, :if => :authenticating_with_password?
10
-
10
+
11
11
  class << self
12
12
  attr_accessor :configured_password_methods
13
13
  end
14
14
  end
15
15
  end
16
-
16
+
17
17
  # Password configuration
18
18
  module Config
19
19
  # Authlogic tries to validate the credentials passed to it. One part of validation is actually finding the user and
@@ -23,8 +23,9 @@ module Authlogic
23
23
  # You can change what method UserSession calls by specifying it here. Then in your User model you can make that method do
24
24
  # anything you want, giving you complete control of how users are found by the UserSession.
25
25
  #
26
- # Let's take an example: You want to allow users to login by username or email. Set this to the name of the class method
27
- # that does this in the User model. Let's call it "find_by_username_or_email"
26
+ # Let's take an example: You want to allow users to login by username or email.
27
+ # Set this to the name of the class method that does this in the User model. Let's
28
+ # call it "find_by_username_or_email"
28
29
  #
29
30
  # class User < ActiveRecord::Base
30
31
  # def self.find_by_username_or_email(login)
@@ -32,8 +33,10 @@ module Authlogic
32
33
  # end
33
34
  # end
34
35
  #
35
- # Now just specify the name of this method for this configuration option and you are all set. You can do anything you
36
- # want here. Maybe you allow users to have multiple logins and you want to search a has_many relationship, etc. The sky is the limit.
36
+ # Now just specify the name of this method for this configuration option and you
37
+ # are all set. You can do anything you want here. Maybe you allow users to have
38
+ # multiple logins and you want to search a has_many relationship, etc. The sky is
39
+ # the limit.
37
40
  #
38
41
  # * <tt>Default:</tt> "find_by_smart_case_login_field"
39
42
  # * <tt>Accepts:</tt> Symbol or String
@@ -41,10 +44,11 @@ module Authlogic
41
44
  rw_config(:find_by_login_method, value, "find_by_smart_case_login_field")
42
45
  end
43
46
  alias_method :find_by_login_method=, :find_by_login_method
44
-
45
- # The text used to identify credentials (username/password) combination when a bad login attempt occurs.
46
- # When you show error messages for a bad login, it's considered good security practice to hide which field
47
- # the user has entered incorrectly (the login field or the password field). For a full explanation, see
47
+
48
+ # The text used to identify credentials (username/password) combination when a bad
49
+ # login attempt occurs. When you show error messages for a bad login, it's
50
+ # considered good security practice to hide which field the user has entered
51
+ # incorrectly (the login field or the password field). For a full explanation, see
48
52
  # http://www.gnucitizen.org/blog/username-enumeration-vulnerabilities/
49
53
  #
50
54
  # Example of use:
@@ -56,9 +60,9 @@ module Authlogic
56
60
  # This would make the error message for bad logins and bad passwords look identical:
57
61
  #
58
62
  # Login/Password combination is not valid
59
- #
63
+ #
60
64
  # Alternatively you may use a custom message:
61
- #
65
+ #
62
66
  # class UserSession < AuthLogic::Session::Base
63
67
  # generalize_credentials_error_messages "Your login information is invalid"
64
68
  # end
@@ -71,18 +75,20 @@ module Authlogic
71
75
  #
72
76
  # If you are developing an app where security is an extreme priority (such as a financial application),
73
77
  # then you should enable this. Otherwise, leaving this off is fine.
74
- #
78
+ #
75
79
  # * <tt>Default</tt> false
76
80
  # * <tt>Accepts:</tt> Boolean
77
81
  def generalize_credentials_error_messages(value = nil)
78
82
  rw_config(:generalize_credentials_error_messages, value, false)
79
83
  end
80
84
  alias_method :generalize_credentials_error_messages=, :generalize_credentials_error_messages
81
-
82
- # The name of the method you want Authlogic to create for storing the login / username. Keep in mind this is just for your
83
- # Authlogic::Session, if you want it can be something completely different than the field in your model. So if you wanted people to
84
- # login with a field called "login" and then find users by email this is compeltely doable. See the find_by_login_method configuration
85
- # option for more details.
85
+
86
+ # The name of the method you want Authlogic to create for storing the login /
87
+ # username. Keep in mind this is just for your Authlogic::Session, if you want it
88
+ # can be something completely different than the field in your model. So if you
89
+ # wanted people to login with a field called "login" and then find users by email
90
+ # this is completely doable. See the find_by_login_method configuration option for
91
+ # more details.
86
92
  #
87
93
  # * <tt>Default:</tt> klass.login_field || klass.email_field
88
94
  # * <tt>Accepts:</tt> Symbol or String
@@ -90,7 +96,7 @@ module Authlogic
90
96
  rw_config(:login_field, value, klass.login_field || klass.email_field)
91
97
  end
92
98
  alias_method :login_field=, :login_field
93
-
99
+
94
100
  # Works exactly like login_field, but for the password instead. Returns :password if a login_field exists.
95
101
  #
96
102
  # * <tt>Default:</tt> :password
@@ -99,7 +105,7 @@ module Authlogic
99
105
  rw_config(:password_field, value, login_field && :password)
100
106
  end
101
107
  alias_method :password_field=, :password_field
102
-
108
+
103
109
  # The name of the method in your model used to verify the password. This should be an instance method. It should also
104
110
  # be prepared to accept a raw password and a crytped password.
105
111
  #
@@ -110,7 +116,7 @@ module Authlogic
110
116
  end
111
117
  alias_method :verify_password_method=, :verify_password_method
112
118
  end
113
-
119
+
114
120
  # Password related instance methods
115
121
  module InstanceMethods
116
122
  def initialize(*args)
@@ -120,7 +126,7 @@ module Authlogic
120
126
  end
121
127
  super
122
128
  end
123
-
129
+
124
130
  # Returns the login_field / password_field credentials combination in hash form.
125
131
  def credentials
126
132
  if authenticating_with_password?
@@ -132,11 +138,12 @@ module Authlogic
132
138
  super
133
139
  end
134
140
  end
135
-
141
+
136
142
  # Accepts the login_field / password_field credentials combination in hash form.
137
143
  def credentials=(value)
138
144
  super
139
- values = value.is_a?(Array) ? value : [value]
145
+ values = parse_param_val(value) # add strong parameters check
146
+
140
147
  if values.first.is_a?(Hash)
141
148
  values.first.with_indifferent_access.slice(login_field, password_field).each do |field, value|
142
149
  next if value.blank?
@@ -144,18 +151,19 @@ module Authlogic
144
151
  end
145
152
  end
146
153
  end
147
-
154
+
148
155
  def invalid_password?
149
156
  invalid_password == true
150
157
  end
151
-
158
+
152
159
  private
160
+
153
161
  def configure_password_methods
154
162
  if login_field
155
163
  self.class.send(:attr_writer, login_field) if !respond_to?("#{login_field}=")
156
164
  self.class.send(:attr_reader, login_field) if !respond_to?(login_field)
157
165
  end
158
-
166
+
159
167
  if password_field
160
168
  self.class.send(:attr_writer, password_field) if !respond_to?("#{password_field}=")
161
169
  self.class.send(:define_method, password_field) {} if !respond_to?(password_field)
@@ -174,16 +182,19 @@ module Authlogic
174
182
  def authenticating_with_password?
175
183
  login_field && (!send(login_field).nil? || !send("protected_#{password_field}").nil?)
176
184
  end
177
-
185
+
178
186
  def validate_by_password
179
187
  self.invalid_password = false
180
-
188
+
181
189
  # check for blank fields
182
- errors.add(login_field, I18n.t('error_messages.login_blank', :default => "cannot be blank")) if send(login_field).blank?
183
- errors.add(password_field, I18n.t('error_messages.password_blank', :default => "cannot be blank")) if send("protected_#{password_field}").blank?
190
+ if send(login_field).blank?
191
+ errors.add(login_field, I18n.t('error_messages.login_blank', :default => "cannot be blank"))
192
+ end
193
+ if send("protected_#{password_field}").blank?
194
+ errors.add(password_field, I18n.t('error_messages.password_blank', :default => "cannot be blank"))
195
+ end
184
196
  return if errors.count > 0
185
197
 
186
- # check for unknown login
187
198
  self.attempted_record = search_for_record(find_by_login_method, send(login_field))
188
199
  if attempted_record.blank?
189
200
  generalize_credentials_error_messages? ?
@@ -201,19 +212,19 @@ module Authlogic
201
212
  return
202
213
  end
203
214
  end
204
-
215
+
205
216
  attr_accessor :invalid_password
206
-
217
+
207
218
  def find_by_login_method
208
219
  self.class.find_by_login_method
209
220
  end
210
-
221
+
211
222
  def login_field
212
223
  self.class.login_field
213
224
  end
214
-
225
+
215
226
  def add_general_credentials_error
216
- error_message =
227
+ error_message =
217
228
  if self.class.generalize_credentials_error_messages.is_a? String
218
229
  self.class.generalize_credentials_error_messages
219
230
  else
@@ -221,18 +232,29 @@ module Authlogic
221
232
  end
222
233
  errors.add(:base, I18n.t('error_messages.general_credentials_error', :default => error_message))
223
234
  end
224
-
235
+
225
236
  def generalize_credentials_error_messages?
226
237
  self.class.generalize_credentials_error_messages
227
238
  end
228
-
239
+
229
240
  def password_field
230
241
  self.class.password_field
231
242
  end
232
-
243
+
233
244
  def verify_password_method
234
245
  self.class.verify_password_method
235
246
  end
247
+
248
+ # In Rails 5 the ActionController::Parameters no longer inherits from HashWithIndifferentAccess.
249
+ # See: http://guides.rubyonrails.org/upgrading_ruby_on_rails.html#actioncontroller-parameters-no-longer-inherits-from-hashwithindifferentaccess
250
+ # This method converts the ActionController::Parameters to a Hash
251
+ def parse_param_val(value)
252
+ if value.first.class.name == "ActionController::Parameters"
253
+ [value.first.to_h]
254
+ else
255
+ value.is_a?(Array) ? value : [value]
256
+ end
257
+ end
236
258
  end
237
259
  end
238
260
  end
@@ -8,11 +8,12 @@ module Authlogic
8
8
  def self.included(klass)
9
9
  klass.after_save :reset_perishable_token!
10
10
  end
11
-
11
+
12
12
  private
13
+
13
14
  def reset_perishable_token!
14
15
  record.reset_perishable_token if record.respond_to?(:reset_perishable_token) && !record.disable_perishable_token_maintenance?
15
16
  end
16
17
  end
17
18
  end
18
- end
19
+ end
@@ -8,7 +8,7 @@ module Authlogic
8
8
  include InstanceMethods
9
9
  end
10
10
  end
11
-
11
+
12
12
  module ClassMethods
13
13
  # This is how you persist a session. This finds the record for the current session using
14
14
  # a variety of methods. It basically tries to "log in" the user without the user having
@@ -34,7 +34,7 @@ module Authlogic
34
34
  #
35
35
  # See the id method for more information on ids.
36
36
  def find(id = nil, priority_record = nil)
37
- session = new({:priority_record => priority_record}, id)
37
+ session = new({ :priority_record => priority_record }, id)
38
38
  session.priority_record = priority_record
39
39
  if session.persisting?
40
40
  session
@@ -43,7 +43,7 @@ module Authlogic
43
43
  end
44
44
  end
45
45
  end
46
-
46
+
47
47
  module InstanceMethods
48
48
  # Let's you know if the session is being persisted or not, meaning the user does not have to explicitly log in
49
49
  # in order to be logged in. If the session has no associated record, it will try to find a record and persist
@@ -9,7 +9,7 @@ module Authlogic
9
9
  attr_accessor :priority_record
10
10
  end
11
11
  end
12
-
12
+
13
13
  # Setting priority record if it is passed. The only way it can be passed is through an array:
14
14
  #
15
15
  # session.credentials = [real_user_object, priority_user_object]
@@ -18,17 +18,18 @@ module Authlogic
18
18
  values = value.is_a?(Array) ? value : [value]
19
19
  self.priority_record = values[1] if values[1].class < ::ActiveRecord::Base
20
20
  end
21
-
21
+
22
22
  private
23
+
23
24
  def attempted_record=(value)
24
25
  value = priority_record if value == priority_record
25
26
  super
26
27
  end
27
-
28
+
28
29
  def save_record(alternate_record = nil)
29
30
  r = alternate_record || record
30
31
  super if r != priority_record
31
32
  end
32
33
  end
33
34
  end
34
- end
35
+ end
@@ -2,10 +2,13 @@ require 'request_store'
2
2
 
3
3
  module Authlogic
4
4
  module Session
5
- # Authentication can be scoped, and it's easy, you just need to define how you want to scope everything. This should help you:
5
+ # Authentication can be scoped, and it's easy, you just need to define how you want to
6
+ # scope everything. This should help you:
6
7
  #
7
- # 1. Want to scope by a parent object? Ex: An account has many users. Checkout Authlogic::AuthenticatesMany
8
- # 2. Want to scope the validations in your model? Ex: 2 users can have the same login under different accounts. See Authlogic::ActsAsAuthentic::Scope
8
+ # 1. Want to scope by a parent object? Ex: An account has many users.
9
+ # Checkout Authlogic::AuthenticatesMany
10
+ # 2. Want to scope the validations in your model? Ex: 2 users can have the same login
11
+ # under different accounts. See Authlogic::ActsAsAuthentic::Scope
9
12
  module Scopes # :nodoc:
10
13
  def self.included(klass)
11
14
  klass.class_eval do
@@ -22,11 +25,15 @@ module Authlogic
22
25
  RequestStore.store[:authlogic_scope]
23
26
  end
24
27
 
25
- # What with_scopes focuses on is scoping the query when finding the object and the name of the cookie / session. It works very similar to
26
- # ActiveRecord::Base#with_scopes. It accepts a hash with any of the following options:
28
+ # What with_scopes focuses on is scoping the query when finding the object and the
29
+ # name of the cookie / session. It works very similar to
30
+ # ActiveRecord::Base#with_scopes. It accepts a hash with any of the following
31
+ # options:
27
32
  #
28
- # * <tt>find_options:</tt> any options you can pass into ActiveRecord::Base.find. This is used when trying to find the record.
29
- # * <tt>id:</tt> The id of the session, this gets merged with the real id. For information ids see the id method.
33
+ # * <tt>find_options:</tt> any options you can pass into ActiveRecord::Base.find.
34
+ # This is used when trying to find the record.
35
+ # * <tt>id:</tt> The id of the session, this gets merged with the real id. For
36
+ # information ids see the id method.
30
37
  #
31
38
  # Here is how you use it:
32
39
  #
@@ -34,7 +41,8 @@ module Authlogic
34
41
  # UserSession.find
35
42
  # end
36
43
  #
37
- # Eseentially what the above does is scope the searching of the object with the sql you provided. So instead of:
44
+ # Essentially what the above does is scope the searching of the object with the
45
+ # sql you provided. So instead of:
38
46
  #
39
47
  # User.where("login = 'ben'").first
40
48
  #
@@ -42,7 +50,8 @@ module Authlogic
42
50
  #
43
51
  # User.where("login = 'ben' and account_id = 2").first
44
52
  #
45
- # You will also notice the :id option. This works just like the id method. It scopes your cookies. So the name of your cookie will be:
53
+ # You will also notice the :id option. This works just like the id method. It
54
+ # scopes your cookies. So the name of your cookie will be:
46
55
  #
47
56
  # account_2_user_credentials
48
57
  #
@@ -69,6 +78,7 @@ module Authlogic
69
78
  end
70
79
 
71
80
  private
81
+
72
82
  def scope=(value)
73
83
  RequestStore.store[:authlogic_scope] = value
74
84
  end
@@ -87,6 +97,7 @@ module Authlogic
87
97
  end
88
98
 
89
99
  private
100
+
90
101
  # Used for things like cookie_key, session_key, etc.
91
102
  def build_key(last_part)
92
103
  [scope[:id], super].compact.join("_")
@@ -28,12 +28,14 @@ module Authlogic
28
28
  # Instance methods for the session feature.
29
29
  module InstanceMethods
30
30
  private
31
+
31
32
  # Tries to validate the session from information in the session
32
33
  def persist_by_session
33
34
  persistence_token, record_id = session_credentials
34
35
  if !persistence_token.nil?
35
- # Allow finding by persistence token, because when records are created the session is maintained in a before_save, when there is no id.
36
- # This is done for performance reasons and to save on queries.
36
+ # Allow finding by persistence token, because when records are created the
37
+ # session is maintained in a before_save, when there is no id. This is done
38
+ # for performance reasons and to save on queries.
37
39
  record = record_id.nil? ?
38
40
  search_for_record("find_by_persistence_token", persistence_token.to_s) :
39
41
  search_for_record("find_by_#{klass.primary_key}", record_id.to_s)
@@ -45,7 +47,10 @@ module Authlogic
45
47
  end
46
48
 
47
49
  def session_credentials
48
- [controller.session[session_key], controller.session["#{session_key}_#{klass.primary_key}"]].collect { |i| i.nil? ? i : i.to_s }.compact
50
+ [
51
+ controller.session[session_key],
52
+ controller.session["#{session_key}_#{klass.primary_key}"]
53
+ ].collect { |i| i.nil? ? i : i.to_s }.compact
49
54
  end
50
55
 
51
56
  def session_key
@@ -59,4 +64,4 @@ module Authlogic
59
64
  end
60
65
  end
61
66
  end
62
- end
67
+ end
@@ -1,7 +1,8 @@
1
1
  module Authlogic
2
2
  module Session
3
- # Think about financial websites, if you are inactive for a certain period of time you will be asked to
4
- # log back in on your next request. You can do this with Authlogic easily, there are 2 parts to this:
3
+ # Think about financial websites, if you are inactive for a certain period
4
+ # of time you will be asked to log back in on your next request. You can do
5
+ # this with Authlogic easily, there are 2 parts to this:
5
6
  #
6
7
  # 1. Define the timeout threshold:
7
8
  #
@@ -15,9 +16,10 @@ module Authlogic
15
16
  # logout_on_timeout true # default if false
16
17
  # end
17
18
  #
18
- # This will require a user to log back in if they are inactive for more than 10 minutes. In order for
19
- # this feature to be used you must have a last_request_at datetime column in your table for whatever model
20
- # you are authenticating with.
19
+ # This will require a user to log back in if they are inactive for more than
20
+ # 10 minutes. In order for this feature to be used you must have a
21
+ # last_request_at datetime column in your table for whatever model you are
22
+ # authenticating with.
21
23
  module Timeout
22
24
  def self.included(klass)
23
25
  klass.class_eval do
@@ -28,22 +30,33 @@ module Authlogic
28
30
  attr_accessor :stale_record
29
31
  end
30
32
  end
31
-
33
+
32
34
  # Configuration for the timeout feature.
33
35
  module Config
34
- # With acts_as_authentic you get a :logged_in_timeout configuration option. If this is set, after this amount of time has passed the user
35
- # will be marked as logged out. Obviously, since web based apps are on a per request basis, we have to define a time limit threshold that
36
- # determines when we consider a user to be "logged out". Meaning, if they login and then leave the website, when do mark them as logged out?
37
- # I recommend just using this as a fun feature on your website or reports, giving you a ballpark number of users logged in and active. This is
38
- # not meant to be a dead accurate representation of a users logged in state, since there is really no real way to do this with web based apps.
39
- # Think about a user that logs in and doesn't log out. There is no action that tells you that the user isn't technically still logged in and
40
- # active.
36
+ # With acts_as_authentic you get a :logged_in_timeout configuration
37
+ # option. If this is set, after this amount of time has passed the user
38
+ # will be marked as logged out. Obviously, since web based apps are on a
39
+ # per request basis, we have to define a time limit threshold that
40
+ # determines when we consider a user to be "logged out". Meaning, if
41
+ # they login and then leave the website, when do mark them as logged
42
+ # out? I recommend just using this as a fun feature on your website or
43
+ # reports, giving you a ballpark number of users logged in and active.
44
+ # This is not meant to be a dead accurate representation of a users
45
+ # logged in state, since there is really no real way to do this with web
46
+ # based apps. Think about a user that logs in and doesn't log out. There
47
+ # is no action that tells you that the user isn't technically still
48
+ # logged in and active.
41
49
  #
42
- # That being said, you can use that feature to require a new login if their session timesout. Similar to how financial sites work. Just set this option to
43
- # true and if your record returns true for stale? then they will be required to log back in.
50
+ # That being said, you can use that feature to require a new login if
51
+ # their session times out. Similar to how financial sites work. Just set
52
+ # this option to true and if your record returns true for stale? then
53
+ # they will be required to log back in.
44
54
  #
45
- # Lastly, UserSession.find will still return a object is the session is stale, but you will not get a record. This allows you to determine if the
46
- # user needs to log back in because their session went stale, or because they just aren't logged in. Just call current_user_session.stale? as your flag.
55
+ # Lastly, UserSession.find will still return a object is the session is
56
+ # stale, but you will not get a record. This allows you to determine if
57
+ # the user needs to log back in because their session went stale, or
58
+ # because they just aren't logged in. Just call
59
+ # current_user_session.stale? as your flag.
47
60
  #
48
61
  # * <tt>Default:</tt> false
49
62
  # * <tt>Accepts:</tt> Boolean
@@ -52,11 +65,14 @@ module Authlogic
52
65
  end
53
66
  alias_method :logout_on_timeout=, :logout_on_timeout
54
67
  end
55
-
68
+
56
69
  # Instance methods for the timeout feature.
57
70
  module InstanceMethods
58
- # Tells you if the record is stale or not. Meaning the record has timed out. This will only return true if you set logout_on_timeout to true in your configuration.
59
- # Basically how a bank website works. If you aren't active over a certain period of time your session becomes stale and requires you to log back in.
71
+ # Tells you if the record is stale or not. Meaning the record has timed
72
+ # out. This will only return true if you set logout_on_timeout to true
73
+ # in your configuration. Basically how a bank website works. If you
74
+ # aren't active over a certain period of time your session becomes stale
75
+ # and requires you to log back in.
60
76
  def stale?
61
77
  if remember_me?
62
78
  remember_me_expired?
@@ -64,19 +80,20 @@ module Authlogic
64
80
  !stale_record.nil? || (logout_on_timeout? && record && record.logged_out?)
65
81
  end
66
82
  end
67
-
83
+
68
84
  private
85
+
69
86
  def reset_stale_state
70
87
  self.stale_record = nil
71
88
  end
72
-
89
+
73
90
  def enforce_timeout
74
91
  if stale?
75
92
  self.stale_record = record
76
93
  self.record = nil
77
94
  end
78
95
  end
79
-
96
+
80
97
  def logout_on_timeout?
81
98
  self.class.logout_on_timeout == true
82
99
  end