devise 3.0.0 → 4.8.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 (242) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +351 -0
  3. data/MIT-LICENSE +2 -1
  4. data/README.md +422 -130
  5. data/app/controllers/devise/confirmations_controller.rb +17 -6
  6. data/app/controllers/devise/omniauth_callbacks_controller.rb +12 -6
  7. data/app/controllers/devise/passwords_controller.rb +23 -8
  8. data/app/controllers/devise/registrations_controller.rb +70 -28
  9. data/app/controllers/devise/sessions_controller.rb +49 -17
  10. data/app/controllers/devise/unlocks_controller.rb +11 -4
  11. data/app/controllers/devise_controller.rb +74 -34
  12. data/app/helpers/devise_helper.rb +23 -18
  13. data/app/mailers/devise/mailer.rb +25 -10
  14. data/app/views/devise/confirmations/new.html.erb +9 -5
  15. data/app/views/devise/mailer/confirmation_instructions.html.erb +1 -1
  16. data/app/views/devise/mailer/email_changed.html.erb +7 -0
  17. data/app/views/devise/mailer/password_change.html.erb +3 -0
  18. data/app/views/devise/mailer/reset_password_instructions.html.erb +1 -1
  19. data/app/views/devise/mailer/unlock_instructions.html.erb +1 -1
  20. data/app/views/devise/passwords/edit.html.erb +16 -7
  21. data/app/views/devise/passwords/new.html.erb +9 -5
  22. data/app/views/devise/registrations/edit.html.erb +29 -15
  23. data/app/views/devise/registrations/new.html.erb +20 -9
  24. data/app/views/devise/sessions/new.html.erb +19 -10
  25. data/app/views/devise/shared/_error_messages.html.erb +15 -0
  26. data/app/views/devise/shared/{_links.erb → _links.html.erb} +10 -10
  27. data/app/views/devise/unlocks/new.html.erb +9 -5
  28. data/config/locales/en.yml +26 -20
  29. data/lib/devise/controllers/helpers.rb +122 -125
  30. data/lib/devise/controllers/rememberable.rb +14 -14
  31. data/lib/devise/controllers/scoped_views.rb +3 -1
  32. data/lib/devise/controllers/sign_in_out.rb +121 -0
  33. data/lib/devise/controllers/store_location.rb +76 -0
  34. data/lib/devise/controllers/url_helpers.rb +10 -8
  35. data/lib/devise/delegator.rb +2 -0
  36. data/lib/devise/encryptor.rb +24 -0
  37. data/lib/devise/failure_app.rb +132 -42
  38. data/lib/devise/hooks/activatable.rb +7 -6
  39. data/lib/devise/hooks/csrf_cleaner.rb +9 -0
  40. data/lib/devise/hooks/forgetable.rb +3 -1
  41. data/lib/devise/hooks/lockable.rb +5 -3
  42. data/lib/devise/hooks/proxy.rb +23 -0
  43. data/lib/devise/hooks/rememberable.rb +7 -4
  44. data/lib/devise/hooks/timeoutable.rb +18 -8
  45. data/lib/devise/hooks/trackable.rb +3 -1
  46. data/lib/devise/mailers/helpers.rb +15 -18
  47. data/lib/devise/mapping.rb +9 -3
  48. data/lib/devise/models/authenticatable.rb +102 -80
  49. data/lib/devise/models/confirmable.rb +154 -72
  50. data/lib/devise/models/database_authenticatable.rb +125 -25
  51. data/lib/devise/models/lockable.rb +50 -29
  52. data/lib/devise/models/omniauthable.rb +3 -1
  53. data/lib/devise/models/recoverable.rb +72 -50
  54. data/lib/devise/models/registerable.rb +4 -0
  55. data/lib/devise/models/rememberable.rb +65 -32
  56. data/lib/devise/models/timeoutable.rb +4 -8
  57. data/lib/devise/models/trackable.rb +20 -4
  58. data/lib/devise/models/validatable.rb +16 -9
  59. data/lib/devise/models.rb +6 -13
  60. data/lib/devise/modules.rb +12 -11
  61. data/lib/devise/omniauth/config.rb +2 -0
  62. data/lib/devise/omniauth/url_helpers.rb +14 -5
  63. data/lib/devise/omniauth.rb +4 -5
  64. data/lib/devise/orm/active_record.rb +5 -1
  65. data/lib/devise/orm/mongoid.rb +6 -2
  66. data/lib/devise/parameter_filter.rb +4 -0
  67. data/lib/devise/parameter_sanitizer.rb +144 -34
  68. data/lib/devise/rails/deprecated_constant_accessor.rb +39 -0
  69. data/lib/devise/rails/routes.rb +191 -127
  70. data/lib/devise/rails/warden_compat.rb +2 -1
  71. data/lib/devise/rails.rb +13 -20
  72. data/lib/devise/secret_key_finder.rb +27 -0
  73. data/lib/devise/strategies/authenticatable.rb +21 -22
  74. data/lib/devise/strategies/base.rb +3 -1
  75. data/lib/devise/strategies/database_authenticatable.rb +15 -4
  76. data/lib/devise/strategies/rememberable.rb +15 -3
  77. data/lib/devise/test/controller_helpers.rb +167 -0
  78. data/lib/devise/test/integration_helpers.rb +63 -0
  79. data/lib/devise/test_helpers.rb +7 -123
  80. data/lib/devise/time_inflector.rb +4 -2
  81. data/lib/devise/token_generator.rb +32 -0
  82. data/lib/devise/version.rb +3 -1
  83. data/lib/devise.rb +124 -78
  84. data/lib/generators/active_record/devise_generator.rb +64 -15
  85. data/lib/generators/active_record/templates/migration.rb +9 -8
  86. data/lib/generators/active_record/templates/migration_existing.rb +9 -8
  87. data/lib/generators/devise/controllers_generator.rb +46 -0
  88. data/lib/generators/devise/devise_generator.rb +10 -6
  89. data/lib/generators/devise/install_generator.rb +19 -1
  90. data/lib/generators/devise/orm_helpers.rb +17 -9
  91. data/lib/generators/devise/views_generator.rb +51 -28
  92. data/lib/generators/mongoid/devise_generator.rb +24 -24
  93. data/lib/generators/templates/README +13 -12
  94. data/lib/generators/templates/controllers/README +14 -0
  95. data/lib/generators/templates/controllers/confirmations_controller.rb +30 -0
  96. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +30 -0
  97. data/lib/generators/templates/controllers/passwords_controller.rb +34 -0
  98. data/lib/generators/templates/controllers/registrations_controller.rb +62 -0
  99. data/lib/generators/templates/controllers/sessions_controller.rb +27 -0
  100. data/lib/generators/templates/controllers/unlocks_controller.rb +30 -0
  101. data/lib/generators/templates/devise.rb +118 -53
  102. data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
  103. data/lib/generators/templates/markerb/email_changed.markerb +7 -0
  104. data/lib/generators/templates/markerb/password_change.markerb +3 -0
  105. data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
  106. data/lib/generators/templates/markerb/unlock_instructions.markerb +1 -1
  107. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +6 -2
  108. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +12 -4
  109. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +5 -2
  110. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +14 -6
  111. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +12 -4
  112. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +11 -6
  113. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +5 -2
  114. metadata +73 -294
  115. data/.gitignore +0 -10
  116. data/.travis.yml +0 -20
  117. data/.yardopts +0 -9
  118. data/CHANGELOG.rdoc +0 -941
  119. data/CONTRIBUTING.md +0 -14
  120. data/Gemfile +0 -31
  121. data/Gemfile.lock +0 -159
  122. data/Rakefile +0 -35
  123. data/app/views/devise/_links.erb +0 -3
  124. data/devise.gemspec +0 -26
  125. data/devise.png +0 -0
  126. data/gemfiles/Gemfile.rails-3.2.x +0 -31
  127. data/gemfiles/Gemfile.rails-3.2.x.lock +0 -156
  128. data/lib/devise/models/token_authenticatable.rb +0 -89
  129. data/lib/devise/strategies/token_authenticatable.rb +0 -91
  130. data/test/controllers/custom_strategy_test.rb +0 -62
  131. data/test/controllers/helpers_test.rb +0 -253
  132. data/test/controllers/internal_helpers_test.rb +0 -120
  133. data/test/controllers/passwords_controller_test.rb +0 -32
  134. data/test/controllers/sessions_controller_test.rb +0 -99
  135. data/test/controllers/url_helpers_test.rb +0 -59
  136. data/test/delegator_test.rb +0 -19
  137. data/test/devise_test.rb +0 -83
  138. data/test/failure_app_test.rb +0 -221
  139. data/test/generators/active_record_generator_test.rb +0 -73
  140. data/test/generators/devise_generator_test.rb +0 -39
  141. data/test/generators/install_generator_test.rb +0 -13
  142. data/test/generators/mongoid_generator_test.rb +0 -23
  143. data/test/generators/views_generator_test.rb +0 -67
  144. data/test/helpers/devise_helper_test.rb +0 -51
  145. data/test/integration/authenticatable_test.rb +0 -699
  146. data/test/integration/confirmable_test.rb +0 -299
  147. data/test/integration/database_authenticatable_test.rb +0 -84
  148. data/test/integration/http_authenticatable_test.rb +0 -115
  149. data/test/integration/lockable_test.rb +0 -242
  150. data/test/integration/omniauthable_test.rb +0 -133
  151. data/test/integration/recoverable_test.rb +0 -335
  152. data/test/integration/registerable_test.rb +0 -349
  153. data/test/integration/rememberable_test.rb +0 -165
  154. data/test/integration/timeoutable_test.rb +0 -150
  155. data/test/integration/token_authenticatable_test.rb +0 -205
  156. data/test/integration/trackable_test.rb +0 -92
  157. data/test/mailers/confirmation_instructions_test.rb +0 -111
  158. data/test/mailers/reset_password_instructions_test.rb +0 -92
  159. data/test/mailers/unlock_instructions_test.rb +0 -87
  160. data/test/mapping_test.rb +0 -127
  161. data/test/models/authenticatable_test.rb +0 -13
  162. data/test/models/confirmable_test.rb +0 -452
  163. data/test/models/database_authenticatable_test.rb +0 -226
  164. data/test/models/lockable_test.rb +0 -282
  165. data/test/models/omniauthable_test.rb +0 -7
  166. data/test/models/recoverable_test.rb +0 -222
  167. data/test/models/registerable_test.rb +0 -7
  168. data/test/models/rememberable_test.rb +0 -175
  169. data/test/models/serializable_test.rb +0 -49
  170. data/test/models/timeoutable_test.rb +0 -46
  171. data/test/models/token_authenticatable_test.rb +0 -55
  172. data/test/models/trackable_test.rb +0 -13
  173. data/test/models/validatable_test.rb +0 -127
  174. data/test/models_test.rb +0 -163
  175. data/test/omniauth/config_test.rb +0 -57
  176. data/test/omniauth/url_helpers_test.rb +0 -54
  177. data/test/orm/active_record.rb +0 -10
  178. data/test/orm/mongoid.rb +0 -13
  179. data/test/parameter_sanitizer_test.rb +0 -58
  180. data/test/rails_app/Rakefile +0 -6
  181. data/test/rails_app/app/active_record/admin.rb +0 -6
  182. data/test/rails_app/app/active_record/shim.rb +0 -2
  183. data/test/rails_app/app/active_record/user.rb +0 -6
  184. data/test/rails_app/app/controllers/admins/sessions_controller.rb +0 -6
  185. data/test/rails_app/app/controllers/admins_controller.rb +0 -11
  186. data/test/rails_app/app/controllers/application_controller.rb +0 -9
  187. data/test/rails_app/app/controllers/home_controller.rb +0 -25
  188. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +0 -2
  189. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +0 -2
  190. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +0 -14
  191. data/test/rails_app/app/controllers/users_controller.rb +0 -31
  192. data/test/rails_app/app/helpers/application_helper.rb +0 -3
  193. data/test/rails_app/app/mailers/users/mailer.rb +0 -12
  194. data/test/rails_app/app/mongoid/admin.rb +0 -29
  195. data/test/rails_app/app/mongoid/shim.rb +0 -23
  196. data/test/rails_app/app/mongoid/user.rb +0 -42
  197. data/test/rails_app/app/views/admins/index.html.erb +0 -1
  198. data/test/rails_app/app/views/admins/sessions/new.html.erb +0 -2
  199. data/test/rails_app/app/views/home/admin_dashboard.html.erb +0 -1
  200. data/test/rails_app/app/views/home/index.html.erb +0 -1
  201. data/test/rails_app/app/views/home/join.html.erb +0 -1
  202. data/test/rails_app/app/views/home/private.html.erb +0 -1
  203. data/test/rails_app/app/views/home/user_dashboard.html.erb +0 -1
  204. data/test/rails_app/app/views/layouts/application.html.erb +0 -24
  205. data/test/rails_app/app/views/users/edit_form.html.erb +0 -1
  206. data/test/rails_app/app/views/users/index.html.erb +0 -1
  207. data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +0 -1
  208. data/test/rails_app/app/views/users/sessions/new.html.erb +0 -1
  209. data/test/rails_app/bin/bundle +0 -3
  210. data/test/rails_app/bin/rails +0 -4
  211. data/test/rails_app/bin/rake +0 -4
  212. data/test/rails_app/config/application.rb +0 -40
  213. data/test/rails_app/config/boot.rb +0 -8
  214. data/test/rails_app/config/database.yml +0 -18
  215. data/test/rails_app/config/environment.rb +0 -5
  216. data/test/rails_app/config/environments/development.rb +0 -34
  217. data/test/rails_app/config/environments/production.rb +0 -84
  218. data/test/rails_app/config/environments/test.rb +0 -36
  219. data/test/rails_app/config/initializers/backtrace_silencers.rb +0 -7
  220. data/test/rails_app/config/initializers/devise.rb +0 -178
  221. data/test/rails_app/config/initializers/inflections.rb +0 -2
  222. data/test/rails_app/config/initializers/secret_token.rb +0 -8
  223. data/test/rails_app/config/initializers/session_store.rb +0 -1
  224. data/test/rails_app/config/routes.rb +0 -104
  225. data/test/rails_app/config.ru +0 -4
  226. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +0 -74
  227. data/test/rails_app/db/schema.rb +0 -52
  228. data/test/rails_app/lib/shared_admin.rb +0 -14
  229. data/test/rails_app/lib/shared_user.rb +0 -25
  230. data/test/rails_app/public/404.html +0 -26
  231. data/test/rails_app/public/422.html +0 -26
  232. data/test/rails_app/public/500.html +0 -26
  233. data/test/rails_app/public/favicon.ico +0 -0
  234. data/test/routes_test.rb +0 -250
  235. data/test/support/assertions.rb +0 -40
  236. data/test/support/helpers.rb +0 -91
  237. data/test/support/integration.rb +0 -92
  238. data/test/support/locale/en.yml +0 -4
  239. data/test/support/webrat/integrations/rails.rb +0 -24
  240. data/test/test_helper.rb +0 -34
  241. data/test/test_helpers_test.rb +0 -151
  242. data/test/test_models.rb +0 -26
