authlogic 3.8.0 → 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. checksums.yaml +7 -0
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +28 -0
  3. data/.github/ISSUE_TEMPLATE/feature_proposal.md +32 -0
  4. data/.github/triage.md +86 -0
  5. data/.gitignore +4 -3
  6. data/.rubocop.yml +109 -9
  7. data/.rubocop_todo.yml +38 -355
  8. data/.travis.yml +11 -35
  9. data/CHANGELOG.md +345 -2
  10. data/CONTRIBUTING.md +45 -14
  11. data/Gemfile +3 -2
  12. data/README.md +244 -90
  13. data/Rakefile +10 -10
  14. data/UPGRADING.md +22 -0
  15. data/authlogic.gemspec +34 -21
  16. data/doc/use_normal_rails_validation.md +82 -0
  17. data/gemfiles/Gemfile.rails-4.2.x +6 -0
  18. data/{test/gemfiles → gemfiles}/Gemfile.rails-5.1.x +2 -2
  19. data/{test/gemfiles → gemfiles}/Gemfile.rails-5.2.x +2 -2
  20. data/lib/authlogic/acts_as_authentic/base.rb +36 -24
  21. data/lib/authlogic/acts_as_authentic/email.rb +65 -31
  22. data/lib/authlogic/acts_as_authentic/logged_in_status.rb +14 -9
  23. data/lib/authlogic/acts_as_authentic/login.rb +61 -45
  24. data/lib/authlogic/acts_as_authentic/magic_columns.rb +6 -6
  25. data/lib/authlogic/acts_as_authentic/password.rb +267 -146
  26. data/lib/authlogic/acts_as_authentic/perishable_token.rb +24 -19
  27. data/lib/authlogic/acts_as_authentic/persistence_token.rb +10 -15
  28. data/lib/authlogic/acts_as_authentic/queries/find_with_case.rb +67 -0
  29. data/lib/authlogic/acts_as_authentic/restful_authentication.rb +50 -14
  30. data/lib/authlogic/acts_as_authentic/session_maintenance.rb +88 -60
  31. data/lib/authlogic/acts_as_authentic/single_access_token.rb +23 -11
  32. data/lib/authlogic/acts_as_authentic/validations_scope.rb +9 -6
  33. data/lib/authlogic/authenticates_many/association.rb +7 -7
  34. data/lib/authlogic/authenticates_many/base.rb +37 -21
  35. data/lib/authlogic/config.rb +21 -10
  36. data/lib/authlogic/controller_adapters/abstract_adapter.rb +38 -11
  37. data/lib/authlogic/controller_adapters/rack_adapter.rb +9 -5
  38. data/lib/authlogic/controller_adapters/rails_adapter.rb +12 -7
  39. data/lib/authlogic/controller_adapters/sinatra_adapter.rb +2 -2
  40. data/lib/authlogic/crypto_providers/aes256.rb +37 -32
  41. data/lib/authlogic/crypto_providers/bcrypt.rb +21 -15
  42. data/lib/authlogic/crypto_providers/md5.rb +4 -2
  43. data/lib/authlogic/crypto_providers/scrypt.rb +22 -17
  44. data/lib/authlogic/crypto_providers/sha1.rb +11 -5
  45. data/lib/authlogic/crypto_providers/sha256.rb +13 -9
  46. data/lib/authlogic/crypto_providers/sha512.rb +0 -21
  47. data/lib/authlogic/crypto_providers/wordpress.rb +32 -3
  48. data/lib/authlogic/crypto_providers.rb +91 -0
  49. data/lib/authlogic/i18n.rb +26 -19
  50. data/lib/authlogic/random.rb +10 -28
  51. data/lib/authlogic/regex.rb +59 -28
  52. data/lib/authlogic/session/activation.rb +10 -7
  53. data/lib/authlogic/session/active_record_trickery.rb +13 -9
  54. data/lib/authlogic/session/base.rb +15 -4
  55. data/lib/authlogic/session/brute_force_protection.rb +40 -33
  56. data/lib/authlogic/session/callbacks.rb +94 -46
  57. data/lib/authlogic/session/cookies.rb +130 -45
  58. data/lib/authlogic/session/existence.rb +21 -11
  59. data/lib/authlogic/session/foundation.rb +64 -14
  60. data/lib/authlogic/session/http_auth.rb +35 -28
  61. data/lib/authlogic/session/id.rb +9 -4
  62. data/lib/authlogic/session/klass.rb +15 -12
  63. data/lib/authlogic/session/magic_columns.rb +58 -55
  64. data/lib/authlogic/session/magic_states.rb +25 -19
  65. data/lib/authlogic/session/params.rb +42 -28
  66. data/lib/authlogic/session/password.rb +130 -120
  67. data/lib/authlogic/session/perishable_token.rb +5 -4
  68. data/lib/authlogic/session/persistence.rb +18 -12
  69. data/lib/authlogic/session/priority_record.rb +15 -12
  70. data/lib/authlogic/session/scopes.rb +51 -32
  71. data/lib/authlogic/session/session.rb +38 -28
  72. data/lib/authlogic/session/timeout.rb +13 -13
  73. data/lib/authlogic/session/unauthorized_record.rb +18 -13
  74. data/lib/authlogic/session/validation.rb +9 -9
  75. data/lib/authlogic/test_case/mock_controller.rb +5 -4
  76. data/lib/authlogic/test_case/mock_cookie_jar.rb +47 -3
  77. data/lib/authlogic/test_case/mock_request.rb +6 -3
  78. data/lib/authlogic/test_case/rails_request_adapter.rb +3 -2
  79. data/lib/authlogic/test_case.rb +70 -2
  80. data/lib/authlogic/version.rb +21 -0
  81. data/lib/authlogic.rb +51 -49
  82. data/test/acts_as_authentic_test/base_test.rb +3 -1
  83. data/test/acts_as_authentic_test/email_test.rb +43 -42
  84. data/test/acts_as_authentic_test/logged_in_status_test.rb +6 -4
  85. data/test/acts_as_authentic_test/login_test.rb +77 -80
  86. data/test/acts_as_authentic_test/magic_columns_test.rb +3 -1
  87. data/test/acts_as_authentic_test/password_test.rb +51 -37
  88. data/test/acts_as_authentic_test/perishable_token_test.rb +13 -5
  89. data/test/acts_as_authentic_test/persistence_token_test.rb +7 -1
  90. data/test/acts_as_authentic_test/restful_authentication_test.rb +14 -3
  91. data/test/acts_as_authentic_test/session_maintenance_test.rb +69 -15
  92. data/test/acts_as_authentic_test/single_access_test.rb +3 -1
  93. data/test/adapter_test.rb +23 -0
  94. data/test/authenticates_many_test.rb +3 -1
  95. data/test/config_test.rb +11 -9
  96. data/test/crypto_provider_test/aes256_test.rb +3 -1
  97. data/test/crypto_provider_test/bcrypt_test.rb +3 -1
  98. data/test/crypto_provider_test/scrypt_test.rb +3 -1
  99. data/test/crypto_provider_test/sha1_test.rb +3 -1
  100. data/test/crypto_provider_test/sha256_test.rb +3 -1
  101. data/test/crypto_provider_test/sha512_test.rb +3 -1
  102. data/test/crypto_provider_test/wordpress_test.rb +26 -0
  103. data/test/fixtures/companies.yml +2 -2
  104. data/test/fixtures/employees.yml +1 -1
  105. data/test/i18n_test.rb +6 -4
  106. data/test/libs/affiliate.rb +2 -0
  107. data/test/libs/company.rb +4 -2
  108. data/test/libs/employee.rb +2 -0
  109. data/test/libs/employee_session.rb +2 -0
  110. data/test/libs/ldaper.rb +2 -0
  111. data/test/libs/project.rb +2 -0
  112. data/test/libs/user.rb +2 -0
  113. data/test/libs/user_session.rb +4 -2
  114. data/test/random_test.rb +10 -38
  115. data/test/session_test/activation_test.rb +3 -1
  116. data/test/session_test/active_record_trickery_test.rb +7 -4
  117. data/test/session_test/brute_force_protection_test.rb +11 -9
  118. data/test/session_test/callbacks_test.rb +12 -4
  119. data/test/session_test/cookies_test.rb +48 -5
  120. data/test/session_test/existence_test.rb +18 -5
  121. data/test/session_test/foundation_test.rb +19 -1
  122. data/test/session_test/http_auth_test.rb +11 -7
  123. data/test/session_test/id_test.rb +3 -1
  124. data/test/session_test/klass_test.rb +3 -1
  125. data/test/session_test/magic_columns_test.rb +13 -13
  126. data/test/session_test/magic_states_test.rb +3 -1
  127. data/test/session_test/params_test.rb +13 -5
  128. data/test/session_test/password_test.rb +10 -8
  129. data/test/session_test/perishability_test.rb +3 -1
  130. data/test/session_test/persistence_test.rb +4 -1
  131. data/test/session_test/scopes_test.rb +16 -8
  132. data/test/session_test/session_test.rb +6 -4
  133. data/test/session_test/timeout_test.rb +4 -2
  134. data/test/session_test/unauthorized_record_test.rb +4 -2
  135. data/test/session_test/validation_test.rb +3 -1
  136. data/test/test_helper.rb +84 -45
  137. metadata +87 -73
  138. data/.github/ISSUE_TEMPLATE.md +0 -13
  139. data/test/gemfiles/Gemfile.rails-3.2.x +0 -7
  140. data/test/gemfiles/Gemfile.rails-4.0.x +0 -7
  141. data/test/gemfiles/Gemfile.rails-4.1.x +0 -7
  142. data/test/gemfiles/Gemfile.rails-4.2.x +0 -7
  143. data/test/gemfiles/Gemfile.rails-5.0.x +0 -6
