devise 3.5.3 → 4.7.1

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 (256) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +256 -1099
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +254 -67
  5. data/app/controllers/devise/confirmations_controller.rb +3 -1
  6. data/app/controllers/devise/omniauth_callbacks_controller.rb +8 -6
  7. data/app/controllers/devise/passwords_controller.rb +7 -4
  8. data/app/controllers/devise/registrations_controller.rb +39 -18
  9. data/app/controllers/devise/sessions_controller.rb +9 -7
  10. data/app/controllers/devise/unlocks_controller.rb +4 -2
  11. data/app/controllers/devise_controller.rb +23 -10
  12. data/app/helpers/devise_helper.rb +12 -19
  13. data/app/mailers/devise/mailer.rb +6 -0
  14. data/app/views/devise/confirmations/new.html.erb +2 -2
  15. data/app/views/devise/mailer/email_changed.html.erb +7 -0
  16. data/app/views/devise/passwords/edit.html.erb +3 -3
  17. data/app/views/devise/passwords/new.html.erb +2 -2
  18. data/app/views/devise/registrations/edit.html.erb +9 -5
  19. data/app/views/devise/registrations/new.html.erb +4 -4
  20. data/app/views/devise/sessions/new.html.erb +4 -4
  21. data/app/views/devise/shared/_error_messages.html.erb +15 -0
  22. data/app/views/devise/shared/_links.html.erb +7 -7
  23. data/app/views/devise/unlocks/new.html.erb +2 -2
  24. data/config/locales/en.yml +4 -1
  25. data/lib/devise/controllers/helpers.rb +23 -20
  26. data/lib/devise/controllers/rememberable.rb +11 -2
  27. data/lib/devise/controllers/scoped_views.rb +2 -0
  28. data/lib/devise/controllers/sign_in_out.rb +34 -11
  29. data/lib/devise/controllers/store_location.rb +25 -7
  30. data/lib/devise/controllers/url_helpers.rb +2 -0
  31. data/lib/devise/delegator.rb +2 -0
  32. data/lib/devise/encryptor.rb +6 -4
  33. data/lib/devise/failure_app.rb +75 -37
  34. data/lib/devise/hooks/activatable.rb +2 -0
  35. data/lib/devise/hooks/csrf_cleaner.rb +2 -0
  36. data/lib/devise/hooks/forgetable.rb +2 -0
  37. data/lib/devise/hooks/lockable.rb +6 -1
  38. data/lib/devise/hooks/proxy.rb +3 -1
  39. data/lib/devise/hooks/rememberable.rb +2 -0
  40. data/lib/devise/hooks/timeoutable.rb +5 -2
  41. data/lib/devise/hooks/trackable.rb +2 -0
  42. data/lib/devise/mailers/helpers.rb +7 -4
  43. data/lib/devise/mapping.rb +2 -0
  44. data/lib/devise/models/authenticatable.rb +51 -26
  45. data/lib/devise/models/confirmable.rb +89 -27
  46. data/lib/devise/models/database_authenticatable.rb +88 -21
  47. data/lib/devise/models/lockable.rb +15 -5
  48. data/lib/devise/models/omniauthable.rb +2 -0
  49. data/lib/devise/models/recoverable.rb +32 -20
  50. data/lib/devise/models/registerable.rb +4 -0
  51. data/lib/devise/models/rememberable.rb +42 -26
  52. data/lib/devise/models/timeoutable.rb +2 -6
  53. data/lib/devise/models/trackable.rb +15 -1
  54. data/lib/devise/models/validatable.rb +10 -3
  55. data/lib/devise/models.rb +3 -1
  56. data/lib/devise/modules.rb +2 -0
  57. data/lib/devise/omniauth/config.rb +2 -0
  58. data/lib/devise/omniauth/url_helpers.rb +14 -5
  59. data/lib/devise/omniauth.rb +2 -0
  60. data/lib/devise/orm/active_record.rb +5 -1
  61. data/lib/devise/orm/mongoid.rb +6 -2
  62. data/lib/devise/parameter_filter.rb +4 -0
  63. data/lib/devise/parameter_sanitizer.rb +139 -65
  64. data/lib/devise/rails/routes.rb +44 -33
  65. data/lib/devise/rails/warden_compat.rb +3 -10
  66. data/lib/devise/rails.rb +7 -16
  67. data/lib/devise/secret_key_finder.rb +27 -0
  68. data/lib/devise/strategies/authenticatable.rb +3 -1
  69. data/lib/devise/strategies/base.rb +2 -0
  70. data/lib/devise/strategies/database_authenticatable.rb +11 -4
  71. data/lib/devise/strategies/rememberable.rb +5 -6
  72. data/lib/devise/test/controller_helpers.rb +165 -0
  73. data/lib/devise/test/integration_helpers.rb +63 -0
  74. data/lib/devise/test_helpers.rb +7 -124
  75. data/lib/devise/time_inflector.rb +2 -0
  76. data/lib/devise/token_generator.rb +3 -41
  77. data/lib/devise/version.rb +3 -1
  78. data/lib/devise.rb +61 -40
  79. data/lib/generators/active_record/devise_generator.rb +29 -10
  80. data/lib/generators/active_record/templates/migration.rb +4 -2
  81. data/lib/generators/active_record/templates/migration_existing.rb +4 -2
  82. data/lib/generators/devise/controllers_generator.rb +3 -1
  83. data/lib/generators/devise/devise_generator.rb +4 -2
  84. data/lib/generators/devise/install_generator.rb +17 -0
  85. data/lib/generators/devise/orm_helpers.rb +10 -21
  86. data/lib/generators/devise/views_generator.rb +7 -8
  87. data/lib/generators/mongoid/devise_generator.rb +7 -5
  88. data/lib/generators/templates/README +1 -8
  89. data/lib/generators/templates/controllers/confirmations_controller.rb +2 -0
  90. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +2 -0
  91. data/lib/generators/templates/controllers/passwords_controller.rb +2 -0
  92. data/lib/generators/templates/controllers/registrations_controller.rb +6 -4
  93. data/lib/generators/templates/controllers/sessions_controller.rb +4 -2
  94. data/lib/generators/templates/controllers/unlocks_controller.rb +2 -0
  95. data/lib/generators/templates/devise.rb +50 -20
  96. data/lib/generators/templates/markerb/email_changed.markerb +7 -0
  97. data/lib/generators/templates/markerb/password_change.markerb +2 -2
  98. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +5 -1
  99. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +10 -2
  100. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +4 -1
  101. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +11 -3
  102. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +11 -3
  103. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +7 -2
  104. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +4 -1
  105. metadata +13 -310
  106. data/.gitignore +0 -10
  107. data/.travis.yml +0 -44
  108. data/.yardopts +0 -9
  109. data/CODE_OF_CONDUCT.md +0 -22
  110. data/CONTRIBUTING.md +0 -16
  111. data/Gemfile +0 -29
  112. data/Gemfile.lock +0 -183
  113. data/Rakefile +0 -36
  114. data/devise.gemspec +0 -27
  115. data/devise.png +0 -0
  116. data/gemfiles/Gemfile.rails-3.2-stable +0 -29
  117. data/gemfiles/Gemfile.rails-3.2-stable.lock +0 -172
  118. data/gemfiles/Gemfile.rails-4.0-stable +0 -29
  119. data/gemfiles/Gemfile.rails-4.0-stable.lock +0 -166
  120. data/gemfiles/Gemfile.rails-4.1-stable +0 -29
  121. data/gemfiles/Gemfile.rails-4.1-stable.lock +0 -172
  122. data/gemfiles/Gemfile.rails-4.2-stable +0 -29
  123. data/gemfiles/Gemfile.rails-4.2-stable.lock +0 -194
  124. data/script/cached-bundle +0 -49
  125. data/script/s3-put +0 -71
  126. data/test/controllers/custom_registrations_controller_test.rb +0 -40
  127. data/test/controllers/custom_strategy_test.rb +0 -62
  128. data/test/controllers/helper_methods_test.rb +0 -21
  129. data/test/controllers/helpers_test.rb +0 -316
  130. data/test/controllers/inherited_controller_i18n_messages_test.rb +0 -51
  131. data/test/controllers/internal_helpers_test.rb +0 -129
  132. data/test/controllers/load_hooks_controller_test.rb +0 -19
  133. data/test/controllers/passwords_controller_test.rb +0 -31
  134. data/test/controllers/sessions_controller_test.rb +0 -103
  135. data/test/controllers/url_helpers_test.rb +0 -65
  136. data/test/delegator_test.rb +0 -19
  137. data/test/devise_test.rb +0 -107
  138. data/test/failure_app_test.rb +0 -315
  139. data/test/generators/active_record_generator_test.rb +0 -109
  140. data/test/generators/controllers_generator_test.rb +0 -48
  141. data/test/generators/devise_generator_test.rb +0 -39
  142. data/test/generators/install_generator_test.rb +0 -13
  143. data/test/generators/mongoid_generator_test.rb +0 -23
  144. data/test/generators/views_generator_test.rb +0 -103
  145. data/test/helpers/devise_helper_test.rb +0 -49
  146. data/test/integration/authenticatable_test.rb +0 -729
  147. data/test/integration/confirmable_test.rb +0 -324
  148. data/test/integration/database_authenticatable_test.rb +0 -95
  149. data/test/integration/http_authenticatable_test.rb +0 -105
  150. data/test/integration/lockable_test.rb +0 -239
  151. data/test/integration/omniauthable_test.rb +0 -135
  152. data/test/integration/recoverable_test.rb +0 -347
  153. data/test/integration/registerable_test.rb +0 -359
  154. data/test/integration/rememberable_test.rb +0 -176
  155. data/test/integration/timeoutable_test.rb +0 -184
  156. data/test/integration/trackable_test.rb +0 -92
  157. data/test/mailers/confirmation_instructions_test.rb +0 -115
  158. data/test/mailers/reset_password_instructions_test.rb +0 -96
  159. data/test/mailers/unlock_instructions_test.rb +0 -91
  160. data/test/mapping_test.rb +0 -134
  161. data/test/models/authenticatable_test.rb +0 -23
  162. data/test/models/confirmable_test.rb +0 -489
  163. data/test/models/database_authenticatable_test.rb +0 -269
  164. data/test/models/lockable_test.rb +0 -328
  165. data/test/models/omniauthable_test.rb +0 -7
  166. data/test/models/recoverable_test.rb +0 -251
  167. data/test/models/registerable_test.rb +0 -7
  168. data/test/models/rememberable_test.rb +0 -204
  169. data/test/models/serializable_test.rb +0 -49
  170. data/test/models/timeoutable_test.rb +0 -51
  171. data/test/models/trackable_test.rb +0 -41
  172. data/test/models/validatable_test.rb +0 -127
  173. data/test/models_test.rb +0 -153
  174. data/test/omniauth/config_test.rb +0 -57
  175. data/test/omniauth/url_helpers_test.rb +0 -54
  176. data/test/orm/active_record.rb +0 -10
  177. data/test/orm/mongoid.rb +0 -13
  178. data/test/parameter_sanitizer_test.rb +0 -81
  179. data/test/rails_app/Rakefile +0 -6
  180. data/test/rails_app/app/active_record/admin.rb +0 -6
  181. data/test/rails_app/app/active_record/shim.rb +0 -2
  182. data/test/rails_app/app/active_record/user.rb +0 -6
  183. data/test/rails_app/app/active_record/user_on_engine.rb +0 -7
  184. data/test/rails_app/app/active_record/user_on_main_app.rb +0 -7
  185. data/test/rails_app/app/active_record/user_without_email.rb +0 -8
  186. data/test/rails_app/app/controllers/admins/sessions_controller.rb +0 -6
  187. data/test/rails_app/app/controllers/admins_controller.rb +0 -6
  188. data/test/rails_app/app/controllers/application_controller.rb +0 -12
  189. data/test/rails_app/app/controllers/application_with_fake_engine.rb +0 -30
  190. data/test/rails_app/app/controllers/custom/registrations_controller.rb +0 -31
  191. data/test/rails_app/app/controllers/home_controller.rb +0 -25
  192. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +0 -2
  193. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +0 -2
  194. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +0 -14
  195. data/test/rails_app/app/controllers/users_controller.rb +0 -31
  196. data/test/rails_app/app/helpers/application_helper.rb +0 -3
  197. data/test/rails_app/app/mailers/users/from_proc_mailer.rb +0 -3
  198. data/test/rails_app/app/mailers/users/mailer.rb +0 -3
  199. data/test/rails_app/app/mailers/users/reply_to_mailer.rb +0 -4
  200. data/test/rails_app/app/mongoid/admin.rb +0 -29
  201. data/test/rails_app/app/mongoid/shim.rb +0 -23
  202. data/test/rails_app/app/mongoid/user.rb +0 -39
  203. data/test/rails_app/app/mongoid/user_on_engine.rb +0 -39
  204. data/test/rails_app/app/mongoid/user_on_main_app.rb +0 -39
  205. data/test/rails_app/app/mongoid/user_without_email.rb +0 -33
  206. data/test/rails_app/app/views/admins/index.html.erb +0 -1
  207. data/test/rails_app/app/views/admins/sessions/new.html.erb +0 -2
  208. data/test/rails_app/app/views/home/admin_dashboard.html.erb +0 -1
  209. data/test/rails_app/app/views/home/index.html.erb +0 -1
  210. data/test/rails_app/app/views/home/join.html.erb +0 -1
  211. data/test/rails_app/app/views/home/private.html.erb +0 -1
  212. data/test/rails_app/app/views/home/user_dashboard.html.erb +0 -1
  213. data/test/rails_app/app/views/layouts/application.html.erb +0 -24
  214. data/test/rails_app/app/views/users/edit_form.html.erb +0 -1
  215. data/test/rails_app/app/views/users/index.html.erb +0 -1
  216. data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +0 -1
  217. data/test/rails_app/app/views/users/sessions/new.html.erb +0 -1
  218. data/test/rails_app/bin/bundle +0 -3
  219. data/test/rails_app/bin/rails +0 -4
  220. data/test/rails_app/bin/rake +0 -4
  221. data/test/rails_app/config/application.rb +0 -40
  222. data/test/rails_app/config/boot.rb +0 -14
  223. data/test/rails_app/config/database.yml +0 -18
  224. data/test/rails_app/config/environment.rb +0 -5
  225. data/test/rails_app/config/environments/development.rb +0 -30
  226. data/test/rails_app/config/environments/production.rb +0 -84
  227. data/test/rails_app/config/environments/test.rb +0 -41
  228. data/test/rails_app/config/initializers/backtrace_silencers.rb +0 -7
  229. data/test/rails_app/config/initializers/devise.rb +0 -180
  230. data/test/rails_app/config/initializers/inflections.rb +0 -2
  231. data/test/rails_app/config/initializers/secret_token.rb +0 -8
  232. data/test/rails_app/config/initializers/session_store.rb +0 -1
  233. data/test/rails_app/config/routes.rb +0 -125
  234. data/test/rails_app/config.ru +0 -4
  235. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +0 -71
  236. data/test/rails_app/db/schema.rb +0 -55
  237. data/test/rails_app/lib/shared_admin.rb +0 -17
  238. data/test/rails_app/lib/shared_user.rb +0 -29
  239. data/test/rails_app/lib/shared_user_without_email.rb +0 -26
  240. data/test/rails_app/lib/shared_user_without_omniauth.rb +0 -13
  241. data/test/rails_app/public/404.html +0 -26
  242. data/test/rails_app/public/422.html +0 -26
  243. data/test/rails_app/public/500.html +0 -26
  244. data/test/rails_app/public/favicon.ico +0 -0
  245. data/test/rails_test.rb +0 -9
  246. data/test/routes_test.rb +0 -264
  247. data/test/support/action_controller/record_identifier.rb +0 -10
  248. data/test/support/assertions.rb +0 -39
  249. data/test/support/helpers.rb +0 -77
  250. data/test/support/integration.rb +0 -92
  251. data/test/support/locale/en.yml +0 -8
  252. data/test/support/mongoid.yml +0 -6
  253. data/test/support/webrat/integrations/rails.rb +0 -24
  254. data/test/test_helper.rb +0 -34
  255. data/test/test_helpers_test.rb +0 -178
  256. data/test/test_models.rb +0 -33