@@ -1,4 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'devise/hooks/activatable'
4
+ require 'devise/hooks/csrf_cleaner'
5
+ require 'devise/rails/deprecated_constant_accessor'
2
6
 
3
7
  module Devise
4
8
  module Models
@@ -28,9 +32,7 @@ module Devise
28
32
  # It also accepts an array specifying the strategies that should allow params authentication.
29
33
  #
30
34
  # * +skip_session_storage+: By default Devise will store the user in session.
31
- # You can skip storage for http and token auth by appending values to array:
32
- # :skip_session_storage => [:token_auth] or :skip_session_storage => [:http_auth, :token_auth],
33
- # by default is set to :skip_session_storage => [:http_auth].
35
+ # By default is set to skip_session_storage: [:http_auth].
34
36
  #
35
37
  # == active_for_authentication?
36
38
  #
@@ -38,7 +40,7 @@ module Devise
38
40
  # calling model.active_for_authentication?. This method is overwritten by other devise modules. For instance,
39
41
  # :confirmable overwrites .active_for_authentication? to only return true if your model was confirmed.
40
42
  #
41
- # You overwrite this method yourself, but if you do, don't forget to call super:
43
+ # You can overwrite this method yourself, but if you do, don't forget to call super:
42
44
  #
43
45
  # def active_for_authentication?
