authlogic 3.4.6 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. checksums.yaml +5 -5
  2. data/.github/ISSUE_TEMPLATE.md +13 -0
  3. data/.github/triage.md +87 -0
  4. data/.gitignore +4 -0
  5. data/.rubocop.yml +127 -0
  6. data/.rubocop_todo.yml +65 -0
  7. data/.travis.yml +18 -10
  8. data/CHANGELOG.md +156 -6
  9. data/CONTRIBUTING.md +71 -3
  10. data/Gemfile +2 -2
  11. data/README.md +386 -0
  12. data/Rakefile +13 -7
  13. data/UPGRADING.md +22 -0
  14. data/authlogic.gemspec +33 -22
  15. data/lib/authlogic.rb +60 -52
  16. data/lib/authlogic/acts_as_authentic/base.rb +40 -26
  17. data/lib/authlogic/acts_as_authentic/email.rb +96 -32
  18. data/lib/authlogic/acts_as_authentic/logged_in_status.rb +36 -12
  19. data/lib/authlogic/acts_as_authentic/login.rb +114 -49
  20. data/lib/authlogic/acts_as_authentic/magic_columns.rb +17 -6
  21. data/lib/authlogic/acts_as_authentic/password.rb +296 -139
  22. data/lib/authlogic/acts_as_authentic/perishable_token.rb +34 -20
  23. data/lib/authlogic/acts_as_authentic/persistence_token.rb +20 -24
  24. data/lib/authlogic/acts_as_authentic/queries/find_with_case.rb +67 -0
  25. data/lib/authlogic/acts_as_authentic/restful_authentication.rb +68 -23
  26. data/lib/authlogic/acts_as_authentic/session_maintenance.rb +128 -85
  27. data/lib/authlogic/acts_as_authentic/single_access_token.rb +41 -25
  28. data/lib/authlogic/acts_as_authentic/validations_scope.rb +8 -8
  29. data/lib/authlogic/authenticates_many/association.rb +22 -14
  30. data/lib/authlogic/authenticates_many/base.rb +35 -16
  31. data/lib/authlogic/config.rb +10 -10
  32. data/lib/authlogic/controller_adapters/abstract_adapter.rb +40 -12
  33. data/lib/authlogic/controller_adapters/rack_adapter.rb +15 -8
  34. data/lib/authlogic/controller_adapters/rails_adapter.rb +42 -22
  35. data/lib/authlogic/controller_adapters/sinatra_adapter.rb +3 -3
  36. data/lib/authlogic/crypto_providers.rb +91 -0
  37. data/lib/authlogic/crypto_providers/aes256.rb +42 -14
  38. data/lib/authlogic/crypto_providers/bcrypt.rb +35 -20
  39. data/lib/authlogic/crypto_providers/md5.rb +11 -9
  40. data/lib/authlogic/crypto_providers/scrypt.rb +26 -13
  41. data/lib/authlogic/crypto_providers/sha1.rb +14 -8
  42. data/lib/authlogic/crypto_providers/sha256.rb +16 -12
  43. data/lib/authlogic/crypto_providers/sha512.rb +8 -24
  44. data/lib/authlogic/crypto_providers/wordpress.rb +44 -15
  45. data/lib/authlogic/i18n.rb +33 -20
  46. data/lib/authlogic/i18n/translator.rb +1 -1
  47. data/lib/authlogic/random.rb +12 -29
  48. data/lib/authlogic/regex.rb +59 -27
  49. data/lib/authlogic/session/activation.rb +36 -23
  50. data/lib/authlogic/session/active_record_trickery.rb +13 -10
  51. data/lib/authlogic/session/base.rb +20 -8
  52. data/lib/authlogic/session/brute_force_protection.rb +87 -56
  53. data/lib/authlogic/session/callbacks.rb +99 -49
  54. data/lib/authlogic/session/cookies.rb +128 -59
  55. data/lib/authlogic/session/existence.rb +29 -19
  56. data/lib/authlogic/session/foundation.rb +70 -16
  57. data/lib/authlogic/session/http_auth.rb +39 -31
  58. data/lib/authlogic/session/id.rb +27 -15
  59. data/lib/authlogic/session/klass.rb +17 -13
  60. data/lib/authlogic/session/magic_columns.rb +78 -59
  61. data/lib/authlogic/session/magic_states.rb +50 -27
  62. data/lib/authlogic/session/params.rb +79 -50
  63. data/lib/authlogic/session/password.rb +197 -118
  64. data/lib/authlogic/session/perishable_token.rb +12 -6
  65. data/lib/authlogic/session/persistence.rb +20 -14
  66. data/lib/authlogic/session/priority_record.rb +20 -16
  67. data/lib/authlogic/session/scopes.rb +63 -33
  68. data/lib/authlogic/session/session.rb +40 -25
  69. data/lib/authlogic/session/timeout.rb +51 -34
  70. data/lib/authlogic/session/unauthorized_record.rb +24 -18
  71. data/lib/authlogic/session/validation.rb +32 -21
  72. data/lib/authlogic/test_case.rb +123 -35
  73. data/lib/authlogic/test_case/mock_controller.rb +14 -13
  74. data/lib/authlogic/test_case/mock_cookie_jar.rb +14 -5
  75. data/lib/authlogic/test_case/mock_logger.rb +1 -1
  76. data/lib/authlogic/test_case/mock_request.rb +9 -4
  77. data/lib/authlogic/test_case/rails_request_adapter.rb +8 -7
  78. data/lib/authlogic/version.rb +21 -0
  79. data/test/acts_as_authentic_test/base_test.rb +1 -1
  80. data/test/acts_as_authentic_test/email_test.rb +80 -63
  81. data/test/acts_as_authentic_test/logged_in_status_test.rb +14 -8
  82. data/test/acts_as_authentic_test/login_test.rb +91 -49
  83. data/test/acts_as_authentic_test/magic_columns_test.rb +13 -13
  84. data/test/acts_as_authentic_test/password_test.rb +82 -60
  85. data/test/acts_as_authentic_test/perishable_token_test.rb +31 -25
  86. data/test/acts_as_authentic_test/persistence_token_test.rb +9 -5
  87. data/test/acts_as_authentic_test/restful_authentication_test.rb +18 -9
  88. data/test/acts_as_authentic_test/session_maintenance_test.rb +86 -22
  89. data/test/acts_as_authentic_test/single_access_test.rb +15 -15
  90. data/test/adapter_test.rb +21 -0
  91. data/test/authenticates_many_test.rb +26 -11
  92. data/test/config_test.rb +9 -9
  93. data/test/crypto_provider_test/aes256_test.rb +3 -3
  94. data/test/crypto_provider_test/bcrypt_test.rb +1 -1
  95. data/test/crypto_provider_test/scrypt_test.rb +2 -2
  96. data/test/crypto_provider_test/sha1_test.rb +4 -4
  97. data/test/crypto_provider_test/sha256_test.rb +2 -2
  98. data/test/crypto_provider_test/sha512_test.rb +3 -3
  99. data/test/crypto_provider_test/wordpress_test.rb +24 -0
  100. data/test/gemfiles/Gemfile.rails-4.2.x +2 -2
  101. data/test/gemfiles/Gemfile.rails-5.0.x +6 -0
  102. data/test/gemfiles/Gemfile.rails-5.1.x +6 -0
  103. data/test/gemfiles/Gemfile.rails-5.2.x +6 -0
  104. data/test/gemfiles/Gemfile.rails-master +6 -0
  105. data/test/i18n_test.rb +9 -9
  106. data/test/libs/affiliate.rb +2 -2
  107. data/test/libs/company.rb +4 -4
  108. data/test/libs/employee.rb +2 -2
  109. data/test/libs/employee_session.rb +1 -1
  110. data/test/libs/ldaper.rb +1 -1
  111. data/test/libs/project.rb +1 -1
  112. data/test/libs/user_session.rb +2 -2
  113. data/test/random_test.rb +9 -38
  114. data/test/session_test/activation_test.rb +7 -7
  115. data/test/session_test/active_record_trickery_test.rb +9 -6
  116. data/test/session_test/brute_force_protection_test.rb +26 -21
  117. data/test/session_test/callbacks_test.rb +10 -4
  118. data/test/session_test/cookies_test.rb +54 -20
  119. data/test/session_test/existence_test.rb +45 -23
  120. data/test/session_test/foundation_test.rb +17 -1
  121. data/test/session_test/http_auth_test.rb +11 -12
  122. data/test/session_test/id_test.rb +3 -3
  123. data/test/session_test/klass_test.rb +2 -2
  124. data/test/session_test/magic_columns_test.rb +15 -17
  125. data/test/session_test/magic_states_test.rb +17 -19
  126. data/test/session_test/params_test.rb +26 -20
  127. data/test/session_test/password_test.rb +11 -12
  128. data/test/session_test/perishability_test.rb +5 -5
  129. data/test/session_test/persistence_test.rb +4 -3
  130. data/test/session_test/scopes_test.rb +15 -9
  131. data/test/session_test/session_test.rb +7 -6
  132. data/test/session_test/timeout_test.rb +16 -14
  133. data/test/session_test/unauthorized_record_test.rb +3 -3
  134. data/test/session_test/validation_test.rb +5 -5
  135. data/test/test_helper.rb +115 -49
  136. metadata +107 -36
  137. data/README.rdoc +0 -232
  138. data/test/gemfiles/Gemfile.rails-3.2.x +0 -7
  139. data/test/gemfiles/Gemfile.rails-4.0.x +0 -7
  140. data/test/gemfiles/Gemfile.rails-4.1.x +0 -7
