authlogic 3.8.0 → 6.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 (150) hide show
  1. checksums.yaml +7 -0
  2. data/lib/authlogic/acts_as_authentic/base.rb +33 -36
  3. data/lib/authlogic/acts_as_authentic/email.rb +8 -141
  4. data/lib/authlogic/acts_as_authentic/logged_in_status.rb +17 -10
  5. data/lib/authlogic/acts_as_authentic/login.rb +14 -165
  6. data/lib/authlogic/acts_as_authentic/magic_columns.rb +13 -10
  7. data/lib/authlogic/acts_as_authentic/password.rb +186 -254
  8. data/lib/authlogic/acts_as_authentic/perishable_token.rb +30 -22
  9. data/lib/authlogic/acts_as_authentic/persistence_token.rb +19 -18
  10. data/lib/authlogic/acts_as_authentic/queries/case_sensitivity.rb +53 -0
  11. data/lib/authlogic/acts_as_authentic/queries/find_with_case.rb +83 -0
  12. data/lib/authlogic/acts_as_authentic/session_maintenance.rb +94 -62
  13. data/lib/authlogic/acts_as_authentic/single_access_token.rb +28 -14
  14. data/lib/authlogic/config.rb +29 -10
  15. data/lib/authlogic/controller_adapters/abstract_adapter.rb +43 -13
  16. data/lib/authlogic/controller_adapters/rack_adapter.rb +11 -5
  17. data/lib/authlogic/controller_adapters/rails_adapter.rb +11 -29
  18. data/lib/authlogic/controller_adapters/sinatra_adapter.rb +8 -2
  19. data/lib/authlogic/cookie_credentials.rb +63 -0
  20. data/lib/authlogic/crypto_providers/bcrypt.rb +24 -18
  21. data/lib/authlogic/crypto_providers/md5/v2.rb +35 -0
  22. data/lib/authlogic/crypto_providers/md5.rb +8 -6
  23. data/lib/authlogic/crypto_providers/scrypt.rb +24 -17
  24. data/lib/authlogic/crypto_providers/sha1/v2.rb +41 -0
  25. data/lib/authlogic/crypto_providers/sha1.rb +12 -5
  26. data/lib/authlogic/crypto_providers/sha256/v2.rb +58 -0
  27. data/lib/authlogic/crypto_providers/sha256.rb +18 -9
  28. data/lib/authlogic/crypto_providers/sha512/v2.rb +39 -0
  29. data/lib/authlogic/crypto_providers/sha512.rb +9 -26
  30. data/lib/authlogic/crypto_providers.rb +77 -1
  31. data/lib/authlogic/errors.rb +35 -0
  32. data/lib/authlogic/i18n/translator.rb +4 -1
  33. data/lib/authlogic/i18n.rb +29 -20
  34. data/lib/authlogic/random.rb +12 -28
  35. data/lib/authlogic/session/base.rb +2087 -33
  36. data/lib/authlogic/session/magic_column/assigns_last_request_at.rb +46 -0
  37. data/lib/authlogic/test_case/mock_controller.rb +7 -4
  38. data/lib/authlogic/test_case/mock_cookie_jar.rb +19 -3
  39. data/lib/authlogic/test_case/mock_logger.rb +2 -0
  40. data/lib/authlogic/test_case/mock_request.rb +8 -3
  41. data/lib/authlogic/test_case/rails_request_adapter.rb +5 -2
  42. data/lib/authlogic/test_case.rb +74 -2
  43. data/lib/authlogic/version.rb +22 -0
  44. data/lib/authlogic.rb +33 -54
  45. metadata +208 -234
  46. data/.github/ISSUE_TEMPLATE.md +0 -13
  47. data/.gitignore +0 -14
  48. data/.rubocop.yml +0 -33
  49. data/.rubocop_todo.yml +0 -391
  50. data/.travis.yml +0 -48
  51. data/CHANGELOG.md +0 -5
  52. data/CONTRIBUTING.md +0 -60
  53. data/Gemfile +0 -5
  54. data/LICENSE +0 -20
  55. data/README.md +0 -294
  56. data/Rakefile +0 -21
  57. data/authlogic.gemspec +0 -27
  58. data/lib/authlogic/acts_as_authentic/restful_authentication.rb +0 -70
  59. data/lib/authlogic/acts_as_authentic/validations_scope.rb +0 -32
  60. data/lib/authlogic/authenticates_many/association.rb +0 -50
  61. data/lib/authlogic/authenticates_many/base.rb +0 -65
  62. data/lib/authlogic/crypto_providers/aes256.rb +0 -66
  63. data/lib/authlogic/crypto_providers/wordpress.rb +0 -43
  64. data/lib/authlogic/regex.rb +0 -48
  65. data/lib/authlogic/session/activation.rb +0 -70
  66. data/lib/authlogic/session/active_record_trickery.rb +0 -61
  67. data/lib/authlogic/session/brute_force_protection.rb +0 -120
  68. data/lib/authlogic/session/callbacks.rb +0 -105
  69. data/lib/authlogic/session/cookies.rb +0 -244
  70. data/lib/authlogic/session/existence.rb +0 -93
  71. data/lib/authlogic/session/foundation.rb +0 -55
  72. data/lib/authlogic/session/http_auth.rb +0 -100
  73. data/lib/authlogic/session/id.rb +0 -48
  74. data/lib/authlogic/session/klass.rb +0 -70
  75. data/lib/authlogic/session/magic_columns.rb +0 -116
  76. data/lib/authlogic/session/magic_states.rb +0 -76
  77. data/lib/authlogic/session/params.rb +0 -116
  78. data/lib/authlogic/session/password.rb +0 -308
  79. data/lib/authlogic/session/perishable_token.rb +0 -23
  80. data/lib/authlogic/session/persistence.rb +0 -71
  81. data/lib/authlogic/session/priority_record.rb +0 -35
  82. data/lib/authlogic/session/scopes.rb +0 -119
  83. data/lib/authlogic/session/session.rb +0 -67
  84. data/lib/authlogic/session/timeout.rb +0 -103
  85. data/lib/authlogic/session/unauthorized_record.rb +0 -51
  86. data/lib/authlogic/session/validation.rb +0 -93
  87. data/test/acts_as_authentic_test/base_test.rb +0 -25
  88. data/test/acts_as_authentic_test/email_test.rb +0 -240
  89. data/test/acts_as_authentic_test/logged_in_status_test.rb +0 -62
  90. data/test/acts_as_authentic_test/login_test.rb +0 -156
  91. data/test/acts_as_authentic_test/magic_columns_test.rb +0 -27
  92. data/test/acts_as_authentic_test/password_test.rb +0 -249
  93. data/test/acts_as_authentic_test/perishable_token_test.rb +0 -90
  94. data/test/acts_as_authentic_test/persistence_token_test.rb +0 -56
  95. data/test/acts_as_authentic_test/restful_authentication_test.rb +0 -37
  96. data/test/acts_as_authentic_test/session_maintenance_test.rb +0 -96
  97. data/test/acts_as_authentic_test/single_access_test.rb +0 -44
  98. data/test/authenticates_many_test.rb +0 -31
  99. data/test/config_test.rb +0 -36
  100. data/test/crypto_provider_test/aes256_test.rb +0 -14
  101. data/test/crypto_provider_test/bcrypt_test.rb +0 -14
  102. data/test/crypto_provider_test/scrypt_test.rb +0 -14
  103. data/test/crypto_provider_test/sha1_test.rb +0 -23
  104. data/test/crypto_provider_test/sha256_test.rb +0 -14
  105. data/test/crypto_provider_test/sha512_test.rb +0 -14
  106. data/test/fixtures/companies.yml +0 -5
  107. data/test/fixtures/employees.yml +0 -17
  108. data/test/fixtures/projects.yml +0 -3
  109. data/test/fixtures/users.yml +0 -41
  110. data/test/gemfiles/Gemfile.rails-3.2.x +0 -7
  111. data/test/gemfiles/Gemfile.rails-4.0.x +0 -7
  112. data/test/gemfiles/Gemfile.rails-4.1.x +0 -7
  113. data/test/gemfiles/Gemfile.rails-4.2.x +0 -7
  114. data/test/gemfiles/Gemfile.rails-5.0.x +0 -6
  115. data/test/gemfiles/Gemfile.rails-5.1.x +0 -6
  116. data/test/gemfiles/Gemfile.rails-5.2.x +0 -6
  117. data/test/i18n/lol.yml +0 -4
  118. data/test/i18n_test.rb +0 -33
  119. data/test/libs/affiliate.rb +0 -7
  120. data/test/libs/company.rb +0 -6
  121. data/test/libs/employee.rb +0 -7
  122. data/test/libs/employee_session.rb +0 -2
  123. data/test/libs/ldaper.rb +0 -3
  124. data/test/libs/project.rb +0 -3
  125. data/test/libs/user.rb +0 -7
  126. data/test/libs/user_session.rb +0 -25
  127. data/test/random_test.rb +0 -43
  128. data/test/session_test/activation_test.rb +0 -43
  129. data/test/session_test/active_record_trickery_test.rb +0 -75
  130. data/test/session_test/brute_force_protection_test.rb +0 -108
  131. data/test/session_test/callbacks_test.rb +0 -34
  132. data/test/session_test/cookies_test.rb +0 -201
  133. data/test/session_test/credentials_test.rb +0 -0
  134. data/test/session_test/existence_test.rb +0 -75
  135. data/test/session_test/foundation_test.rb +0 -6
  136. data/test/session_test/http_auth_test.rb +0 -56
  137. data/test/session_test/id_test.rb +0 -17
  138. data/test/session_test/klass_test.rb +0 -40
  139. data/test/session_test/magic_columns_test.rb +0 -62
  140. data/test/session_test/magic_states_test.rb +0 -58
  141. data/test/session_test/params_test.rb +0 -53
  142. data/test/session_test/password_test.rb +0 -105
  143. data/test/session_test/perishability_test.rb +0 -15
  144. data/test/session_test/persistence_test.rb +0 -32
  145. data/test/session_test/scopes_test.rb +0 -60
  146. data/test/session_test/session_test.rb +0 -78
  147. data/test/session_test/timeout_test.rb +0 -82
  148. data/test/session_test/unauthorized_record_test.rb +0 -13
  149. data/test/session_test/validation_test.rb +0 -23
  150. data/test/test_helper.rb +0 -233
