authlogic 3.8.0 → 4.0.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 (102) hide show
  1. checksums.yaml +7 -0
  2. data/.github/triage.md +87 -0
  3. data/.gitignore +2 -1
  4. data/.rubocop.yml +62 -6
  5. data/.rubocop_todo.yml +51 -267
  6. data/.travis.yml +4 -26
  7. data/CHANGELOG.md +226 -2
  8. data/CONTRIBUTING.md +15 -5
  9. data/Gemfile +2 -2
  10. data/README.md +183 -91
  11. data/Rakefile +1 -1
  12. data/UPGRADING.md +20 -0
  13. data/authlogic.gemspec +25 -16
  14. data/lib/authlogic.rb +45 -45
  15. data/lib/authlogic/acts_as_authentic/base.rb +18 -11
  16. data/lib/authlogic/acts_as_authentic/email.rb +32 -28
  17. data/lib/authlogic/acts_as_authentic/logged_in_status.rb +1 -1
  18. data/lib/authlogic/acts_as_authentic/login.rb +32 -42
  19. data/lib/authlogic/acts_as_authentic/magic_columns.rb +6 -6
  20. data/lib/authlogic/acts_as_authentic/password.rb +53 -31
  21. data/lib/authlogic/acts_as_authentic/perishable_token.rb +18 -17
  22. data/lib/authlogic/acts_as_authentic/persistence_token.rb +7 -12
  23. data/lib/authlogic/acts_as_authentic/queries/find_with_case.rb +64 -0
  24. data/lib/authlogic/acts_as_authentic/restful_authentication.rb +11 -3
  25. data/lib/authlogic/acts_as_authentic/session_maintenance.rb +30 -10
  26. data/lib/authlogic/acts_as_authentic/single_access_token.rb +4 -4
  27. data/lib/authlogic/authenticates_many/association.rb +3 -3
  28. data/lib/authlogic/authenticates_many/base.rb +2 -2
  29. data/lib/authlogic/config.rb +0 -1
  30. data/lib/authlogic/controller_adapters/abstract_adapter.rb +11 -4
  31. data/lib/authlogic/controller_adapters/rack_adapter.rb +7 -3
  32. data/lib/authlogic/controller_adapters/rails_adapter.rb +2 -0
  33. data/lib/authlogic/crypto_providers/aes256.rb +1 -1
  34. data/lib/authlogic/crypto_providers/bcrypt.rb +1 -1
  35. data/lib/authlogic/crypto_providers/scrypt.rb +6 -6
  36. data/lib/authlogic/crypto_providers/sha1.rb +10 -5
  37. data/lib/authlogic/crypto_providers/sha256.rb +11 -8
  38. data/lib/authlogic/crypto_providers/wordpress.rb +2 -2
  39. data/lib/authlogic/i18n.rb +4 -2
  40. data/lib/authlogic/random.rb +10 -28
  41. data/lib/authlogic/regex.rb +11 -8
  42. data/lib/authlogic/session/activation.rb +6 -3
  43. data/lib/authlogic/session/active_record_trickery.rb +13 -9
  44. data/lib/authlogic/session/base.rb +15 -4
  45. data/lib/authlogic/session/brute_force_protection.rb +14 -7
  46. data/lib/authlogic/session/callbacks.rb +53 -30
  47. data/lib/authlogic/session/cookies.rb +57 -16
  48. data/lib/authlogic/session/existence.rb +21 -11
  49. data/lib/authlogic/session/foundation.rb +56 -10
  50. data/lib/authlogic/session/http_auth.rb +15 -8
  51. data/lib/authlogic/session/klass.rb +7 -5
  52. data/lib/authlogic/session/magic_columns.rb +24 -11
  53. data/lib/authlogic/session/magic_states.rb +11 -4
  54. data/lib/authlogic/session/params.rb +6 -2
  55. data/lib/authlogic/session/password.rb +46 -73
  56. data/lib/authlogic/session/persistence.rb +11 -7
  57. data/lib/authlogic/session/priority_record.rb +7 -4
  58. data/lib/authlogic/session/scopes.rb +15 -6
  59. data/lib/authlogic/session/session.rb +20 -10
  60. data/lib/authlogic/session/timeout.rb +2 -2
  61. data/lib/authlogic/session/unauthorized_record.rb +1 -1
  62. data/lib/authlogic/session/validation.rb +1 -1
  63. data/lib/authlogic/test_case.rb +65 -2
  64. data/lib/authlogic/test_case/mock_controller.rb +5 -4
  65. data/lib/authlogic/test_case/mock_cookie_jar.rb +11 -2
  66. data/lib/authlogic/test_case/mock_request.rb +5 -1
  67. data/lib/authlogic/test_case/rails_request_adapter.rb +3 -2
  68. data/lib/authlogic/version.rb +16 -0
  69. data/test/acts_as_authentic_test/email_test.rb +33 -34
  70. data/test/acts_as_authentic_test/logged_in_status_test.rb +1 -1
  71. data/test/acts_as_authentic_test/login_test.rb +73 -78
  72. data/test/acts_as_authentic_test/password_test.rb +30 -18
  73. data/test/acts_as_authentic_test/perishable_token_test.rb +9 -3
  74. data/test/acts_as_authentic_test/persistence_token_test.rb +4 -0
  75. data/test/acts_as_authentic_test/session_maintenance_test.rb +66 -14
  76. data/test/adapter_test.rb +21 -0
  77. data/test/gemfiles/Gemfile.rails-4.2.x +2 -2
  78. data/test/gemfiles/Gemfile.rails-5.0.x +2 -2
  79. data/test/gemfiles/Gemfile.rails-master +6 -0
  80. data/test/i18n_test.rb +1 -1
  81. data/test/libs/company.rb +2 -2
  82. data/test/random_test.rb +7 -37
  83. data/test/session_test/active_record_trickery_test.rb +4 -3
  84. data/test/session_test/brute_force_protection_test.rb +8 -8
  85. data/test/session_test/callbacks_test.rb +1 -1
  86. data/test/session_test/cookies_test.rb +27 -4
  87. data/test/session_test/existence_test.rb +15 -4
  88. data/test/session_test/foundation_test.rb +16 -0
  89. data/test/session_test/http_auth_test.rb +3 -1
  90. data/test/session_test/magic_columns_test.rb +10 -12
  91. data/test/session_test/params_test.rb +4 -1
  92. data/test/session_test/password_test.rb +7 -7
  93. data/test/session_test/persistence_test.rb +1 -0
  94. data/test/session_test/scopes_test.rb +7 -7
  95. data/test/session_test/session_test.rb +2 -2
  96. data/test/session_test/timeout_test.rb +1 -1
  97. data/test/session_test/unauthorized_record_test.rb +1 -1
  98. data/test/test_helper.rb +111 -103
  99. metadata +68 -64
  100. data/test/gemfiles/Gemfile.rails-3.2.x +0 -7
  101. data/test/gemfiles/Gemfile.rails-4.0.x +0 -7
  102. data/test/gemfiles/Gemfile.rails-4.1.x +0 -7