@@ -1,9 +1,15 @@
1
1
  module Authlogic
2
2
  module ActsAsAuthentic
3
- # This provides a handy token that is "perishable". Meaning the token is only good for a certain amount of time. This is perfect for
4
- # resetting password, confirming accounts, etc. Typically during these actions you send them this token in via their email. Once they
5
- # use the token and do what they need to do, that token should expire. Don't worry about maintaining this, changing it, or expiring it
6
- # yourself. Authlogic does all of this for you. See the sub modules for all of the tools Authlogic 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.
7
13
  module PerishableToken
8
14
  def self.included(klass)
9
15
  klass.class_eval do
@@ -12,21 +18,26 @@ module Authlogic
12
18
  end
13
19
  end
14
20
 
15
- # Change how the perishable token works.
21
+ # Configure the perishable token.
16
22
  module Config
17
- # When using the find_using_perishable_token method the token can expire. If the token is expired, no
18
- # record will be returned. Use this option to specify how long the token is valid for.
23
+ # When using the find_using_perishable_token method the token can
24
+ # expire. If the token is expired, no record will be returned. Use this
25
+ # option to specify how long the token is valid for.
19
26
  #
20
27
  # * <tt>Default:</tt> 10.minutes
21
28
  # * <tt>Accepts:</tt> Fixnum