@@ -1,13 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/object/try"
2
4
  require "active_support/core_ext/hash/slice"
3
5
 
4
- module ActionDispatch::Routing
5
- class RouteSet #:nodoc:
6
- # Ensure Devise modules are included only after loading routes, because we
7
- # need devise_for mappings already declared to create filters and helpers.
8
- def finalize_with_devise!
9
- result = finalize_without_devise!
10
-
6
+ module Devise
7
+ module RouteSet
8
+ def finalize!
9
+ result = super
11
10
  @devise_finalized ||= begin
12
11
  if Devise.router_name.nil? && defined?(@devise_finalized) && self != Rails.application.try(:routes)
13
12
  warn "[DEVISE] We have detected that you are using devise_for inside engine routes. " \
@@ -21,10 +20,16 @@ module ActionDispatch::Routing
21
20
  Devise.regenerate_helpers!
22
21
  true
23
22
  end
24
-
25
23
  result
26
24
  end
27
- alias_method_chain :finalize!, :devise
25
+ end
26
+ end
27
+
28
+ module ActionDispatch::Routing
29
+ class RouteSet #:nodoc:
30
+ # Ensure Devise modules are included only after loading routes, because we
31
+ # need devise_for mappings already declared to create filters and helpers.
32
+ prepend Devise::RouteSet
28
33
  end
