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,308 +0,0 @@
1
- module Authlogic
2
- module Session
3
- # Handles authenticating via a traditional username and password.
4
- module Password
5
- def self.included(klass)
6
- klass.class_eval do
7
- extend Config
8
- include InstanceMethods
9
- validate :validate_by_password, :if => :authenticating_with_password?
10
-
11
- class << self
12
- attr_accessor :configured_password_methods
13
- end
14
- end
15
- end
16
-
17
- # Password configuration
18
- module Config
19
- # Authlogic tries to validate the credentials passed to it. One part of
20
- # validation is actually finding the user and making sure it exists.
21
- # What method it uses the do this is up to you.
22
- #
23
- # Let's say you have a UserSession that is authenticating a User. By
24
- # default UserSession will call User.find_by_login(login). You can
25
- # change what method UserSession calls by specifying it here. Then in
26
- # your User model you can make that method do anything you want, giving
27
- # you complete control of how users are found by the UserSession.
28
- #
29
- # Let's take an example: You want to allow users to login by username or
30
- # email. Set this to the name of the class method that does this in the
31
- # User model. Let's call it "find_by_username_or_email"
32
- #
33
- # class User < ActiveRecord::Base
34
- # def self.find_by_username_or_email(login)
35
- # find_by_username(login) || find_by_email(login)
36
- # end
37
- # end
38
- #
39
- # Now just specify the name of this method for this configuration option
40
- # and you are all set. You can do anything you want here. Maybe you
41
- # allow users to have multiple logins and you want to search a has_many
42
- # relationship, etc. The sky is the limit.
43
- #
44
- # * <tt>Default:</tt> "find_by_smart_case_login_field"
45
- # * <tt>Accepts:</tt> Symbol or String
46
- def find_by_login_method(value = nil)
47
- rw_config(:find_by_login_method, value, "find_by_smart_case_login_field")
48
- end
49
- alias_method :find_by_login_method=, :find_by_login_method
50
-
51
- # The text used to identify credentials (username/password) combination
52
- # when a bad login attempt occurs. When you show error messages for a
53
- # bad login, it's considered good security practice to hide which field
54
- # the user has entered incorrectly (the login field or the password
55
- # field). For a full explanation, see
56
- # http://www.gnucitizen.org/blog/username-enumeration-vulnerabilities/
57
- #
58
- # Example of use:
59
- #
60
- # class UserSession < Authlogic::Session::Base
61
- # generalize_credentials_error_messages true
62
- # end
63
- #
64
- # This would make the error message for bad logins and bad passwords
65
- # look identical:
66
- #
67
- # Login/Password combination is not valid
68
- #
69
- # Alternatively you may use a custom message:
70
- #
71
- # class UserSession < AuthLogic::Session::Base
72
- # generalize_credentials_error_messages "Your login information is invalid"
73
- # end
74
- #
75
- # This will instead show your custom error message when the UserSession is invalid.
76
- #
77
- # The downside to enabling this is that is can be too vague for a user
78
- # that has a hard time remembering their username and password
79
- # combinations. It also disables the ability to to highlight the field
80
- # with the error when you use form_for.
81
- #
82
- # If you are developing an app where security is an extreme priority
83
- # (such as a financial application), then you should enable this.
84
- # Otherwise, leaving this off is fine.
85
- #
86
- # * <tt>Default</tt> false
87
- # * <tt>Accepts:</tt> Boolean
88
- def generalize_credentials_error_messages(value = nil)
89
- rw_config(:generalize_credentials_error_messages, value, false)
90
- end
91
- alias_method :generalize_credentials_error_messages=, :generalize_credentials_error_messages
92
-
93
- # The name of the method you want Authlogic to create for storing the
94
- # login / username. Keep in mind this is just for your
95
- # Authlogic::Session, if you want it can be something completely
96
- # different than the field in your model. So if you wanted people to
97
- # login with a field called "login" and then find users by email this is
98
- # completely doable. See the find_by_login_method configuration option
99
- # for more details.
100
- #
101
- # * <tt>Default:</tt> klass.login_field || klass.email_field
102
- # * <tt>Accepts:</tt> Symbol or String
103
- def login_field(value = nil)
104
- rw_config(:login_field, value, klass.login_field || klass.email_field)
105
- end
106
- alias_method :login_field=, :login_field
107
-
108
- # Works exactly like login_field, but for the password instead. Returns
109
- # :password if a login_field exists.
110
- #
111
- # * <tt>Default:</tt> :password
112
- # * <tt>Accepts:</tt> Symbol or String
113
- def password_field(value = nil)
114
- rw_config(:password_field, value, login_field && :password)
115
- end
116
- alias_method :password_field=, :password_field
117
-
118
- # The name of the method in your model used to verify the password. This
119
- # should be an instance method. It should also be prepared to accept a
120
- # raw password and a crytped password.
121
- #
122
- # * <tt>Default:</tt> "valid_password?"
123
- # * <tt>Accepts:</tt> Symbol or String
124
- def verify_password_method(value = nil)
125
- rw_config(:verify_password_method, value, "valid_password?")
126
- end
127
- alias_method :verify_password_method=, :verify_password_method
128
- end
129
-
130
- # Password-related instance methods
131
- module InstanceMethods
132
- E_AC_PARAMETERS = <<-STR.strip_heredoc.freeze
133
- You have passed an ActionController::Parameters to Authlogic 3. That's
134
- OK for now, but in Authlogic 4, it will raise an error. Please
135
- replace:
136
-
137
- UserSession.new(user_session_params)
138
- UserSession.create(user_session_params)
139
-
140
- with
141
-
142
- UserSession.new(user_session_params.to_h)
143
- UserSession.create(user_session_params.to_h)
144
-
145
- And don't forget to `permit`!
146
-
147
- During the transition of rails to Strong Parameters, it has been
148
- common for Authlogic users to forget to `permit` their params. They
149
- would pass their params into Authlogic, we'd call `to_h`, and they'd
150
- be surprised when authentication failed.
151
-
152
- In 2018, people are still making this mistake. We'd like to help them
153
- and make authlogic a little simpler at the same time, so in Authlogic
154
- 3.7.0, we deprecated the use of ActionController::Parameters.
155
-
156
- We discussed this issue thoroughly between late 2016 and early
157
- 2018. Notable discussions include:
158
-
159
- - https://github.com/binarylogic/authlogic/issues/512
160
- - https://github.com/binarylogic/authlogic/pull/558
161
- - https://github.com/binarylogic/authlogic/pull/577
162
- STR
163
-
164
- def initialize(*args)
165
- if !self.class.configured_password_methods
166
- configure_password_methods
167
- self.class.configured_password_methods = true
168
- end
169
- super
170
- end
171
-
172
- # Returns the login_field / password_field credentials combination in
173
- # hash form.
174
- def credentials
175
- if authenticating_with_password?
176
- details = {}
177
- details[login_field.to_sym] = send(login_field)
178
- details[password_field.to_sym] = "<protected>"
179
- details
180
- else
181
- super
182
- end
183
- end
184
-
185
- # Accepts the login_field / password_field credentials combination in
186
- # hash form.
187
- def credentials=(value)
188
- super
189
- values = parse_param_val(value) # add strong parameters check
190
-
191
- if values.first.is_a?(Hash)
192
- values.first.with_indifferent_access.slice(login_field, password_field).each do |field, value|
193
- next if value.blank?
194
- send("#{field}=", value)
195
- end
196
- end
197
- end
198
-
199
- def invalid_password?
200
- invalid_password == true
201
- end
202
-
203
- private
204
-
205
- def configure_password_methods
206
- if login_field
207
- self.class.send(:attr_writer, login_field) if !respond_to?("#{login_field}=")
208
- self.class.send(:attr_reader, login_field) if !respond_to?(login_field)
209
- end
210
-
211
- if password_field
212
- self.class.send(:attr_writer, password_field) if !respond_to?("#{password_field}=")
213
- self.class.send(:define_method, password_field) {} if !respond_to?(password_field)
214
-
215
- # The password should not be accessible publicly. This way forms
216
- # using form_for don't fill the password with the attempted
217
- # password. To prevent this we just create this method that is
218
- # private.
219
- self.class.class_eval <<-"end_eval", __FILE__, __LINE__
220
- private
221
- def protected_#{password_field}
222
- @#{password_field}
223
- end
224
- end_eval
225
- end
226
- end
227
-
228
- def authenticating_with_password?
229
- login_field && (!send(login_field).nil? || !send("protected_#{password_field}").nil?)
230
- end
231
-
232
- def validate_by_password
233
- self.invalid_password = false
234
-
235
- # check for blank fields
236
- if send(login_field).blank?
237
- errors.add(login_field, I18n.t('error_messages.login_blank', :default => "cannot be blank"))
238
- end
239
- if send("protected_#{password_field}").blank?
240
- errors.add(password_field, I18n.t('error_messages.password_blank', :default => "cannot be blank"))
241
- end
242
- return if errors.count > 0
243
-
244
- self.attempted_record = search_for_record(find_by_login_method, send(login_field))
245
- if attempted_record.blank?
246
- generalize_credentials_error_messages? ?
247
- add_general_credentials_error :
248
- errors.add(login_field, I18n.t('error_messages.login_not_found', :default => "is not valid"))
249
- return
250
- end
251
-
252
- # check for invalid password
253
- if !attempted_record.send(verify_password_method, send("protected_#{password_field}"))
254
- self.invalid_password = true
255
- generalize_credentials_error_messages? ?
256
- add_general_credentials_error :
257
- errors.add(password_field, I18n.t('error_messages.password_invalid', :default => "is not valid"))
258
- return
259
- end
260
- end
261
-
262
- attr_accessor :invalid_password
263
-
264
- def find_by_login_method
265
- self.class.find_by_login_method
266
- end
267
-
268
- def login_field
269
- self.class.login_field
270
- end
271
-
272
- def add_general_credentials_error
273
- error_message =
274
- if self.class.generalize_credentials_error_messages.is_a? String
275
- self.class.generalize_credentials_error_messages
276
- else
277
- "#{login_field.to_s.humanize}/Password combination is not valid"
278
- end
279
- errors.add(:base, I18n.t('error_messages.general_credentials_error', :default => error_message))
280
- end
281
-
282
- def generalize_credentials_error_messages?
283
- self.class.generalize_credentials_error_messages
284
- end
285
-
286
- def password_field
287
- self.class.password_field
288
- end
289
-
290
- def verify_password_method
291
- self.class.verify_password_method
292
- end
293
-
294
- # In Rails 5 the ActionController::Parameters no longer inherits from HashWithIndifferentAccess.
295
- # See: http://guides.rubyonrails.org/upgrading_ruby_on_rails.html#actioncontroller-parameters-no-longer-inherits-from-hashwithindifferentaccess
296
- # This method converts the ActionController::Parameters to a Hash
297
- def parse_param_val(value)
298
- if value.first.class.name == "ActionController::Parameters"
299
- ActiveSupport::Deprecation.warn(E_AC_PARAMETERS)
300
- [value.first.to_h]
301
- else
302
- value.is_a?(Array) ? value : [value]
303
- end
304
- end
305
- end
306
- end
307
- end
308
- end
@@ -1,23 +0,0 @@
1
- module Authlogic
2
- module Session
3
- # Maintains the perishable token, which is helpful for confirming records or
4
- # authorizing records to reset their password. All that this module does is
5
- # reset it after a session have been saved, just keep it changing. The more
6
- # it changes, the tighter the security.
7
- #
8
- # See Authlogic::ActsAsAuthentic::PerishableToken for more information.
9
- module PerishableToken
10
- def self.included(klass)
11
- klass.after_save :reset_perishable_token!
12
- end
13
-
14
- private
15
-
16
- def reset_perishable_token!
17
- if record.respond_to?(:reset_perishable_token) && !record.disable_perishable_token_maintenance?
18
- record.reset_perishable_token
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,71 +0,0 @@
1
- module Authlogic
2
- module Session
3
- # Responsible for allowing you to persist your sessions.
4
- module Persistence
5
- def self.included(klass)
6
- klass.class_eval do
7
- extend ClassMethods
8
- include InstanceMethods
9
- end
10
- end
11
-
12
- module ClassMethods
13
- # This is how you persist a session. This finds the record for the current session using
14
- # a variety of methods. It basically tries to "log in" the user without the user having
15
- # to explicitly log in. Check out the other Authlogic::Session modules for more information.
16
- #
17
- # The best way to use this method is something like:
18
- #
19
- # helper_method :current_user_session, :current_user
20
- #
21
- # def current_user_session
22
- # return @current_user_session if defined?(@current_user_session)
23
- # @current_user_session = UserSession.find
24
- # end
25
- #
26
- # def current_user
27
- # return @current_user if defined?(@current_user)
28
- # @current_user = current_user_session && current_user_session.user
29
- # end
30
- #
31
- # Also, this method accepts a single parameter as the id, to find session that you marked with an id:
32
- #
33
- # UserSession.find(:secure)
34
- #
35
- # See the id method for more information on ids.
36
- def find(id = nil, priority_record = nil)
37
- session = new({ :priority_record => priority_record }, id)
38
- session.priority_record = priority_record
39
- if session.persisting?
40
- session
41
- else
42
- nil
43
- end
44
- end
45
- end
46
-
47
- module InstanceMethods
48
- # Let's you know if the session is being persisted or not, meaning the user does not have to explicitly log in
49
- # in order to be logged in. If the session has no associated record, it will try to find a record and persist
50
- # the session. This is the method that the class level method find uses to ultimately persist the session.
51
- def persisting?
52
- return true if !record.nil?
53
- self.attempted_record = nil
54
- self.remember_me = !cookie_credentials.nil? && !cookie_credentials[2].nil?
55
- before_persisting
56
- persist
57
- ensure_authentication_attempted
58
- if errors.empty? && !attempted_record.nil?
59
- self.record = attempted_record
60
- after_persisting
61
- save_record
62
- self.new_session = false
63
- true
64
- else
65
- false
66
- end
67
- end
68
- end
69
- end
70
- end
71
- end
@@ -1,35 +0,0 @@
1
- module Authlogic
2
- module Session
3
- # The point of this module is to avoid the StaleObjectError raised when lock_version is implemented in ActiveRecord.
4
- # We accomplish this by using a "priority record". Meaning this record is used if possible, it gets priority.
5
- # This way we don't save a record behind the scenes thus making an object being used stale.
6
- module PriorityRecord
7
- def self.included(klass)
8
- klass.class_eval do
9
- attr_accessor :priority_record
10
- end
11
- end
12
-
13
- # Setting priority record if it is passed. The only way it can be passed is through an array:
14
- #
15
- # session.credentials = [real_user_object, priority_user_object]
16
- def credentials=(value)
17
- super
18
- values = value.is_a?(Array) ? value : [value]
19
- self.priority_record = values[1] if values[1].class < ::ActiveRecord::Base
20
- end
21
-
22
- private
23
-
24
- def attempted_record=(value)
25
- value = priority_record if value == priority_record
26
- super
27
- end
28
-
29
- def save_record(alternate_record = nil)
30
- r = alternate_record || record
31
- super if r != priority_record
32
- end
33
- end
34
- end
35
- end
@@ -1,119 +0,0 @@
1
- require 'request_store'
2
-
3
- module Authlogic
4
- module Session
5
- # Authentication can be scoped, and it's easy, you just need to define how you want to
6
- # scope everything. This should help you:
7
- #
8
- # 1. Want to scope by a parent object? Ex: An account has many users.
9
- # Checkout Authlogic::AuthenticatesMany
10
- # 2. Want to scope the validations in your model? Ex: 2 users can have the same login
11
- # under different accounts. See Authlogic::ActsAsAuthentic::Scope
12
- module Scopes # :nodoc:
13
- def self.included(klass)
14
- klass.class_eval do
15
- extend ClassMethods
16
- include InstanceMethods
17
- attr_writer :scope
18
- end
19
- end
20
-
21
- # = Scopes
22
- module ClassMethods
23
- # The current scope set, should be used in the block passed to with_scope.
24
- def scope
25
- RequestStore.store[:authlogic_scope]
26
- end
27
-
28
- # What with_scopes focuses on is scoping the query when finding the object and the
29
- # name of the cookie / session. It works very similar to
30
- # ActiveRecord::Base#with_scopes. It accepts a hash with any of the following
31
- # options:
32
- #
33
- # * <tt>find_options:</tt> any options you can pass into ActiveRecord::Base.find.
34
- # This is used when trying to find the record.
35
- # * <tt>id:</tt> The id of the session, this gets merged with the real id. For
36
- # information ids see the id method.
37
- #
38
- # Here is how you use it:
39
- #
40
- # UserSession.with_scope(:find_options => {:conditions => "account_id = 2"}, :id => "account_2") do
41
- # UserSession.find
42
- # end
43
- #
44
- # Essentially what the above does is scope the searching of the object with the
45
- # sql you provided. So instead of:
46
- #
47
- # User.where("login = 'ben'").first
48
- #
49
- # it would be:
50
- #
51
- # User.where("login = 'ben' and account_id = 2").first
52
- #
53
- # You will also notice the :id option. This works just like the id method. It
54
- # scopes your cookies. So the name of your cookie will be:
55
- #
56
- # account_2_user_credentials
57
- #
58
- # instead of:
59
- #
60
- # user_credentials
61
- #
62
- # What is also nifty about scoping with an :id is that it merges your id's. So if you do:
63
- #
64
- # UserSession.with_scope(:find_options => {:conditions => "account_id = 2"}, :id => "account_2") do
65
- # session = UserSession.new
66
- # session.id = :secure
67
- # end
68
- #
69
- # The name of your cookies will be:
70
- #
71
- # secure_account_2_user_credentials
72
- def with_scope(options = {}, &block)
73
- raise ArgumentError.new("You must provide a block") unless block_given?
74
- self.scope = options
75
- result = yield
76
- self.scope = nil
77
- result
78
- end
79
-
80
- private
81
-
82
- def scope=(value)
83
- RequestStore.store[:authlogic_scope] = value
84
- end
85
- end
86
-
87
- module InstanceMethods
88
- # Setting the scope if it exists upon instantiation.
89
- def initialize(*args)
90
- self.scope = self.class.scope
91
- super
92
- end
93
-
94
- # The scope of the current object
95
- def scope
96
- @scope ||= {}
97
- end
98
-
99
- private
100
-
101
- # Used for things like cookie_key, session_key, etc.
102
- def build_key(last_part)
103
- [scope[:id], super].compact.join("_")
104
- end
105
-
106
- def search_for_record(*args)
107
- session_scope = if scope[:find_options].is_a?(ActiveRecord::Relation)
108
- scope[:find_options]
109
- else
110
- klass.send(:where, scope[:find_options] && scope[:find_options][:conditions] || {})
111
- end
112
- session_scope.scoping do
113
- klass.send(*args)
114
- end
115
- end
116
- end
117
- end
118
- end
119
- end
@@ -1,67 +0,0 @@
1
- module Authlogic
2
- module Session
3
- # Handles all parts of authentication that deal with sessions. Such as persisting a session and saving / destroy a session.
4
- module Session
5
- def self.included(klass)
6
- klass.class_eval do
7
- extend Config
8
- include InstanceMethods
9
- persist :persist_by_session
10
- after_save :update_session
11
- after_destroy :update_session
12
- after_persisting :update_session, :unless => :single_access?
13
- end
14
- end
15
-
16
- # Configuration for the session feature.
17
- module Config
18
- # Works exactly like cookie_key, but for sessions. See cookie_key for more info.
19
- #
20
- # * <tt>Default:</tt> cookie_key
21
- # * <tt>Accepts:</tt> Symbol or String
22
- def session_key(value = nil)
23
- rw_config(:session_key, value, cookie_key)
24
- end
25
- alias_method :session_key=, :session_key
26
- end
27
-
28
- # Instance methods for the session feature.
29
- module InstanceMethods
30
- private
31
-
32
- # Tries to validate the session from information in the session
33
- def persist_by_session
34
- persistence_token, record_id = session_credentials
35
- if !persistence_token.nil?
36
- # Allow finding by persistence token, because when records are created the
37
- # session is maintained in a before_save, when there is no id. This is done
38
- # for performance reasons and to save on queries.
39
- record = record_id.nil? ?
40
- search_for_record("find_by_persistence_token", persistence_token.to_s) :
41
- search_for_record("find_by_#{klass.primary_key}", record_id.to_s)
42
- self.unauthorized_record = record if record && record.persistence_token == persistence_token
43
- valid?
44
- else
45
- false
46
- end
47
- end
48
-
49
- def session_credentials
50
- [
51
- controller.session[session_key],
52
- controller.session["#{session_key}_#{klass.primary_key}"]
53
- ].collect { |i| i.nil? ? i : i.to_s }.compact
54
- end
55
-
56
- def session_key
57
- build_key(self.class.session_key)
58
- end
59
-
60
- def update_session
61
- controller.session[session_key] = record && record.persistence_token
62
- controller.session["#{session_key}_#{klass.primary_key}"] = record && record.send(record.class.primary_key)
63
- end
64
- end
65
- end
66
- end
67
- end