44
46
  # super && special_condition_is_valid?
@@ -54,13 +56,16 @@ module Devise
54
56
  module Authenticatable
55
57
  extend ActiveSupport::Concern
56
58
 
57
- BLACKLIST_FOR_SERIALIZATION = [:encrypted_password, :reset_password_token, :reset_password_sent_at,
59
+ UNSAFE_ATTRIBUTES_FOR_SERIALIZATION = [:encrypted_password, :reset_password_token, :reset_password_sent_at,
58
60
  :remember_created_at, :sign_in_count, :current_sign_in_at, :last_sign_in_at, :current_sign_in_ip,
59
61
  :last_sign_in_ip, :password_salt, :confirmation_token, :confirmed_at, :confirmation_sent_at,
60
- :remember_token, :unconfirmed_email, :failed_attempts, :unlock_token, :locked_at, :authentication_token]
62
+ :remember_token, :unconfirmed_email, :failed_attempts, :unlock_token, :locked_at]
63
+
64
+ include Devise::DeprecatedConstantAccessor
65
+ deprecate_constant "BLACKLIST_FOR_SERIALIZATION", "Devise::Models::Authenticatable::UNSAFE_ATTRIBUTES_FOR_SERIALIZATION"
61
66
 
62
67
  included do
63
- class_attribute :devise_modules, :instance_writer => false
68
+ class_attribute :devise_modules, instance_writer: false
64
69
  self.devise_modules ||= []