22
29
  def perishable_token_valid_for(value = nil)
23
- 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
+ )
24
35
  end
25
36
  alias_method :perishable_token_valid_for=, :perishable_token_valid_for
26
37
 
27
- # Authlogic tries to expire and change the perishable token as much as possible, without compromising
28
- # it's purpose. This is for security reasons. If you want to manage it yourself, you can stop
29
- # Authlogic from getting your in way by setting this to true.
38
+ # Authlogic tries to expire and change the perishable token as much as
39
+ # possible, without compromising its purpose. If you want to manage it
40
+ # yourself, set this to true.
30
41
  #
31
42
  # * <tt>Default:</tt> false
32
43
  # * <tt>Accepts:</tt> Boolean
@@ -39,28 +50,30 @@ module Authlogic
39
50
  # All methods relating to the perishable token.
40
51
  module Methods
41
52
  def self.included(klass)
42
- return if !klass.column_names.include?("perishable_token")
53
+ return unless klass.column_names.include?("perishable_token")
43
54
 
44
55
  klass.class_eval do
45
56
  extend ClassMethods
46
57
  include InstanceMethods
47
58
 
48
- validates_uniqueness_of :perishable_token, :if => :perishable_token_changed?
49
- 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?
50
61
  end
51
62
  end
52
63
 