@@ -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
@@ -25,14 +27,17 @@ module Authlogic
25
27
  # * <tt>Default:</tt> 10.minutes
26
28
  # * <tt>Accepts:</tt> Fixnum
27
29
  def perishable_token_valid_for(value = nil)
28
- rw_config(:perishable_token_valid_for, (!value.nil? && value.to_i) || value, 10.minutes.to_i)
30
+ rw_config(
31
+ :perishable_token_valid_for,
32
+ (!value.nil? && value.to_i) || value,
33
+ 10.minutes.to_i
34
+ )
29
35
  end
30
36
  alias_method :perishable_token_valid_for=, :perishable_token_valid_for
31
37
 
32
38
  # 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.
39
+ # possible, without compromising its purpose. If you want to manage it
40
+ # yourself, set this to true.
36
41
  #
37
42
  # * <tt>Default:</tt> false
38
43
  # * <tt>Accepts:</tt> Boolean
@@ -45,18 +50,18 @@ module Authlogic
45
50
  # All methods relating to the perishable token.
46
51
  module Methods
47
52
  def self.included(klass)
48
- return if !klass.column_names.include?("perishable_token")
53
+ return unless klass.column_names.include?("perishable_token")
49
54
 
50
55
  klass.class_eval do
51
56
  extend ClassMethods
