devise 2.1.2 → 3.5.10
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of devise might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/.travis.yml +39 -10
- data/.yardopts +9 -0
- data/{CHANGELOG.rdoc → CHANGELOG.md} +445 -112
- data/CODE_OF_CONDUCT.md +22 -0
- data/CONTRIBUTING.md +16 -0
- data/Gemfile +10 -15
- data/Gemfile.lock +151 -129
- data/MIT-LICENSE +1 -1
- data/README.md +256 -96
- data/Rakefile +4 -2
- data/app/controllers/devise/confirmations_controller.rb +15 -7
- data/app/controllers/devise/omniauth_callbacks_controller.rb +6 -2
- data/app/controllers/devise/passwords_controller.rb +33 -9
- data/app/controllers/devise/registrations_controller.rb +66 -26
- data/app/controllers/devise/sessions_controller.rb +52 -21
- data/app/controllers/devise/unlocks_controller.rb +11 -6
- data/app/controllers/devise_controller.rb +65 -58
- data/app/helpers/devise_helper.rb +2 -2
- data/app/mailers/devise/mailer.rb +19 -10
- data/app/views/devise/confirmations/new.html.erb +8 -4
- data/app/views/devise/mailer/confirmation_instructions.html.erb +2 -2
- data/app/views/devise/mailer/password_change.html.erb +3 -0
- data/app/views/devise/mailer/reset_password_instructions.html.erb +2 -2
- data/app/views/devise/mailer/unlock_instructions.html.erb +2 -2
- data/app/views/devise/passwords/edit.html.erb +15 -6
- data/app/views/devise/passwords/new.html.erb +8 -4
- data/app/views/devise/registrations/edit.html.erb +29 -15
- data/app/views/devise/registrations/new.html.erb +19 -8
- data/app/views/devise/sessions/new.html.erb +17 -8
- data/app/views/devise/shared/{_links.erb → _links.html.erb} +4 -4
- data/app/views/devise/unlocks/new.html.erb +8 -4
- data/config/locales/en.yml +51 -47
- data/devise.gemspec +8 -6
- data/devise.png +0 -0
- data/gemfiles/Gemfile.rails-3.2-stable +29 -0
- data/gemfiles/Gemfile.rails-3.2-stable.lock +172 -0
- data/gemfiles/Gemfile.rails-4.0-stable +30 -0
- data/gemfiles/Gemfile.rails-4.0-stable.lock +166 -0
- data/gemfiles/Gemfile.rails-4.1-stable +30 -0
- data/gemfiles/Gemfile.rails-4.1-stable.lock +171 -0
- data/gemfiles/Gemfile.rails-4.2-stable +30 -0
- data/gemfiles/Gemfile.rails-4.2-stable.lock +193 -0
- data/lib/devise/controllers/helpers.rb +126 -108
- data/lib/devise/controllers/rememberable.rb +19 -17
- data/lib/devise/controllers/scoped_views.rb +1 -1
- data/lib/devise/controllers/sign_in_out.rb +96 -0
- data/lib/devise/controllers/store_location.rb +58 -0
- data/lib/devise/controllers/url_helpers.rb +7 -7
- data/lib/devise/encryptor.rb +22 -0
- data/lib/devise/failure_app.rb +85 -25
- data/lib/devise/hooks/activatable.rb +5 -6
- data/lib/devise/hooks/csrf_cleaner.rb +7 -0
- data/lib/devise/hooks/forgetable.rb +1 -1
- data/lib/devise/hooks/lockable.rb +2 -2
- data/lib/devise/hooks/proxy.rb +21 -0
- data/lib/devise/hooks/rememberable.rb +5 -4
- data/lib/devise/hooks/timeoutable.rb +16 -8
- data/lib/devise/hooks/trackable.rb +1 -1
- data/lib/devise/mailers/helpers.rb +27 -23
- data/lib/devise/mapping.rb +11 -7
- data/lib/devise/models/authenticatable.rb +82 -66
- data/lib/devise/models/confirmable.rb +142 -55
- data/lib/devise/models/database_authenticatable.rb +59 -15
- data/lib/devise/models/lockable.rb +41 -30
- data/lib/devise/models/omniauthable.rb +3 -3
- data/lib/devise/models/recoverable.rb +56 -41
- data/lib/devise/models/rememberable.rb +65 -27
- data/lib/devise/models/timeoutable.rb +2 -8
- data/lib/devise/models/trackable.rb +6 -4
- data/lib/devise/models/validatable.rb +9 -9
- data/lib/devise/models.rb +4 -13
- data/lib/devise/modules.rb +10 -11
- data/lib/devise/omniauth/url_helpers.rb +2 -2
- data/lib/devise/orm/active_record.rb +1 -1
- data/lib/devise/orm/mongoid.rb +1 -1
- data/lib/devise/{param_filter.rb → parameter_filter.rb} +10 -11
- data/lib/devise/parameter_sanitizer.rb +99 -0
- data/lib/devise/rails/routes.rb +173 -115
- data/lib/devise/rails/warden_compat.rb +10 -31
- data/lib/devise/rails.rb +14 -12
- data/lib/devise/strategies/authenticatable.rb +26 -26
- data/lib/devise/strategies/base.rb +1 -1
- data/lib/devise/strategies/database_authenticatable.rb +8 -4
- data/lib/devise/strategies/rememberable.rb +15 -5
- data/lib/devise/test_helpers.rb +7 -5
- data/lib/devise/time_inflector.rb +14 -0
- data/lib/devise/token_generator.rb +70 -0
- data/lib/devise/version.rb +1 -1
- data/lib/devise.rb +110 -52
- data/lib/generators/active_record/devise_generator.rb +34 -18
- data/lib/generators/active_record/templates/migration.rb +5 -6
- data/lib/generators/active_record/templates/migration_existing.rb +5 -6
- data/lib/generators/devise/controllers_generator.rb +44 -0
- data/lib/generators/devise/devise_generator.rb +5 -3
- data/lib/generators/devise/install_generator.rb +5 -0
- data/lib/generators/devise/orm_helpers.rb +25 -6
- data/lib/generators/devise/views_generator.rb +52 -22
- data/lib/generators/mongoid/devise_generator.rb +21 -26
- data/lib/generators/templates/README +9 -5
- data/lib/generators/templates/controllers/README +14 -0
- data/lib/generators/templates/controllers/confirmations_controller.rb +28 -0
- data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +28 -0
- data/lib/generators/templates/controllers/passwords_controller.rb +32 -0
- data/lib/generators/templates/controllers/registrations_controller.rb +60 -0
- data/lib/generators/templates/controllers/sessions_controller.rb +25 -0
- data/lib/generators/templates/controllers/unlocks_controller.rb +28 -0
- data/lib/generators/templates/devise.rb +80 -43
- data/lib/generators/templates/markerb/confirmation_instructions.markerb +2 -2
- 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 +2 -2
- data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +3 -2
- data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +4 -4
- data/lib/generators/templates/simple_form_for/passwords/new.html.erb +2 -2
- data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +11 -6
- data/lib/generators/templates/simple_form_for/registrations/new.html.erb +4 -4
- data/lib/generators/templates/simple_form_for/sessions/new.html.erb +6 -6
- data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +3 -2
- data/script/cached-bundle +49 -0
- data/script/s3-put +71 -0
- data/test/controllers/custom_registrations_controller_test.rb +40 -0
- data/test/controllers/helper_methods_test.rb +21 -0
- data/test/controllers/helpers_test.rb +95 -32
- data/test/controllers/inherited_controller_i18n_messages_test.rb +51 -0
- data/test/controllers/internal_helpers_test.rb +39 -14
- data/test/controllers/load_hooks_controller_test.rb +19 -0
- data/test/controllers/passwords_controller_test.rb +31 -0
- data/test/controllers/sessions_controller_test.rb +66 -6
- data/test/controllers/url_helpers_test.rb +10 -4
- data/test/delegator_test.rb +1 -1
- data/test/devise_test.rb +45 -10
- data/test/failure_app_test.rb +121 -27
- data/test/generators/active_record_generator_test.rb +48 -8
- data/test/generators/controllers_generator_test.rb +48 -0
- data/test/generators/devise_generator_test.rb +2 -2
- data/test/generators/mongoid_generator_test.rb +3 -3
- data/test/generators/views_generator_test.rb +54 -3
- data/test/helpers/devise_helper_test.rb +18 -20
- data/test/integration/authenticatable_test.rb +161 -65
- data/test/integration/confirmable_test.rb +146 -77
- data/test/integration/database_authenticatable_test.rb +43 -30
- data/test/integration/http_authenticatable_test.rb +30 -22
- data/test/integration/lockable_test.rb +64 -49
- data/test/integration/omniauthable_test.rb +17 -15
- data/test/integration/recoverable_test.rb +111 -70
- data/test/integration/registerable_test.rb +114 -79
- data/test/integration/rememberable_test.rb +87 -31
- data/test/integration/timeoutable_test.rb +77 -33
- data/test/integration/trackable_test.rb +5 -5
- data/test/mailers/confirmation_instructions_test.rb +28 -8
- data/test/mailers/reset_password_instructions_test.rb +21 -8
- data/test/mailers/unlock_instructions_test.rb +20 -6
- data/test/mapping_test.rb +12 -5
- data/test/models/authenticatable_test.rb +17 -1
- data/test/models/confirmable_test.rb +216 -62
- data/test/models/database_authenticatable_test.rb +129 -49
- data/test/models/lockable_test.rb +132 -45
- data/test/models/recoverable_test.rb +100 -54
- data/test/models/rememberable_test.rb +89 -94
- data/test/models/serializable_test.rb +12 -11
- data/test/models/timeoutable_test.rb +6 -1
- data/test/models/trackable_test.rb +28 -0
- data/test/models/validatable_test.rb +31 -21
- data/test/models_test.rb +22 -48
- data/test/omniauth/config_test.rb +4 -4
- data/test/omniauth/url_helpers_test.rb +7 -4
- data/test/orm/active_record.rb +1 -0
- data/test/orm/mongoid.rb +2 -3
- data/test/parameter_sanitizer_test.rb +81 -0
- data/test/rails_app/Rakefile +0 -4
- data/test/rails_app/app/active_record/shim.rb +1 -1
- data/test/rails_app/app/active_record/user_on_engine.rb +7 -0
- data/test/rails_app/app/active_record/user_on_main_app.rb +7 -0
- data/test/rails_app/app/active_record/user_without_email.rb +8 -0
- data/test/rails_app/app/controllers/admins/sessions_controller.rb +1 -1
- data/test/rails_app/app/controllers/admins_controller.rb +0 -5
- data/test/rails_app/app/controllers/application_controller.rb +6 -2
- data/test/rails_app/app/controllers/application_with_fake_engine.rb +30 -0
- data/test/rails_app/app/controllers/custom/registrations_controller.rb +31 -0
- data/test/rails_app/app/controllers/home_controller.rb +1 -1
- data/test/rails_app/app/controllers/publisher/registrations_controller.rb +1 -1
- data/test/rails_app/app/controllers/publisher/sessions_controller.rb +1 -1
- data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +4 -4
- data/test/rails_app/app/controllers/users_controller.rb +12 -4
- data/test/rails_app/app/mailers/users/from_proc_mailer.rb +3 -0
- data/test/rails_app/app/mailers/users/mailer.rb +1 -1
- data/test/rails_app/app/mailers/users/reply_to_mailer.rb +4 -0
- data/test/rails_app/app/mongoid/admin.rb +12 -10
- data/test/rails_app/app/mongoid/shim.rb +4 -5
- data/test/rails_app/app/mongoid/user.rb +19 -22
- data/test/rails_app/app/mongoid/user_on_engine.rb +39 -0
- data/test/rails_app/app/mongoid/user_on_main_app.rb +39 -0
- data/test/rails_app/app/mongoid/user_without_email.rb +33 -0
- data/test/rails_app/app/views/admins/sessions/new.html.erb +1 -1
- data/test/rails_app/app/views/home/admin_dashboard.html.erb +1 -1
- data/test/rails_app/app/views/home/index.html.erb +1 -1
- data/test/rails_app/app/views/home/join.html.erb +1 -1
- data/test/rails_app/app/views/home/user_dashboard.html.erb +1 -1
- data/test/rails_app/app/views/layouts/application.html.erb +1 -1
- data/test/rails_app/app/views/users/edit_form.html.erb +1 -0
- data/test/rails_app/bin/bundle +3 -0
- data/test/rails_app/bin/rails +4 -0
- data/test/rails_app/bin/rake +4 -0
- data/test/rails_app/config/application.rb +4 -5
- data/test/rails_app/config/boot.rb +9 -3
- data/test/rails_app/config/environment.rb +2 -2
- data/test/rails_app/config/environments/development.rb +19 -7
- data/test/rails_app/config/environments/production.rb +68 -17
- data/test/rails_app/config/environments/test.rb +24 -16
- data/test/rails_app/config/initializers/devise.rb +22 -20
- data/test/rails_app/config/initializers/secret_token.rb +8 -2
- data/test/rails_app/config/initializers/session_store.rb +1 -0
- data/test/rails_app/config/routes.rb +71 -46
- data/test/rails_app/db/migrate/20100401102949_create_tables.rb +9 -12
- data/test/rails_app/db/schema.rb +21 -18
- data/test/rails_app/lib/shared_admin.rb +7 -4
- data/test/rails_app/lib/shared_user.rb +6 -3
- data/test/rails_app/lib/shared_user_without_email.rb +26 -0
- data/test/rails_app/lib/shared_user_without_omniauth.rb +13 -0
- data/test/rails_test.rb +9 -0
- data/test/routes_test.rb +94 -78
- data/test/support/action_controller/record_identifier.rb +10 -0
- data/test/support/assertions.rb +2 -3
- data/test/support/helpers.rb +18 -32
- data/test/support/integration.rb +17 -16
- data/test/support/locale/en.yml +4 -0
- data/test/support/mongoid.yml +6 -0
- data/test/test_helper.rb +8 -1
- data/test/test_helpers_test.rb +64 -20
- data/test/test_models.rb +33 -0
- data/test/time_helpers.rb +137 -0
- metadata +172 -51
- data/app/views/devise/_links.erb +0 -3
- data/gemfiles/Gemfile.rails-3.1.x +0 -35
- data/gemfiles/Gemfile.rails-3.1.x.lock +0 -167
- data/lib/devise/models/token_authenticatable.rb +0 -77
- data/lib/devise/strategies/token_authenticatable.rb +0 -56
- data/test/indifferent_hash.rb +0 -33
- data/test/integration/token_authenticatable_test.rb +0 -161
- data/test/models/token_authenticatable_test.rb +0 -55
- data/test/rails_app/script/rails +0 -10
@@ -0,0 +1,58 @@
|
|
1
|
+
require "uri"
|
2
|
+
|
3
|
+
module Devise
|
4
|
+
module Controllers
|
5
|
+
# Provide the ability to store a location.
|
6
|
+
# Used to redirect back to a desired path after sign in.
|
7
|
+
# Included by default in all controllers.
|
8
|
+
module StoreLocation
|
9
|
+
# Returns and delete (if it's navigational format) the url stored in the session for
|
10
|
+
# the given scope. Useful for giving redirect backs after sign up:
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
#
|
14
|
+
# redirect_to stored_location_for(:user) || root_path
|
15
|
+
#
|
16
|
+
def stored_location_for(resource_or_scope)
|
17
|
+
session_key = stored_location_key_for(resource_or_scope)
|
18
|
+
|
19
|
+
if is_navigational_format?
|
20
|
+
session.delete(session_key)
|
21
|
+
else
|
22
|
+
session[session_key]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Stores the provided location to redirect the user after signing in.
|
27
|
+
# Useful in combination with the `stored_location_for` helper.
|
28
|
+
#
|
29
|
+
# Example:
|
30
|
+
#
|
31
|
+
# store_location_for(:user, dashboard_path)
|
32
|
+
# redirect_to user_omniauth_authorize_path(:facebook)
|
33
|
+
#
|
34
|
+
def store_location_for(resource_or_scope, location)
|
35
|
+
session_key = stored_location_key_for(resource_or_scope)
|
36
|
+
uri = parse_uri(location)
|
37
|
+
if uri
|
38
|
+
path = [uri.path.sub(/\A\/+/, '/'), uri.query].compact.join('?')
|
39
|
+
path = [path, uri.fragment].compact.join('#')
|
40
|
+
session[session_key] = path
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def parse_uri(location)
|
47
|
+
location && URI.parse(location)
|
48
|
+
rescue URI::InvalidURIError
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def stored_location_key_for(resource_or_scope)
|
53
|
+
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
54
|
+
"#{scope}_return_to"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -42,14 +42,14 @@ module Devise
|
|
42
42
|
[:path, :url].each do |path_or_url|
|
43
43
|
actions.each do |action|
|
44
44
|
action = action ? "#{action}_" : ""
|
45
|
-
method = "#{action}#{module_name}_#{path_or_url}"
|
45
|
+
method = :"#{action}#{module_name}_#{path_or_url}"
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
47
|
+
define_method method do |resource_or_scope, *args|
|
48
|
+
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
49
|
+
router_name = Devise.mappings[scope].router_name
|
50
|
+
context = router_name ? send(router_name) : _devise_route_context
|
51
|
+
context.send("#{action}#{scope}_#{module_name}_#{path_or_url}", *args)
|
52
|
+
end
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'bcrypt'
|
2
|
+
|
3
|
+
module Devise
|
4
|
+
module Encryptor
|
5
|
+
def self.digest(klass, password)
|
6
|
+
if klass.pepper.present?
|
7
|
+
password = "#{password}#{klass.pepper}"
|
8
|
+
end
|
9
|
+
::BCrypt::Password.create(password, cost: klass.stretches).to_s
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.compare(klass, encrypted_password, password)
|
13
|
+
return false if encrypted_password.blank?
|
14
|
+
bcrypt = ::BCrypt::Password.new(encrypted_password)
|
15
|
+
if klass.pepper.present?
|
16
|
+
password = "#{password}#{klass.pepper}"
|
17
|
+
end
|
18
|
+
password = ::BCrypt::Engine.hash_secret(password, bcrypt.salt)
|
19
|
+
Devise.secure_compare(password, encrypted_password)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/devise/failure_app.rb
CHANGED
@@ -13,16 +13,21 @@ module Devise
|
|
13
13
|
include Rails.application.routes.url_helpers
|
14
14
|
include Rails.application.routes.mounted_helpers
|
15
15
|
|
16
|
-
|
16
|
+
include Devise::Controllers::StoreLocation
|
17
|
+
|
18
|
+
delegate :flash, to: :request
|
17
19
|
|
18
20
|
def self.call(env)
|
19
21
|
@respond ||= action(:respond)
|
20
22
|
@respond.call(env)
|
21
23
|
end
|
22
24
|
|
25
|
+
# Try retrieving the URL options from the parent controller (usually
|
26
|
+
# ApplicationController). Instance methods are not supported at the moment,
|
27
|
+
# so only the class-level attribute is used.
|
23
28
|
def self.default_url_options(*args)
|
24
|
-
if defined?(
|
25
|
-
|
29
|
+
if defined?(Devise.parent_controller.constantize)
|
30
|
+
Devise.parent_controller.constantize.try(:default_url_options) || {}
|
26
31
|
else
|
27
32
|
{}
|
28
33
|
end
|
@@ -46,30 +51,55 @@ module Devise
|
|
46
51
|
end
|
47
52
|
|
48
53
|
def recall
|
49
|
-
|
50
|
-
|
54
|
+
config = Rails.application.config
|
55
|
+
|
56
|
+
if config.try(:relative_url_root)
|
57
|
+
base_path = Pathname.new(config.relative_url_root)
|
58
|
+
full_path = Pathname.new(attempted_path)
|
59
|
+
|
60
|
+
env["SCRIPT_NAME"] = config.relative_url_root
|
61
|
+
env["PATH_INFO"] = '/' + full_path.relative_path_from(base_path).to_s
|
62
|
+
else
|
63
|
+
env["PATH_INFO"] = attempted_path
|
64
|
+
end
|
65
|
+
|
66
|
+
flash.now[:alert] = i18n_message(:invalid) if is_flashing_format?
|
51
67
|
self.response = recall_app(warden_options[:recall]).call(env)
|
52
68
|
end
|
53
69
|
|
54
70
|
def redirect
|
55
71
|
store_location!
|
56
|
-
if
|
57
|
-
flash
|
58
|
-
|
59
|
-
|
60
|
-
|
72
|
+
if is_flashing_format?
|
73
|
+
if flash[:timedout] && flash[:alert]
|
74
|
+
flash.keep(:timedout)
|
75
|
+
flash.keep(:alert)
|
76
|
+
else
|
77
|
+
flash[:alert] = i18n_message
|
78
|
+
end
|
61
79
|
end
|
62
80
|
redirect_to redirect_url
|
63
81
|
end
|
64
82
|
|
65
83
|
protected
|
66
84
|
|
85
|
+
def i18n_options(options)
|
86
|
+
options
|
87
|
+
end
|
88
|
+
|
67
89
|
def i18n_message(default = nil)
|
68
90
|
message = warden_message || default || :unauthenticated
|
69
91
|
|
70
92
|
if message.is_a?(Symbol)
|
71
|
-
|
72
|
-
|
93
|
+
options = {}
|
94
|
+
options[:resource_name] = scope
|
95
|
+
options[:scope] = "devise.failure"
|
96
|
+
options[:default] = [message]
|
97
|
+
auth_keys = scope_class.authentication_keys
|
98
|
+
keys = auth_keys.respond_to?(:keys) ? auth_keys.keys : auth_keys
|
99
|
+
options[:authentication_keys] = keys.join(I18n.translate(:"support.array.words_connector"))
|
100
|
+
options = i18n_options(options)
|
101
|
+
|
102
|
+
I18n.t(:"#{scope}.#{message}", options)
|
73
103
|
else
|
74
104
|
message.to_s
|
75
105
|
end
|
@@ -77,27 +107,47 @@ module Devise
|
|
77
107
|
|
78
108
|
def redirect_url
|
79
109
|
if warden_message == :timeout
|
80
|
-
flash[:timedout] = true
|
81
|
-
|
110
|
+
flash[:timedout] = true if is_flashing_format?
|
111
|
+
|
112
|
+
path = if request.get?
|
113
|
+
attempted_path
|
114
|
+
else
|
115
|
+
request.referrer
|
116
|
+
end
|
117
|
+
|
118
|
+
path || scope_url
|
82
119
|
else
|
83
|
-
|
120
|
+
scope_url
|
84
121
|
end
|
85
122
|
end
|
86
123
|
|
87
|
-
def
|
124
|
+
def route(scope)
|
125
|
+
:"new_#{scope}_session_url"
|
126
|
+
end
|
127
|
+
|
128
|
+
def scope_url
|
88
129
|
opts = {}
|
89
|
-
route =
|
130
|
+
route = route(scope)
|
90
131
|
opts[:format] = request_format unless skip_format?
|
91
132
|
|
92
133
|
config = Rails.application.config
|
93
|
-
opts[:script_name] = (config.relative_url_root if config.respond_to?(:relative_url_root))
|
94
134
|
|
95
|
-
|
135
|
+
# Rails 4.2 goes into an infinite loop if opts[:script_name] is unset
|
136
|
+
if (Rails::VERSION::MAJOR >= 4) && (Rails::VERSION::MINOR >= 2)
|
137
|
+
opts[:script_name] = (config.relative_url_root if config.respond_to?(:relative_url_root))
|
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
|
143
|
+
|
144
|
+
router_name = Devise.mappings[scope].router_name || Devise.available_router_name
|
145
|
+
context = send(router_name)
|
96
146
|
|
97
147
|
if context.respond_to?(route)
|
98
148
|
context.send(route, opts)
|
99
|
-
elsif respond_to?(:
|
100
|
-
|
149
|
+
elsif respond_to?(:root_url)
|
150
|
+
root_url(opts)
|
101
151
|
else
|
102
152
|
"/"
|
103
153
|
end
|
@@ -126,16 +176,16 @@ module Devise
|
|
126
176
|
# It does not make sense to send authenticate headers in ajax requests
|
127
177
|
# or if the user disabled them.
|
128
178
|
def http_auth_header?
|
129
|
-
|
179
|
+
scope_class.http_authenticatable && !request.xhr?
|
130
180
|
end
|
131
181
|
|
132
182
|
def http_auth_body
|
133
183
|
return i18n_message unless request_format
|
134
184
|
method = "to_#{request_format}"
|
135
185
|
if method == "to_xml"
|
136
|
-
{ :
|
186
|
+
{ error: i18n_message }.to_xml(root: "errors")
|
137
187
|
elsif {}.respond_to?(method)
|
138
|
-
{ :
|
188
|
+
{ error: i18n_message }.send(method)
|
139
189
|
else
|
140
190
|
i18n_message
|
141
191
|
end
|
@@ -164,6 +214,10 @@ module Devise
|
|
164
214
|
@scope ||= warden_options[:scope] || Devise.default_scope
|
165
215
|
end
|
166
216
|
|
217
|
+
def scope_class
|
218
|
+
@scope_class ||= Devise.mappings[scope].to
|
219
|
+
end
|
220
|
+
|
167
221
|
def attempted_path
|
168
222
|
warden_options[:attempted_path]
|
169
223
|
end
|
@@ -173,13 +227,19 @@ module Devise
|
|
173
227
|
# yet, but we still need to store the uri based on scope, so different scopes
|
174
228
|
# would never use the same uri to redirect.
|
175
229
|
def store_location!
|
176
|
-
|
230
|
+
store_location_for(scope, attempted_path) if request.get? && !http_auth?
|
177
231
|
end
|
178
232
|
|
179
233
|
def is_navigational_format?
|
180
234
|
Devise.navigational_formats.include?(request_format)
|
181
235
|
end
|
182
236
|
|
237
|
+
# Check if flash messages should be emitted. Default is to do it on
|
238
|
+
# navigational formats
|
239
|
+
def is_flashing_format?
|
240
|
+
is_navigational_format?
|
241
|
+
end
|
242
|
+
|
183
243
|
def request_format
|
184
244
|
@request_format ||= request.format.try(:ref)
|
185
245
|
end
|
@@ -1,11 +1,10 @@
|
|
1
|
-
# Deny user access whenever
|
2
|
-
#
|
3
|
-
#
|
4
|
-
# in each request and in case the user is using other strategies beside Devise ones.
|
1
|
+
# Deny user access whenever their account is not active yet.
|
2
|
+
# We need this as hook to validate the user activity on each request
|
3
|
+
# and in case the user is using other strategies beside Devise ones.
|
5
4
|
Warden::Manager.after_set_user do |record, warden, options|
|
6
5
|
if record && record.respond_to?(:active_for_authentication?) && !record.active_for_authentication?
|
7
6
|
scope = options[:scope]
|
8
7
|
warden.logout(scope)
|
9
|
-
throw :warden, :
|
8
|
+
throw :warden, scope: scope, message: record.inactive_message
|
10
9
|
end
|
11
|
-
end
|
10
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
Warden::Manager.after_authentication do |record, warden, options|
|
2
|
+
clean_up_for_winning_strategy = !warden.winning_strategy.respond_to?(:clean_up_csrf?) ||
|
3
|
+
warden.winning_strategy.clean_up_csrf?
|
4
|
+
if Devise.clean_up_csrf_token_on_authentication && clean_up_for_winning_strategy
|
5
|
+
warden.request.session.try(:delete, :_csrf_token)
|
6
|
+
end
|
7
|
+
end
|
@@ -4,6 +4,6 @@
|
|
4
4
|
# This avoids forgetting deleted users.
|
5
5
|
Warden::Manager.before_logout do |record, warden, options|
|
6
6
|
if record.respond_to?(:forget_me!)
|
7
|
-
Devise::
|
7
|
+
Devise::Hooks::Proxy.new(warden).forget_me(record)
|
8
8
|
end
|
9
9
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# After each sign in, if resource responds to failed_attempts, sets it to 0
|
2
2
|
# This is only triggered when the user is explicitly set (with set_user)
|
3
|
-
Warden::Manager.after_set_user :
|
3
|
+
Warden::Manager.after_set_user except: :fetch do |record, warden, options|
|
4
4
|
if record.respond_to?(:failed_attempts) && warden.authenticated?(options[:scope])
|
5
|
-
record.update_attribute(:failed_attempts, 0)
|
5
|
+
record.update_attribute(:failed_attempts, 0) unless record.failed_attempts.to_i.zero?
|
6
6
|
end
|
7
7
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Devise
|
2
|
+
module Hooks
|
3
|
+
# A small warden proxy so we can remember, forget and
|
4
|
+
# sign out users from hooks.
|
5
|
+
class Proxy #:nodoc:
|
6
|
+
include Devise::Controllers::Rememberable
|
7
|
+
include Devise::Controllers::SignInOut
|
8
|
+
|
9
|
+
attr_reader :warden
|
10
|
+
delegate :cookies, :env, to: :warden
|
11
|
+
|
12
|
+
def initialize(warden)
|
13
|
+
@warden = warden
|
14
|
+
end
|
15
|
+
|
16
|
+
def session
|
17
|
+
warden.request.session
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
|
-
Warden::Manager.after_set_user :
|
1
|
+
Warden::Manager.after_set_user except: :fetch do |record, warden, options|
|
2
2
|
scope = options[:scope]
|
3
|
-
if record.respond_to?(:remember_me) &&
|
4
|
-
|
3
|
+
if record.respond_to?(:remember_me) && options[:store] != false &&
|
4
|
+
record.remember_me && warden.authenticated?(scope)
|
5
|
+
Devise::Hooks::Proxy.new(warden).remember_me(record)
|
5
6
|
end
|
6
|
-
end
|
7
|
+
end
|
@@ -7,19 +7,27 @@ Warden::Manager.after_set_user do |record, warden, options|
|
|
7
7
|
scope = options[:scope]
|
8
8
|
env = warden.request.env
|
9
9
|
|
10
|
-
if record && record.respond_to?(:timedout?) && warden.authenticated?(scope) &&
|
10
|
+
if record && record.respond_to?(:timedout?) && warden.authenticated?(scope) &&
|
11
|
+
options[:store] != false && !env['devise.skip_timeoutable']
|
11
12
|
last_request_at = warden.session(scope)['last_request_at']
|
12
13
|
|
13
|
-
if
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
if last_request_at.is_a? Integer
|
15
|
+
last_request_at = Time.at(last_request_at).utc
|
16
|
+
elsif last_request_at.is_a? String
|
17
|
+
last_request_at = Time.parse(last_request_at)
|
18
|
+
end
|
19
|
+
|
20
|
+
proxy = Devise::Hooks::Proxy.new(warden)
|
21
|
+
|
22
|
+
if record.timedout?(last_request_at) &&
|
23
|
+
!env['devise.skip_timeout'] &&
|
24
|
+
!proxy.remember_me_is_active?(record)
|
25
|
+
Devise.sign_out_all_scopes ? proxy.sign_out : proxy.sign_out(scope)
|
26
|
+
throw :warden, scope: scope, message: :timeout
|
19
27
|
end
|
20
28
|
|
21
29
|
unless env['devise.skip_trackable']
|
22
|
-
warden.session(scope)['last_request_at'] = Time.now.utc
|
30
|
+
warden.session(scope)['last_request_at'] = Time.now.utc.to_i
|
23
31
|
end
|
24
32
|
end
|
25
33
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# This is only triggered when the user is explicitly set (with set_user)
|
3
3
|
# and on authentication. Retrieving the user from session (:fetch) does
|
4
4
|
# not trigger it.
|
5
|
-
Warden::Manager.after_set_user :
|
5
|
+
Warden::Manager.after_set_user except: :fetch do |record, warden, options|
|
6
6
|
if record.respond_to?(:update_tracked_fields!) && warden.authenticated?(options[:scope]) && !warden.request.env['devise.skip_trackable']
|
7
7
|
record.update_tracked_fields!(warden.request)
|
8
8
|
end
|
@@ -11,9 +11,9 @@ module Devise
|
|
11
11
|
protected
|
12
12
|
|
13
13
|
# Configure default email options
|
14
|
-
def devise_mail(record, action)
|
14
|
+
def devise_mail(record, action, opts={})
|
15
15
|
initialize_from_record(record)
|
16
|
-
mail headers_for(action)
|
16
|
+
mail headers_for(action, opts)
|
17
17
|
end
|
18
18
|
|
19
19
|
def initialize_from_record(record)
|
@@ -25,28 +25,32 @@ module Devise
|
|
25
25
|
@devise_mapping ||= Devise.mappings[scope_name]
|
26
26
|
end
|
27
27
|
|
28
|
-
def headers_for(action)
|
28
|
+
def headers_for(action, opts)
|
29
29
|
headers = {
|
30
|
-
:
|
31
|
-
:
|
32
|
-
:
|
33
|
-
:
|
34
|
-
|
30
|
+
subject: subject_for(action),
|
31
|
+
to: resource.email,
|
32
|
+
from: mailer_sender(devise_mapping),
|
33
|
+
reply_to: mailer_reply_to(devise_mapping),
|
34
|
+
template_path: template_paths,
|
35
|
+
template_name: action
|
36
|
+
}.merge(opts)
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
@email = headers[:to]
|
39
|
+
headers
|
40
|
+
end
|
39
41
|
|
40
|
-
|
41
|
-
|
42
|
-
|
42
|
+
def mailer_reply_to(mapping)
|
43
|
+
mailer_sender(mapping, :reply_to)
|
44
|
+
end
|
43
45
|
|
44
|
-
|
46
|
+
def mailer_from(mapping)
|
47
|
+
mailer_sender(mapping, :from)
|
45
48
|
end
|
46
49
|
|
47
|
-
def mailer_sender(mapping)
|
48
|
-
|
49
|
-
|
50
|
+
def mailer_sender(mapping, sender = :from)
|
51
|
+
default_sender = default_params[sender]
|
52
|
+
if default_sender.present?
|
53
|
+
default_sender.respond_to?(:to_proc) ? instance_eval(&default_sender) : default_sender
|
50
54
|
elsif Devise.mailer_sender.is_a?(Proc)
|
51
55
|
Devise.mailer_sender.call(mapping.name)
|
52
56
|
else
|
@@ -55,12 +59,12 @@ module Devise
|
|
55
59
|
end
|
56
60
|
|
57
61
|
def template_paths
|
58
|
-
template_path =
|
62
|
+
template_path = _prefixes.dup
|
59
63
|
template_path.unshift "#{@devise_mapping.scoped_path}/mailer" if self.class.scoped_views?
|
60
64
|
template_path
|
61
65
|
end
|
62
66
|
|
63
|
-
# Setup a subject doing an I18n lookup. At first, it
|
67
|
+
# Setup a subject doing an I18n lookup. At first, it attempts to set a subject
|
64
68
|
# based on the current mapping:
|
65
69
|
#
|
66
70
|
# en:
|
@@ -77,9 +81,9 @@ module Devise
|
|
77
81
|
# confirmation_instructions:
|
78
82
|
# subject: '...'
|
79
83
|
#
|
80
|
-
def
|
81
|
-
I18n.t(:"#{
|
82
|
-
:
|
84
|
+
def subject_for(key)
|
85
|
+
I18n.t(:"#{devise_mapping.name}_subject", scope: [:devise, :mailer, key],
|
86
|
+
default: [:subject, key.to_s.humanize])
|
83
87
|
end
|
84
88
|
end
|
85
89
|
end
|