@@ -1,13 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Authlogic
2
4
  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.
5
+ # This provides a handy token that is "perishable", meaning the token is
6
+ # only good for a certain amount of time.
7
+ #
8
+ # This is useful for resetting password, confirming accounts, etc. Typically
9
+ # during these actions you send them this token in an email. Once they use
10
+ # the token and do what they need to do, that token should expire.
11
+ #
12
+ # Don't worry about maintaining the token, changing it, or expiring it
13
+ # yourself. Authlogic does all of this for you. See the sub modules for all
14
+ # of the tools Authlogic provides to you.
11
15
  module PerishableToken
12
16
  def self.included(klass)
13
17
  klass.class_eval do
@@ -16,7 +20,7 @@ module Authlogic
16
20
  end
17
21
  end
18
22
 
19
- # Change how the perishable token works.
23
+ # Configure the perishable token.
20
24
  module Config
21
25
  # When using the find_using_perishable_token method the token can
22
26
  # expire. If the token is expired, no record will be returned. Use this
@@ -25,38 +29,42 @@ module Authlogic
25
29
  # * <tt>Default:</tt> 10.minutes
26
30
  # * <tt>Accepts:</tt> Fixnum
27
31
  def perishable_token_valid_for(value = nil)
28
- rw_config(:perishable_token_valid_for, (!value.nil? && value.to_i) || value, 10.minutes.to_i)
32
+ rw_config(
33
+ :perishable_token_valid_for,
34
+ (!value.nil? && value.to_i) || value,
35
+ 10.minutes.to_i
36
+ )
29
37
  end