52
57
  include InstanceMethods
53
58
 
54
- validates_uniqueness_of :perishable_token, :if => :perishable_token_changed?
55
- before_save :reset_perishable_token, :unless => :disable_perishable_token_maintenance?
59
+ validates_uniqueness_of :perishable_token, if: :perishable_token_changed?
60
+ before_save :reset_perishable_token, unless: :disable_perishable_token_maintenance?
56
61
  end
57
62
  end
58
63
 
59
- # Class level methods for the perishable token
64
+ # Class methods for the perishable token
60
65
  module ClassMethods
61
66
  # Use this method to find a record with a perishable token. This
62
67
  # method does 2 things for you:
@@ -68,7 +73,7 @@ module Authlogic
68
73
  # second parameter:
69
74
  #
70
75
  # User.find_using_perishable_token(token, 1.hour)
71
- def find_using_perishable_token(token, age = self.perishable_token_valid_for)
76
+ def find_using_perishable_token(token, age = perishable_token_valid_for)
72
77
  return if token.blank?
73
78
  age = age.to_i
74
79
 
@@ -99,7 +104,7 @@ module Authlogic
99
104
  # Same as reset_perishable_token, but then saves the record afterwards.
100
105
  def reset_perishable_token!
101
106
  reset_perishable_token
102
- save_without_session_maintenance(:validate => false)
107
+ save_without_session_maintenance(validate: false)
103
108
  end