29
34
 
30
35
  class Mapper
@@ -84,17 +89,17 @@ module ActionDispatch::Routing
84
89
  #
85
90
  # You can configure your routes with some options:
86
91
  #
87
- # * class_name: setup a different class to be looked up by devise, if it cannot be
92
+ # * class_name: set up a different class to be looked up by devise, if it cannot be
88
93
  # properly found by the route name.
89
94
  #
90
95
  # devise_for :users, class_name: 'Account'
91
96
  #
92
- # * path: allows you to setup path name that will be used, as rails routes does.
93
- # The following route configuration would setup your route as /accounts instead of /users:
97
+ # * path: allows you to set up path name that will be used, as rails routes does.
98
+ # The following route configuration would set up your route as /accounts instead of /users:
94
99
  #
95
100
  # devise_for :users, path: 'accounts'
96
101
  #
97
- # * singular: setup the singular name for the given resource. This is used as the helper methods
102
+ # * singular: set up the singular name for the given resource. This is used as the helper methods
98
103
  # names in controller ("authenticate_#{singular}!", "#{singular}_signed_in?", "current_#{singular}"
99
104
  # and "#{singular}_session"), as the scope name in routes and as the scope given to warden.
100
105
  #
@@ -105,7 +110,7 @@ module ActionDispatch::Routing
105
110
  # end