30
- alias_method :perishable_token_valid_for=, :perishable_token_valid_for
38
+ alias perishable_token_valid_for= perishable_token_valid_for
31
39
 
32
40
  # 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.
41
+ # possible, without compromising its purpose. If you want to manage it
42
+ # yourself, set this to true.
36
43
  #
37
44
  # * <tt>Default:</tt> false
38
45
  # * <tt>Accepts:</tt> Boolean
39
46
  def disable_perishable_token_maintenance(value = nil)
40
47
  rw_config(:disable_perishable_token_maintenance, value, false)
41
48
  end
42
- alias_method :disable_perishable_token_maintenance=, :disable_perishable_token_maintenance
49
+ alias disable_perishable_token_maintenance= disable_perishable_token_maintenance
43
50
  end
44
51
 
45
52
  # All methods relating to the perishable token.
46
53
  module Methods
47
54
  def self.included(klass)
48
- return if !klass.column_names.include?("perishable_token")
55
+ return unless klass.column_names.include?("perishable_token")
49
56
 
50
57
  klass.class_eval do
51
58
  extend ClassMethods
52
59
  include InstanceMethods
53
60
 
54
- validates_uniqueness_of :perishable_token, :if => :perishable_token_changed?
55
- before_save :reset_perishable_token, :unless => :disable_perishable_token_maintenance?
61
+ validates_uniqueness_of :perishable_token, case_sensitive: true,
62
+ if: :will_save_change_to_perishable_token?
63
+ before_save :reset_perishable_token, unless: :disable_perishable_token_maintenance?
56
64
  end