104
109
 
105
110
  # 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, &:forget!)
43
38
  end
44
39
  end
45
40
 
@@ -53,15 +48,15 @@ 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
 
60
55
  private
61
56
 
62
- def reset_persistence_token?
63
- persistence_token.blank?
64
- end
57
+ def reset_persistence_token?
58
+ persistence_token.blank?
59
+ end
65
60
  end
66
61
  end
67
62
  end
@@ -0,0 +1,67 @@
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
+ # Dup ActiveRecord.gem_version before freezing, in case someone
10
+ # else wants to modify it. Freezing modifies an object in place.
11
+ # https://github.com/binarylogic/authlogic/pull/590
12
+ AR_GEM_VERSION = ActiveRecord.gem_version.dup.freeze
13
+
14
+ # @api private
15
+ def initialize(model_class, field, value, sensitive)
16
+ @model_class = model_class
17
+ @field = field.to_s
18
+ @value = value
19
+ @sensitive = sensitive
20
+ end
21
+
22
+ # @api private
23
+ def execute
24
+ bind(relation).first
25
+ end
26
+
27
+ private
28
+
29
+ # @api private
30
+ def bind(relation)
31
+ if AR_GEM_VERSION >= Gem::Version.new("5")
32
+ bind = ActiveRecord::Relation::QueryAttribute.new(
33
+ @field,
34
+ @value,
35
+ ActiveRecord::Type::Value.new
36
+ )
37
+ @model_class.where(relation, bind)
38
+ else
39
+ @model_class.where(relation)
40
+ end
41
+ end
42
+
43
+ # @api private
44
+ def relation
45
+ if !@sensitive
46
+ @model_class.connection.case_insensitive_comparison(
47
+ @model_class.arel_table,
48
+ @field,
49
+ @model_class.columns_hash[@field],
50
+ @value
51
+ )
52
+ elsif AR_GEM_VERSION >= Gem::Version.new("5.0")
53
+ @model_class.connection.case_sensitive_comparison(
54
+ @model_class.arel_table,
55
+ @field,
56
+ @model_class.columns_hash[@field],
57
+ @value
58
+ )
59
+ else
60
+ value = @model_class.connection.case_sensitive_modifier(@value, @field)
61
+ @model_class.arel_table[@field].eq(value)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -10,7 +10,18 @@ module Authlogic
10
10
  end
11
11
  end
12
12
 
13
+ # Configures the restful_authentication aspect of acts_as_authentic.
14
+ # These methods become class methods of ::ActiveRecord::Base.
13
15
  module Config
16
+ DPR_MSG = <<~STR.squish
17
+ Support for transitioning to authlogic from restful_authentication
18
+ (%s) is deprecated without replacement. restful_authentication is no
19
+ longer used in the ruby community, and the transition away from it is
20
+ complete. There is only one version of restful_authentication on
21
+ rubygems.org, it was released in 2009, and it's only compatible with
22
+ rails 2.3. It has been nine years since it was released.
23
+ STR
24
+
14
25
  # Switching an existing app to Authlogic from restful_authentication? No
