devise 4.1.1 → 5.0.4
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +68 -111
- data/MIT-LICENSE +2 -1
- data/README.md +315 -98
- data/app/controllers/devise/confirmations_controller.rb +3 -0
- data/app/controllers/devise/omniauth_callbacks_controller.rb +7 -5
- data/app/controllers/devise/passwords_controller.rb +10 -2
- data/app/controllers/devise/registrations_controller.rb +42 -20
- data/app/controllers/devise/sessions_controller.rb +9 -7
- data/app/controllers/devise/unlocks_controller.rb +3 -0
- data/app/controllers/devise_controller.rb +19 -3
- data/app/helpers/devise_helper.rb +3 -23
- data/app/mailers/devise/mailer.rb +10 -4
- data/app/views/devise/confirmations/new.html.erb +3 -3
- data/app/views/devise/mailer/email_changed.html.erb +7 -0
- data/app/views/devise/passwords/edit.html.erb +6 -6
- data/app/views/devise/passwords/new.html.erb +4 -4
- data/app/views/devise/registrations/edit.html.erb +13 -10
- data/app/views/devise/registrations/new.html.erb +9 -9
- data/app/views/devise/sessions/new.html.erb +8 -8
- data/app/views/devise/shared/_error_messages.html.erb +15 -0
- data/app/views/devise/shared/_links.html.erb +13 -13
- data/app/views/devise/unlocks/new.html.erb +3 -3
- data/config/locales/en.yml +5 -2
- data/lib/devise/controllers/helpers.rb +24 -9
- data/lib/devise/controllers/rememberable.rb +3 -1
- data/lib/devise/controllers/responder.rb +35 -0
- data/lib/devise/controllers/scoped_views.rb +2 -0
- data/lib/devise/controllers/sign_in_out.rb +31 -21
- data/lib/devise/controllers/store_location.rb +25 -7
- data/lib/devise/controllers/url_helpers.rb +3 -1
- data/lib/devise/delegator.rb +2 -0
- data/lib/devise/encryptor.rb +2 -0
- data/lib/devise/failure_app.rb +71 -38
- data/lib/devise/hooks/activatable.rb +3 -1
- data/lib/devise/hooks/csrf_cleaner.rb +8 -1
- data/lib/devise/hooks/forgetable.rb +2 -0
- data/lib/devise/hooks/lockable.rb +4 -2
- data/lib/devise/hooks/proxy.rb +3 -1
- data/lib/devise/hooks/rememberable.rb +2 -0
- data/lib/devise/hooks/timeoutable.rb +5 -3
- data/lib/devise/hooks/trackable.rb +2 -0
- data/lib/devise/mailers/helpers.rb +15 -18
- data/lib/devise/mapping.rb +4 -2
- data/lib/devise/models/authenticatable.rb +58 -44
- data/lib/devise/models/confirmable.rb +52 -14
- data/lib/devise/models/database_authenticatable.rb +52 -20
- data/lib/devise/models/lockable.rb +19 -5
- data/lib/devise/models/omniauthable.rb +4 -2
- data/lib/devise/models/recoverable.rb +22 -21
- data/lib/devise/models/registerable.rb +4 -0
- data/lib/devise/models/rememberable.rb +6 -4
- data/lib/devise/models/timeoutable.rb +3 -1
- data/lib/devise/models/trackable.rb +15 -1
- data/lib/devise/models/validatable.rb +10 -6
- data/lib/devise/models.rb +4 -1
- data/lib/devise/modules.rb +2 -0
- data/lib/devise/omniauth/config.rb +2 -0
- data/lib/devise/omniauth/url_helpers.rb +2 -51
- data/lib/devise/omniauth.rb +4 -5
- data/lib/devise/orm/active_record.rb +5 -1
- data/lib/devise/orm/mongoid.rb +6 -2
- data/lib/devise/orm.rb +80 -0
- data/lib/devise/parameter_filter.rb +4 -0
- data/lib/devise/parameter_sanitizer.rb +16 -58
- data/lib/devise/rails/routes.rb +12 -11
- data/lib/devise/rails/warden_compat.rb +2 -0
- data/lib/devise/rails.rb +16 -6
- data/lib/devise/strategies/authenticatable.rb +3 -1
- data/lib/devise/strategies/base.rb +2 -0
- data/lib/devise/strategies/database_authenticatable.rb +8 -1
- data/lib/devise/strategies/rememberable.rb +2 -0
- data/lib/devise/test/controller_helpers.rb +156 -0
- data/lib/devise/test/integration_helpers.rb +63 -0
- data/lib/devise/time_inflector.rb +2 -0
- data/lib/devise/token_generator.rb +2 -0
- data/lib/devise/version.rb +3 -1
- data/lib/devise.rb +69 -28
- data/lib/generators/active_record/devise_generator.rb +38 -16
- data/lib/generators/active_record/templates/migration.rb +3 -1
- data/lib/generators/active_record/templates/migration_existing.rb +2 -0
- data/lib/generators/devise/controllers_generator.rb +4 -2
- data/lib/generators/devise/devise_generator.rb +5 -3
- data/lib/generators/devise/install_generator.rb +3 -5
- data/lib/generators/devise/orm_helpers.rb +5 -3
- data/lib/generators/devise/views_generator.rb +8 -9
- data/lib/generators/mongoid/devise_generator.rb +7 -5
- data/lib/generators/templates/README +9 -8
- data/lib/generators/templates/controllers/confirmations_controller.rb +2 -0
- data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +3 -1
- data/lib/generators/templates/controllers/passwords_controller.rb +2 -0
- data/lib/generators/templates/controllers/registrations_controller.rb +4 -2
- data/lib/generators/templates/controllers/sessions_controller.rb +3 -1
- data/lib/generators/templates/controllers/unlocks_controller.rb +2 -0
- data/lib/generators/templates/devise.rb +59 -11
- data/lib/generators/templates/markerb/email_changed.markerb +7 -0
- data/lib/generators/templates/markerb/password_change.markerb +2 -2
- data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +5 -1
- data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +10 -2
- data/lib/generators/templates/simple_form_for/passwords/new.html.erb +5 -2
- data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +12 -4
- data/lib/generators/templates/simple_form_for/registrations/new.html.erb +11 -3
- data/lib/generators/templates/simple_form_for/sessions/new.html.erb +7 -2
- data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +4 -1
- metadata +23 -302
- data/.gitignore +0 -10
- data/.travis.yml +0 -44
- data/.yardopts +0 -9
- data/CODE_OF_CONDUCT.md +0 -22
- data/CONTRIBUTING.md +0 -16
- data/Gemfile +0 -30
- data/Gemfile.lock +0 -182
- data/Rakefile +0 -36
- data/bin/test +0 -13
- data/devise.gemspec +0 -26
- data/devise.png +0 -0
- data/gemfiles/Gemfile.rails-4.1-stable +0 -30
- data/gemfiles/Gemfile.rails-4.1-stable.lock +0 -170
- data/gemfiles/Gemfile.rails-4.2-stable +0 -30
- data/gemfiles/Gemfile.rails-4.2-stable.lock +0 -192
- data/gemfiles/Gemfile.rails-5.0-beta +0 -37
- data/gemfiles/Gemfile.rails-5.0-beta.lock +0 -199
- data/lib/devise/test_helpers.rb +0 -137
- data/test/controllers/custom_registrations_controller_test.rb +0 -40
- data/test/controllers/custom_strategy_test.rb +0 -64
- data/test/controllers/helper_methods_test.rb +0 -22
- data/test/controllers/helpers_test.rb +0 -316
- data/test/controllers/inherited_controller_i18n_messages_test.rb +0 -51
- data/test/controllers/internal_helpers_test.rb +0 -127
- data/test/controllers/load_hooks_controller_test.rb +0 -19
- data/test/controllers/passwords_controller_test.rb +0 -32
- data/test/controllers/sessions_controller_test.rb +0 -106
- data/test/controllers/url_helpers_test.rb +0 -65
- data/test/delegator_test.rb +0 -19
- data/test/devise_test.rb +0 -107
- data/test/failure_app_test.rb +0 -320
- data/test/generators/active_record_generator_test.rb +0 -83
- data/test/generators/controllers_generator_test.rb +0 -48
- data/test/generators/devise_generator_test.rb +0 -39
- data/test/generators/install_generator_test.rb +0 -24
- data/test/generators/mongoid_generator_test.rb +0 -23
- data/test/generators/views_generator_test.rb +0 -103
- data/test/helpers/devise_helper_test.rb +0 -49
- data/test/integration/authenticatable_test.rb +0 -698
- data/test/integration/confirmable_test.rb +0 -324
- data/test/integration/database_authenticatable_test.rb +0 -95
- data/test/integration/http_authenticatable_test.rb +0 -106
- data/test/integration/lockable_test.rb +0 -240
- data/test/integration/omniauthable_test.rb +0 -135
- data/test/integration/recoverable_test.rb +0 -347
- data/test/integration/registerable_test.rb +0 -357
- data/test/integration/rememberable_test.rb +0 -211
- data/test/integration/timeoutable_test.rb +0 -184
- data/test/integration/trackable_test.rb +0 -92
- data/test/mailers/confirmation_instructions_test.rb +0 -115
- data/test/mailers/reset_password_instructions_test.rb +0 -96
- data/test/mailers/unlock_instructions_test.rb +0 -91
- data/test/mapping_test.rb +0 -134
- data/test/models/authenticatable_test.rb +0 -23
- data/test/models/confirmable_test.rb +0 -511
- data/test/models/database_authenticatable_test.rb +0 -269
- data/test/models/lockable_test.rb +0 -350
- data/test/models/omniauthable_test.rb +0 -7
- data/test/models/recoverable_test.rb +0 -251
- data/test/models/registerable_test.rb +0 -7
- data/test/models/rememberable_test.rb +0 -169
- data/test/models/serializable_test.rb +0 -49
- data/test/models/timeoutable_test.rb +0 -51
- data/test/models/trackable_test.rb +0 -41
- data/test/models/validatable_test.rb +0 -119
- data/test/models_test.rb +0 -153
- data/test/omniauth/config_test.rb +0 -57
- data/test/omniauth/url_helpers_test.rb +0 -51
- data/test/orm/active_record.rb +0 -17
- data/test/orm/mongoid.rb +0 -13
- data/test/parameter_sanitizer_test.rb +0 -131
- data/test/rails_app/Rakefile +0 -6
- data/test/rails_app/app/active_record/admin.rb +0 -6
- data/test/rails_app/app/active_record/shim.rb +0 -2
- data/test/rails_app/app/active_record/user.rb +0 -7
- data/test/rails_app/app/active_record/user_on_engine.rb +0 -7
- data/test/rails_app/app/active_record/user_on_main_app.rb +0 -7
- data/test/rails_app/app/active_record/user_without_email.rb +0 -8
- data/test/rails_app/app/controllers/admins/sessions_controller.rb +0 -6
- data/test/rails_app/app/controllers/admins_controller.rb +0 -6
- data/test/rails_app/app/controllers/application_controller.rb +0 -11
- data/test/rails_app/app/controllers/application_with_fake_engine.rb +0 -30
- data/test/rails_app/app/controllers/custom/registrations_controller.rb +0 -31
- data/test/rails_app/app/controllers/home_controller.rb +0 -29
- data/test/rails_app/app/controllers/publisher/registrations_controller.rb +0 -2
- data/test/rails_app/app/controllers/publisher/sessions_controller.rb +0 -2
- data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +0 -14
- data/test/rails_app/app/controllers/users_controller.rb +0 -31
- data/test/rails_app/app/helpers/application_helper.rb +0 -3
- data/test/rails_app/app/mailers/users/from_proc_mailer.rb +0 -3
- data/test/rails_app/app/mailers/users/mailer.rb +0 -3
- data/test/rails_app/app/mailers/users/reply_to_mailer.rb +0 -4
- data/test/rails_app/app/mongoid/admin.rb +0 -29
- data/test/rails_app/app/mongoid/shim.rb +0 -23
- data/test/rails_app/app/mongoid/user.rb +0 -39
- data/test/rails_app/app/mongoid/user_on_engine.rb +0 -39
- data/test/rails_app/app/mongoid/user_on_main_app.rb +0 -39
- data/test/rails_app/app/mongoid/user_without_email.rb +0 -33
- data/test/rails_app/app/views/admins/index.html.erb +0 -1
- data/test/rails_app/app/views/admins/sessions/new.html.erb +0 -2
- data/test/rails_app/app/views/home/admin_dashboard.html.erb +0 -1
- data/test/rails_app/app/views/home/index.html.erb +0 -1
- data/test/rails_app/app/views/home/join.html.erb +0 -1
- data/test/rails_app/app/views/home/private.html.erb +0 -1
- data/test/rails_app/app/views/home/user_dashboard.html.erb +0 -1
- data/test/rails_app/app/views/layouts/application.html.erb +0 -24
- data/test/rails_app/app/views/users/edit_form.html.erb +0 -1
- data/test/rails_app/app/views/users/index.html.erb +0 -1
- data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +0 -1
- data/test/rails_app/app/views/users/sessions/new.html.erb +0 -1
- data/test/rails_app/bin/bundle +0 -3
- data/test/rails_app/bin/rails +0 -4
- data/test/rails_app/bin/rake +0 -4
- data/test/rails_app/config/application.rb +0 -44
- data/test/rails_app/config/boot.rb +0 -14
- data/test/rails_app/config/database.yml +0 -18
- data/test/rails_app/config/environment.rb +0 -5
- data/test/rails_app/config/environments/development.rb +0 -30
- data/test/rails_app/config/environments/production.rb +0 -84
- data/test/rails_app/config/environments/test.rb +0 -46
- data/test/rails_app/config/initializers/backtrace_silencers.rb +0 -7
- data/test/rails_app/config/initializers/devise.rb +0 -180
- data/test/rails_app/config/initializers/inflections.rb +0 -2
- data/test/rails_app/config/initializers/secret_token.rb +0 -3
- data/test/rails_app/config/initializers/session_store.rb +0 -1
- data/test/rails_app/config/routes.rb +0 -126
- data/test/rails_app/config.ru +0 -4
- data/test/rails_app/db/migrate/20100401102949_create_tables.rb +0 -71
- data/test/rails_app/db/schema.rb +0 -55
- data/test/rails_app/lib/shared_admin.rb +0 -17
- data/test/rails_app/lib/shared_user.rb +0 -30
- data/test/rails_app/lib/shared_user_without_email.rb +0 -26
- data/test/rails_app/lib/shared_user_without_omniauth.rb +0 -13
- data/test/rails_app/public/404.html +0 -26
- data/test/rails_app/public/422.html +0 -26
- data/test/rails_app/public/500.html +0 -26
- data/test/rails_app/public/favicon.ico +0 -0
- data/test/rails_test.rb +0 -9
- data/test/routes_test.rb +0 -279
- data/test/support/action_controller/record_identifier.rb +0 -10
- data/test/support/assertions.rb +0 -39
- data/test/support/helpers.rb +0 -77
- data/test/support/http_method_compatibility.rb +0 -51
- data/test/support/integration.rb +0 -92
- data/test/support/locale/en.yml +0 -8
- data/test/support/mongoid.yml +0 -6
- data/test/support/webrat/integrations/rails.rb +0 -33
- data/test/test_helper.rb +0 -34
- data/test/test_helpers_test.rb +0 -178
- data/test/test_models.rb +0 -33
data/lib/devise/rails/routes.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
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
|
|
|
@@ -133,10 +135,10 @@ module ActionDispatch::Routing
|
|
|
133
135
|
# * failure_app: a rack app which is invoked whenever there is a failure. Strings representing a given
|
|
134
136
|
# are also allowed as parameter.
|
|
135
137
|
#
|
|
136
|
-
# * sign_out_via: the HTTP method(s) accepted for the :sign_out action (default: :
|
|
138
|
+
# * sign_out_via: the HTTP method(s) accepted for the :sign_out action (default: :delete),
|
|
137
139
|
# if you wish to restrict this to accept only :post or :delete requests you should do:
|
|
138
140
|
#
|
|
139
|
-
# devise_for :users, sign_out_via: [:
|
|
141
|
+
# devise_for :users, sign_out_via: [:get, :post]
|
|
140
142
|
#
|
|
141
143
|
# You need to make sure that your sign_out controls trigger a request with a matching HTTP method.
|
|
142
144
|
#
|
|
@@ -233,7 +235,6 @@ module ActionDispatch::Routing
|
|
|
233
235
|
options[:constraints] = (@scope[:constraints] || {}).merge(options[:constraints] || {})
|
|
234
236
|
options[:defaults] = (@scope[:defaults] || {}).merge(options[:defaults] || {})
|
|
235
237
|
options[:options] = @scope[:options] || {}
|
|
236
|
-
options[:options][:format] = false if options[:format] == false
|
|
237
238
|
|
|
238
239
|
resources.map!(&:to_sym)
|
|
239
240
|
|
|
@@ -285,7 +286,7 @@ module ActionDispatch::Routing
|
|
|
285
286
|
# root to: "admin/dashboard#show", as: :user_root
|
|
286
287
|
# end
|
|
287
288
|
#
|
|
288
|
-
def authenticate(scope=nil, block=nil)
|
|
289
|
+
def authenticate(scope = nil, block = nil)
|
|
289
290
|
constraints_for(:authenticate!, scope, block) do
|
|
290
291
|
yield
|
|
291
292
|
end
|
|
@@ -309,7 +310,7 @@ module ActionDispatch::Routing
|
|
|
309
310
|
#
|
|
310
311
|
# root to: 'landing#show'
|
|
311
312
|
#
|
|
312
|
-
def authenticated(scope=nil, block=nil)
|
|
313
|
+
def authenticated(scope = nil, block = nil)
|
|
313
314
|
constraints_for(:authenticate?, scope, block) do
|
|
314
315
|
yield
|
|
315
316
|
end
|
|
@@ -326,7 +327,7 @@ module ActionDispatch::Routing
|
|
|
326
327
|
#
|
|
327
328
|
# root to: 'dashboard#show'
|
|
328
329
|
#
|
|
329
|
-
def unauthenticated(scope=nil)
|
|
330
|
+
def unauthenticated(scope = nil)
|
|
330
331
|
constraint = lambda do |request|
|
|
331
332
|
not request.env["warden"].authenticate? scope: scope
|
|
332
333
|
end
|
|
@@ -338,7 +339,7 @@ module ActionDispatch::Routing
|
|
|
338
339
|
|
|
339
340
|
# Sets the devise scope to be used in the controller. If you have custom routes,
|
|
340
341
|
# you are required to call this method (also aliased as :as) in order to specify
|
|
341
|
-
# to which controller it is
|
|
342
|
+
# to which controller it is targeted.
|
|
342
343
|
#
|
|
343
344
|
# as :user do
|
|
344
345
|
# get "sign_in", to: "devise/sessions#new"
|
|
@@ -411,7 +412,7 @@ module ActionDispatch::Routing
|
|
|
411
412
|
controller: controllers[:registrations]
|
|
412
413
|
}
|
|
413
414
|
|
|
414
|
-
resource :registration, options do
|
|
415
|
+
resource :registration, **options do
|
|
415
416
|
get :cancel
|
|
416
417
|
end
|
|
417
418
|
end
|
|
@@ -445,7 +446,7 @@ ERROR
|
|
|
445
446
|
match "#{path_prefix}/#{provider}",
|
|
446
447
|
to: "#{controllers[:omniauth_callbacks]}#passthru",
|
|
447
448
|
as: "#{provider}_omniauth_authorize",
|
|
448
|
-
via:
|
|
449
|
+
via: OmniAuth.config.allowed_request_methods
|
|
449
450
|
|
|
450
451
|
match "#{path_prefix}/#{provider}/callback",
|
|
451
452
|
to: "#{controllers[:omniauth_callbacks]}##{provider}",
|
|
@@ -460,7 +461,7 @@ ERROR
|
|
|
460
461
|
current_scope = @scope.dup
|
|
461
462
|
|
|
462
463
|
exclusive = { as: new_as, path: new_path, module: nil }
|
|
463
|
-
exclusive.merge!(options.slice(:constraints, :defaults, :options))
|
|
464
|
+
exclusive.merge!(options.slice(:constraints, :format, :defaults, :options))
|
|
464
465
|
|
|
465
466
|
if @scope.respond_to? :new
|
|
466
467
|
@scope = @scope.new exclusive
|
|
@@ -472,7 +473,7 @@ ERROR
|
|
|
472
473
|
@scope = current_scope
|
|
473
474
|
end
|
|
474
475
|
|
|
475
|
-
def constraints_for(method_to_apply, scope=nil, block=nil)
|
|
476
|
+
def constraints_for(method_to_apply, scope = nil, block = nil)
|
|
476
477
|
constraint = lambda do |request|
|
|
477
478
|
request.env['warden'].send(method_to_apply, scope: scope) &&
|
|
478
479
|
(block.nil? || block.call(request.env["warden"].user(scope)))
|
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,13 @@ 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
|
|
16
|
+
config.before_eager_load do |app|
|
|
17
|
+
app.reload_routes! if Devise.reload_routes
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
initializer "devise.deprecator" do |app|
|
|
21
|
+
app.deprecators[:devise] = Devise.deprecator if app.respond_to?(:deprecators)
|
|
22
|
+
end
|
|
15
23
|
|
|
16
24
|
initializer "devise.url_helpers" do
|
|
17
25
|
Devise.include_helpers(Devise::Controllers)
|
|
@@ -30,11 +38,7 @@ module Devise
|
|
|
30
38
|
end
|
|
31
39
|
|
|
32
40
|
initializer "devise.secret_key" do |app|
|
|
33
|
-
|
|
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
|
|
41
|
+
Devise.secret_key ||= app.secret_key_base
|
|
38
42
|
|
|
39
43
|
Devise.token_generator ||=
|
|
40
44
|
if secret_key = Devise.secret_key
|
|
@@ -43,5 +47,11 @@ module Devise
|
|
|
43
47
|
)
|
|
44
48
|
end
|
|
45
49
|
end
|
|
50
|
+
|
|
51
|
+
initializer "devise.configure_zeitwerk" do
|
|
52
|
+
if Rails.autoloaders.zeitwerk_enabled? && !defined?(ActionMailer)
|
|
53
|
+
Rails.autoloaders.main.ignore("#{root}/app/mailers/devise/mailer.rb")
|
|
54
|
+
end
|
|
55
|
+
end
|
|
46
56
|
end
|
|
47
57
|
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
|
-
#
|
|
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
|
require 'devise/strategies/authenticatable'
|
|
2
4
|
|
|
3
5
|
module Devise
|
|
@@ -14,8 +16,13 @@ module Devise
|
|
|
14
16
|
success!(resource)
|
|
15
17
|
end
|
|
16
18
|
|
|
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.
|
|
17
22
|
mapping.to.new.password = password if !hashed && Devise.paranoid
|
|
18
|
-
|
|
23
|
+
unless resource
|
|
24
|
+
Devise.paranoid ? fail(:invalid) : fail(:not_found_in_database)
|
|
25
|
+
end
|
|
19
26
|
end
|
|
20
27
|
end
|
|
21
28
|
end
|
|
@@ -0,0 +1,156 @@
|
|
|
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
|
+
ruby2_keywords(:process) if respond_to?(:ruby2_keywords, true)
|
|
41
|
+
|
|
42
|
+
# We need to set up the environment variables and the response in the controller.
|
|
43
|
+
def setup_controller_for_warden #:nodoc:
|
|
44
|
+
@request.env['action_controller.instance'] = @controller
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Quick access to Warden::Proxy.
|
|
48
|
+
def warden #:nodoc:
|
|
49
|
+
@request.env['warden'] ||= begin
|
|
50
|
+
manager = Warden::Manager.new(nil) do |config|
|
|
51
|
+
config.merge! Devise.warden_config
|
|
52
|
+
end
|
|
53
|
+
Warden::Proxy.new(@request.env, manager)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# sign_in a given resource by storing its keys in the session.
|
|
58
|
+
# This method bypass any warden authentication callback.
|
|
59
|
+
#
|
|
60
|
+
# * +resource+ - The resource that should be authenticated
|
|
61
|
+
# * +scope+ - An optional +Symbol+ with the scope where the resource
|
|
62
|
+
# should be signed in with.
|
|
63
|
+
# Examples:
|
|
64
|
+
#
|
|
65
|
+
# sign_in users(:alice)
|
|
66
|
+
# sign_in users(:alice), scope: :admin
|
|
67
|
+
def sign_in(resource, scope: nil)
|
|
68
|
+
scope ||= Devise::Mapping.find_scope!(resource)
|
|
69
|
+
|
|
70
|
+
warden.instance_variable_get(:@users).delete(scope)
|
|
71
|
+
warden.session_serializer.store(resource, scope)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Sign out a given resource or scope by calling logout on Warden.
|
|
75
|
+
# This method bypass any warden logout callback.
|
|
76
|
+
#
|
|
77
|
+
# Examples:
|
|
78
|
+
#
|
|
79
|
+
# sign_out :user # sign_out(scope)
|
|
80
|
+
# sign_out @user # sign_out(resource)
|
|
81
|
+
#
|
|
82
|
+
def sign_out(resource_or_scope)
|
|
83
|
+
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
|
84
|
+
@controller.instance_variable_set(:"@current_#{scope}", nil)
|
|
85
|
+
user = warden.instance_variable_get(:@users).delete(scope)
|
|
86
|
+
warden.session_serializer.delete(scope, user)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
protected
|
|
90
|
+
|
|
91
|
+
# Catch warden continuations and handle like the middleware would.
|
|
92
|
+
# Returns nil when interrupted, otherwise the normal result of the block.
|
|
93
|
+
def _catch_warden(&block)
|
|
94
|
+
result = catch(:warden, &block)
|
|
95
|
+
|
|
96
|
+
env = @controller.request.env
|
|
97
|
+
|
|
98
|
+
result ||= {}
|
|
99
|
+
|
|
100
|
+
# Set the response. In production, the rack result is returned
|
|
101
|
+
# from Warden::Manager#call, which the following is modelled on.
|
|
102
|
+
case result
|
|
103
|
+
when Array
|
|
104
|
+
if result.first == 401 && intercept_401?(env) # does this happen during testing?
|
|
105
|
+
_process_unauthenticated(env)
|
|
106
|
+
else
|
|
107
|
+
result
|
|
108
|
+
end
|
|
109
|
+
when Hash
|
|
110
|
+
_process_unauthenticated(env, result)
|
|
111
|
+
else
|
|
112
|
+
result
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def _process_unauthenticated(env, options = {})
|
|
117
|
+
options[:action] ||= :unauthenticated
|
|
118
|
+
proxy = request.env['warden']
|
|
119
|
+
result = options[:result] || proxy.result
|
|
120
|
+
|
|
121
|
+
ret = case result
|
|
122
|
+
when :redirect
|
|
123
|
+
body = proxy.message || "You are being redirected to #{proxy.headers['Location']}"
|
|
124
|
+
[proxy.status, proxy.headers, [body]]
|
|
125
|
+
when :custom
|
|
126
|
+
proxy.custom_response
|
|
127
|
+
else
|
|
128
|
+
request.env["PATH_INFO"] = "/#{options[:action]}"
|
|
129
|
+
request.env["warden.options"] = options
|
|
130
|
+
Warden::Manager._run_callbacks(:before_failure, env, options)
|
|
131
|
+
|
|
132
|
+
status, headers, response = Devise.warden_config[:failure_app].call(env).to_a
|
|
133
|
+
@controller.response.headers.merge!(headers)
|
|
134
|
+
@controller.status = status
|
|
135
|
+
@controller.response_body = response.body
|
|
136
|
+
nil # causes process return @response
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# ensure that the controller response is set up. In production, this is
|
|
140
|
+
# not necessary since warden returns the results to rack. However, at
|
|
141
|
+
# testing time, we want the response to be available to the testing
|
|
142
|
+
# framework to verify what would be returned to rack.
|
|
143
|
+
if ret.is_a?(Array)
|
|
144
|
+
status, headers, body = *ret
|
|
145
|
+
# ensure the controller response is set to our response.
|
|
146
|
+
@controller.response ||= @response
|
|
147
|
+
@response.status = status
|
|
148
|
+
@response.headers.merge!(headers)
|
|
149
|
+
@response.body = body
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
ret
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
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 successful 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
|
data/lib/devise/version.rb
CHANGED
data/lib/devise.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'rails'
|
|
2
4
|
require 'active_support/core_ext/numeric/time'
|
|
3
5
|
require 'active_support/dependencies'
|
|
@@ -11,15 +13,16 @@ module Devise
|
|
|
11
13
|
autoload :Encryptor, 'devise/encryptor'
|
|
12
14
|
autoload :FailureApp, 'devise/failure_app'
|
|
13
15
|
autoload :OmniAuth, 'devise/omniauth'
|
|
16
|
+
autoload :Orm, 'devise/orm'
|
|
14
17
|
autoload :ParameterFilter, 'devise/parameter_filter'
|
|
15
18
|
autoload :ParameterSanitizer, 'devise/parameter_sanitizer'
|
|
16
|
-
autoload :TestHelpers, 'devise/test_helpers'
|
|
17
19
|
autoload :TimeInflector, 'devise/time_inflector'
|
|
18
20
|
autoload :TokenGenerator, 'devise/token_generator'
|
|
19
21
|
|
|
20
22
|
module Controllers
|
|
21
23
|
autoload :Helpers, 'devise/controllers/helpers'
|
|
22
24
|
autoload :Rememberable, 'devise/controllers/rememberable'
|
|
25
|
+
autoload :Responder, 'devise/controllers/responder'
|
|
23
26
|
autoload :ScopedViews, 'devise/controllers/scoped_views'
|
|
24
27
|
autoload :SignInOut, 'devise/controllers/sign_in_out'
|
|
25
28
|
autoload :StoreLocation, 'devise/controllers/store_location'
|
|
@@ -39,19 +42,24 @@ module Devise
|
|
|
39
42
|
autoload :Authenticatable, 'devise/strategies/authenticatable'
|
|
40
43
|
end
|
|
41
44
|
|
|
45
|
+
module Test
|
|
46
|
+
autoload :ControllerHelpers, 'devise/test/controller_helpers'
|
|
47
|
+
autoload :IntegrationHelpers, 'devise/test/integration_helpers'
|
|
48
|
+
end
|
|
49
|
+
|
|
42
50
|
# Constants which holds devise configuration for extensions. Those should
|
|
43
51
|
# not be modified by the "end user" (this is why they are constants).
|
|
44
52
|
ALL = []
|
|
45
|
-
CONTROLLERS =
|
|
46
|
-
ROUTES =
|
|
47
|
-
STRATEGIES =
|
|
48
|
-
URL_HELPERS =
|
|
53
|
+
CONTROLLERS = {}
|
|
54
|
+
ROUTES = {}
|
|
55
|
+
STRATEGIES = {}
|
|
56
|
+
URL_HELPERS = {}
|
|
49
57
|
|
|
50
58
|
# Strategies that do not require user input.
|
|
51
59
|
NO_INPUT = []
|
|
52
60
|
|
|
53
61
|
# True values used to check params
|
|
54
|
-
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE']
|
|
62
|
+
TRUE_VALUES = [true, 1, '1', 'on', 'ON', 't', 'T', 'true', 'TRUE']
|
|
55
63
|
|
|
56
64
|
# Secret key used by the key generator
|
|
57
65
|
mattr_accessor :secret_key
|
|
@@ -63,7 +71,7 @@ module Devise
|
|
|
63
71
|
|
|
64
72
|
# The number of times to hash the password.
|
|
65
73
|
mattr_accessor :stretches
|
|
66
|
-
@@stretches =
|
|
74
|
+
@@stretches = 12
|
|
67
75
|
|
|
68
76
|
# The default key used when authenticating over http auth.
|
|
69
77
|
mattr_accessor :http_authentication_key
|
|
@@ -144,11 +152,15 @@ module Devise
|
|
|
144
152
|
mattr_accessor :timeout_in
|
|
145
153
|
@@timeout_in = 30.minutes
|
|
146
154
|
|
|
147
|
-
# Used to hash the password. Please generate one with
|
|
155
|
+
# Used to hash the password. Please generate one with rails secret.
|
|
148
156
|
mattr_accessor :pepper
|
|
149
157
|
@@pepper = nil
|
|
150
158
|
|
|
151
|
-
# Used to
|
|
159
|
+
# Used to send notification to the original user email when their email is changed.
|
|
160
|
+
mattr_accessor :send_email_changed_notification
|
|
161
|
+
@@send_email_changed_notification = false
|
|
162
|
+
|
|
163
|
+
# Used to enable sending notification to user when their password is changed.
|
|
152
164
|
mattr_accessor :send_password_change_notification
|
|
153
165
|
@@send_password_change_notification = false
|
|
154
166
|
|
|
@@ -205,7 +217,16 @@ module Devise
|
|
|
205
217
|
|
|
206
218
|
# Which formats should be treated as navigational.
|
|
207
219
|
mattr_accessor :navigational_formats
|
|
208
|
-
@@navigational_formats = ["*/*", :html]
|
|
220
|
+
@@navigational_formats = ["*/*", :html, :turbo_stream]
|
|
221
|
+
|
|
222
|
+
# The default responder used by Devise, used to customize status codes with:
|
|
223
|
+
#
|
|
224
|
+
# `config.responder.error_status`
|
|
225
|
+
# `config.responder.redirect_status`
|
|
226
|
+
#
|
|
227
|
+
# Can be replaced by a custom application responder.
|
|
228
|
+
mattr_accessor :responder
|
|
229
|
+
@@responder = Devise::Controllers::Responder
|
|
209
230
|
|
|
210
231
|
# When set to true, signing out a user signs out all other scopes.
|
|
211
232
|
mattr_accessor :sign_out_all_scopes
|
|
@@ -242,15 +263,28 @@ module Devise
|
|
|
242
263
|
mattr_accessor :clean_up_csrf_token_on_authentication
|
|
243
264
|
@@clean_up_csrf_token_on_authentication = true
|
|
244
265
|
|
|
266
|
+
# When false, Devise will not attempt to reload routes on eager load.
|
|
267
|
+
# This can reduce the time taken to boot the app but if your application
|
|
268
|
+
# requires the Devise mappings to be loaded during boot time the application
|
|
269
|
+
# won't boot properly.
|
|
270
|
+
mattr_accessor :reload_routes
|
|
271
|
+
@@reload_routes = true
|
|
272
|
+
|
|
245
273
|
# PRIVATE CONFIGURATION
|
|
246
274
|
|
|
247
275
|
# Store scopes mappings.
|
|
248
|
-
|
|
249
|
-
|
|
276
|
+
@@mappings = {}
|
|
277
|
+
def self.mappings
|
|
278
|
+
# Starting from Rails 8.0, routes are lazy-loaded by default in test and development environments.
|
|
279
|
+
# However, Devise's mappings are built during the routes loading phase.
|
|
280
|
+
# To ensure it works correctly, we need to load the routes first before accessing @@mappings.
|
|
281
|
+
Rails.application.try(:reload_routes_unless_loaded)
|
|
282
|
+
@@mappings
|
|
283
|
+
end
|
|
250
284
|
|
|
251
285
|
# OmniAuth configurations.
|
|
252
286
|
mattr_reader :omniauth_configs
|
|
253
|
-
@@omniauth_configs =
|
|
287
|
+
@@omniauth_configs = {}
|
|
254
288
|
|
|
255
289
|
# Define a set of modules that are called when a mapping is added.
|
|
256
290
|
mattr_reader :helpers
|
|
@@ -274,6 +308,10 @@ module Devise
|
|
|
274
308
|
mattr_accessor :token_generator
|
|
275
309
|
@@token_generator = nil
|
|
276
310
|
|
|
311
|
+
# When set to false, changing a password does not automatically sign in a user
|
|
312
|
+
mattr_accessor :sign_in_after_change_password
|
|
313
|
+
@@sign_in_after_change_password = true
|
|
314
|
+
|
|
277
315
|
# Default way to set up Devise. Run rails generate devise_install to create
|
|
278
316
|
# a fresh initializer with all configuration values.
|
|
279
317
|
def self.setup
|
|
@@ -281,22 +319,26 @@ module Devise
|
|
|
281
319
|
end
|
|
282
320
|
|
|
283
321
|
class Getter
|
|
284
|
-
def initialize
|
|
322
|
+
def initialize(name)
|
|
285
323
|
@name = name
|
|
286
324
|
end
|
|
287
325
|
|
|
288
326
|
def get
|
|
289
|
-
|
|
327
|
+
# TODO: Remove AS::Dependencies usage when dropping support to Rails < 7.
|
|
328
|
+
if ActiveSupport::Dependencies.respond_to?(:constantize)
|
|
329
|
+
ActiveSupport::Dependencies.constantize(@name)
|
|
330
|
+
else
|
|
331
|
+
@name.constantize
|
|
332
|
+
end
|
|
290
333
|
end
|
|
291
334
|
end
|
|
292
335
|
|
|
293
336
|
def self.ref(arg)
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
else
|
|
298
|
-
ActiveSupport::Dependencies.ref(arg)
|
|
337
|
+
# TODO: Remove AS::Dependencies usage when dropping support to Rails < 7.
|
|
338
|
+
if ActiveSupport::Dependencies.respond_to?(:reference)
|
|
339
|
+
ActiveSupport::Dependencies.reference(arg)
|
|
299
340
|
end
|
|
341
|
+
Getter.new(arg)
|
|
300
342
|
end
|
|
301
343
|
|
|
302
344
|
def self.available_router_name
|
|
@@ -403,9 +445,9 @@ module Devise
|
|
|
403
445
|
# Devise.setup do |config|
|
|
404
446
|
# config.allow_unconfirmed_access_for = 2.days
|
|
405
447
|
#
|
|
406
|
-
# config.warden do |
|
|
448
|
+
# config.warden do |warden_config|
|
|
407
449
|
# # Configure warden to use other strategies, like oauth.
|
|
408
|
-
#
|
|
450
|
+
# warden_config.oauth(:twitter)
|
|
409
451
|
# end
|
|
410
452
|
# end
|
|
411
453
|
def self.warden(&block)
|
|
@@ -417,7 +459,6 @@ module Devise
|
|
|
417
459
|
# config.omniauth :github, APP_ID, APP_SECRET
|
|
418
460
|
#
|
|
419
461
|
def self.omniauth(provider, *args)
|
|
420
|
-
@@helpers << Devise::OmniAuth::UrlHelpers
|
|
421
462
|
config = Devise::OmniAuth::Config.new(provider, args)
|
|
422
463
|
@@omniauth_configs[config.strategy_name.to_sym] = config
|
|
423
464
|
end
|
|
@@ -476,12 +517,12 @@ module Devise
|
|
|
476
517
|
|
|
477
518
|
# constant-time comparison algorithm to prevent timing attacks
|
|
478
519
|
def self.secure_compare(a, b)
|
|
479
|
-
return false if a.
|
|
480
|
-
|
|
520
|
+
return false if a.nil? || b.nil?
|
|
521
|
+
ActiveSupport::SecurityUtils.secure_compare(a, b)
|
|
522
|
+
end
|
|
481
523
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
res == 0
|
|
524
|
+
def self.deprecator
|
|
525
|
+
@deprecator ||= ActiveSupport::Deprecation.new("5.0", "Devise")
|
|
485
526
|
end
|
|
486
527
|
end
|
|
487
528
|
|