57
65
  end
58
66
 
59
- # Class level methods for the perishable token
67
+ # :nodoc:
60
68
  module ClassMethods
61
69
  # Use this method to find a record with a perishable token. This
62
70
  # method does 2 things for you:
@@ -68,7 +76,7 @@ module Authlogic
68
76
  # second parameter:
69
77
  #
70
78
  # User.find_using_perishable_token(token, 1.hour)
71
- def find_using_perishable_token(token, age = self.perishable_token_valid_for)
79
+ def find_using_perishable_token(token, age = perishable_token_valid_for)
72
80
  return if token.blank?
73
81
  age = age.to_i
74
82
 
@@ -89,7 +97,7 @@ module Authlogic
89
97
  end
90
98
  end
91
99
 
92
- # Instance level methods for the perishable token.
100
+ # :nodoc:
93
101
  module InstanceMethods
94
102
  # Resets the perishable token to a random friendly token.
95
103
  def reset_perishable_token
@@ -99,7 +107,7 @@ module Authlogic
99
107
  # Same as reset_perishable_token, but then saves the record afterwards.
100
108
  def reset_perishable_token!
101
109
  reset_perishable_token
102
- save_without_session_maintenance(:validate => false)
110
+ save_without_session_maintenance(validate: false)
103
111
  end
104
112
 
105
113
  # A convenience method based on the
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Authlogic
2
4
  module ActsAsAuthentic
3
5
  # Maintains the persistence token, the token responsible for persisting sessions. This token
@@ -16,34 +18,33 @@ module Authlogic
16
18
  extend ClassMethods
17
19
  include InstanceMethods
18
20
 
21
+ # If the table does not have a password column, then
22
+ # `after_password_set` etc. will not be defined. See
23
+ # `Authlogic::ActsAsAuthentic::Password::Callbacks.included`
19
24
  if respond_to?(:after_password_set) && respond_to?(:after_password_verification)
20
25
  after_password_set :reset_persistence_token
21
- after_password_verification :reset_persistence_token!, :if => :reset_persistence_token?
26
+ after_password_verification :reset_persistence_token!, if: :reset_persistence_token?
22
27
  end
23
28
 
24
29
  validates_presence_of :persistence_token
25
- validates_uniqueness_of :persistence_token, :if => :persistence_token_changed?
30
+ validates_uniqueness_of :persistence_token, case_sensitive: true,
31
+ if: :will_save_change_to_persistence_token?
26
32
 
27
- before_validation :reset_persistence_token, :if => :reset_persistence_token?
33
+ before_validation :reset_persistence_token, if: :reset_persistence_token?
28
34
  end
29
35
  end
30
36
 
31
- # Class level methods for the persistence token.
37
+ # :nodoc:
32
38
  module ClassMethods
33
- # Resets ALL persistence tokens in the database, which will require all users to reauthenticate.
39
+ # Resets ALL persistence tokens in the database, which will require
40
+ # all users to re-authenticate.
34
41
  def forget_all
35
42
  # 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?
43
+ find_each(batch_size: 50, &:forget!)
43
44
  end
44
45
  end
45
46
 