65
70
 
66
71
  before_validation :downcase_keys
@@ -96,29 +101,31 @@ module Devise
96
101
  def authenticatable_salt
97
102
  end
98
103
 
99
- array = %w(serializable_hash)
100
- # to_xml does not call serializable_hash on 3.1
101
- array << "to_xml" if Rails::VERSION::STRING[0,3] == "3.1"
102
-
103
- array.each do |method|
104
- class_eval <<-RUBY, __FILE__, __LINE__
105
- # Redefine to_xml and serializable_hash in models for more secure defaults.
106
- # By default, it removes from the serializable model all attributes that
107
- # are *not* accessible. You can remove this default by using :force_except
108
- # and passing a new list of attributes you want to exempt. All attributes
109
- # given to :except will simply add names to exempt to Devise internal list.
110
- def #{method}(options=nil)
111
- options ||= {}
112
- options[:except] = Array(options[:except])
113
-
114
- if options[:force_except]
115
- options[:except].concat Array(options[:force_except])
116
- else
117
- options[:except].concat BLACKLIST_FOR_SERIALIZATION
118
- end
119
- super(options)
120
- end
121
- RUBY
104
+ # Redefine serializable_hash in models for more secure defaults.
105
+ # By default, it removes from the serializable model all attributes that
106
+ # are *not* accessible. You can remove this default by using :force_except
107
+ # and passing a new list of attributes you want to exempt. All attributes
108
+ # given to :except will simply add names to exempt to Devise internal list.
109
+ def serializable_hash(options = nil)
110
+ options = options.try(:dup) || {}
111
+ options[:except] = Array(options[:except]).dup
112
+
113
+ if options[:force_except]
114
+ options[:except].concat Array(options[:force_except])
115
+ else
116
+ options[:except].concat UNSAFE_ATTRIBUTES_FOR_SERIALIZATION
117
+ end
118
+
119
+ super(options)
120
+ end
121
+
122
+ # Redefine inspect using serializable_hash, to ensure we don't accidentally
123
+ # leak passwords into exceptions.
124
+ def inspect
125
+ inspection = serializable_hash.collect do |k,v|
126
+ "#{k}: #{respond_to?(:attribute_for_inspect) ? attribute_for_inspect(k) : v.inspect}"
127
+ end
128
+ "#<#{self.class} #{inspection.join(", ")}>"
122
129
  end