53
- # Class level methods for the perishable token
64
+ # Class methods for the perishable token
54
65
  module ClassMethods
55
- # Use this method to find a record with a perishable token. This method does 2 things for you:
66
+ # Use this method to find a record with a perishable token. This
67
+ # method does 2 things for you:
56
68
  #
57
69
  # 1. It ignores blank tokens
58
70
  # 2. It enforces the perishable_token_valid_for configuration option.
59
71
  #
60
- # If you want to use a different timeout value, just pass it as the second parameter:
72
+ # If you want to use a different timeout value, just pass it as the
73
+ # second parameter:
61
74
  #
62
75
  # User.find_using_perishable_token(token, 1.hour)
63
- def find_using_perishable_token(token, age = self.perishable_token_valid_for)
76
+ def find_using_perishable_token(token, age = perishable_token_valid_for)
64
77
  return if token.blank?
65
78
  age = age.to_i
66
79
 
@@ -91,10 +104,11 @@ module Authlogic
91
104
  # Same as reset_perishable_token, but then saves the record afterwards.
92
105
  def reset_perishable_token!
93
106
  reset_perishable_token
94
- save_without_session_maintenance(:validate => false)
107
+ save_without_session_maintenance(validate: false)
95
108
  end
96
109
 
97
- # A convenience method based on the disable_perishable_token_maintenance configuration option.
110
+ # A convenience method based on the
111
+ # disable_perishable_token_maintenance configuration option.
98
112
  def disable_perishable_token_maintenance?
99
113
  self.class.disable_perishable_token_maintenance == true
100
114
  end
@@ -8,61 +8,57 @@ module Authlogic
8
8
  add_acts_as_authentic_module(Methods)
9
9
  end
10
10
  end
11
-
11
+
12
12
  # Methods for the persistence token.
13
13
  module Methods
14
14
  def self.included(klass)
15
15
  klass.class_eval do
16
16
  extend ClassMethods
17
17
  include InstanceMethods
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?
26
-
27
- before_validation :reset_persistence_token, :if => :reset_persistence_token?
25
+ validates_uniqueness_of :persistence_token, if: :persistence_token_changed?
26
+
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
+
46
41
  # Instance level methods for the persistence token.
47
42
  module InstanceMethods
48
43
  # Resets the persistence_token field to a random hex value.
49
44
  def reset_persistence_token
50
45
  self.persistence_token = Authlogic::Random.hex_token
51
46
  end
52
-
47
+
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
- def reset_persistence_token?
62
- persistence_token.blank?
63
- end
56
+
57
+ def reset_persistence_token?
58
+ persistence_token.blank?
59
+ end
64
60
  end
65
61
  end
66
62
  end
67
63
  end
68
- end
64
+ 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
@@ -1,6 +1,7 @@
1
1
  module Authlogic
2
2
  module ActsAsAuthentic
3
- # This module is responsible for transitioning existing applications from the restful_authentication plugin.
3
+ # This module is responsible for transitioning existing applications from
4
+ # the restful_authentication plugin.
4
5
  module RestfulAuthentication
5
6
  def self.included(klass)
6
7
  klass.class_eval do
@@ -9,11 +10,25 @@ module Authlogic
9
10
  end
10
11
  end
11
12
 
13
+ # Configures the restful_authentication aspect of acts_as_authentic.
14
+ # These methods become class methods of ::ActiveRecord::Base.
12
15
  module Config