46
- # Instance level methods for the persistence token.
47
+ # :nodoc:
47
48
  module InstanceMethods
48
49
  # Resets the persistence_token field to a random hex value.
49
50
  def reset_persistence_token
@@ -53,15 +54,15 @@ module Authlogic
53
54
  # Same as reset_persistence_token, but then saves the record.
54
55
  def reset_persistence_token!
55
56
  reset_persistence_token
56
- save_without_session_maintenance(:validate => false)
57
+ save_without_session_maintenance(validate: false)
57
58
  end
58
- alias_method :forget!, :reset_persistence_token!
59
+ alias forget! reset_persistence_token!
59
60
 
60
61
  private
61
62
 
62
- def reset_persistence_token?
63
- persistence_token.blank?
64
- end
63
+ def reset_persistence_token?
64
+ persistence_token.blank?
65
+ end
65
66
  end
66
67
  end
67
68
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Authlogic
4
+ module ActsAsAuthentic
5
+ module Queries
6
+ # @api private
7
+ class CaseSensitivity
8
+ E_UNABLE_TO_DETERMINE_SENSITIVITY = <<~EOS
9
+ Authlogic was unable to determine what case-sensitivity to use when
10
+ searching for email/login. To specify a sensitivity, validate the
11
+ uniqueness of the email/login and use the `case_sensitive` option,
12
+ like this:
13
+
14
+ validates :email, uniqueness: { case_sensitive: false }
15
+
16
+ Authlogic will now perform a case-insensitive query.
17
+ EOS
18
+
19
+ # @api private
20
+ def initialize(model_class, attribute)
21
+ @model_class = model_class
22
+ @attribute = attribute.to_sym
23
+ end
24
+
25
+ # @api private
26
+ def sensitive?
27
+ sensitive = uniqueness_validator_options[:case_sensitive]
28
+ if sensitive.nil?
29
+ ::Kernel.warn(E_UNABLE_TO_DETERMINE_SENSITIVITY)
30
+ false
31
+ else
32
+ sensitive
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ # @api private
39
+ def uniqueness_validator
40
+ @model_class.validators.select { |v|
41
+ v.is_a?(::ActiveRecord::Validations::UniquenessValidator) &&
42
+ v.attributes == [@attribute]
43
+ }.first
44
+ end
45
+
46
+ # @api private
47
+ def uniqueness_validator_options
48
+ uniqueness_validator&.options || {}
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,83 @@
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
+ #
8
+ # We use the rails methods `case_insensitive_comparison` and
9
+ # `case_sensitive_comparison`. These methods nicely take into account
10
+ # MySQL collations. (Consider the case where a user *says* they want a
11
+ # case-sensitive uniqueness validation, but then they configure their
12
+ # database to have an insensitive collation. Rails will handle this for
13
+ # us, by downcasing, see
14
+ # `active_record/connection_adapters/abstract_mysql_adapter.rb`) So that's
15
+ # great! But, these methods are not part of rails' public API, so there
16
+ # are no docs. So, everything we know about how to use the methods
17
+ # correctly comes from mimicing what we find in
18
+ # `active_record/validations/uniqueness.rb`.
19
+ #
20
+ # @api private
21
+ class FindWithCase
22
+ # Dup ActiveRecord.gem_version before freezing, in case someone
23
+ # else wants to modify it. Freezing modifies an object in place.
24
+ # https://github.com/binarylogic/authlogic/pull/590
25
+ AR_GEM_VERSION = ::ActiveRecord.gem_version.dup.freeze
26
+
27
+ # @api private
28
+ def initialize(model_class, field, value, sensitive)
29
+ @model_class = model_class
30
+ @field = field.to_s
31
+ @value = value
32
+ @sensitive = sensitive
33
+ end
34
+
35
+ # @api private
36
+ def execute
37
+ @model_class.where(comparison).first
38
+ end
39
+
40
+ private
41
+
42
+ # @api private
43
+ # @return Arel::Nodes::Equality
44
+ def comparison
45
+ @sensitive ? sensitive_comparison : insensitive_comparison
46
+ end
47
+
48
+ # @api private
49
+ def insensitive_comparison
50
+ if AR_GEM_VERSION > Gem::Version.new("5.3")
51
+ @model_class.connection.case_insensitive_comparison(
52
+ @model_class.arel_table[@field], @value
53
+ )
54
+ else
55
+ @model_class.connection.case_insensitive_comparison(
56
+ @model_class.arel_table,
57
+ @field,
58
+ @model_class.columns_hash[@field],
59
+ @value
60
+ )
61
+ end
62
+ end
63
+
64
+ # @api private
65
+ def sensitive_comparison
66
+ bound_value = @model_class.predicate_builder.build_bind_attribute(@field, @value)
67
+ if AR_GEM_VERSION > Gem::Version.new("5.3")
68
+ @model_class.connection.case_sensitive_comparison(
69
+ @model_class.arel_table[@field], bound_value
70
+ )
71
+ else
72
+ @model_class.connection.case_sensitive_comparison(
73
+ @model_class.arel_table,
74
+ @field,
75
+ @model_class.columns_hash[@field],
76
+ bound_value
77
+ )
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Authlogic
2
4
  module ActsAsAuthentic