106
111
  #
107
112
  # class ManagerController < ApplicationController
108
- # before_filter authenticate_manager!
113
+ # before_action authenticate_manager!
109
114
  #
110
115
  # def show
111
116
  # @manager = current_manager
@@ -130,10 +135,10 @@ module ActionDispatch::Routing
130
135
  # * failure_app: a rack app which is invoked whenever there is a failure. Strings representing a given
131
136
  # are also allowed as parameter.
132
137
  #
133
- # * sign_out_via: the HTTP method(s) accepted for the :sign_out action (default: :get),
138
+ # * sign_out_via: the HTTP method(s) accepted for the :sign_out action (default: :delete),
134
139
  # if you wish to restrict this to accept only :post or :delete requests you should do:
135
140
  #
136
- # devise_for :users, sign_out_via: [:post, :delete]
141
+ # devise_for :users, sign_out_via: [:get, :post]
137
142
  #
138
143
  # You need to make sure that your sign_out controls trigger a request with a matching HTTP method.
139
144
  #
@@ -335,7 +340,7 @@ module ActionDispatch::Routing
335
340
 
336
341
  # Sets the devise scope to be used in the controller. If you have custom routes,
337
342
  # you are required to call this method (also aliased as :as) in order to specify
338
- # to which controller it is targetted.
343
+ # to which controller it is targeted.
339
344
  #