13
- # Switching an existing app to Authlogic from restful_authentication? No problem, just set this true and your users won't know
14
- # anything changed. From your database perspective nothing will change at all. Authlogic will continue to encrypt passwords
15
- # just like restful_authentication, so your app won't skip a beat. Although, might consider transitioning your users to a newer
16
- # and stronger algorithm. Checkout the transition_from_restful_authentication option.
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
+
25
+ # Switching an existing app to Authlogic from restful_authentication? No
26
+ # problem, just set this true and your users won't know anything
27
+ # changed. From your database perspective nothing will change at all.
28
+ # Authlogic will continue to encrypt passwords just like
29
+ # restful_authentication, so your app won't skip a beat. Although, might
30
+ # consider transitioning your users to a newer and stronger algorithm.
31
+ # Checkout the transition_from_restful_authentication option.
17
32
  #
18
33
  # * <tt>Default:</tt> false
19
34
  # * <tt>Accepts:</tt> Boolean
@@ -22,39 +37,69 @@ module Authlogic
22
37
  set_restful_authentication_config if value
23
38
  r
24
39
  end
25
- alias_method :act_like_restful_authentication=, :act_like_restful_authentication
26
40
 
27
- # This works just like act_like_restful_authentication except that it will start transitioning your users to the algorithm you
28
- # specify with the crypto provider option. The next time they log in it will resave their password with the new algorithm
29
- # and any new record will use the new algorithm as well. Make sure to update your users table if you are using the default
30
- # migration since it will set crypted_password and salt columns to a maximum width of 40 characters which is not enough.
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
48
+
49
+ # This works just like act_like_restful_authentication except that it
50
+ # will start transitioning your users to the algorithm you specify with
51
+ # the crypto provider option. The next time they log in it will resave
52
+ # their password with the new algorithm and any new record will use the
53
+ # new algorithm as well. Make sure to update your users table if you are
54
+ # using the default migration since it will set crypted_password and
55
+ # salt columns to a maximum width of 40 characters which is not enough.
31
56
  def transition_from_restful_authentication(value = nil)
32
57
  r = rw_config(:transition_from_restful_authentication, value, false)
33
58
  set_restful_authentication_config if value
34
59
  r
35
60
  end
36
- 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
37
69
 
38
70
  private
39
- def set_restful_authentication_config
40
- crypto_provider_key = act_like_restful_authentication ? :crypto_provider : :transition_from_crypto_providers
41
- self.send("#{crypto_provider_key}=", CryptoProviders::Sha1)
42
- if !defined?(::REST_AUTH_SITE_KEY) || ::REST_AUTH_SITE_KEY.nil?
43
- class_eval("::REST_AUTH_SITE_KEY = ''") if !defined?(::REST_AUTH_SITE_KEY)
44
- CryptoProviders::Sha1.stretches = 1
71
+
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__)
45
77
  end
78
+ CryptoProviders::Sha1.stretches = 1
46
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
47
90
  end
48
91
 
92
+ # :nodoc:
49
93
  module InstanceMethods
50
94
  private
51
- def act_like_restful_authentication?
52
- self.class.act_like_restful_authentication == true
53
- end
54
95
 
55
- def transition_from_restful_authentication?
56
- self.class.transition_from_restful_authentication == true
57
- end
96
+ def act_like_restful_authentication?
97
+ self.class.act_like_restful_authentication == true
98
+ end
99
+
100
+ def transition_from_restful_authentication?
101
+ self.class.transition_from_restful_authentication == true
102
+ end
58
103
  end
59
104
  end
60
105
  end
@@ -1,22 +1,26 @@
1
1
  module Authlogic
2
2
  module ActsAsAuthentic
3
- # This is one of my favorite features that I think is pretty cool. It's things like this that make a library great
4
- # and let you know you are on the right track.
3
+ # This is one of my favorite features that I think is pretty cool. It's
4
+ # things like this that make a library great and let you know you are on the
5
+ # right track.
5
6
  #