@@ -17,15 +17,15 @@ module Authlogic
17
17
  klass.class_eval do
18
18
  if column_names.include?("login_count")
19
19
  validates_numericality_of :login_count,
20
- :only_integer => true,
21
- :greater_than_or_equal_to => 0,
22
- :allow_nil => true
20
+ only_integer: true,
21
+ greater_than_or_equal_to: 0,
22
+ allow_nil: true
23
23
  end
24
24
  if column_names.include?("failed_login_count")
25
25
  validates_numericality_of :failed_login_count,
26
- :only_integer => true,
27
- :greater_than_or_equal_to => 0,
28
- :allow_nil => true
26
+ only_integer: true,
27
+ greater_than_or_equal_to: 0,
28
+ allow_nil: true
29
29
  end
30
30
  end
31
31
  end
@@ -107,7 +107,7 @@ module Authlogic
107
107
  # * <tt>Default:</tt> {:minimum => 8, :if => :require_password?}
108
108
  # * <tt>Accepts:</tt> Hash of options accepted by validates_length_of
109
109
  def validates_length_of_password_field_options(value = nil)
110
- rw_config(:validates_length_of_password_field_options, value, { :minimum => 8, :if => :require_password? })
110
+ rw_config(:validates_length_of_password_field_options, value, minimum: 8, if: :require_password?)
111
111
  end