15
26
  # problem, just set this true and your users won't know anything
16
27
  # changed. From your database perspective nothing will change at all.
@@ -26,7 +37,14 @@ module Authlogic
26
37
  set_restful_authentication_config if value
27
38
  r
28
39
  end
29
- alias_method :act_like_restful_authentication=, :act_like_restful_authentication
40
+
41
+ def act_like_restful_authentication=(value = nil)
42
+ ::ActiveSupport::Deprecation.warn(
43
+ format(DPR_MSG, "act_like_restful_authentication="),
44
+ caller(1)
45
+ )
46
+ act_like_restful_authentication(value)
47
+ end
30
48
 
31
49
  # This works just like act_like_restful_authentication except that it
32
50
  # will start transitioning your users to the algorithm you specify with
@@ -40,30 +58,48 @@ module Authlogic
40
58
  set_restful_authentication_config if value
41
59
  r
42
60
  end
43
- alias_method :transition_from_restful_authentication=, :transition_from_restful_authentication
61
+
62
+ def transition_from_restful_authentication=(value = nil)
63
+ ::ActiveSupport::Deprecation.warn(
64
+ format(DPR_MSG, "transition_from_restful_authentication="),
65
+ caller(1)
66
+ )
67
+ transition_from_restful_authentication(value)
68
+ end
44
69
 
45
70
  private
46
71
 
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)
50
- if !defined?(::REST_AUTH_SITE_KEY) || ::REST_AUTH_SITE_KEY.nil?
51
- class_eval("::REST_AUTH_SITE_KEY = ''") if !defined?(::REST_AUTH_SITE_KEY)
52
- CryptoProviders::Sha1.stretches = 1
72
+ def set_restful_authentication_config
73
+ self.restful_auth_crypto_provider = CryptoProviders::Sha1
74
+ if !defined?(::REST_AUTH_SITE_KEY) || ::REST_AUTH_SITE_KEY.nil?
75
+ unless defined?(::REST_AUTH_SITE_KEY)
76
+ class_eval("::REST_AUTH_SITE_KEY = ''", __FILE__, __LINE__)
53
77
  end
78
+ CryptoProviders::Sha1.stretches = 1
54
79
  end
80
+ end
81
+
82
+ # @api private
83
+ def restful_auth_crypto_provider=(provider)
84
+ if act_like_restful_authentication
85
+ self.crypto_provider = provider
86
+ else
87
+ self.transition_from_crypto_providers = provider
88
+ end
89
+ end
55
90
  end
56
91
 
92
+ # :nodoc:
57
93
  module InstanceMethods
58
94
  private
59
95
 
60
- def act_like_restful_authentication?
61
- self.class.act_like_restful_authentication == true
62
- end
96
+ def act_like_restful_authentication?
97
+ self.class.act_like_restful_authentication == true
98
+ end
63
99
 
64
- def transition_from_restful_authentication?
65
- self.class.transition_from_restful_authentication == true
66
- end
100
+ def transition_from_restful_authentication?
101
+ self.class.transition_from_restful_authentication == true
102
+ end
67
103
  end
68
104
  end
69
105
  end
@@ -29,18 +29,28 @@ module Authlogic
29
29
  end
30
30
  end
31
31
 
32
+ # Configuration for the session maintenance aspect of acts_as_authentic.
33
+ # These methods become class methods of ::ActiveRecord::Base.
32
34
  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.
35
+ # In order to turn off automatic maintenance of sessions
36
+ # after create, just set this to false.
37
37
  #
38
38
  # * <tt>Default:</tt> true
39
39
  # * <tt>Accepts:</tt> Boolean