3
5
  # This is one of my favorite features that I think is pretty cool. It's
@@ -29,18 +31,28 @@ module Authlogic
29
31
  end
30
32
  end
31
33
 
34
+ # Configuration for the session maintenance aspect of acts_as_authentic.
35
+ # These methods become class methods of ::ActiveRecord::Base.
32
36
  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.
37
+ # In order to turn off automatic maintenance of sessions
38
+ # after create, just set this to false.
37
39
  #
38
40
  # * <tt>Default:</tt> true
39
41
  # * <tt>Accepts:</tt> Boolean
40
- def maintain_sessions(value = nil)
41
- rw_config(:maintain_sessions, value, true)
42
+ def log_in_after_create(value = nil)
43
+ rw_config(:log_in_after_create, value, true)
42
44
  end
43
- alias_method :maintain_sessions=, :maintain_sessions
45
+ alias log_in_after_create= log_in_after_create
46
+
47
+ # In order to turn off automatic maintenance of sessions when updating
48
+ # the password, just set this to false.
49
+ #
50
+ # * <tt>Default:</tt> true
51
+ # * <tt>Accepts:</tt> Boolean
52
+ def log_in_after_password_change(value = nil)
53
+ rw_config(:log_in_after_password_change, value, true)
54
+ end
55
+ alias log_in_after_password_change= log_in_after_password_change
44
56
 
45
57
  # As you may know, authlogic sessions can be separate by id (See
46
58
  # Authlogic::Session::Base#id). You can specify here what session ids
@@ -52,7 +64,7 @@ module Authlogic
52
64
  def session_ids(value = nil)
53
65
  rw_config(:session_ids, value, [nil])
54
66
  end
55
- alias_method :session_ids=, :session_ids
67
+ alias session_ids= session_ids
56
68
 
57
69
  # The name of the associated session class. This is inferred by the name
58
70
  # of the model.
@@ -60,17 +72,23 @@ module Authlogic
60
72
  # * <tt>Default:</tt> "#{klass.name}Session".constantize
61
73
  # * <tt>Accepts:</tt> Class
62
74
  def session_class(value = nil)
63
- const = "#{base_class.name}Session".constantize rescue nil
75
+ const = begin
76
+ "#{base_class.name}Session".constantize
77
+ rescue NameError
78
+ nil
79
+ end
64
80
  rw_config(:session_class, value, const)
65
81
  end
66
- alias_method :session_class=, :session_class
82
+ alias session_class= session_class
67
83
  end
68
84
 
85
+ # This module, as one of the `acts_as_authentic_modules`, is only included
86
+ # into an ActiveRecord model if that model calls `acts_as_authentic`.
69
87
  module Methods
70
88
  def self.included(klass)
71
89
  klass.class_eval do
72
- before_save :get_session_information, :if => :update_sessions?
73
- before_save :maintain_sessions, :if => :update_sessions?
90
+ before_save :get_session_information, if: :update_sessions?
91
+ before_save :maintain_sessions, if: :update_sessions?
74
92
  end
75
93
  end
76
94
 
@@ -84,70 +102,84 @@ module Authlogic
84
102
 
85
103
  private
86
104
 