112
112
  alias_method :validates_length_of_password_field_options=, :validates_length_of_password_field_options
113
113
 
@@ -121,7 +121,8 @@ module Authlogic
121
121
  #
122
122
  # merge_validates_length_of_password_field_options :my_option => my_value
123
123
  def merge_validates_length_of_password_field_options(options = {})
124
- self.validates_length_of_password_field_options = validates_length_of_password_field_options.merge(options)
124
+ self.validates_length_of_password_field_options =
125
+ validates_length_of_password_field_options.merge(options)
125
126
  end
126
127
 
127
128
  # A hash of options for the validates_confirmation_of call for the password field.
@@ -135,14 +136,16 @@ module Authlogic
135
136
  # * <tt>Default:</tt> {:if => :require_password?}
136
137
  # * <tt>Accepts:</tt> Hash of options accepted by validates_confirmation_of
137
138
  def validates_confirmation_of_password_field_options(value = nil)
138
- rw_config(:validates_confirmation_of_password_field_options, value, { :if => :require_password? })
139
+ rw_config(:validates_confirmation_of_password_field_options, value, if: :require_password?)
139
140
  end
140
- alias_method :validates_confirmation_of_password_field_options=, :validates_confirmation_of_password_field_options
141
+ alias_method :validates_confirmation_of_password_field_options=,
142
+ :validates_confirmation_of_password_field_options
141
143
 
142
144
  # See merge_validates_length_of_password_field_options. The same thing, except for
143
145
  # validates_confirmation_of_password_field_options
144
146
  def merge_validates_confirmation_of_password_field_options(options = {})
145
- self.validates_confirmation_of_password_field_options = validates_confirmation_of_password_field_options.merge(options)
147
+ self.validates_confirmation_of_password_field_options =
148
+ validates_confirmation_of_password_field_options.merge(options)
146
149
  end
147
150
 
148
151
  # A hash of options for the validates_length_of call for the password_confirmation
@@ -210,33 +213,36 @@ module Authlogic
210
213
  METHODS = [
211
214
  "before_password_set", "after_password_set",
212
215
  "before_password_verification", "after_password_verification"
213
- ]
216
+ ].freeze
214
217
 
215
218
  def self.included(klass)
216
219
  return if klass.crypted_password_field.nil?
217
- klass.define_callbacks *METHODS
220
+ klass.define_callbacks(*METHODS)
218
221
 
219
222
  # If Rails 3, support the new callback syntax
220
- if klass.send(klass.respond_to?(:singleton_class) ? :singleton_class : :metaclass).method_defined?(:set_callback)
223
+ singleton_class_method_name = klass.respond_to?(:singleton_class) ? :singleton_class : :metaclass
224
+ if klass.send(singleton_class_method_name).method_defined?(:set_callback)
221
225
  METHODS.each do |method|
222
- klass.class_eval <<-"end_eval", __FILE__, __LINE__
226
+ klass.class_eval <<-EOS, __FILE__, __LINE__
223
227
  def self.#{method}(*methods, &block)
224
228
  set_callback :#{method}, *methods, &block
225
229
  end
226
- end_eval
230
+ EOS
227
231
  end
228
232
  end
229
233
  end
