devise 3.5.10 → 4.7.3
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 +265 -1129
- data/MIT-LICENSE +2 -1
- data/README.md +291 -96
- 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 +7 -4
- 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 +10 -4
- 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/passwords/edit.html.erb +3 -3
- 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 +7 -7
- data/app/views/devise/unlocks/new.html.erb +2 -2
- data/config/locales/en.yml +5 -2
- data/lib/devise/controllers/helpers.rb +30 -27
- data/lib/devise/controllers/rememberable.rb +3 -1
- data/lib/devise/controllers/scoped_views.rb +2 -0
- data/lib/devise/controllers/sign_in_out.rb +37 -14
- 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 +75 -38
- 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 +6 -1
- data/lib/devise/hooks/proxy.rb +3 -1
- data/lib/devise/hooks/rememberable.rb +2 -0
- data/lib/devise/hooks/timeoutable.rb +4 -2
- 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 +57 -31
- data/lib/devise/models/confirmable.rb +90 -29
- data/lib/devise/models/database_authenticatable.rb +93 -22
- data/lib/devise/models/lockable.rb +11 -5
- data/lib/devise/models/omniauthable.rb +2 -0
- data/lib/devise/models/recoverable.rb +33 -21
- data/lib/devise/models/registerable.rb +4 -0
- data/lib/devise/models/rememberable.rb +6 -11
- data/lib/devise/models/timeoutable.rb +2 -0
- 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 +2 -0
- 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/routes.rb +48 -37
- 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 +3 -1
- data/lib/devise/strategies/base.rb +2 -0
- data/lib/devise/strategies/database_authenticatable.rb +11 -4
- data/lib/devise/strategies/rememberable.rb +2 -0
- 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 +57 -40
- data/lib/generators/active_record/devise_generator.rb +29 -10
- 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 +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 +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 +63 -21
- 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 +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 +15 -314
- 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 -187
- data/Rakefile +0 -36
- data/devise.gemspec +0 -27
- data/devise.png +0 -0
- data/gemfiles/Gemfile.rails-3.2-stable +0 -29
- data/gemfiles/Gemfile.rails-3.2-stable.lock +0 -172
- data/gemfiles/Gemfile.rails-4.0-stable +0 -30
- data/gemfiles/Gemfile.rails-4.0-stable.lock +0 -166
- data/gemfiles/Gemfile.rails-4.1-stable +0 -30
- data/gemfiles/Gemfile.rails-4.1-stable.lock +0 -171
- data/gemfiles/Gemfile.rails-4.2-stable +0 -30
- data/gemfiles/Gemfile.rails-4.2-stable.lock +0 -193
- 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/helper_methods_test.rb +0 -21
- 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 -315
- 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 -103
- 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 -135
- data/test/integration/recoverable_test.rb +0 -347
- data/test/integration/registerable_test.rb +0 -359
- data/test/integration/rememberable_test.rb +0 -214
- 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 -127
- data/test/models_test.rb +0 -153
- 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/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 -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/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 -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 -125
- 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_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 -264
- 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/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/test/time_helpers.rb +0 -137
data/config/locales/en.yml
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Additional translations at https://github.com/
|
1
|
+
# Additional translations at https://github.com/heartcombo/devise/wiki/I18n
|
2
2
|
|
3
3
|
en:
|
4
4
|
devise:
|
@@ -23,6 +23,8 @@ en:
|
|
23
23
|
subject: "Reset password instructions"
|
24
24
|
unlock_instructions:
|
25
25
|
subject: "Unlock instructions"
|
26
|
+
email_changed:
|
27
|
+
subject: "Email Changed"
|
26
28
|
password_change:
|
27
29
|
subject: "Password Changed"
|
28
30
|
omniauth_callbacks:
|
@@ -40,8 +42,9 @@ en:
|
|
40
42
|
signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated."
|
41
43
|
signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked."
|
42
44
|
signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
|
43
|
-
update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the
|
45
|
+
update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirmation link to confirm your new email address."
|
44
46
|
updated: "Your account has been updated successfully."
|
47
|
+
updated_but_not_signed_in: "Your account has been updated successfully, but since your password was changed, you need to sign in again"
|
45
48
|
sessions:
|
46
49
|
signed_in: "Signed in successfully."
|
47
50
|
signed_out: "Signed out successfully."
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Devise
|
2
4
|
module Controllers
|
3
5
|
# Those helpers are convenience methods added to ApplicationController.
|
@@ -30,18 +32,18 @@ module Devise
|
|
30
32
|
# current_bloggers # Currently signed in user and admin
|
31
33
|
#
|
32
34
|
# Use:
|
33
|
-
#
|
34
|
-
#
|
35
|
+
# before_action :authenticate_blogger! # Redirects unless either a user or an admin are authenticated
|
36
|
+
# before_action ->{ authenticate_blogger! :admin } # Redirects to the admin login page
|
35
37
|
# current_blogger :user # Preferably returns a User if one is signed in
|
36
38
|
#
|
37
|
-
def devise_group(group_name, opts={})
|
39
|
+
def devise_group(group_name, opts = {})
|
38
40
|
mappings = "[#{ opts[:contains].map { |m| ":#{m}" }.join(',') }]"
|
39
41
|
|
40
42
|
class_eval <<-METHODS, __FILE__, __LINE__ + 1
|
41
|
-
def authenticate_#{group_name}!(
|
43
|
+
def authenticate_#{group_name}!(favorite = nil, opts = {})
|
42
44
|
unless #{group_name}_signed_in?
|
43
45
|
mappings = #{mappings}
|
44
|
-
mappings.unshift mappings.delete(
|
46
|
+
mappings.unshift mappings.delete(favorite.to_sym) if favorite
|
45
47
|
mappings.each do |mapping|
|
46
48
|
opts[:scope] = mapping
|
47
49
|
warden.authenticate!(opts) if !devise_controller? || opts.delete(:force)
|
@@ -55,9 +57,9 @@ module Devise
|
|
55
57
|
end
|
56
58
|
end
|
57
59
|
|
58
|
-
def current_#{group_name}(
|
60
|
+
def current_#{group_name}(favorite = nil)
|
59
61
|
mappings = #{mappings}
|
60
|
-
mappings.unshift mappings.delete(
|
62
|
+
mappings.unshift mappings.delete(favorite.to_sym) if favorite
|
61
63
|
mappings.each do |mapping|
|
62
64
|
current = warden.authenticate(scope: mapping)
|
63
65
|
return current if current
|
@@ -84,7 +86,7 @@ module Devise
|
|
84
86
|
end
|
85
87
|
|
86
88
|
# Define authentication filters and accessor helpers based on mappings.
|
87
|
-
# These filters should be used inside the controllers as
|
89
|
+
# These filters should be used inside the controllers as before_actions,
|
88
90
|
# so you can control the scope of the user who should be signed in to
|
89
91
|
# access that specific controller/action.
|
90
92
|
# Example:
|
@@ -104,14 +106,14 @@ module Devise
|
|
104
106
|
# admin_session # Session data available only to the admin scope
|
105
107
|
#
|
106
108
|
# Use:
|
107
|
-
#
|
108
|
-
#
|
109
|
+
# before_action :authenticate_user! # Tell devise to use :user map
|
110
|
+
# before_action :authenticate_admin! # Tell devise to use :admin map
|
109
111
|
#
|
110
112
|
def self.define_helpers(mapping) #:nodoc:
|
111
113
|
mapping = mapping.name
|
112
114
|
|
113
115
|
class_eval <<-METHODS, __FILE__, __LINE__ + 1
|
114
|
-
def authenticate_#{mapping}!(opts={})
|
116
|
+
def authenticate_#{mapping}!(opts = {})
|
115
117
|
opts[:scope] = :#{mapping}
|
116
118
|
warden.authenticate!(opts) if !devise_controller? || opts.delete(:force)
|
117
119
|
end
|
@@ -138,27 +140,23 @@ module Devise
|
|
138
140
|
|
139
141
|
# The main accessor for the warden proxy instance
|
140
142
|
def warden
|
141
|
-
request.env['warden']
|
143
|
+
request.env['warden'] or raise MissingWarden
|
142
144
|
end
|
143
145
|
|
144
146
|
# Return true if it's a devise_controller. false to all controllers unless
|
145
147
|
# the controllers defined inside devise. Useful if you want to apply a before
|
146
148
|
# filter to all controllers, except the ones in devise:
|
147
149
|
#
|
148
|
-
#
|
150
|
+
# before_action :my_filter, unless: :devise_controller?
|
149
151
|
def devise_controller?
|
150
152
|
is_a?(::DeviseController)
|
151
153
|
end
|
152
154
|
|
153
|
-
#
|
155
|
+
# Set up a param sanitizer to filter parameters using strong_parameters. See
|
154
156
|
# lib/devise/parameter_sanitizer.rb for more info. Override this
|
155
157
|
# method in your application controller to use your own parameter sanitizer.
|
156
158
|
def devise_parameter_sanitizer
|
157
|
-
@devise_parameter_sanitizer ||=
|
158
|
-
Devise::ParameterSanitizer.new(resource_class, resource_name, params)
|
159
|
-
else
|
160
|
-
Devise::BaseSanitizer.new(resource_class, resource_name, params)
|
161
|
-
end
|
159
|
+
@devise_parameter_sanitizer ||= Devise::ParameterSanitizer.new(resource_class, resource_name, params)
|
162
160
|
end
|
163
161
|
|
164
162
|
# Tell warden that params authentication is allowed for that specific page.
|
@@ -254,7 +252,7 @@ module Devise
|
|
254
252
|
# Overwrite Rails' handle unverified request to sign out all scopes,
|
255
253
|
# clear run strategies and remove cached variables.
|
256
254
|
def handle_unverified_request
|
257
|
-
super # call the default
|
255
|
+
super # call the default behavior which resets/nullifies/raises
|
258
256
|
request.env["devise.skip_storage"] = true
|
259
257
|
sign_out_all_scopes(false)
|
260
258
|
end
|
@@ -270,21 +268,26 @@ module Devise
|
|
270
268
|
# Check if flash messages should be emitted. Default is to do it on
|
271
269
|
# navigational formats
|
272
270
|
def is_flashing_format?
|
273
|
-
is_navigational_format?
|
271
|
+
request.respond_to?(:flash) && is_navigational_format?
|
274
272
|
end
|
275
273
|
|
276
274
|
private
|
277
275
|
|
278
|
-
def expire_session_data_after_sign_in!
|
279
|
-
ActiveSupport::Deprecation.warn "expire_session_data_after_sign_in! is deprecated " \
|
280
|
-
"in favor of expire_data_after_sign_in!"
|
281
|
-
expire_data_after_sign_in!
|
282
|
-
end
|
283
|
-
|
284
276
|
def expire_data_after_sign_out!
|
285
277
|
Devise.mappings.each { |_,m| instance_variable_set("@current_#{m.name}", nil) }
|
286
278
|
super
|
287
279
|
end
|
288
280
|
end
|
289
281
|
end
|
282
|
+
|
283
|
+
class MissingWarden < StandardError
|
284
|
+
def initialize
|
285
|
+
super "Devise could not find the `Warden::Proxy` instance on your request environment.\n" + \
|
286
|
+
"Make sure that your application is loading Devise and Warden as expected and that " + \
|
287
|
+
"the `Warden::Manager` middleware is present in your middleware stack.\n" + \
|
288
|
+
"If you are seeing this on one of your tests, ensure that your tests are either " + \
|
289
|
+
"executing the Rails middleware stack or that your tests are using the `Devise::Test::ControllerHelpers` " + \
|
290
|
+
"module to inject the `request.env['warden']` object for you."
|
291
|
+
end
|
292
|
+
end
|
290
293
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Devise
|
2
4
|
module Controllers
|
3
5
|
# A module that may be optionally included in a controller in order
|
@@ -18,7 +20,7 @@ module Devise
|
|
18
20
|
|
19
21
|
# Remembers the given resource by setting up a cookie
|
20
22
|
def remember_me(resource)
|
21
|
-
return if env["devise.skip_storage"]
|
23
|
+
return if request.env["devise.skip_storage"]
|
22
24
|
scope = Devise::Mapping.find_scope!(resource)
|
23
25
|
resource.remember_me!
|
24
26
|
cookies.signed[remember_key(resource, scope)] = remember_cookie_values(resource)
|
@@ -1,31 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Devise
|
2
4
|
module Controllers
|
3
5
|
# Provide sign in and sign out functionality.
|
4
6
|
# Included by default in all controllers.
|
5
7
|
module SignInOut
|
6
8
|
# Return true if the given scope is signed in session. If no scope given, return
|
7
|
-
# true if any scope is signed in.
|
8
|
-
|
9
|
+
# true if any scope is signed in. This will run authentication hooks, which may
|
10
|
+
# cause exceptions to be thrown from this method; if you simply want to check
|
11
|
+
# if a scope has already previously been authenticated without running
|
12
|
+
# authentication hooks, you can directly call `warden.authenticated?(scope: scope)`
|
13
|
+
def signed_in?(scope = nil)
|
9
14
|
[scope || Devise.mappings.keys].flatten.any? do |_scope|
|
10
15
|
warden.authenticate?(scope: _scope)
|
11
16
|
end
|
12
17
|
end
|
13
18
|
|
14
19
|
# Sign in a user that already was authenticated. This helper is useful for logging
|
15
|
-
# users in after sign up.
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
# signed in, but we want to refresh the credentials in session.
|
20
|
+
# users in after sign up. All options given to sign_in is passed forward
|
21
|
+
# to the set_user method in warden.
|
22
|
+
# If you are using a custom warden strategy and the timeoutable module, you have to
|
23
|
+
# set `env["devise.skip_timeout"] = true` in the request to use this method, like we do
|
24
|
+
# in the sessions controller: https://github.com/heartcombo/devise/blob/master/app/controllers/devise/sessions_controller.rb#L7
|
21
25
|
#
|
22
26
|
# Examples:
|
23
27
|
#
|
24
28
|
# sign_in :user, @user # sign_in(scope, resource)
|
25
29
|
# sign_in @user # sign_in(resource)
|
26
|
-
# sign_in @user, event: :authentication
|
27
|
-
# sign_in @user, store: false
|
28
|
-
# sign_in @user, bypass: true # sign_in(resource, options)
|
30
|
+
# sign_in @user, event: :authentication # sign_in(resource, options)
|
31
|
+
# sign_in @user, store: false # sign_in(resource, options)
|
29
32
|
#
|
30
33
|
def sign_in(resource_or_scope, *args)
|
31
34
|
options = args.extract_options!
|
@@ -35,6 +38,13 @@ module Devise
|
|
35
38
|
expire_data_after_sign_in!
|
36
39
|
|
37
40
|
if options[:bypass]
|
41
|
+
ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc, caller)
|
42
|
+
[Devise] bypass option is deprecated and it will be removed in future version of Devise.
|
43
|
+
Please use bypass_sign_in method instead.
|
44
|
+
Example:
|
45
|
+
|
46
|
+
bypass_sign_in(user)
|
47
|
+
DEPRECATION
|
38
48
|
warden.session_serializer.store(resource, scope)
|
39
49
|
elsif warden.user(scope) == resource && !options.delete(:force)
|
40
50
|
# Do nothing. User already signed in and we are not forcing it.
|
@@ -44,6 +54,20 @@ module Devise
|
|
44
54
|
end
|
45
55
|
end
|
46
56
|
|
57
|
+
# Sign in a user bypassing the warden callbacks and stores the user
|
58
|
+
# straight in session. This option is useful in cases the user is already
|
59
|
+
# signed in, but we want to refresh the credentials in session.
|
60
|
+
#
|
61
|
+
# Examples:
|
62
|
+
#
|
63
|
+
# bypass_sign_in @user, scope: :user
|
64
|
+
# bypass_sign_in @user
|
65
|
+
def bypass_sign_in(resource, scope: nil)
|
66
|
+
scope ||= Devise::Mapping.find_scope!(resource)
|
67
|
+
expire_data_after_sign_in!
|
68
|
+
warden.session_serializer.store(resource, scope)
|
69
|
+
end
|
70
|
+
|
47
71
|
# Sign out a given user or scope. This helper is useful for signing out a user
|
48
72
|
# after deleting accounts. Returns true if there was a logout and false if there
|
49
73
|
# is no user logged in on the referred scope
|
@@ -53,12 +77,11 @@ module Devise
|
|
53
77
|
# sign_out :user # sign_out(scope)
|
54
78
|
# sign_out @user # sign_out(resource)
|
55
79
|
#
|
56
|
-
def sign_out(resource_or_scope=nil)
|
80
|
+
def sign_out(resource_or_scope = nil)
|
57
81
|
return sign_out_all_scopes unless resource_or_scope
|
58
82
|
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
59
83
|
user = warden.user(scope: scope, run_callbacks: false) # If there is no user
|
60
84
|
|
61
|
-
warden.raw_session.inspect # Without this inspect here. The session does not clear.
|
62
85
|
warden.logout(scope)
|
63
86
|
warden.clear_strategies_cache!(scope: scope)
|
64
87
|
instance_variable_set(:"@current_#{scope}", nil)
|
@@ -69,7 +92,7 @@ module Devise
|
|
69
92
|
# Sign out all active users or scopes. This helper is useful for signing out all roles
|
70
93
|
# in one click. This signs out ALL scopes in warden. Returns true if there was at least one logout
|
71
94
|
# and false if there was no user logged in on all scopes.
|
72
|
-
def sign_out_all_scopes(lock=true)
|
95
|
+
def sign_out_all_scopes(lock = true)
|
73
96
|
users = Devise.mappings.keys.map { |s| warden.user(scope: s, run_callbacks: false) }
|
74
97
|
|
75
98
|
warden.logout
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "uri"
|
2
4
|
|
3
5
|
module Devise
|
@@ -29,16 +31,13 @@ module Devise
|
|
29
31
|
# Example:
|
30
32
|
#
|
31
33
|
# store_location_for(:user, dashboard_path)
|
32
|
-
# redirect_to
|
34
|
+
# redirect_to user_facebook_omniauth_authorize_path
|
33
35
|
#
|
34
36
|
def store_location_for(resource_or_scope, location)
|
35
37
|
session_key = stored_location_key_for(resource_or_scope)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
path = [path, uri.fragment].compact.join('#')
|
40
|
-
session[session_key] = path
|
41
|
-
end
|
38
|
+
|
39
|
+
path = extract_path_from_location(location)
|
40
|
+
session[session_key] = path if path
|
42
41
|
end
|
43
42
|
|
44
43
|
private
|
@@ -53,6 +52,25 @@ module Devise
|
|
53
52
|
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
54
53
|
"#{scope}_return_to"
|
55
54
|
end
|
55
|
+
|
56
|
+
def extract_path_from_location(location)
|
57
|
+
uri = parse_uri(location)
|
58
|
+
|
59
|
+
if uri
|
60
|
+
path = remove_domain_from_uri(uri)
|
61
|
+
path = add_fragment_back_to_path(uri, path)
|
62
|
+
|
63
|
+
path
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def remove_domain_from_uri(uri)
|
68
|
+
[uri.path.sub(/\A\/+/, '/'), uri.query].compact.join('?')
|
69
|
+
end
|
70
|
+
|
71
|
+
def add_fragment_back_to_path(uri, path)
|
72
|
+
[path, uri.fragment].compact.join('#')
|
73
|
+
end
|
56
74
|
end
|
57
75
|
end
|
58
76
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Devise
|
2
4
|
module Controllers
|
3
5
|
# Create url helpers to be used with resource/scope configuration. Acts as
|
@@ -32,7 +34,7 @@ module Devise
|
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
35
|
-
def self.generate_helpers!(routes=nil)
|
37
|
+
def self.generate_helpers!(routes = nil)
|
36
38
|
routes ||= begin
|
37
39
|
mappings = Devise.mappings.values.map(&:used_helpers).flatten.uniq
|
38
40
|
Devise::URL_HELPERS.slice(*mappings)
|
data/lib/devise/delegator.rb
CHANGED
data/lib/devise/encryptor.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'bcrypt'
|
2
4
|
|
3
5
|
module Devise
|
@@ -9,14 +11,14 @@ module Devise
|
|
9
11
|
::BCrypt::Password.create(password, cost: klass.stretches).to_s
|
10
12
|
end
|
11
13
|
|
12
|
-
def self.compare(klass,
|
13
|
-
return false if
|
14
|
-
bcrypt = ::BCrypt::Password.new(
|
14
|
+
def self.compare(klass, hashed_password, password)
|
15
|
+
return false if hashed_password.blank?
|
16
|
+
bcrypt = ::BCrypt::Password.new(hashed_password)
|
15
17
|
if klass.pepper.present?
|
16
18
|
password = "#{password}#{klass.pepper}"
|
17
19
|
end
|
18
20
|
password = ::BCrypt::Engine.hash_secret(password, bcrypt.salt)
|
19
|
-
Devise.secure_compare(password,
|
21
|
+
Devise.secure_compare(password, hashed_password)
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
data/lib/devise/failure_app.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "action_controller/metal"
|
2
4
|
|
3
5
|
module Devise
|
4
6
|
# Failure application that will be called every time :warden is thrown from
|
5
|
-
# any strategy or hook.
|
6
|
-
# page based on current scope and mapping. If no scope is given,
|
7
|
-
# to the default_url.
|
7
|
+
# any strategy or hook. It is responsible for redirecting the user to the sign
|
8
|
+
# in page based on current scope and mapping. If no scope is given, it
|
9
|
+
# redirects to the default_url.
|
8
10
|
class FailureApp < ActionController::Metal
|
9
|
-
include ActionController::RackDelegation
|
10
11
|
include ActionController::UrlFor
|
11
12
|
include ActionController::Redirecting
|
12
13
|
|
@@ -22,7 +23,7 @@ module Devise
|
|
22
23
|
@respond.call(env)
|
23
24
|
end
|
24
25
|
|
25
|
-
# Try retrieving the URL options from the parent controller (usually
|
26
|
+
# Try retrieving the URL options from the parent controller (usually
|
26
27
|
# ApplicationController). Instance methods are not supported at the moment,
|
27
28
|
# so only the class-level attribute is used.
|
28
29
|
def self.default_url_options(*args)
|
@@ -51,20 +52,26 @@ module Devise
|
|
51
52
|
end
|
52
53
|
|
53
54
|
def recall
|
54
|
-
|
55
|
-
|
56
|
-
if config.try(:relative_url_root)
|
57
|
-
base_path = Pathname.new(config.relative_url_root)
|
55
|
+
header_info = if relative_url_root?
|
56
|
+
base_path = Pathname.new(relative_url_root)
|
58
57
|
full_path = Pathname.new(attempted_path)
|
59
58
|
|
60
|
-
|
61
|
-
|
59
|
+
{ "SCRIPT_NAME" => relative_url_root,
|
60
|
+
"PATH_INFO" => '/' + full_path.relative_path_from(base_path).to_s }
|
62
61
|
else
|
63
|
-
|
62
|
+
{ "PATH_INFO" => attempted_path }
|
63
|
+
end
|
64
|
+
|
65
|
+
header_info.each do | var, value|
|
66
|
+
if request.respond_to?(:set_header)
|
67
|
+
request.set_header(var, value)
|
68
|
+
else
|
69
|
+
request.env[var] = value
|
70
|
+
end
|
64
71
|
end
|
65
72
|
|
66
73
|
flash.now[:alert] = i18n_message(:invalid) if is_flashing_format?
|
67
|
-
self.response = recall_app(warden_options[:recall]).call(env)
|
74
|
+
self.response = recall_app(warden_options[:recall]).call(request.env)
|
68
75
|
end
|
69
76
|
|
70
77
|
def redirect
|
@@ -95,11 +102,11 @@ module Devise
|
|
95
102
|
options[:scope] = "devise.failure"
|
96
103
|
options[:default] = [message]
|
97
104
|
auth_keys = scope_class.authentication_keys
|
98
|
-
keys = auth_keys.respond_to?(:keys) ? auth_keys.keys : auth_keys
|
105
|
+
keys = (auth_keys.respond_to?(:keys) ? auth_keys.keys : auth_keys).map { |key| scope_class.human_attribute_name(key) }
|
99
106
|
options[:authentication_keys] = keys.join(I18n.translate(:"support.array.words_connector"))
|
100
107
|
options = i18n_options(options)
|
101
108
|
|
102
|
-
I18n.t(:"#{scope}.#{message}", options)
|
109
|
+
I18n.t(:"#{scope}.#{message}", **options)
|
103
110
|
else
|
104
111
|
message.to_s
|
105
112
|
end
|
@@ -127,23 +134,29 @@ module Devise
|
|
127
134
|
|
128
135
|
def scope_url
|
129
136
|
opts = {}
|
130
|
-
route = route(scope)
|
131
|
-
opts[:format] = request_format unless skip_format?
|
132
137
|
|
133
|
-
|
138
|
+
# Initialize script_name with nil to prevent infinite loops in
|
139
|
+
# authenticated mounted engines in rails 4.2 and 5.0
|
140
|
+
opts[:script_name] = nil
|
134
141
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
else
|
139
|
-
if config.respond_to?(:relative_url_root) && config.relative_url_root.present?
|
140
|
-
opts[:script_name] = config.relative_url_root
|
141
|
-
end
|
142
|
-
end
|
142
|
+
route = route(scope)
|
143
|
+
|
144
|
+
opts[:format] = request_format unless skip_format?
|
143
145
|
|
144
146
|
router_name = Devise.mappings[scope].router_name || Devise.available_router_name
|
145
147
|
context = send(router_name)
|
146
148
|
|
149
|
+
if relative_url_root?
|
150
|
+
opts[:script_name] = relative_url_root
|
151
|
+
|
152
|
+
# We need to add the rootpath to `script_name` manually for applications that use a Rails
|
153
|
+
# version lower than 5.1. Otherwise, it is going to generate a wrong path for Engines
|
154
|
+
# that use Devise. Remove it when the support of Rails 5.0 is dropped.
|
155
|
+
elsif root_path_defined?(context) && !rails_51_and_up?
|
156
|
+
rootpath = context.routes.url_helpers.root_path
|
157
|
+
opts[:script_name] = rootpath.chomp('/') if rootpath.length > 1
|
158
|
+
end
|
159
|
+
|
147
160
|
if context.respond_to?(route)
|
148
161
|
context.send(route, opts)
|
149
162
|
elsif respond_to?(:root_url)
|
@@ -157,12 +170,12 @@ module Devise
|
|
157
170
|
%w(html */*).include? request_format.to_s
|
158
171
|
end
|
159
172
|
|
160
|
-
# Choose whether we should respond in
|
173
|
+
# Choose whether we should respond in an HTTP authentication fashion,
|
161
174
|
# including 401 and optional headers.
|
162
175
|
#
|
163
|
-
# This method allows the user to explicitly disable
|
164
|
-
# on
|
165
|
-
# handling the errors on their own. This is useful in case your
|
176
|
+
# This method allows the user to explicitly disable HTTP authentication
|
177
|
+
# on AJAX requests in case they want to redirect on failures instead of
|
178
|
+
# handling the errors on their own. This is useful in case your AJAX API
|
166
179
|
# is the same as your public API and uses a format like JSON (so you
|
167
180
|
# cannot mark JSON as a navigational format).
|
168
181
|
def http_auth?
|
@@ -173,7 +186,7 @@ module Devise
|
|
173
186
|
end
|
174
187
|
end
|
175
188
|
|
176
|
-
# It
|
189
|
+
# It doesn't make sense to send authenticate headers in AJAX requests
|
177
190
|
# or if the user disabled them.
|
178
191
|
def http_auth_header?
|
179
192
|
scope_class.http_authenticatable && !request.xhr?
|
@@ -199,11 +212,11 @@ module Devise
|
|
199
212
|
end
|
200
213
|
|
201
214
|
def warden
|
202
|
-
env[
|
215
|
+
request.respond_to?(:get_header) ? request.get_header("warden") : request.env["warden"]
|
203
216
|
end
|
204
217
|
|
205
218
|
def warden_options
|
206
|
-
env[
|
219
|
+
request.respond_to?(:get_header) ? request.get_header("warden.options") : request.env["warden.options"]
|
207
220
|
end
|
208
221
|
|
209
222
|
def warden_message
|
@@ -222,10 +235,10 @@ module Devise
|
|
222
235
|
warden_options[:attempted_path]
|
223
236
|
end
|
224
237
|
|
225
|
-
# Stores requested
|
226
|
-
# scoped session provided by warden here, since the user is not
|
227
|
-
# yet, but we still need to store the
|
228
|
-
# would never use the same
|
238
|
+
# Stores requested URI to redirect the user after signing in. We can't use
|
239
|
+
# the scoped session provided by warden here, since the user is not
|
240
|
+
# authenticated yet, but we still need to store the URI based on scope, so
|
241
|
+
# different scopes would never use the same URI to redirect.
|
229
242
|
def store_location!
|
230
243
|
store_location_for(scope, attempted_path) if request.get? && !http_auth?
|
231
244
|
end
|
@@ -237,11 +250,35 @@ module Devise
|
|
237
250
|
# Check if flash messages should be emitted. Default is to do it on
|
238
251
|
# navigational formats
|
239
252
|
def is_flashing_format?
|
240
|
-
is_navigational_format?
|
253
|
+
request.respond_to?(:flash) && is_navigational_format?
|
241
254
|
end
|
242
255
|
|
243
256
|
def request_format
|
244
257
|
@request_format ||= request.format.try(:ref)
|
245
258
|
end
|
259
|
+
|
260
|
+
def relative_url_root
|
261
|
+
@relative_url_root ||= begin
|
262
|
+
config = Rails.application.config
|
263
|
+
|
264
|
+
config.try(:relative_url_root) || config.action_controller.try(:relative_url_root)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def relative_url_root?
|
269
|
+
relative_url_root.present?
|
270
|
+
end
|
271
|
+
|
272
|
+
ActiveSupport.run_load_hooks(:devise_failure_app, self)
|
273
|
+
|
274
|
+
private
|
275
|
+
|
276
|
+
def root_path_defined?(context)
|
277
|
+
defined?(context.routes) && context.routes.url_helpers.respond_to?(:root_path)
|
278
|
+
end
|
279
|
+
|
280
|
+
def rails_51_and_up?
|
281
|
+
Rails.gem_version >= Gem::Version.new("5.1")
|
282
|
+
end
|
246
283
|
end
|
247
284
|
end
|
@@ -1,7 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# After each sign in, if resource responds to failed_attempts, sets it to 0
|
2
4
|
# This is only triggered when the user is explicitly set (with set_user)
|
3
5
|
Warden::Manager.after_set_user except: :fetch do |record, warden, options|
|
4
6
|
if record.respond_to?(:failed_attempts) && warden.authenticated?(options[:scope])
|
5
|
-
|
7
|
+
unless record.failed_attempts.to_i.zero?
|
8
|
+
record.failed_attempts = 0
|
9
|
+
record.save(validate: false)
|
10
|
+
end
|
6
11
|
end
|
7
12
|
end
|
data/lib/devise/hooks/proxy.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Devise
|
2
4
|
module Hooks
|
3
5
|
# A small warden proxy so we can remember, forget and
|
@@ -7,7 +9,7 @@ module Devise
|
|
7
9
|
include Devise::Controllers::SignInOut
|
8
10
|
|
9
11
|
attr_reader :warden
|
10
|
-
delegate :cookies, :
|
12
|
+
delegate :cookies, :request, to: :warden
|
11
13
|
|
12
14
|
def initialize(warden)
|
13
15
|
@warden = warden
|