40
- def maintain_sessions(value = nil)
41
- rw_config(:maintain_sessions, value, true)
40
+ def log_in_after_create(value = nil)
41
+ rw_config(:log_in_after_create, value, true)
42
42
  end
43
- alias_method :maintain_sessions=, :maintain_sessions
43
+ alias_method :log_in_after_create=, :log_in_after_create
44
+
45
+ # In order to turn off automatic maintenance of sessions when updating
46
+ # the password, just set this to false.
47
+ #
48
+ # * <tt>Default:</tt> true
49
+ # * <tt>Accepts:</tt> Boolean
50
+ def log_in_after_password_change(value = nil)
51
+ rw_config(:log_in_after_password_change, value, true)
52
+ end
53
+ alias_method :log_in_after_password_change=, :log_in_after_password_change
44
54
 
45
55
  # As you may know, authlogic sessions can be separate by id (See
46
56
  # Authlogic::Session::Base#id). You can specify here what session ids
@@ -60,17 +70,23 @@ module Authlogic
60
70
  # * <tt>Default:</tt> "#{klass.name}Session".constantize
61
71
  # * <tt>Accepts:</tt> Class
62
72
  def session_class(value = nil)
63
- const = "#{base_class.name}Session".constantize rescue nil
73
+ const = begin
74
+ "#{base_class.name}Session".constantize
75
+ rescue NameError
76
+ nil
77
+ end
64
78
  rw_config(:session_class, value, const)
65
79
  end
66
80
  alias_method :session_class=, :session_class
67
81
  end
68
82
 
83
+ # This module, as one of the `acts_as_authentic_modules`, is only included
84
+ # into an ActiveRecord model if that model calls `acts_as_authentic`.
69
85
  module Methods
70
86
  def self.included(klass)
71
87
  klass.class_eval do
72
- before_save :get_session_information, :if => :update_sessions?
73
- before_save :maintain_sessions, :if => :update_sessions?
88
+ before_save :get_session_information, if: :update_sessions?
89
+ before_save :maintain_sessions, if: :update_sessions?
74
90
  end
75
91
  end
76
92
 
@@ -84,70 +100,82 @@ module Authlogic
84
100
 
85
101
  private
86
102
 
87
- def skip_session_maintenance=(value)
88
- @skip_session_maintenance = value
89
- end
103
+ def skip_session_maintenance=(value)
104
+ @skip_session_maintenance = value
105
+ end
90
106
 
91
- def skip_session_maintenance
92
- @skip_session_maintenance ||= false
93
- end
107
+ def skip_session_maintenance
108
+ @skip_session_maintenance ||= false
109
+ end
94
110
 
95
- def update_sessions?
96
- !skip_session_maintenance &&
97
- session_class &&
98
- session_class.activated? &&
99
- self.class.maintain_sessions == true &&
100
- !session_ids.blank? &&
101
- persistence_token_changed?
102
- end
111
+ def update_sessions?
112
+ !skip_session_maintenance &&
113
+ session_class &&
114
+ session_class.activated? &&
115
+ maintain_session? &&
116
+ !session_ids.blank? &&
117
+ persistence_token_changed?
118
+ end
119
+
120
+ def maintain_session?
121
+ log_in_after_create? || log_in_after_password_change?
122
+ end
103
123
 
104
- def get_session_information
105
- # Need to determine if we are completely logged out, or logged in as
106
- # another user.
107
- @_sessions = []
124
+ def get_session_information
125
+ # Need to determine if we are completely logged out, or logged in as
126
+ # another user.
127
+ @_sessions = []
108
128
 
109
- session_ids.each do |session_id|
110
- session = session_class.find(session_id, self)
111
- @_sessions << session if session && session.record
112
- end
129
+ session_ids.each do |session_id|
130
+ session = session_class.find(session_id, self)
131
+ @_sessions << session if session&.record
113
132
  end
133
+ end
114
134
 