87
- def skip_session_maintenance=(value)
88
- @skip_session_maintenance = value
89
- end
105
+ def skip_session_maintenance=(value)
106
+ @skip_session_maintenance = value
107
+ end
90
108
 
91
- def skip_session_maintenance
92
- @skip_session_maintenance ||= false
93
- end
109
+ def skip_session_maintenance
110
+ @skip_session_maintenance ||= false
111
+ end
94
112
 
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
113
+ def update_sessions?
114
+ !skip_session_maintenance &&
115
+ session_class &&
116
+ session_class.activated? &&
117
+ maintain_session? &&
118
+ !session_ids.blank? &&
119
+ will_save_change_to_persistence_token?
120
+ end
121
+
122
+ def maintain_session?
123
+ log_in_after_create? || log_in_after_password_change?
124
+ end
103
125
 
104
- def get_session_information
105
- # Need to determine if we are completely logged out, or logged in as
106
- # another user.
107
- @_sessions = []
126
+ def get_session_information
127
+ # Need to determine if we are completely logged out, or logged in as
128
+ # another user.
129
+ @_sessions = []
108
130
 
109
- session_ids.each do |session_id|
110
- session = session_class.find(session_id, self)
111
- @_sessions << session if session && session.record
112
- end
131
+ session_ids.each do |session_id|
132
+ session = session_class.find(session_id, self)
133
+ @_sessions << session if session&.record
113
134
  end
135
+ end
114
136
 
115
- def maintain_sessions
116
- if @_sessions.empty?
117
- create_session
118
- else
119
- update_sessions
120
- end
137
+ def maintain_sessions
138
+ if @_sessions.empty?
139
+ create_session
140
+ else
141
+ update_sessions
121
142
  end
143
+ end
122
144
 
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)
145
+ def create_session
146
+ # We only want to automatically login into the first session, since
147
+ # this is the main session. The other sessions are sessions that
148
+ # need to be created after logging into the main session.
149
+ session_id = session_ids.first
150
+ session_class.create(*[self, self, session_id].compact)
151
+
152
+ true
153
+ end
129
154
 
130
- return true
155
+ def update_sessions
156
+ # We found sessions above, let's update them with the new info
157
+ @_sessions.each do |stale_session|
158
+ next if stale_session.record != self
159
+ stale_session.unauthorized_record = self
160
+ stale_session.save
131
161
  end
132
162
 
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
163
+ true
164
+ end
140
165
 
141
- return true
142
- end
166
+ def session_ids
167
+ self.class.session_ids
168
+ end
143
169
 
144
- def session_ids
145
- self.class.session_ids
146
- end
170
+ def session_class
171
+ self.class.session_class
172
+ end
147
173
 
148
- def session_class
149
- self.class.session_class
150
- end
174
+ def log_in_after_create?
175
+ new_record? && self.class.log_in_after_create
176
+ end
177
+
178
+ def log_in_after_password_change?
179
+ persisted? &&
180
+ will_save_change_to_persistence_token? &&
181
+ self.class.log_in_after_password_change
182
+ end
151
183
  end
152
184
  end
153
185
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Authlogic
2
4
  module ActsAsAuthentic
3
- # This module is responsible for maintaining the single_access token. For more
4
- # information the single access token and how to use it, see the
5
- # Authlogic::Session::Params module.
5
+ # This module is responsible for maintaining the single_access token. For
6
+ # more information the single access token and how to use it, see "Params"
7
+ # in `Session::Base`.
6
8
  module SingleAccessToken
7
9
  def self.included(klass)
8
10
  klass.class_eval do
@@ -12,6 +14,8 @@ module Authlogic
12
14
  end
13
15
 
14
16
  # All configuration for the single_access token aspect of acts_as_authentic.
17
+ #
18
+ # These methods become class methods of ::ActiveRecord::Base.
15
19
  module Config
16
20
  # The single access token is used for authentication via URLs, such as a private
17
21
  # feed. That being said, if the user changes their password, that token probably
@@ -23,24 +27,34 @@ module Authlogic
23
27
  def change_single_access_token_with_password(value = nil)
24
28
  rw_config(:change_single_access_token_with_password, value, false)
25
29
  end