340
345
  # as :user do
341
346
  # get "sign_in", to: "devise/sessions#new"
@@ -428,27 +433,29 @@ options to another `devise_for` call outside the scope. Here is an example:
428
433
  end
429
434
  ERROR
430
435
  end
431
-
432
- path, @scope[:path] = @scope[:path], nil
436
+ current_scope = @scope.dup
437
+ if @scope.respond_to? :new
438
+ @scope = @scope.new path: nil
439
+ else
440
+ @scope[:path] = nil
441
+ end
433
442
  path_prefix = Devise.omniauth_path_prefix || "/#{mapping.fullpath}/auth".squeeze("/")
434
443
 
435
444
  set_omniauth_path_prefix!(path_prefix)
436
445
 
437
- providers = Regexp.union(mapping.to.omniauth_providers.map(&:to_s))
446
+ mapping.to.omniauth_providers.each do |provider|
447
+ match "#{path_prefix}/#{provider}",
448
+ to: "#{controllers[:omniauth_callbacks]}#passthru",
449
+ as: "#{provider}_omniauth_authorize",
450
+ via: [:get, :post]
438
451
 
439
- match "#{path_prefix}/:provider",
440
- constraints: { provider: providers },
441
- to: "#{controllers[:omniauth_callbacks]}#passthru",
442
- as: :omniauth_authorize,
443
- via: [:get, :post]
444
-
445
- match "#{path_prefix}/:action/callback",
446
- constraints: { action: providers },
447
- to: "#{controllers[:omniauth_callbacks]}#:action",
448
- as: :omniauth_callback,
449
- via: [:get, :post]
452
+ match "#{path_prefix}/#{provider}/callback",
453
+ to: "#{controllers[:omniauth_callbacks]}##{provider}",
454
+ as: "#{provider}_omniauth_callback",
455
+ via: [:get, :post]
456
+ end
450
457
  ensure
451
- @scope[:path] = path
458
+ @scope = current_scope
452
459
  end
453
460
 
454
461
  def with_devise_exclusive_scope(new_path, new_as, options) #:nodoc:
@@ -457,7 +464,11 @@ ERROR
457
464
  exclusive = { as: new_as, path: new_path, module: nil }
458
465
  exclusive.merge!(options.slice(:constraints, :defaults, :options))
459
466
 
460
- exclusive.each_pair { |key, value| @scope[key] = value }
467
+ if @scope.respond_to? :new
468
+ @scope = @scope.new exclusive
469
+ else
470
+ exclusive.each_pair { |key, value| @scope[key] = value }
471
+ end
461
472
  yield
462
473
  ensure
463
474
  @scope = current_scope
@@ -1,19 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Warden::Mixins::Common
2
4
  def request
3
5
  @request ||= ActionDispatch::Request.new(env)
4
6
  end
5
7
 