115
- def maintain_sessions
116
- if @_sessions.empty?
117
- create_session
118
- else
119
- update_sessions
120
- end
135
+ def maintain_sessions
136
+ if @_sessions.empty?
137
+ create_session
138
+ else
139
+ update_sessions
121
140
  end
141
+ end
122
142
 
123
- def create_session
124
- # We only want to automatically login into the first session, since
125
- # this is the main session. The other sessions are sessions that
126
- # need to be created after logging into the main session.
127
- session_id = session_ids.first
128
- session_class.create(*[self, self, session_id].compact)
143
+ def create_session
144
+ # We only want to automatically login into the first session, since
145
+ # this is the main session. The other sessions are sessions that
146
+ # need to be created after logging into the main session.
147
+ session_id = session_ids.first
148
+ session_class.create(*[self, self, session_id].compact)
149
+
150
+ true
151
+ end
129
152
 
130
- return true
153
+ def update_sessions
154
+ # We found sessions above, let's update them with the new info
155
+ @_sessions.each do |stale_session|
156
+ next if stale_session.record != self
157
+ stale_session.unauthorized_record = self
158
+ stale_session.save
131
159
  end
132
160
 
133
- def update_sessions
134
- # We found sessions above, let's update them with the new info
135
- @_sessions.each do |stale_session|
136
- next if stale_session.record != self
137
- stale_session.unauthorized_record = self
138
- stale_session.save
139
- end
161
+ true
162
+ end
140
163
 
141
- return true
142
- end
164
+ def session_ids
165
+ self.class.session_ids
166
+ end
143
167
 
144
- def session_ids
145
- self.class.session_ids
146
- end
168
+ def session_class
169
+ self.class.session_class
170
+ end
147
171
 
148
- def session_class
149
- self.class.session_class
150
- end
172
+ def log_in_after_create?
173
+ new_record? && self.class.log_in_after_create
174
+ end
175
+
176
+ def log_in_after_password_change?
177
+ persistence_token_changed? && self.class.log_in_after_password_change
178
+ end
151
179
  end
152
180
  end
153
181
  end
@@ -12,6 +12,8 @@ module Authlogic
12
12
  end
13
13
 
14
14
  # All configuration for the single_access token aspect of acts_as_authentic.
15
+ #
16
+ # These methods become class methods of ::ActiveRecord::Base.
15
17
  module Config
16
18
  # The single access token is used for authentication via URLs, such as a private
17
19
  # feed. That being said, if the user changes their password, that token probably
@@ -23,24 +25,34 @@ module Authlogic
23
25
  def change_single_access_token_with_password(value = nil)
24
26
  rw_config(:change_single_access_token_with_password, value, false)
25
27
  end
26
- alias_method :change_single_access_token_with_password=, :change_single_access_token_with_password
28
+ alias_method(
29
+ :change_single_access_token_with_password=,
30
+ :change_single_access_token_with_password
31
+ )
27
32
  end
28
33
 
29
34
  # All method, for the single_access token aspect of acts_as_authentic.
35
+ #
36
+ # This module, as one of the `acts_as_authentic_modules`, is only included
37
+ # into an ActiveRecord model if that model calls `acts_as_authentic`.
30
38
  module Methods
31
39
  def self.included(klass)
32
- return if !klass.column_names.include?("single_access_token")
40
+ return unless klass.column_names.include?("single_access_token")
33
41
 
34
42
  klass.class_eval do
35
43
  include InstanceMethods
36
- validates_uniqueness_of :single_access_token, :if => :single_access_token_changed?
37
- before_validation :reset_single_access_token, :if => :reset_single_access_token?
44
+ validates_uniqueness_of :single_access_token, if: :single_access_token_changed?
45
+ before_validation :reset_single_access_token, if: :reset_single_access_token?
38
46
  if respond_to?(:after_password_set)