6
- # Just to clear up any confusion, Authlogic stores both the record id and the persistence token in the session.
7
- # Why? So stale sessions can not be persisted. It stores the id so it can quickly find the record, and the
8
- # persistence token to ensure no sessions are stale. So if the persistence token changes, the user must log
9
- # back in.
7
+ # Just to clear up any confusion, Authlogic stores both the record id and
8
+ # the persistence token in the session. Why? So stale sessions can not be
9
+ # persisted. It stores the id so it can quickly find the record, and the
10
+ # persistence token to ensure no sessions are stale. So if the persistence
11
+ # token changes, the user must log back in.
10
12
  #
11
- # Well, the persistence token changes with the password. What happens if the user changes his own password?
12
- # He shouldn't have to log back in, he's the one that made the change.
13
+ # Well, the persistence token changes with the password. What happens if the
14
+ # user changes his own password? He shouldn't have to log back in, he's the
15
+ # one that made the change.
13
16
  #
14
- # That being said, wouldn't it be nice if their session and cookie information was automatically updated?
15
- # Instead of cluttering up your controller with redundant session code. The same thing goes for new
17
+ # That being said, wouldn't it be nice if their session and cookie
18
+ # information was automatically updated? Instead of cluttering up your
19
+ # controller with redundant session code. The same thing goes for new
16
20
  # registrations.
17
21
  #
18
- # That's what this module is all about. This will automatically maintain the cookie and session values as
19
- # records are saved.
22
+ # That's what this module is all about. This will automatically maintain the
23
+ # cookie and session values as records are saved.
20
24
  module SessionMaintenance
21
25
  def self.included(klass)
22
26
  klass.class_eval do
@@ -24,21 +28,33 @@ module Authlogic
24
28
  add_acts_as_authentic_module(Methods)
25
29
  end
26
30
  end
27
-
31
+
32
+ # Configuration for the session maintenance aspect of acts_as_authentic.
33
+ # These methods become class methods of ::ActiveRecord::Base.
28
34
  module Config
29
- # This is more of a convenience method. In order to turn off automatic maintenance of sessions just
30
- # set this to false, or you can also set the session_ids method to a blank array. Both accomplish
31
- # the same 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
+ #
38
+ # * <tt>Default:</tt> true
39
+ # * <tt>Accepts:</tt> Boolean
40
+ def log_in_after_create(value = nil)
41
+ rw_config(:log_in_after_create, value, true)
42
+ end
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.
32
47
  #
33
48
  # * <tt>Default:</tt> true
34
49
  # * <tt>Accepts:</tt> Boolean
35
- def maintain_sessions(value = nil)
36
- rw_config(:maintain_sessions, value, true)
50
+ def log_in_after_password_change(value = nil)
51
+ rw_config(:log_in_after_password_change, value, true)
37
52
  end
38
- alias_method :maintain_sessions=, :maintain_sessions
39
-
40
- # As you may know, authlogic sessions can be separate by id (See Authlogic::Session::Base#id). You can
41
- # specify here what session ids you want auto maintained. By default it is the main session, which has
53
+ alias_method :log_in_after_password_change=, :log_in_after_password_change
54
+
55
+ # As you may know, authlogic sessions can be separate by id (See
56
+ # Authlogic::Session::Base#id). You can specify here what session ids
57
+ # you want auto maintained. By default it is the main session, which has
42
58
  # an id of nil.
43
59
  #
44
60
  # * <tt>Default:</tt> [nil]
@@ -47,26 +63,33 @@ module Authlogic
47
63
  rw_config(:session_ids, value, [nil])
48
64
  end
49
65
  alias_method :session_ids=, :session_ids
50
-
51
- # The name of the associated session class. This is inferred by the name of the model.
66
+
67
+ # The name of the associated session class. This is inferred by the name
68
+ # of the model.
52
69
  #