26
- alias_method :change_single_access_token_with_password=, :change_single_access_token_with_password
30
+ alias change_single_access_token_with_password= change_single_access_token_with_password
27
31
  end
28
32
 
29
33
  # All method, for the single_access token aspect of acts_as_authentic.
34
+ #
35
+ # This module, as one of the `acts_as_authentic_modules`, is only included
36
+ # into an ActiveRecord model if that model calls `acts_as_authentic`.
30
37
  module Methods
31
38
  def self.included(klass)
32
- return if !klass.column_names.include?("single_access_token")
39
+ return unless klass.column_names.include?("single_access_token")
33
40
 
34
41
  klass.class_eval do
35
42
  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?
43
+ validates_uniqueness_of :single_access_token,
44
+ case_sensitive: true,
45
+ if: :will_save_change_to_single_access_token?
46
+
47
+ before_validation :reset_single_access_token, if: :reset_single_access_token?
38
48
  if respond_to?(:after_password_set)
39
- after_password_set(:reset_single_access_token, :if => :change_single_access_token_with_password?)
49
+ after_password_set(
50
+ :reset_single_access_token,
51
+ if: :change_single_access_token_with_password?
52
+ )
40
53
  end
41
54
  end
42
55
  end
43
56
 
57
+ # :nodoc:
44
58
  module InstanceMethods
45
59
  # Resets the single_access_token to a random friendly token.
46
60
  def reset_single_access_token
@@ -55,13 +69,13 @@ module Authlogic
55
69
 
56
70
  protected
57
71
 
58
- def reset_single_access_token?
59
- single_access_token.blank?
60
- end
72
+ def reset_single_access_token?
73
+ single_access_token.blank?
74
+ end
61
75
 
62
- def change_single_access_token_with_password?
63
- self.class.change_single_access_token_with_password == true
64
- end
76
+ def change_single_access_token_with_password?
77
+ self.class.change_single_access_token_with_password == true
78
+ end
65
79
  end
66
80
  end
67
81
  end
@@ -1,8 +1,21 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module Authlogic
4
+ # Mixed into `Authlogic::ActsAsAuthentic::Base` and
5
+ # `Authlogic::Session::Base`.
3
6
  module Config
7
+ E_USE_NORMAL_RAILS_VALIDATION = <<~EOS
8
+ This Authlogic configuration option (%s) is deprecated. Use normal
9
+ ActiveRecord validation instead. Detailed instructions:
10
+ https://github.com/binarylogic/authlogic/blob/master/doc/use_normal_rails_validation.md
11
+ EOS
12
+
4
13
  def self.extended(klass)
5
14
  klass.class_eval do
15
+ # TODO: Is this a confusing name, given this module is mixed into
16
+ # both `Authlogic::ActsAsAuthentic::Base` and
17
+ # `Authlogic::Session::Base`? Perhaps a more generic name, like
18
+ # `authlogic_config` would be better?
6
19
  class_attribute :acts_as_authentic_config
7
20
  self.acts_as_authentic_config ||= {}
8
21
  end
@@ -10,15 +23,21 @@ module Authlogic
10
23
 
11
24
  private
12
25
 
13
- # This is a one-liner method to write a config setting, read the config
14
- # setting, and also set a default value for the setting.
15
- def rw_config(key, value, default_value = nil)
16
- if value.nil?
17
- acts_as_authentic_config.include?(key) ? acts_as_authentic_config[key] : default_value
18
- else
19
- self.acts_as_authentic_config = acts_as_authentic_config.merge(key => value)
20
- value
21
- end
26
+ def deprecate_authlogic_config(method_name)
27
+ ::ActiveSupport::Deprecation.warn(
28
+ format(E_USE_NORMAL_RAILS_VALIDATION, method_name)
29
+ )
30
+ end
31
+
32
+ # This is a one-liner method to write a config setting, read the config
33
+ # setting, and also set a default value for the setting.
34
+ def rw_config(key, value, default_value = nil)
35
+ if value.nil?
36
+ acts_as_authentic_config.include?(key) ? acts_as_authentic_config[key] : default_value
37
+ else
38
+ self.acts_as_authentic_config = acts_as_authentic_config.merge(key => value)
39
+ value
22
40
  end
41
+ end
23
42
  end
24
43
  end