6
- # Deprecate: Remove this check once we move to Rails 4 only.
7
- NULL_STORE =
8
- defined?(ActionController::RequestForgeryProtection::ProtectionMethods::NullSession::NullSessionHash) ?
9
- ActionController::RequestForgeryProtection::ProtectionMethods::NullSession::NullSessionHash : nil
10
-
11
8
  def reset_session!
12
- # Calling reset_session on NULL_STORE causes it fail.
13
- # This is a bug that needs to be fixed in Rails.
14
- unless NULL_STORE && request.session.is_a?(NULL_STORE)
15
- request.reset_session
16
- end
9
+ request.reset_session
17
10
  end
18
11
 
19
12
  def cookies
data/lib/devise/rails.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'devise/rails/routes'
2
4
  require 'devise/rails/warden_compat'
3
5
 
@@ -11,7 +13,9 @@ module Devise
11
13
  end
12
14
 
13
15
  # Force routes to be loaded if we are doing any eager load.
14
- config.before_eager_load { |app| app.reload_routes! }
16
+ config.before_eager_load do |app|
17
+ app.reload_routes! if Devise.reload_routes
18
+ end
15
19
 
16
20
  initializer "devise.url_helpers" do
17
21
  Devise.include_helpers(Devise::Controllers)
@@ -30,27 +34,14 @@ module Devise
30
34
  end
31
35
 
32
36
  initializer "devise.secret_key" do |app|
33
- if app.respond_to?(:secrets)
34
- Devise.secret_key ||= app.secrets.secret_key_base
35
- elsif app.config.respond_to?(:secret_key_base)
36
- Devise.secret_key ||= app.config.secret_key_base
37
- end
37
+ Devise.secret_key ||= Devise::SecretKeyFinder.new(app).find
38
38
 
39
39
  Devise.token_generator ||=
40
40
  if secret_key = Devise.secret_key
41
41
  Devise::TokenGenerator.new(
42
- Devise::CachingKeyGenerator.new(Devise::KeyGenerator.new(secret_key))
42
+ ActiveSupport::CachingKeyGenerator.new(ActiveSupport::KeyGenerator.new(secret_key))
43
43
  )
44
44
  end
45
45
  end
46
-
47
- initializer "devise.fix_routes_proxy_missing_respond_to_bug" do
48
- # Deprecate: Remove once we move to Rails 4 only.
49
- ActionDispatch::Routing::RoutesProxy.class_eval do
50
- def respond_to?(method, include_private = false)
51
- super || routes.url_helpers.respond_to?(method)
52
- end
53
- end
54
- end
55
46
  end
56
47
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Devise
4
+ class SecretKeyFinder
5
+ def initialize(application)
6
+ @application = application
7
+ end
8
+
9
+ def find
10
+ if @application.respond_to?(:credentials) && key_exists?(@application.credentials)
11
+ @application.credentials.secret_key_base
12
+ elsif @application.respond_to?(:secrets) && key_exists?(@application.secrets)
13
+ @application.secrets.secret_key_base
14
+ elsif @application.config.respond_to?(:secret_key_base) && key_exists?(@application.config)
15
+ @application.config.secret_key_base
16
+ elsif @application.respond_to?(:secret_key_base) && key_exists?(@application)
17
+ @application.secret_key_base
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def key_exists?(object)
24
+ object.secret_key_base.present?
25
+ end
26
+ end
27
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'devise/strategies/base'
2
4
 
3
5
  module Devise
@@ -26,7 +28,7 @@ module Devise
26
28
  private
27
29
 
28
30
  # Receives a resource and check if it is valid by calling valid_for_authentication?
29
- # An optional block that will be triggered while validating can be optionally
31
+ # A block that will be triggered while validating can be optionally
30
32
  # given as parameter. Check Devise::Models::Authenticatable.valid_for_authentication?
31
33
  # for more information.
32
34
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Devise
2
4
  module Strategies
3
5
  # Base strategy for Devise. Responsible for verifying correct scope and mapping.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'devise/strategies/authenticatable'
2
4
 
3
5
  module Devise
@@ -6,16 +8,21 @@ module Devise
6
8
  class DatabaseAuthenticatable < Authenticatable
7
9
  def authenticate!
8
10
  resource = password.present? && mapping.to.find_for_database_authentication(authentication_hash)
9
- encrypted = false
11
+ hashed = false
10
12
 
11
- if validate(resource){ encrypted = true; resource.valid_password?(password) }
13
+ if validate(resource){ hashed = true; resource.valid_password?(password) }
12
14
  remember_me(resource)
13
15
  resource.after_database_authentication
14
16
  success!(resource)
15
17
  end
16
18
 