123
130
 
124
131
  protected
@@ -128,70 +135,97 @@ module Devise
128
135
  end
129
136
 
130
137
  # This is an internal method called every time Devise needs
131
- # to send a notification/mail. This can be overriden if you
138
+ # to send a notification/mail. This can be overridden if you
132
139
  # need to customize the e-mail delivery logic. For instance,
133
- # if you are using a queue to deliver e-mails (delayed job,
134
- # sidekiq, resque, etc), you must add the delivery to the queue
140
+ # if you are using a queue to deliver e-mails (active job, delayed
141
+ # job, sidekiq, resque, etc), you must add the delivery to the queue
135
142
  # just after the transaction was committed. To achieve this,
136
143
  # you can override send_devise_notification to store the
137
- # deliveries until the after_commit callback is triggered:
144
+ # deliveries until the after_commit callback is triggered.
145
+ #
146
+ # The following example uses Active Job's `deliver_later` :
138
147
  #
139
148
  # class User
140
149
  # devise :database_authenticatable, :confirmable
141
150
  #
142
- # after_commit :send_pending_notifications
151
+ # after_commit :send_pending_devise_notifications
143
152
  #
144
153
  # protected
145
154
  #
146
- # def send_devise_notification(notification, opts = {})
147
- # # if the record is new or changed then delay the
155
+ # def send_devise_notification(notification, *args)
156
+ # # If the record is new or changed then delay the
148
157
  # # delivery until the after_commit callback otherwise
