authlogic 3.8.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
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