53
70
  # * <tt>Default:</tt> "#{klass.name}Session".constantize
54
71
  # * <tt>Accepts:</tt> Class
55
72
  def session_class(value = nil)
56
- const = "#{base_class.name}Session".constantize rescue nil
73
+ const = begin
74
+ "#{base_class.name}Session".constantize
75
+ rescue NameError
76
+ nil
77
+ end
57
78
  rw_config(:session_class, value, const)
58
79
  end
59
80
  alias_method :session_class=, :session_class
60
81
  end
61
-
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`.
62
85
  module Methods
63
86
  def self.included(klass)
64
87
  klass.class_eval do
65
- before_save :get_session_information, :if => :update_sessions?
66
- before_save :maintain_sessions, :if => :update_sessions?
88
+ before_save :get_session_information, if: :update_sessions?
89
+ before_save :maintain_sessions, if: :update_sessions?
67
90
  end
68
91
  end
69
-
92
+
70
93
  # Save the record and skip session maintenance all together.
71
94
  def save_without_session_maintenance(*args)
72
95
  self.skip_session_maintenance = true
@@ -74,66 +97,86 @@ module Authlogic
74
97
  self.skip_session_maintenance = false
75
98
  result
76
99
  end
77
-
100
+
78
101
  private
79
- def skip_session_maintenance=(value)
80
- @skip_session_maintenance = value
81
- end
82
-
83
- def skip_session_maintenance
84
- @skip_session_maintenance ||= false
85
- end
86
-
87
- def update_sessions?
88
- !skip_session_maintenance && session_class && session_class.activated? && self.class.maintain_sessions == true && !session_ids.blank? && persistence_token_changed?
89
- end
90
-
91
- def get_session_information
92
- # Need to determine if we are completely logged out, or logged in as another user
93
- @_sessions = []
94
-
95
- session_ids.each do |session_id|
96
- session = session_class.find(session_id, self)
97
- @_sessions << session if session && session.record
98
- end
99
- end
100
-
101
- def maintain_sessions
102
- if @_sessions.empty?
103
- create_session
104
- else
105
- update_sessions
106
- end
107
- end
108
-
109
- def create_session
110
- # We only want to automatically login into the first session, since this is the main session. The other sessions are sessions
111
- # that need to be created after logging into the main session.
112
- session_id = session_ids.first
113
- session_class.create(*[self, self, session_id].compact)
114
-
115
- return true
116
- end
117
-
118
- def update_sessions
119
- # We found sessions above, let's update them with the new info
120
- @_sessions.each do |stale_session|
121
- next if stale_session.record != self
122
- stale_session.unauthorized_record = self
123
- stale_session.save
124
- end
125
-
126
- return true
102
+
103
+ def skip_session_maintenance=(value)
104
+ @skip_session_maintenance = value
105
+ end
106
+
107
+ def skip_session_maintenance
108
+ @skip_session_maintenance ||= false
109
+ end
110
+
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
123
+
124
+ def get_session_information
125
+ # Need to determine if we are completely logged out, or logged in as
126
+ # another user.
127
+ @_sessions = []
128
+
129
+ session_ids.each do |session_id|
130
+ session = session_class.find(session_id, self)
131
+ @_sessions << session if session && session.record
127
132
  end
128
-
129
- def session_ids
130
- self.class.session_ids
133
+ end
134
+
135
+ def maintain_sessions
136
+ if @_sessions.empty?
137
+ create_session
138
+ else
139
+ update_sessions
131
140
  end
132
-
133
- def session_class
134
- self.class.session_class
141
+ end
142
+
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
152
+
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
135
159
  end
160
+
161
+ true
162
+ end
163
+
164
+ def session_ids
165
+ self.class.session_ids
166
+ end
167
+
168
+ def session_class
169
+ self.class.session_class
170
+ end
171
+
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
136
179
  end
137
180
  end
138
181
  end
139
- end
182
+ end