149
158
  # # send now because after_commit will not be called.
150
- # if new_record? || changed?
151
- # pending_notifications << [notification, opts]
159
+ # # For Rails < 6 use `changed?` instead of `saved_changes?`.
160
+ # if new_record? || saved_changes?
161
+ # pending_devise_notifications << [notification, args]
152
162
  # else
153
- # devise_mailer.send(notification, self, opts).deliver
163
+ # render_and_send_devise_message(notification, *args)
154
164
  # end
155
165
  # end
156
166
  #
157
- # def send_pending_notifications
158
- # pending_notifications.each do |n, opts|
159
- # devise_mailer.send(n, self, opts).deliver
167
+ # private
168
+ #
169
+ # def send_pending_devise_notifications
170
+ # pending_devise_notifications.each do |notification, args|
171
+ # render_and_send_devise_message(notification, *args)
160
172
  # end
161
173
  #
162
174
  # # Empty the pending notifications array because the
163
175
  # # after_commit hook can be called multiple times which
164
176
  # # could cause multiple emails to be sent.
165
- # pending_notifications.clear
177
+ # pending_devise_notifications.clear
166
178
  # end
167
179
  #
168
- # def pending_notifications
169
- # @pending_notifications ||= []
180
+ # def pending_devise_notifications
181
+ # @pending_devise_notifications ||= []
170
182
  # end
183
+ #
184
+ # def render_and_send_devise_message(notification, *args)
185
+ # message = devise_mailer.send(notification, self, *args)
186
+ #
187
+ # # Deliver later with Active Job's `deliver_later`
188
+ # if message.respond_to?(:deliver_later)
189
+ # message.deliver_later
190
+ # # Remove once we move to Rails 4.2+ only, as `deliver` is deprecated.
191
+ # elsif message.respond_to?(:deliver_now)
192
+ # message.deliver_now
193
+ # else
194
+ # message.deliver
195
+ # end
196
+ # end
197
+ #
171
198
  # end
172
199
  #
173
- def send_devise_notification(notification, opts={})
174
- devise_mailer.send(notification, self, opts).deliver
200
+ def send_devise_notification(notification, *args)
201
+ message = devise_mailer.send(notification, self, *args)
202
+ # Remove once we move to Rails 4.2+ only.
203
+ if message.respond_to?(:deliver_now)
204
+ message.deliver_now
205
+ else
206
+ message.deliver
207
+ end
175
208
  end
176
209
 
177
210
  def downcase_keys
178
- self.class.case_insensitive_keys.each { |k| apply_to_attribute_or_variable(k, :downcase!) }
211
+ self.class.case_insensitive_keys.each { |k| apply_to_attribute_or_variable(k, :downcase) }
179
212
  end
180
213
 
181
214
  def strip_whitespace
182
- self.class.strip_whitespace_keys.each { |k| apply_to_attribute_or_variable(k, :strip!) }
215
+ self.class.strip_whitespace_keys.each { |k| apply_to_attribute_or_variable(k, :strip) }
183
216
  end
184
217
 
185
218
  def apply_to_attribute_or_variable(attr, method)