230
234
 
231
- private
232
-
233
- METHODS.each do |method|
234
- class_eval <<-"end_eval", __FILE__, __LINE__
235
- def #{method}
236
- run_callbacks(:#{method}) { |result, object| result == false }
237
- end
238
- end_eval
239
- end
235
+ # TODO: Ideally, once this module is included, the included copies of
236
+ # the following methods would be private. This cannot be accomplished
237
+ # by using calling `private` here in the module. Maybe we can set the
238
+ # privacy inside `included`?
239
+ METHODS.each do |method|
240
+ class_eval <<-EOS, __FILE__, __LINE__
241
+ def #{method}
242
+ run_callbacks(:#{method}) { |result, object| result == false }
243
+ end
244
+ EOS
245
+ end
240
246
  end
241
247
 
242
248
  # The methods related to the password field.
@@ -251,8 +257,14 @@ module Authlogic
251
257
  validates_length_of :password, validates_length_of_password_field_options
252
258
 
253
259
  if require_password_confirmation
254
- validates_confirmation_of :password, validates_confirmation_of_password_field_options
255
- validates_length_of :password_confirmation, validates_length_of_password_confirmation_field_options
260
+ validates_confirmation_of(
261
+ :password,
262
+ validates_confirmation_of_password_field_options
263
+ )
264
+ validates_length_of(
265
+ :password_confirmation,
266
+ validates_length_of_password_confirmation_field_options
267
+ )
256
268
  end
257
269
  end
258
270
 
@@ -300,7 +312,7 @@ module Authlogic
300
312
 
301
313
  crypto_providers.each_with_index do |encryptor, index|
302
314
  if encryptor_matches?(crypted, encryptor, index, attempted_password, check_against_database)
303
- if transition_password?(index, encryptor, crypted, check_against_database)
315
+ if transition_password?(index, encryptor, check_against_database)
304
316
  transition_password(attempted_password)
305
317
  end
306
318
  after_password_verification
@@ -322,7 +334,7 @@ module Authlogic
322
334
  # Resets the password to a random friendly token and then saves the record.
323
335
  def reset_password!
324
336
  reset_password
325
- save_without_session_maintenance(:validate => false)
337
+ save_without_session_maintenance(validate: false)
326
338
  end
327
339
  alias_method :randomize_password!, :reset_password!
328
340
 
@@ -373,18 +385,28 @@ module Authlogic
373
385
  end
374
386
 
375
387
  # Determines if we need to transition the password.
376
- # If the index > 0 then we are using an "transition from" crypto provider.
377
- # If the encryptor has a cost and the cost it outdated.
378
- # If we aren't using database values
379
- # If we are using database values, only if the password hasn't changed so we don't overwrite any changes
380
- def transition_password?(index, encryptor, crypted, check_against_database)
381
- (index > 0 || (encryptor.respond_to?(:cost_matches?) && !encryptor.cost_matches?(send(crypted_password_field)))) &&
382
- (!check_against_database || !send("#{crypted_password_field}_changed?"))
388
+ #
389
+ # - If the index > 0 then we are using an "transition from" crypto
390
+ # provider.
391
+ # - If the encryptor has a cost and the cost it outdated.
392
+ # - If we aren't using database values
393
+ # - If we are using database values, only if the password hasn't
394
+ # changed so we don't overwrite any changes
395
+ def transition_password?(index, encryptor, check_against_database)
396
+ (
397
+ index > 0 ||
398
+ (encryptor.respond_to?(:cost_matches?) &&
399
+ !encryptor.cost_matches?(send(crypted_password_field)))
400
+ ) &&
401
+ (
402
+ !check_against_database ||
403
+ !send("#{crypted_password_field}_changed?")
404
+ )
383
405
  end
384
406
 
385
407
  def transition_password(attempted_password)
386
408
  self.password = attempted_password
387
- save(:validate => false)
409
+ save(validate: false)
388
410
  end
389
411
 
390
412
  def require_password?
@@ -1,13 +1,15 @@
1
1
  module Authlogic
2
2
  module ActsAsAuthentic
3
- # This provides a handy token that is "perishable". Meaning the token is
4
- # only good for a certain amount of time. This is perfect for resetting
5
- # password, confirming accounts, etc. Typically during these actions you
6
- # send them this token in via their email. Once they use the token and do
7
- # what they need to do, that token should expire. Don't worry about
8
- # maintaining this, changing it, or expiring it yourself. Authlogic does all
9
- # of this for you. See the sub modules for all of the tools Authlogic
10
- # provides to you.
3
+ # This provides a handy token that is "perishable", meaning the token is
4
+ # only good for a certain amount of time.
5
+ #
6
+ # This is useful for resetting password, confirming accounts, etc. Typically
7
+ # during these actions you send them this token in an email. Once they use
8
+ # the token and do what they need to do, that token should expire.
9
+ #
10
+ # Don't worry about maintaining the token, changing it, or expiring it
11
+ # yourself. Authlogic does all of this for you. See the sub modules for all
12
+ # of the tools Authlogic provides to you.
11
13
  module PerishableToken
12
14
  def self.included(klass)
13
15
  klass.class_eval do
@@ -16,7 +18,7 @@ module Authlogic
16
18
  end
17
19
  end
18
20
 
19
- # Change how the perishable token works.
21
+ # Configure the perishable token.
20
22
  module Config
21
23
  # When using the find_using_perishable_token method the token can
22
24
  # expire. If the token is expired, no record will be returned. Use this
@@ -30,9 +32,8 @@ module Authlogic
30
32
  alias_method :perishable_token_valid_for=, :perishable_token_valid_for
31
33
 
32
34
  # Authlogic tries to expire and change the perishable token as much as
33
- # possible, without compromising it's purpose. This is for security
34
- # reasons. If you want to manage it yourself, you can stop Authlogic
35
- # from getting your in way by setting this to true.
35
+ # possible, without compromising its purpose. If you want to manage it
36
+ # yourself, set this to true.
36
37
  #
37
38
  # * <tt>Default:</tt> false
38
39
  # * <tt>Accepts:</tt> Boolean
@@ -45,18 +46,18 @@ module Authlogic
45
46
  # All methods relating to the perishable token.
46
47
  module Methods
47
48
  def self.included(klass)
48
- return if !klass.column_names.include?("perishable_token")
49
+ return unless klass.column_names.include?("perishable_token")
49
50
 
50
51
  klass.class_eval do
51
52
  extend ClassMethods
52
53
  include InstanceMethods
53
54
 
54
- validates_uniqueness_of :perishable_token, :if => :perishable_token_changed?
55
- before_save :reset_perishable_token, :unless => :disable_perishable_token_maintenance?
55
+ validates_uniqueness_of :perishable_token, if: :perishable_token_changed?
56
+ before_save :reset_perishable_token, unless: :disable_perishable_token_maintenance?
56
57
  end
57
58
  end
58
59
 
59
- # Class level methods for the perishable token
60
+ # Class methods for the perishable token
60
61
  module ClassMethods
61
62
  # Use this method to find a record with a perishable token. This
62
63
  # method does 2 things for you:
@@ -99,7 +100,7 @@ module Authlogic
99
100
  # Same as reset_perishable_token, but then saves the record afterwards.
100
101
  def reset_perishable_token!
101
102
  reset_perishable_token
102
- save_without_session_maintenance(:validate => false)
103
+ save_without_session_maintenance(validate: false)
103
104
  end
104
105
 
105
106
  # A convenience method based on the
@@ -18,28 +18,23 @@ module Authlogic
18
18
 
19
19
  if respond_to?(:after_password_set) && respond_to?(:after_password_verification)
20
20
  after_password_set :reset_persistence_token
21
- after_password_verification :reset_persistence_token!, :if => :reset_persistence_token?
21
+ after_password_verification :reset_persistence_token!, if: :reset_persistence_token?
22
22
  end
23
23
 
24
24
  validates_presence_of :persistence_token
25
- validates_uniqueness_of :persistence_token, :if => :persistence_token_changed?
25
+ validates_uniqueness_of :persistence_token, if: :persistence_token_changed?
26
26
 
27
- before_validation :reset_persistence_token, :if => :reset_persistence_token?
27
+ before_validation :reset_persistence_token, if: :reset_persistence_token?
28
28
  end
29
29
  end
30
30
 
31
31
  # Class level methods for the persistence token.
32
32
  module ClassMethods
33
- # Resets ALL persistence tokens in the database, which will require all users to reauthenticate.
33
+ # Resets ALL persistence tokens in the database, which will require
34
+ # all users to re-authenticate.
34
35
  def forget_all
35
36
  # Paginate these to save on memory
36
- records = nil
37
- i = 0
38
- begin
39
- records = limit(50).offset(i)
40
- records.each { |record| record.forget! }
41
- i += 50
42
- end while !records.blank?
37
+ find_each(batch_size: 50) { |record| record.forget! }
43
38
  end
44
39
  end
45
40
 
@@ -53,7 +48,7 @@ module Authlogic
53
48
  # Same as reset_persistence_token, but then saves the record.
54
49
  def reset_persistence_token!
55
50
  reset_persistence_token
56
- save_without_session_maintenance(:validate => false)
51
+ save_without_session_maintenance(validate: false)
57
52
  end
58
53
  alias_method :forget!, :reset_persistence_token!
59
54
 
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Authlogic
4
+ module ActsAsAuthentic
5
+ module Queries
6
+ # The query used by public-API method `find_by_smart_case_login_field`.
7
+ # @api private
8
+ class FindWithCase
9
+ AR_GEM_VERSION = ActiveRecord.gem_version.freeze
10
+
11
+ # @api private
12
+ def initialize(model_class, field, value, sensitive)
13
+ @model_class = model_class
14
+ @field = field.to_s
15
+ @value = value
16
+ @sensitive = sensitive
17
+ end
18
+
19
+ # @api private
20
+ def execute
21
+ bind(relation).first
22
+ end
23
+
24
+ private
25
+
26
+ # @api private
27
+ def bind(relation)
28
+ if AR_GEM_VERSION >= Gem::Version.new('5')
29
+ bind = ActiveRecord::Relation::QueryAttribute.new(
30
+ @field,
31
+ @value,
32
+ ActiveRecord::Type::Value.new
33
+ )
34
+ @model_class.where(relation, bind)
35
+ else
36
+ @model_class.where(relation)
37
+ end
38
+ end
39
+
40
+ # @api private
41
+ def relation
42
+ if !@sensitive
43
+ @model_class.connection.case_insensitive_comparison(
44
+ @model_class.arel_table,
45
+ @field,
46
+ @model_class.columns_hash[@field],
47
+ @value
48
+ )
49
+ elsif AR_GEM_VERSION >= Gem::Version.new('5.0')
50
+ @model_class.connection.case_sensitive_comparison(
51
+ @model_class.arel_table,
52
+ @field,
53
+ @model_class.columns_hash[@field],
54
+ @value
55
+ )
56
+ else
57
+ value = @model_class.connection.case_sensitive_modifier(@value, @field)
58
+ @model_class.arel_table[@field].eq(value)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -45,13 +45,21 @@ module Authlogic
45
45
  private
46
46
 
47
47
  def set_restful_authentication_config
48
- crypto_provider_key = act_like_restful_authentication ? :crypto_provider : :transition_from_crypto_providers
49
- self.send("#{crypto_provider_key}=", CryptoProviders::Sha1)
48
+ self.restful_auth_crypto_provider = CryptoProviders::Sha1
50
49
  if !defined?(::REST_AUTH_SITE_KEY) || ::REST_AUTH_SITE_KEY.nil?
51
- class_eval("::REST_AUTH_SITE_KEY = ''") if !defined?(::REST_AUTH_SITE_KEY)
50
+ class_eval("::REST_AUTH_SITE_KEY = ''") unless defined?(::REST_AUTH_SITE_KEY)
52
51
  CryptoProviders::Sha1.stretches = 1
53
52
  end
54
53
  end
54
+
55
+ # @api private
56
+ def restful_auth_crypto_provider=(provider)
57
+ if act_like_restful_authentication
58
+ self.crypto_provider = provider
59
+ else
60
+ self.transition_from_crypto_providers = provider
61
+ end
62
+ end
55
63
  end
56
64
 
57
65
  module InstanceMethods
@@ -30,17 +30,25 @@ module Authlogic
30
30
  end
31
31
 
32
32
  module Config
33
- # This is more of a convenience method. In order to turn off automatic
34
- # maintenance of sessions just set this to false, or you can also set
35
- # the session_ids method to a blank array. Both accomplish the same
36
- # thing. This method is a little clearer in it's intentions though.
33
+ # In order to turn off automatic maintenance of sessions
34
+ # after create, just set this to false.
37
35
  #
38
36
  # * <tt>Default:</tt> true
39
37
  # * <tt>Accepts:</tt> Boolean
40
- def maintain_sessions(value = nil)
41
- rw_config(:maintain_sessions, value, true)
38
+ def log_in_after_create(value = nil)
39
+ rw_config(:log_in_after_create, value, true)
42
40
  end
43
- alias_method :maintain_sessions=, :maintain_sessions
41
+ alias_method :log_in_after_create=, :log_in_after_create
42
+
43
+ # In order to turn off automatic maintenance of sessions when updating
44
+ # the password, just set this to false.
45
+ #
46
+ # * <tt>Default:</tt> true
47
+ # * <tt>Accepts:</tt> Boolean
48
+ def log_in_after_password_change(value = nil)
49
+ rw_config(:log_in_after_password_change, value, true)
50
+ end
51
+ alias_method :log_in_after_password_change=, :log_in_after_password_change
44
52
 
45
53
  # As you may know, authlogic sessions can be separate by id (See
46
54
  # Authlogic::Session::Base#id). You can specify here what session ids
@@ -69,8 +77,8 @@ module Authlogic
69
77
  module Methods
70
78
  def self.included(klass)
71
79
  klass.class_eval do
72
- before_save :get_session_information, :if => :update_sessions?
73
- before_save :maintain_sessions, :if => :update_sessions?
80
+ before_save :get_session_information, if: :update_sessions?
81
+ before_save :maintain_sessions, if: :update_sessions?
74
82
  end
75
83
  end
76
84
 
@@ -96,11 +104,15 @@ module Authlogic
96
104
  !skip_session_maintenance &&
97
105
  session_class &&
98
106
  session_class.activated? &&
99
- self.class.maintain_sessions == true &&
107
+ maintain_session? &&
100
108
  !session_ids.blank? &&
101
109
  persistence_token_changed?
102
110
  end
103
111
 
112
+ def maintain_session?
113
+ log_in_after_create? || log_in_after_password_change?
114
+ end
115
+
104
116
  def get_session_information
105
117
  # Need to determine if we are completely logged out, or logged in as
106
118
  # another user.
@@ -148,6 +160,14 @@ module Authlogic
148
160
  def session_class
149
161
  self.class.session_class
150
162
  end
163
+
164
+ def log_in_after_create?
165
+ new_record? && self.class.log_in_after_create
166
+ end
167
+
168
+ def log_in_after_password_change?
169
+ persistence_token_changed? && self.class.log_in_after_password_change
170
+ end
151
171
  end
152
172
  end
153
173
  end