17
- mapping.to.new.password = password if !encrypted && Devise.paranoid
18
- fail(:not_found_in_database) unless resource
19
+ # In paranoid mode, hash the password even when a resource doesn't exist for the given authentication key.
20
+ # This is necessary to prevent enumeration attacks - e.g. the request is faster when a resource doesn't
21
+ # exist in the database if the password hashing algorithm is not called.
22
+ mapping.to.new.password = password if !hashed && Devise.paranoid
23
+ unless resource
24
+ Devise.paranoid ? fail(:invalid) : fail(:not_found_in_database)
25
+ end
19
26
  end
20
27
  end
21
28
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'devise/strategies/authenticatable'
2
4
 
3
5
  module Devise
@@ -25,8 +27,7 @@ module Devise
25
27
  end
26
28
 
27
29
  if validate(resource)
28
- remember_me(resource)
29
- extend_remember_me_period(resource)
30
+ remember_me(resource) if extend_remember_me?(resource)
30
31
  resource.after_remembered
31
32
  success!(resource)
32
33
  end
@@ -43,10 +44,8 @@ module Devise
43
44
 
44
45
  private
45
46
 
46
- def extend_remember_me_period(resource)
47
- if resource.respond_to?(:extend_remember_period=)
48
- resource.extend_remember_period = mapping.to.extend_remember_period
49
- end
47
+ def extend_remember_me?(resource)
48
+ resource.respond_to?(:extend_remember_period) && resource.extend_remember_period
50
49
  end
51
50
 
52
51
  def remember_me?
