devise 3.5.1 → 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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +281 -1066
- data/MIT-LICENSE +2 -1
- data/README.md +292 -97
- data/app/controllers/devise/confirmations_controller.rb +3 -1
- data/app/controllers/devise/omniauth_callbacks_controller.rb +8 -6
- data/app/controllers/devise/passwords_controller.rb +10 -7
- data/app/controllers/devise/registrations_controller.rb +39 -18
- data/app/controllers/devise/sessions_controller.rb +9 -7
- data/app/controllers/devise/unlocks_controller.rb +4 -2
- data/app/controllers/devise_controller.rb +25 -12
- data/app/helpers/devise_helper.rb +23 -18
- data/app/mailers/devise/mailer.rb +13 -3
- data/app/views/devise/confirmations/new.html.erb +2 -2
- data/app/views/devise/mailer/email_changed.html.erb +7 -0
- data/app/views/devise/mailer/password_change.html.erb +3 -0
- data/app/views/devise/passwords/edit.html.erb +5 -5
- data/app/views/devise/passwords/new.html.erb +2 -2
- data/app/views/devise/registrations/edit.html.erb +9 -5
- data/app/views/devise/registrations/new.html.erb +4 -4
- data/app/views/devise/sessions/new.html.erb +4 -4
- data/app/views/devise/shared/_error_messages.html.erb +15 -0
- data/app/views/devise/shared/_links.html.erb +8 -8
- data/app/views/devise/unlocks/new.html.erb +2 -2
- data/config/locales/en.yml +7 -2
- data/lib/devise/controllers/helpers.rb +42 -33
- data/lib/devise/controllers/rememberable.rb +11 -2
- data/lib/devise/controllers/scoped_views.rb +2 -0
- data/lib/devise/controllers/sign_in_out.rb +40 -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 +6 -4
- data/lib/devise/failure_app.rb +84 -28
- data/lib/devise/hooks/activatable.rb +2 -0
- data/lib/devise/hooks/csrf_cleaner.rb +2 -0
- 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 +7 -7
- data/lib/devise/hooks/trackable.rb +2 -0
- data/lib/devise/mailers/helpers.rb +7 -4
- data/lib/devise/mapping.rb +3 -1
- data/lib/devise/models/authenticatable.rb +63 -33
- data/lib/devise/models/confirmable.rb +108 -35
- data/lib/devise/models/database_authenticatable.rb +102 -22
- data/lib/devise/models/lockable.rb +24 -6
- data/lib/devise/models/omniauthable.rb +2 -0
- data/lib/devise/models/recoverable.rb +34 -26
- data/lib/devise/models/registerable.rb +4 -0
- data/lib/devise/models/rememberable.rb +42 -26
- data/lib/devise/models/timeoutable.rb +2 -6
- data/lib/devise/models/trackable.rb +15 -1
- data/lib/devise/models/validatable.rb +10 -3
- data/lib/devise/models.rb +3 -1
- data/lib/devise/modules.rb +2 -0
- data/lib/devise/omniauth/config.rb +2 -0
- data/lib/devise/omniauth/url_helpers.rb +14 -5
- 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/parameter_filter.rb +4 -0
- data/lib/devise/parameter_sanitizer.rb +139 -65
- data/lib/devise/rails/deprecated_constant_accessor.rb +39 -0
- data/lib/devise/rails/routes.rb +71 -51
- data/lib/devise/rails/warden_compat.rb +3 -10
- data/lib/devise/rails.rb +7 -16
- data/lib/devise/secret_key_finder.rb +27 -0
- data/lib/devise/strategies/authenticatable.rb +5 -3
- data/lib/devise/strategies/base.rb +2 -0
- data/lib/devise/strategies/database_authenticatable.rb +11 -4
- data/lib/devise/strategies/rememberable.rb +5 -6
- data/lib/devise/test/controller_helpers.rb +167 -0
- data/lib/devise/test/integration_helpers.rb +63 -0
- data/lib/devise/test_helpers.rb +7 -124
- data/lib/devise/time_inflector.rb +2 -0
- data/lib/devise/token_generator.rb +3 -41
- data/lib/devise/version.rb +3 -1
- data/lib/devise.rb +69 -46
- data/lib/generators/active_record/devise_generator.rb +46 -12
- data/lib/generators/active_record/templates/migration.rb +4 -2
- data/lib/generators/active_record/templates/migration_existing.rb +4 -2
- data/lib/generators/devise/controllers_generator.rb +3 -1
- data/lib/generators/devise/devise_generator.rb +5 -3
- data/lib/generators/devise/install_generator.rb +18 -5
- data/lib/generators/devise/orm_helpers.rb +10 -21
- data/lib/generators/devise/views_generator.rb +21 -11
- data/lib/generators/mongoid/devise_generator.rb +7 -5
- data/lib/generators/templates/README +9 -8
- data/lib/generators/templates/controllers/README +1 -1
- 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 +6 -4
- data/lib/generators/templates/controllers/sessions_controller.rb +4 -2
- data/lib/generators/templates/controllers/unlocks_controller.rb +2 -0
- data/lib/generators/templates/devise.rb +65 -23
- data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
- data/lib/generators/templates/markerb/email_changed.markerb +7 -0
- data/lib/generators/templates/markerb/password_change.markerb +3 -0
- data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
- data/lib/generators/templates/markerb/unlock_instructions.markerb +1 -1
- 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 +4 -1
- data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +11 -3
- 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 +21 -306
- data/.gitignore +0 -10
- data/.travis.yml +0 -45
- data/.yardopts +0 -9
- data/CONTRIBUTING.md +0 -14
- data/Gemfile +0 -29
- data/Gemfile.lock +0 -191
- data/Rakefile +0 -36
- data/devise.gemspec +0 -29
- data/devise.png +0 -0
- data/gemfiles/Gemfile.rails-3.2-stable +0 -29
- data/gemfiles/Gemfile.rails-3.2-stable.lock +0 -169
- data/gemfiles/Gemfile.rails-4.0-stable +0 -29
- data/gemfiles/Gemfile.rails-4.0-stable.lock +0 -163
- data/gemfiles/Gemfile.rails-4.1-stable +0 -29
- data/gemfiles/Gemfile.rails-4.1-stable.lock +0 -169
- data/gemfiles/Gemfile.rails-4.2-stable +0 -29
- data/gemfiles/Gemfile.rails-4.2-stable.lock +0 -191
- data/script/cached-bundle +0 -49
- data/script/s3-put +0 -71
- data/test/controllers/custom_registrations_controller_test.rb +0 -40
- data/test/controllers/custom_strategy_test.rb +0 -62
- 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 -129
- data/test/controllers/load_hooks_controller_test.rb +0 -19
- data/test/controllers/passwords_controller_test.rb +0 -31
- data/test/controllers/sessions_controller_test.rb +0 -103
- 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 -298
- data/test/generators/active_record_generator_test.rb +0 -109
- 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 -13
- data/test/generators/mongoid_generator_test.rb +0 -23
- data/test/generators/views_generator_test.rb +0 -96
- data/test/helpers/devise_helper_test.rb +0 -49
- data/test/integration/authenticatable_test.rb +0 -729
- 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 -105
- data/test/integration/lockable_test.rb +0 -239
- data/test/integration/omniauthable_test.rb +0 -133
- data/test/integration/recoverable_test.rb +0 -347
- data/test/integration/registerable_test.rb +0 -359
- data/test/integration/rememberable_test.rb +0 -176
- data/test/integration/timeoutable_test.rb +0 -189
- 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 -468
- data/test/models/database_authenticatable_test.rb +0 -249
- data/test/models/lockable_test.rb +0 -328
- data/test/models/omniauthable_test.rb +0 -7
- data/test/models/recoverable_test.rb +0 -228
- data/test/models/registerable_test.rb +0 -7
- data/test/models/rememberable_test.rb +0 -204
- 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 -127
- data/test/models_test.rb +0 -144
- data/test/omniauth/config_test.rb +0 -57
- data/test/omniauth/url_helpers_test.rb +0 -54
- data/test/orm/active_record.rb +0 -10
- data/test/orm/mongoid.rb +0 -13
- data/test/parameter_sanitizer_test.rb +0 -81
- 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 -6
- 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/controllers/admins/sessions_controller.rb +0 -6
- data/test/rails_app/app/controllers/admins_controller.rb +0 -11
- data/test/rails_app/app/controllers/application_controller.rb +0 -12
- 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 -25
- 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/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 -40
- 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 -41
- 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 -8
- data/test/rails_app/config/initializers/session_store.rb +0 -1
- data/test/rails_app/config/routes.rb +0 -122
- 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 -29
- 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 -264
- data/test/support/action_controller/record_identifier.rb +0 -10
- data/test/support/assertions.rb +0 -39
- data/test/support/helpers.rb +0 -73
- 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 -24
- 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,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
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
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,20 +89,34 @@ module ActionDispatch::Routing
|
|
84
89
|
#
|
85
90
|
# You can configure your routes with some options:
|
86
91
|
#
|
87
|
-
# * class_name:
|
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
|
93
|
-
# The following route configuration would
|
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:
|
98
|
-
#
|
102
|
+
# * singular: set up the singular name for the given resource. This is used as the helper methods
|
103
|
+
# names in controller ("authenticate_#{singular}!", "#{singular}_signed_in?", "current_#{singular}"
|
104
|
+
# and "#{singular}_session"), as the scope name in routes and as the scope given to warden.
|
99
105
|
#
|
100
|
-
# devise_for :
|
106
|
+
# devise_for :admins, singular: :manager
|
107
|
+
#
|
108
|
+
# devise_scope :manager do
|
109
|
+
# ...
|
110
|
+
# end
|
111
|
+
#
|
112
|
+
# class ManagerController < ApplicationController
|
113
|
+
# before_action authenticate_manager!
|
114
|
+
#
|
115
|
+
# def show
|
116
|
+
# @manager = current_manager
|
117
|
+
# ...
|
118
|
+
# end
|
119
|
+
# end
|
101
120
|
#
|
102
121
|
# * path_names: configure different path names to overwrite defaults :sign_in, :sign_out, :sign_up,
|
103
122
|
# :password, :confirmation, :unlock.
|
@@ -116,10 +135,10 @@ module ActionDispatch::Routing
|
|
116
135
|
# * failure_app: a rack app which is invoked whenever there is a failure. Strings representing a given
|
117
136
|
# are also allowed as parameter.
|
118
137
|
#
|
119
|
-
# * 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),
|
120
139
|
# if you wish to restrict this to accept only :post or :delete requests you should do:
|
121
140
|
#
|
122
|
-
# devise_for :users, sign_out_via: [:
|
141
|
+
# devise_for :users, sign_out_via: [:get, :post]
|
123
142
|
#
|
124
143
|
# You need to make sure that your sign_out controls trigger a request with a matching HTTP method.
|
125
144
|
#
|
@@ -268,7 +287,7 @@ module ActionDispatch::Routing
|
|
268
287
|
# root to: "admin/dashboard#show", as: :user_root
|
269
288
|
# end
|
270
289
|
#
|
271
|
-
def authenticate(scope=nil, block=nil)
|
290
|
+
def authenticate(scope = nil, block = nil)
|
272
291
|
constraints_for(:authenticate!, scope, block) do
|
273
292
|
yield
|
274
293
|
end
|
@@ -292,7 +311,7 @@ module ActionDispatch::Routing
|
|
292
311
|
#
|
293
312
|
# root to: 'landing#show'
|
294
313
|
#
|
295
|
-
def authenticated(scope=nil, block=nil)
|
314
|
+
def authenticated(scope = nil, block = nil)
|
296
315
|
constraints_for(:authenticate?, scope, block) do
|
297
316
|
yield
|
298
317
|
end
|
@@ -309,7 +328,7 @@ module ActionDispatch::Routing
|
|
309
328
|
#
|
310
329
|
# root to: 'dashboard#show'
|
311
330
|
#
|
312
|
-
def unauthenticated(scope=nil)
|
331
|
+
def unauthenticated(scope = nil)
|
313
332
|
constraint = lambda do |request|
|
314
333
|
not request.env["warden"].authenticate? scope: scope
|
315
334
|
end
|
@@ -321,7 +340,7 @@ module ActionDispatch::Routing
|
|
321
340
|
|
322
341
|
# Sets the devise scope to be used in the controller. If you have custom routes,
|
323
342
|
# you are required to call this method (also aliased as :as) in order to specify
|
324
|
-
# to which controller it is
|
343
|
+
# to which controller it is targeted.
|
325
344
|
#
|
326
345
|
# as :user do
|
327
346
|
# get "sign_in", to: "devise/sessions#new"
|
@@ -404,42 +423,39 @@ module ActionDispatch::Routing
|
|
404
423
|
raise <<-ERROR
|
405
424
|
Devise does not support scoping OmniAuth callbacks under a dynamic segment
|
406
425
|
and you have set #{mapping.fullpath.inspect}. You can work around by passing
|
407
|
-
`skip: :omniauth_callbacks`
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
match "/users/auth/:action/callback",
|
416
|
-
constraints: { action: /google|facebook/ },
|
417
|
-
to: "devise/omniauth_callbacks#:action",
|
418
|
-
as: :omniauth_callback,
|
419
|
-
via: [:get, :post]
|
426
|
+
`skip: :omniauth_callbacks` to the `devise_for` call and extract omniauth
|
427
|
+
options to another `devise_for` call outside the scope. Here is an example:
|
428
|
+
|
429
|
+
devise_for :users, only: :omniauth_callbacks, controllers: {omniauth_callbacks: 'users/omniauth_callbacks'}
|
430
|
+
|
431
|
+
scope '/(:locale)', locale: /ru|en/ do
|
432
|
+
devise_for :users, skip: :omniauth_callbacks
|
433
|
+
end
|
420
434
|
ERROR
|
421
435
|
end
|
422
|
-
|
423
|
-
|
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
|
424
442
|
path_prefix = Devise.omniauth_path_prefix || "/#{mapping.fullpath}/auth".squeeze("/")
|
425
443
|
|
426
444
|
set_omniauth_path_prefix!(path_prefix)
|
427
445
|
|
428
|
-
|
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]
|
429
451
|
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
match "#{path_prefix}/:action/callback",
|
437
|
-
constraints: { action: providers },
|
438
|
-
to: "#{controllers[:omniauth_callbacks]}#:action",
|
439
|
-
as: :omniauth_callback,
|
440
|
-
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
|
441
457
|
ensure
|
442
|
-
@scope
|
458
|
+
@scope = current_scope
|
443
459
|
end
|
444
460
|
|
445
461
|
def with_devise_exclusive_scope(new_path, new_as, options) #:nodoc:
|
@@ -448,13 +464,17 @@ ERROR
|
|
448
464
|
exclusive = { as: new_as, path: new_path, module: nil }
|
449
465
|
exclusive.merge!(options.slice(:constraints, :defaults, :options))
|
450
466
|
|
451
|
-
|
467
|
+
if @scope.respond_to? :new
|
468
|
+
@scope = @scope.new exclusive
|
469
|
+
else
|
470
|
+
exclusive.each_pair { |key, value| @scope[key] = value }
|
471
|
+
end
|
452
472
|
yield
|
453
473
|
ensure
|
454
474
|
@scope = current_scope
|
455
475
|
end
|
456
476
|
|
457
|
-
def constraints_for(method_to_apply, scope=nil, block=nil)
|
477
|
+
def constraints_for(method_to_apply, scope = nil, block = nil)
|
458
478
|
constraint = lambda do |request|
|
459
479
|
request.env['warden'].send(method_to_apply, scope: scope) &&
|
460
480
|
(block.nil? || block.call(request.env["warden"].user(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
|
-
|
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
|
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
|
-
|
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
|
-
|
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,8 +28,8 @@ module Devise
|
|
26
28
|
private
|
27
29
|
|
28
30
|
# Receives a resource and check if it is valid by calling valid_for_authentication?
|
29
|
-
#
|
30
|
-
# given as parameter. Check Devise::Models::
|
31
|
+
# A block that will be triggered while validating can be optionally
|
32
|
+
# given as parameter. Check Devise::Models::Authenticatable.valid_for_authentication?
|
31
33
|
# for more information.
|
32
34
|
#
|
33
35
|
# In case the resource can't be validated, it will fail with the given
|
@@ -118,7 +120,7 @@ module Devise
|
|
118
120
|
|
119
121
|
# Helper to decode credentials from HTTP.
|
120
122
|
def decode_credentials
|
121
|
-
return [] unless request.authorization && request.authorization =~ /^Basic (.*)/
|
123
|
+
return [] unless request.authorization && request.authorization =~ /^Basic (.*)/mi
|
122
124
|
Base64.decode64($1).split(/:/, 2)
|
123
125
|
end
|
124
126
|
|
@@ -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
|
-
|
11
|
+
hashed = false
|
10
12
|
|
11
|
-
if validate(resource){
|
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
|
-
|
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.
|
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
|
47
|
-
|
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,167 @@
|
|
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, deprecated = nil, scope: nil)
|
68
|
+
if deprecated.present?
|
69
|
+
scope = resource
|
70
|
+
resource = deprecated
|
71
|
+
|
72
|
+
ActiveSupport::Deprecation.warn <<-DEPRECATION.strip_heredoc
|
73
|
+
[Devise] sign_in(:#{scope}, resource) on controller tests is deprecated and will be removed from Devise.
|
74
|
+
Please use sign_in(resource, scope: :#{scope}) instead.
|
75
|
+
DEPRECATION
|
76
|
+
end
|
77
|
+
|
78
|
+
scope ||= Devise::Mapping.find_scope!(resource)
|
79
|
+
|
80
|
+
warden.instance_variable_get(:@users).delete(scope)
|
81
|
+
warden.session_serializer.store(resource, scope)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Sign out a given resource or scope by calling logout on Warden.
|
85
|
+
# This method bypass any warden logout callback.
|
86
|
+
#
|
87
|
+
# Examples:
|
88
|
+
#
|
89
|
+
# sign_out :user # sign_out(scope)
|
90
|
+
# sign_out @user # sign_out(resource)
|
91
|
+
#
|
92
|
+
def sign_out(resource_or_scope)
|
93
|
+
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
94
|
+
@controller.instance_variable_set(:"@current_#{scope}", nil)
|
95
|
+
user = warden.instance_variable_get(:@users).delete(scope)
|
96
|
+
warden.session_serializer.delete(scope, user)
|
97
|
+
end
|
98
|
+
|
99
|
+
protected
|
100
|
+
|
101
|
+
# Catch warden continuations and handle like the middleware would.
|
102
|
+
# Returns nil when interrupted, otherwise the normal result of the block.
|
103
|
+
def _catch_warden(&block)
|
104
|
+
result = catch(:warden, &block)
|
105
|
+
|
106
|
+
env = @controller.request.env
|
107
|
+
|
108
|
+
result ||= {}
|
109
|
+
|
110
|
+
# Set the response. In production, the rack result is returned
|
111
|
+
# from Warden::Manager#call, which the following is modelled on.
|
112
|
+
case result
|
113
|
+
when Array
|
114
|
+
if result.first == 401 && intercept_401?(env) # does this happen during testing?
|
115
|
+
_process_unauthenticated(env)
|
116
|
+
else
|
117
|
+
result
|
118
|
+
end
|
119
|
+
when Hash
|
120
|
+
_process_unauthenticated(env, result)
|
121
|
+
else
|
122
|
+
result
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def _process_unauthenticated(env, options = {})
|
127
|
+
options[:action] ||= :unauthenticated
|
128
|
+
proxy = request.env['warden']
|
129
|
+
result = options[:result] || proxy.result
|
130
|
+
|
131
|
+
ret = case result
|
132
|
+
when :redirect
|
133
|
+
body = proxy.message || "You are being redirected to #{proxy.headers['Location']}"
|
134
|
+
[proxy.status, proxy.headers, [body]]
|
135
|
+
when :custom
|
136
|
+
proxy.custom_response
|
137
|
+
else
|
138
|
+
request.env["PATH_INFO"] = "/#{options[:action]}"
|
139
|
+
request.env["warden.options"] = options
|
140
|
+
Warden::Manager._run_callbacks(:before_failure, env, options)
|
141
|
+
|
142
|
+
status, headers, response = Devise.warden_config[:failure_app].call(env).to_a
|
143
|
+
@controller.response.headers.merge!(headers)
|
144
|
+
@controller.response.content_type = headers["Content-Type"] unless Rails::VERSION::MAJOR >= 5
|
145
|
+
@controller.status = status
|
146
|
+
@controller.response_body = response.body
|
147
|
+
nil # causes process return @response
|
148
|
+
end
|
149
|
+
|
150
|
+
# ensure that the controller response is set up. In production, this is
|
151
|
+
# not necessary since warden returns the results to rack. However, at
|
152
|
+
# testing time, we want the response to be available to the testing
|
153
|
+
# framework to verify what would be returned to rack.
|
154
|
+
if ret.is_a?(Array)
|
155
|
+
status, headers, body = *ret
|
156
|
+
# ensure the controller response is set to our response.
|
157
|
+
@controller.response ||= @response
|
158
|
+
@response.status = status
|
159
|
+
@response.headers.merge!(headers)
|
160
|
+
@response.body = body
|
161
|
+
end
|
162
|
+
|
163
|
+
ret
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
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
|