39
- after_password_set(:reset_single_access_token, :if => :change_single_access_token_with_password?)
47
+ after_password_set(
48
+ :reset_single_access_token,
49
+ if: :change_single_access_token_with_password?
50
+ )
40
51
  end
41
52
  end
42
53
  end
43
54
 
55
+ # :nodoc:
44
56
  module InstanceMethods
45
57
  # Resets the single_access_token to a random friendly token.
46
58
  def reset_single_access_token
@@ -55,13 +67,13 @@ module Authlogic
55
67
 
56
68
  protected
57
69
 
58
- def reset_single_access_token?
59
- single_access_token.blank?
60
- end
70
+ def reset_single_access_token?
71
+ single_access_token.blank?
72
+ end
61
73
 
62
- def change_single_access_token_with_password?
63
- self.class.change_single_access_token_with_password == true
64
- end
74
+ def change_single_access_token_with_password?
75
+ self.class.change_single_access_token_with_password == true
76
+ end
65
77
  end
66
78
  end
67
79
  end
@@ -1,8 +1,8 @@
1
1
  module Authlogic
2
2
  module ActsAsAuthentic
3
- # Allows you to scope everything to specific fields.
4
- # See the Config submodule for more info.
5
- # For information on how to scope off of a parent object see Authlogic::AuthenticatesMany
3
+ # Allows you to scope everything to specific fields. See the Config
4
+ # submodule for more info. For information on how to scope off of a parent
5
+ # object see Authlogic::AuthenticatesMany
6
6
  module ValidationsScope
7
7
  def self.included(klass)
8
8
  klass.class_eval do
@@ -12,9 +12,9 @@ module Authlogic
12
12
 
13
13
  # All configuration for the scope feature.
14
14
  module Config
15
- # Allows you to scope everything to specific field(s). Works just like validates_uniqueness_of.
16
- # For example, let's say a user belongs to a company, and you want to scope everything to the
17
- # company:
15
+ # Allows you to scope everything to specific field(s). Works just like
16
+ # validates_uniqueness_of. For example, let's say a user belongs to a
17
+ # company, and you want to scope everything to the company:
18
18
  #
19
19
  # acts_as_authentic do |c|
20
20
  # c.validations_scope = :company_id
@@ -22,7 +22,10 @@ module Authlogic
22
22
  #
23
23
  # * <tt>Default:</tt> nil
24
24
  # * <tt>Accepts:</tt> Symbol or Array of symbols
25
+ #
26
+ # @deprecated
25
27
  def validations_scope(value = nil)
28
+ deprecate_authlogic_config("validations_scope") if value
26
29
  rw_config(:validations_scope, value)
27
30
  end
28
31
  alias_method :validations_scope=, :validations_scope
@@ -13,7 +13,7 @@ module Authlogic
13
13
  # that specific account. To implement this via ActiveRecord do something
14
14
  # like:
15
15
  #
16
- # class User < ActiveRecord::Base
16
+ # class User < ApplicationRecord
17
17
  # authenticates_many :user_sessions
18
18
  # end
19
19
  class Association
@@ -29,22 +29,22 @@ module Authlogic
29
29
  self.id = id
30
30
  end
31
31
 
32
- [:create, :create!, :find, :new].each do |method|
33
- class_eval <<-"end_eval", __FILE__, __LINE__
32
+ %i[create create! find new].each do |method|
33
+ class_eval <<-EOS, __FILE__, __LINE__ + 1
34
34
  def #{method}(*args)
35
35
  klass.with_scope(scope_options) do
36
36
  klass.#{method}(*args)
37
37
  end
38
38
  end
39
- end_eval
39
+ EOS
40
40
  end
41
41
  alias_method :build, :new
42
42
 
43
43
  private
44
44
 
45
- def scope_options
46
- { :find_options => find_options, :id => id }
47
- end
45
+ def scope_options
46
+ { find_options: find_options, id: id }
47
+ end
48
48
  end
49
49
  end
50
50
  end