@@ -0,0 +1,165 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Devise
4
+ module Test
5
+ # `Devise::Test::ControllerHelpers` provides a facility to test controllers
6
+ # in isolation when using `ActionController::TestCase` allowing you to
7
+ # quickly sign_in or sign_out a user. Do not use
8
+ # `Devise::Test::ControllerHelpers` in integration tests.
9
+ #
10
+ # Examples
11
+ #
12
+ # class PostsTest < ActionController::TestCase
13
+ # include Devise::Test::ControllerHelpers
14
+ #
15
+ # test 'authenticated users can GET index' do
16
+ # sign_in users(:bob)
17
+ #
18
+ # get :index
19
+ # assert_response :success
20
+ # end
21
+ # end
22
+ #
23
+ # Important: you should not test Warden specific behavior (like callbacks)
24
+ # using `Devise::Test::ControllerHelpers` since it is a stub of the actual
25
+ # behavior. Such callbacks should be tested in your integration suite instead.
26
+ module ControllerHelpers
27
+ extend ActiveSupport::Concern
28
+
29
+ included do
30
+ setup :setup_controller_for_warden, :warden
31
+ end
32
+
33
+ # Override process to consider warden.
34
+ def process(*)
35
+ _catch_warden { super }
36
+
37
+ @response
38
+ end
39
+
40
+ # We need to set up the environment variables and the response in the controller.
41
+ def setup_controller_for_warden #:nodoc:
42
+ @request.env['action_controller.instance'] = @controller
43
+ end
44
+
45
+ # Quick access to Warden::Proxy.
46
+ def warden #:nodoc:
47
+ @request.env['warden'] ||= begin
48
+ manager = Warden::Manager.new(nil) do |config|
49
+ config.merge! Devise.warden_config
50
+ end
51
+ Warden::Proxy.new(@request.env, manager)
52
+ end
53
+ end
54
+
55
+ # sign_in a given resource by storing its keys in the session.
56
+ # This method bypass any warden authentication callback.
57
+ #
58
+ # * +resource+ - The resource that should be authenticated
59
+ # * +scope+ - An optional +Symbol+ with the scope where the resource
60
+ # should be signed in with.
61
+ # Examples:
62
+ #
63
+ # sign_in users(:alice)
64
+ # sign_in users(:alice), scope: :admin
65
+ def sign_in(resource, deprecated = nil, scope: nil)
66
+ if deprecated.present?
67
+ scope = resource
68
+ resource = deprecated
69
+
70
+ ActiveSupport::Deprecation.warn <<-DEPRECATION.strip_heredoc
71
+ [Devise] sign_in(:#{scope}, resource) on controller tests is deprecated and will be removed from Devise.
72
+ Please use sign_in(resource, scope: :#{scope}) instead.
73
+ DEPRECATION
74
+ end
75
+
76
+ scope ||= Devise::Mapping.find_scope!(resource)
77
+
78
+ warden.instance_variable_get(:@users).delete(scope)
79
+ warden.session_serializer.store(resource, scope)
80
+ end
81
+
82
+ # Sign out a given resource or scope by calling logout on Warden.
83
+ # This method bypass any warden logout callback.
84
+ #
85
+ # Examples:
86
+ #
87
+ # sign_out :user # sign_out(scope)
88
+ # sign_out @user # sign_out(resource)
89
+ #
90
+ def sign_out(resource_or_scope)
91
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
92
+ @controller.instance_variable_set(:"@current_#{scope}", nil)
93
+ user = warden.instance_variable_get(:@users).delete(scope)
94
+ warden.session_serializer.delete(scope, user)
95
+ end
96
+
97
+ protected
98
+
99
+ # Catch warden continuations and handle like the middleware would.
100
+ # Returns nil when interrupted, otherwise the normal result of the block.
101
+ def _catch_warden(&block)
102
+ result = catch(:warden, &block)
103
+
104
+ env = @controller.request.env
105
+
106
+ result ||= {}
107
+
108
+ # Set the response. In production, the rack result is returned
109
+ # from Warden::Manager#call, which the following is modelled on.
110
+ case result
111
+ when Array
112
+ if result.first == 401 && intercept_401?(env) # does this happen during testing?
113
+ _process_unauthenticated(env)
114
+ else
115
+ result
116
+ end
117
+ when Hash
118
+ _process_unauthenticated(env, result)
119
+ else
120
+ result
121
+ end
122
+ end
123
+
124
+ def _process_unauthenticated(env, options = {})
125
+ options[:action] ||= :unauthenticated
126
+ proxy = request.env['warden']
127
+ result = options[:result] || proxy.result
128
+
129
+ ret = case result
130
+ when :redirect
131
+ body = proxy.message || "You are being redirected to #{proxy.headers['Location']}"
132
+ [proxy.status, proxy.headers, [body]]
133
+ when :custom
134
+ proxy.custom_response
135
+ else
136
+ request.env["PATH_INFO"] = "/#{options[:action]}"
137
+ request.env["warden.options"] = options
138
+ Warden::Manager._run_callbacks(:before_failure, env, options)
139
+
140
+ status, headers, response = Devise.warden_config[:failure_app].call(env).to_a
141
+ @controller.response.headers.merge!(headers)
142
+ @controller.response.content_type = headers["Content-Type"] unless Rails::VERSION::MAJOR >= 5
143
+ @controller.status = status
144
+ @controller.response.body = response.body
145
+ nil # causes process return @response
146
+ end
147
+
148
+ # ensure that the controller response is set up. In production, this is
149
+ # not necessary since warden returns the results to rack. However, at
150
+ # testing time, we want the response to be available to the testing
151
+ # framework to verify what would be returned to rack.
152
+ if ret.is_a?(Array)
153
+ status, headers, body = *ret
154
+ # ensure the controller response is set to our response.
155
+ @controller.response ||= @response
156
+ @response.status = status
157
+ @response.headers.merge!(headers)
158
+ @response.body = body
159
+ end
160
+
161
+ ret
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Devise
4
+ # Devise::Test::IntegrationHelpers is a helper module for facilitating
5
+ # authentication on Rails integration tests to bypass the required steps for
6
+ # signin in or signin out a record.
7
+ #
8
+ # Examples
9
+ #
10
+ # class PostsTest < ActionDispatch::IntegrationTest
11
+ # include Devise::Test::IntegrationHelpers
12
+ #
13
+ # test 'authenticated users can see posts' do
14
+ # sign_in users(:bob)
15
+ #
16
+ # get '/posts'
17
+ # assert_response :success
18
+ # end
19
+ # end
20
+ module Test
21
+ module IntegrationHelpers
22
+ def self.included(base)
23
+ base.class_eval do
24
+ include Warden::Test::Helpers
25
+
26
+ setup :setup_integration_for_devise
27
+ teardown :teardown_integration_for_devise
28
+ end
29
+ end
30
+
31
+ # Signs in a specific resource, mimicking a successfull sign in
32
+ # operation through +Devise::SessionsController#create+.
33
+ #
34
+ # * +resource+ - The resource that should be authenticated
35
+ # * +scope+ - An optional +Symbol+ with the scope where the resource
36
+ # should be signed in with.
37
+ def sign_in(resource, scope: nil)
38
+ scope ||= Devise::Mapping.find_scope!(resource)
39
+
40
+ login_as(resource, scope: scope)
41
+ end
42
+
43
+ # Signs out a specific scope from the session.
44
+ #
45
+ # * +resource_or_scope+ - The resource or scope that should be signed out.
46
+ def sign_out(resource_or_scope)
47
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
48
+
49
+ logout scope
50
+ end
51
+
52
+ protected
53
+
54
+ def setup_integration_for_devise
55
+ Warden.test_mode!
56
+ end
57
+
58
+ def teardown_integration_for_devise
59
+ Warden.test_reset!
60
+ end
61
+ end
62
+ end
63
+ end