186
219
  if self[attr]
187
- self[attr].try(method)
220
+ self[attr] = self[attr].try(method)
188
221
 
189
222
  # Use respond_to? here to avoid a regression where globally
190
223
  # configured strip_whitespace_keys or case_insensitive_keys were
191
- # attempting to strip! or downcase! when a model didn't have the
224
+ # attempting to strip or downcase when a model didn't have the
192
225
  # globally configured key.
193
- elsif respond_to?(attr)
194
- send(attr).try(method)
226
+ elsif respond_to?(attr) && respond_to?("#{attr}=")
227
+ new_value = send(attr).try(method)
228
+ send("#{attr}=", new_value)
195
229
  end
196
230
  end
197
231
 
@@ -231,46 +265,42 @@ module Devise
231
265
  # Example:
232
266
  #
233
267
  # def self.find_for_authentication(tainted_conditions)
234
- # find_first_by_auth_conditions(tainted_conditions, :active => true)
268
+ # find_first_by_auth_conditions(tainted_conditions, active: true)
235
269
  # end
236
270
  #
237
271
  # Finally, notice that Devise also queries for users in other scenarios
238
- # besides authentication, for example when retrieving an user to send
272
+ # besides authentication, for example when retrieving a user to send
239
273
  # an e-mail for password reset. In such cases, find_for_authentication
240
274
  # is not called.
241
275
  def find_for_authentication(tainted_conditions)
242
276
  find_first_by_auth_conditions(tainted_conditions)
243
277
  end
244
278
 
245
- def find_first_by_auth_conditions(tainted_conditions, opts={})
279
+ def find_first_by_auth_conditions(tainted_conditions, opts = {})
246
280
  to_adapter.find_first(devise_parameter_filter.filter(tainted_conditions).merge(opts))
247
281
  end
248
282
 
249
- # Find an initialize a record setting an error if it can't be found.
250
- def find_or_initialize_with_error_by(attribute, value, error=:invalid) #:nodoc:
283
+ # Find or initialize a record setting an error if it can't be found.
284
+ def find_or_initialize_with_error_by(attribute, value, error = :invalid) #:nodoc:
251
285
  find_or_initialize_with_errors([attribute], { attribute => value }, error)
252
286
  end
253
287
 
254
- # Find an initialize a group of attributes based on a list of required attributes.
255
- def find_or_initialize_with_errors(required_attributes, attributes, error=:invalid) #:nodoc:
256
- attributes = attributes.slice(*required_attributes)
257
- attributes.delete_if { |key, value| value.blank? }
288
+ # Find or initialize a record with group of attributes based on a list of required attributes.
289
+ def find_or_initialize_with_errors(required_attributes, attributes, error = :invalid) #:nodoc:
290
+ attributes.try(:permit!)
291
+ attributes = attributes.to_h.with_indifferent_access
292
+ .slice(*required_attributes)
293
+ .delete_if { |key, value| value.blank? }
258
294
 
259
295
  if attributes.size == required_attributes.size
260
- record = find_first_by_auth_conditions(attributes)
296
+ record = find_first_by_auth_conditions(attributes) and return record
261
297
  end
262
298
 
263
- unless record
264
- record = new
265
-
299
+ new(devise_parameter_filter.filter(attributes)).tap do |record|
266
300
  required_attributes.each do |key|
267
- value = attributes[key]
268
- record.send("#{key}=", value)
269
- record.errors.add(key, value.present? ? error : :blank)
301
+ record.errors.add(key, attributes[key].blank? ? :blank : error)
270
302
  end
271
303
  end
272
-
273
- record
274
304
  end
275
305
 
276
306
  protected
@@ -278,14 +308,6 @@ module Devise
278
308
  def devise_parameter_filter
279
309
  @devise_parameter_filter ||= Devise::ParameterFilter.new(case_insensitive_keys, strip_whitespace_keys)
280
310
  end
281
-
282
- # Generate a token by looping and ensuring does not already exist.
283
- def generate_token(column)
284
- loop do
285
- token = Devise.friendly_token
286
- break token unless to_adapter.find_first({ column => token })
287
- end
288
- end
289
311
  end
290
312
  end
291
313
  end