devise 3.2.4 → 4.0.0
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 +4 -4
- data/.gitignore +0 -1
- data/.travis.yml +33 -17
- data/CHANGELOG.md +57 -1033
- data/CODE_OF_CONDUCT.md +22 -0
- data/CONTRIBUTING.md +2 -0
- data/Gemfile +5 -5
- data/Gemfile.lock +138 -115
- data/MIT-LICENSE +1 -1
- data/README.md +124 -65
- data/Rakefile +2 -1
- data/app/controllers/devise/confirmations_controller.rb +7 -3
- data/app/controllers/devise/omniauth_callbacks_controller.rb +8 -4
- data/app/controllers/devise/passwords_controller.rb +16 -6
- data/app/controllers/devise/registrations_controller.rb +22 -10
- data/app/controllers/devise/sessions_controller.rb +42 -14
- data/app/controllers/devise/unlocks_controller.rb +5 -2
- data/app/controllers/devise_controller.rb +63 -29
- data/app/mailers/devise/mailer.rb +4 -0
- data/app/views/devise/confirmations/new.html.erb +7 -3
- data/app/views/devise/mailer/password_change.html.erb +3 -0
- data/app/views/devise/passwords/edit.html.erb +14 -5
- data/app/views/devise/passwords/new.html.erb +7 -3
- data/app/views/devise/registrations/edit.html.erb +19 -9
- data/app/views/devise/registrations/new.html.erb +18 -7
- data/app/views/devise/sessions/new.html.erb +16 -7
- data/app/views/devise/shared/{_links.erb → _links.html.erb} +2 -2
- data/app/views/devise/unlocks/new.html.erb +7 -3
- data/bin/test +13 -0
- data/config/locales/en.yml +19 -16
- data/devise.gemspec +3 -4
- data/gemfiles/{Gemfile.rails-3.2-stable → Gemfile.rails-4.1-stable} +6 -6
- data/gemfiles/Gemfile.rails-4.1-stable.lock +167 -0
- data/gemfiles/{Gemfile.rails-head → Gemfile.rails-4.2-stable} +6 -6
- data/gemfiles/Gemfile.rails-4.2-stable.lock +189 -0
- data/gemfiles/Gemfile.rails-5.0-beta +37 -0
- data/gemfiles/Gemfile.rails-5.0-beta.lock +199 -0
- data/lib/devise/controllers/helpers.rb +94 -27
- data/lib/devise/controllers/rememberable.rb +9 -2
- data/lib/devise/controllers/sign_in_out.rb +2 -9
- data/lib/devise/controllers/store_location.rb +11 -3
- data/lib/devise/controllers/url_helpers.rb +7 -7
- data/lib/devise/encryptor.rb +22 -0
- data/lib/devise/failure_app.rb +72 -23
- data/lib/devise/hooks/activatable.rb +3 -4
- data/lib/devise/hooks/csrf_cleaner.rb +3 -1
- data/lib/devise/hooks/timeoutable.rb +13 -8
- data/lib/devise/mailers/helpers.rb +1 -1
- data/lib/devise/mapping.rb +6 -2
- data/lib/devise/models/authenticatable.rb +32 -28
- data/lib/devise/models/confirmable.rb +55 -22
- data/lib/devise/models/database_authenticatable.rb +32 -19
- data/lib/devise/models/lockable.rb +5 -5
- data/lib/devise/models/recoverable.rb +44 -20
- data/lib/devise/models/rememberable.rb +54 -27
- data/lib/devise/models/timeoutable.rb +0 -6
- data/lib/devise/models/trackable.rb +5 -3
- data/lib/devise/models/validatable.rb +3 -3
- data/lib/devise/models.rb +1 -1
- data/lib/devise/omniauth/url_helpers.rb +62 -4
- data/lib/devise/parameter_sanitizer.rb +176 -61
- data/lib/devise/rails/routes.rb +76 -59
- data/lib/devise/rails/warden_compat.rb +1 -10
- data/lib/devise/rails.rb +2 -11
- data/lib/devise/strategies/authenticatable.rb +15 -6
- data/lib/devise/strategies/database_authenticatable.rb +5 -4
- data/lib/devise/strategies/rememberable.rb +13 -3
- data/lib/devise/test_helpers.rb +12 -7
- data/lib/devise/token_generator.rb +1 -41
- data/lib/devise/version.rb +1 -1
- data/lib/devise.rb +150 -58
- data/lib/generators/active_record/devise_generator.rb +28 -4
- data/lib/generators/active_record/templates/migration.rb +3 -3
- data/lib/generators/active_record/templates/migration_existing.rb +3 -3
- data/lib/generators/devise/controllers_generator.rb +44 -0
- data/lib/generators/devise/install_generator.rb +15 -0
- data/lib/generators/devise/orm_helpers.rb +1 -18
- data/lib/generators/devise/views_generator.rb +14 -3
- data/lib/generators/templates/README +1 -1
- 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 +36 -28
- data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
- 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/passwords/edit.html.erb +1 -1
- data/lib/generators/templates/simple_form_for/registrations/new.html.erb +1 -1
- data/lib/generators/templates/simple_form_for/sessions/new.html.erb +2 -2
- data/test/controllers/custom_registrations_controller_test.rb +40 -0
- data/test/controllers/custom_strategy_test.rb +7 -5
- data/test/controllers/helper_methods_test.rb +22 -0
- data/test/controllers/helpers_test.rb +41 -1
- data/test/controllers/inherited_controller_i18n_messages_test.rb +51 -0
- data/test/controllers/internal_helpers_test.rb +19 -15
- data/test/controllers/load_hooks_controller_test.rb +19 -0
- data/test/controllers/passwords_controller_test.rb +5 -4
- data/test/controllers/sessions_controller_test.rb +24 -21
- data/test/controllers/url_helpers_test.rb +7 -1
- data/test/devise_test.rb +48 -8
- data/test/failure_app_test.rb +107 -19
- data/test/generators/active_record_generator_test.rb +6 -26
- data/test/generators/controllers_generator_test.rb +48 -0
- data/test/generators/install_generator_test.rb +14 -3
- data/test/generators/views_generator_test.rb +8 -1
- data/test/helpers/devise_helper_test.rb +10 -12
- data/test/integration/authenticatable_test.rb +37 -21
- data/test/integration/confirmable_test.rb +54 -14
- data/test/integration/database_authenticatable_test.rb +12 -1
- data/test/integration/http_authenticatable_test.rb +4 -5
- data/test/integration/lockable_test.rb +10 -9
- data/test/integration/omniauthable_test.rb +13 -11
- data/test/integration/recoverable_test.rb +28 -15
- data/test/integration/registerable_test.rb +41 -33
- data/test/integration/rememberable_test.rb +51 -7
- data/test/integration/timeoutable_test.rb +23 -22
- data/test/integration/trackable_test.rb +3 -3
- data/test/mailers/confirmation_instructions_test.rb +10 -10
- data/test/mailers/reset_password_instructions_test.rb +8 -8
- data/test/mailers/unlock_instructions_test.rb +8 -8
- data/test/mapping_test.rb +7 -0
- data/test/models/authenticatable_test.rb +11 -1
- data/test/models/confirmable_test.rb +91 -42
- data/test/models/database_authenticatable_test.rb +26 -6
- data/test/models/lockable_test.rb +29 -17
- data/test/models/recoverable_test.rb +74 -7
- data/test/models/rememberable_test.rb +68 -94
- data/test/models/trackable_test.rb +28 -0
- data/test/models/validatable_test.rb +9 -17
- data/test/models_test.rb +15 -6
- data/test/omniauth/url_helpers_test.rb +4 -7
- data/test/orm/active_record.rb +6 -1
- data/test/parameter_sanitizer_test.rb +103 -53
- data/test/rails_app/app/active_record/user.rb +1 -0
- 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_controller.rb +1 -6
- data/test/rails_app/app/controllers/application_controller.rb +5 -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 +5 -1
- data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +3 -3
- data/test/rails_app/app/controllers/users_controller.rb +6 -6
- data/test/rails_app/app/mailers/users/from_proc_mailer.rb +3 -0
- data/test/rails_app/app/mailers/users/mailer.rb +0 -9
- data/test/rails_app/app/mailers/users/reply_to_mailer.rb +4 -0
- 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/config/application.rb +3 -3
- data/test/rails_app/config/boot.rb +4 -4
- data/test/rails_app/config/environments/production.rb +6 -2
- data/test/rails_app/config/environments/test.rb +13 -3
- data/test/rails_app/config/initializers/devise.rb +15 -16
- data/test/rails_app/config/initializers/secret_token.rb +1 -6
- data/test/rails_app/config/routes.rb +23 -3
- data/test/rails_app/db/migrate/20100401102949_create_tables.rb +2 -2
- data/test/rails_app/lib/shared_user.rb +1 -1
- 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 +33 -16
- data/test/support/assertions.rb +2 -3
- data/test/support/helpers.rb +13 -6
- data/test/support/http_method_compatibility.rb +51 -0
- data/test/support/integration.rb +4 -4
- data/test/support/webrat/integrations/rails.rb +9 -0
- data/test/test_helper.rb +7 -0
- data/test/test_helpers_test.rb +43 -38
- data/test/test_models.rb +3 -3
- metadata +77 -23
- data/gemfiles/Gemfile.rails-4.0-stable +0 -29
data/lib/devise/test_helpers.rb
CHANGED
@@ -16,21 +16,24 @@ module Devise
|
|
16
16
|
# Override process to consider warden.
|
17
17
|
def process(*)
|
18
18
|
# Make sure we always return @response, a la ActionController::TestCase::Behaviour#process, even if warden interrupts
|
19
|
-
_catch_warden { super } || @response
|
19
|
+
_catch_warden { super } # || @response # _catch_warden will setup the @response object
|
20
|
+
|
21
|
+
# process needs to return the ActionDispath::TestResponse object
|
22
|
+
@response
|
20
23
|
end
|
21
24
|
|
22
|
-
# We need to
|
25
|
+
# We need to set up the environment variables and the response in the controller.
|
23
26
|
def setup_controller_for_warden #:nodoc:
|
24
27
|
@request.env['action_controller.instance'] = @controller
|
25
28
|
end
|
26
29
|
|
27
30
|
# Quick access to Warden::Proxy.
|
28
31
|
def warden #:nodoc:
|
29
|
-
@warden ||= begin
|
32
|
+
@request.env['warden'] ||= begin
|
30
33
|
manager = Warden::Manager.new(nil) do |config|
|
31
34
|
config.merge! Devise.warden_config
|
32
35
|
end
|
33
|
-
|
36
|
+
Warden::Proxy.new(@request.env, manager)
|
34
37
|
end
|
35
38
|
end
|
36
39
|
|
@@ -109,8 +112,9 @@ module Devise
|
|
109
112
|
|
110
113
|
status, headers, response = Devise.warden_config[:failure_app].call(env).to_a
|
111
114
|
@controller.response.headers.merge!(headers)
|
112
|
-
|
113
|
-
|
115
|
+
r_opts = { status: status, content_type: headers["Content-Type"], location: headers["Location"] }
|
116
|
+
r_opts[Rails.version.start_with?('5') ? :body : :text] = response.body
|
117
|
+
@controller.send :render, r_opts
|
114
118
|
nil # causes process return @response
|
115
119
|
end
|
116
120
|
|
@@ -122,7 +126,8 @@ module Devise
|
|
122
126
|
# ensure the controller response is set to our response.
|
123
127
|
@controller.response ||= @response
|
124
128
|
@response.status = ret.first
|
125
|
-
@response.headers
|
129
|
+
@response.headers.clear
|
130
|
+
ret.second.each { |k,v| @response[k] = v }
|
126
131
|
@response.body = ret.third
|
127
132
|
end
|
128
133
|
|
@@ -1,11 +1,8 @@
|
|
1
|
-
# Deprecate: Copied verbatim from Rails source, remove once we move to Rails 4 only.
|
2
|
-
require 'thread_safe'
|
3
1
|
require 'openssl'
|
4
|
-
require 'securerandom'
|
5
2
|
|
6
3
|
module Devise
|
7
4
|
class TokenGenerator
|
8
|
-
def initialize(key_generator, digest="SHA256")
|
5
|
+
def initialize(key_generator, digest = "SHA256")
|
9
6
|
@key_generator = key_generator
|
10
7
|
@digest = digest
|
11
8
|
end
|
@@ -30,41 +27,4 @@ module Devise
|
|
30
27
|
@key_generator.generate_key("Devise #{column}")
|
31
28
|
end
|
32
29
|
end
|
33
|
-
|
34
|
-
# KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2
|
35
|
-
# It can be used to derive a number of keys for various purposes from a given secret.
|
36
|
-
# This lets Rails applications have a single secure secret, but avoid reusing that
|
37
|
-
# key in multiple incompatible contexts.
|
38
|
-
class KeyGenerator
|
39
|
-
def initialize(secret, options = {})
|
40
|
-
@secret = secret
|
41
|
-
# The default iterations are higher than required for our key derivation uses
|
42
|
-
# on the off chance someone uses this for password storage
|
43
|
-
@iterations = options[:iterations] || 2**16
|
44
|
-
end
|
45
|
-
|
46
|
-
# Returns a derived key suitable for use. The default key_size is chosen
|
47
|
-
# to be compatible with the default settings of ActiveSupport::MessageVerifier.
|
48
|
-
# i.e. OpenSSL::Digest::SHA1#block_length
|
49
|
-
def generate_key(salt, key_size=64)
|
50
|
-
OpenSSL::PKCS5.pbkdf2_hmac_sha1(@secret, salt, @iterations, key_size)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# CachingKeyGenerator is a wrapper around KeyGenerator which allows users to avoid
|
55
|
-
# re-executing the key generation process when it's called using the same salt and
|
56
|
-
# key_size
|
57
|
-
class CachingKeyGenerator
|
58
|
-
def initialize(key_generator)
|
59
|
-
@key_generator = key_generator
|
60
|
-
@cache_keys = ThreadSafe::Cache.new
|
61
|
-
end
|
62
|
-
|
63
|
-
# Returns a derived key suitable for use. The default key_size is chosen
|
64
|
-
# to be compatible with the default settings of ActiveSupport::MessageVerifier.
|
65
|
-
# i.e. OpenSSL::Digest::SHA1#block_length
|
66
|
-
def generate_key(salt, key_size=64)
|
67
|
-
@cache_keys["#{salt}#{key_size}"] ||= @key_generator.generate_key(salt, key_size)
|
68
|
-
end
|
69
|
-
end
|
70
30
|
end
|
data/lib/devise/version.rb
CHANGED
data/lib/devise.rb
CHANGED
@@ -4,25 +4,26 @@ require 'active_support/dependencies'
|
|
4
4
|
require 'orm_adapter'
|
5
5
|
require 'set'
|
6
6
|
require 'securerandom'
|
7
|
+
require 'responders'
|
7
8
|
|
8
9
|
module Devise
|
9
10
|
autoload :Delegator, 'devise/delegator'
|
11
|
+
autoload :Encryptor, 'devise/encryptor'
|
10
12
|
autoload :FailureApp, 'devise/failure_app'
|
11
13
|
autoload :OmniAuth, 'devise/omniauth'
|
12
14
|
autoload :ParameterFilter, 'devise/parameter_filter'
|
13
|
-
autoload :BaseSanitizer, 'devise/parameter_sanitizer'
|
14
15
|
autoload :ParameterSanitizer, 'devise/parameter_sanitizer'
|
15
16
|
autoload :TestHelpers, 'devise/test_helpers'
|
16
17
|
autoload :TimeInflector, 'devise/time_inflector'
|
17
18
|
autoload :TokenGenerator, 'devise/token_generator'
|
18
19
|
|
19
20
|
module Controllers
|
20
|
-
autoload :Helpers,
|
21
|
-
autoload :Rememberable,
|
22
|
-
autoload :ScopedViews,
|
23
|
-
autoload :SignInOut,
|
24
|
-
autoload :StoreLocation,
|
25
|
-
autoload :UrlHelpers,
|
21
|
+
autoload :Helpers, 'devise/controllers/helpers'
|
22
|
+
autoload :Rememberable, 'devise/controllers/rememberable'
|
23
|
+
autoload :ScopedViews, 'devise/controllers/scoped_views'
|
24
|
+
autoload :SignInOut, 'devise/controllers/sign_in_out'
|
25
|
+
autoload :StoreLocation, 'devise/controllers/store_location'
|
26
|
+
autoload :UrlHelpers, 'devise/controllers/url_helpers'
|
26
27
|
end
|
27
28
|
|
28
29
|
module Hooks
|
@@ -34,7 +35,7 @@ module Devise
|
|
34
35
|
end
|
35
36
|
|
36
37
|
module Strategies
|
37
|
-
autoload :Base,
|
38
|
+
autoload :Base, 'devise/strategies/base'
|
38
39
|
autoload :Authenticatable, 'devise/strategies/authenticatable'
|
39
40
|
end
|
40
41
|
|
@@ -52,33 +53,23 @@ module Devise
|
|
52
53
|
# True values used to check params
|
53
54
|
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE']
|
54
55
|
|
56
|
+
# Track the configs that user explicit changed the default value. It is
|
57
|
+
# helpfull to not warn users about default values changing when they willing
|
58
|
+
# changed.
|
59
|
+
mattr_accessor :app_set_configs
|
60
|
+
@@app_set_configs = Set.new
|
61
|
+
|
55
62
|
# Secret key used by the key generator
|
56
63
|
mattr_accessor :secret_key
|
57
64
|
@@secret_key = nil
|
58
65
|
|
59
|
-
[ :allow_insecure_token_lookup,
|
60
|
-
:allow_insecure_sign_in_after_confirmation,
|
61
|
-
:token_authentication_key ].each do |method|
|
62
|
-
class_eval <<-RUBY
|
63
|
-
def self.#{method}
|
64
|
-
ActiveSupport::Deprecation.warn "Devise.#{method} is deprecated " \
|
65
|
-
"and has no effect"
|
66
|
-
end
|
67
|
-
|
68
|
-
def self.#{method}=(val)
|
69
|
-
ActiveSupport::Deprecation.warn "Devise.#{method}= is deprecated " \
|
70
|
-
"and has no effect"
|
71
|
-
end
|
72
|
-
RUBY
|
73
|
-
end
|
74
|
-
|
75
66
|
# Custom domain or key for cookies. Not set by default
|
76
67
|
mattr_accessor :rememberable_options
|
77
68
|
@@rememberable_options = {}
|
78
69
|
|
79
|
-
# The number of times to
|
70
|
+
# The number of times to hash the password.
|
80
71
|
mattr_accessor :stretches
|
81
|
-
@@stretches =
|
72
|
+
@@stretches = 11
|
82
73
|
|
83
74
|
# The default key used when authenticating over http auth.
|
84
75
|
mattr_accessor :http_authentication_key
|
@@ -86,7 +77,7 @@ module Devise
|
|
86
77
|
|
87
78
|
# Keys used when authenticating a user.
|
88
79
|
mattr_accessor :authentication_keys
|
89
|
-
@@authentication_keys = [
|
80
|
+
@@authentication_keys = [:email]
|
90
81
|
|
91
82
|
# Request keys used when authenticating a user.
|
92
83
|
mattr_accessor :request_keys
|
@@ -94,12 +85,23 @@ module Devise
|
|
94
85
|
|
95
86
|
# Keys that should be case-insensitive.
|
96
87
|
mattr_accessor :case_insensitive_keys
|
97
|
-
@@case_insensitive_keys = [
|
88
|
+
@@case_insensitive_keys = [:email]
|
98
89
|
|
99
90
|
# Keys that should have whitespace stripped.
|
100
|
-
|
91
|
+
# TODO: 4.1 Do: @@strip_whitespace_keys = [:email]
|
92
|
+
mattr_reader :strip_whitespace_keys
|
101
93
|
@@strip_whitespace_keys = []
|
102
94
|
|
95
|
+
def self.strip_whitespace_keys=(strip_whitespace_keys)
|
96
|
+
app_set_configs << :strip_whitespace_keys
|
97
|
+
@@strip_whitespace_keys = strip_whitespace_keys
|
98
|
+
end
|
99
|
+
|
100
|
+
def strip_whitespace_keys=(strip_whitespace_keys)
|
101
|
+
app_set_configs << :strip_whitespace_keys
|
102
|
+
@@strip_whitespace_keys = strip_whitespace_keys
|
103
|
+
end
|
104
|
+
|
103
105
|
# If http authentication is enabled by default.
|
104
106
|
mattr_accessor :http_authenticatable
|
105
107
|
@@http_authenticatable = false
|
@@ -119,8 +121,19 @@ module Devise
|
|
119
121
|
# Email regex used to validate email formats. It simply asserts that
|
120
122
|
# an one (and only one) @ exists in the given string. This is mainly
|
121
123
|
# to give user feedback and not to assert the e-mail validity.
|
122
|
-
|
123
|
-
|
124
|
+
# TODO: 4.1 Do: @@email_regexp = [/\A[^@\s]+@[^@\s]+\z/]
|
125
|
+
mattr_reader :email_regexp
|
126
|
+
@@email_regexp = /\A[^@\s]+@([^@\s]+\.)+[^@\W]+\z/
|
127
|
+
|
128
|
+
def self.email_regexp=(email_regexp)
|
129
|
+
app_set_configs << :email_regexp
|
130
|
+
@@email_regexp = email_regexp
|
131
|
+
end
|
132
|
+
|
133
|
+
def email_regexp=(email_regexp)
|
134
|
+
app_set_configs << :email_regexp
|
135
|
+
@@email_regexp = email_regexp
|
136
|
+
end
|
124
137
|
|
125
138
|
# Range validation for password length
|
126
139
|
mattr_accessor :password_length
|
@@ -134,6 +147,10 @@ module Devise
|
|
134
147
|
mattr_accessor :extend_remember_period
|
135
148
|
@@extend_remember_period = false
|
136
149
|
|
150
|
+
# If true, all the remember me tokens are going to be invalidated when the user signs out.
|
151
|
+
mattr_accessor :expire_all_remember_me_on_sign_out
|
152
|
+
@@expire_all_remember_me_on_sign_out = true
|
153
|
+
|
137
154
|
# Time interval you can access your account before confirming your account.
|
138
155
|
# nil - allows unconfirmed access for unlimited time
|
139
156
|
mattr_accessor :allow_unconfirmed_access_for
|
@@ -145,25 +162,36 @@ module Devise
|
|
145
162
|
|
146
163
|
# Defines which key will be used when confirming an account.
|
147
164
|
mattr_accessor :confirmation_keys
|
148
|
-
@@confirmation_keys = [
|
165
|
+
@@confirmation_keys = [:email]
|
149
166
|
|
150
167
|
# Defines if email should be reconfirmable.
|
151
168
|
# False by default for backwards compatibility.
|
152
|
-
|
169
|
+
# TODO: 4.1 Do: @@reconfirmable = true
|
170
|
+
mattr_reader :reconfirmable
|
153
171
|
@@reconfirmable = false
|
154
172
|
|
173
|
+
def self.reconfirmable=(reconfirmable)
|
174
|
+
app_set_configs << :reconfirmable
|
175
|
+
@@reconfirmable = reconfirmable
|
176
|
+
end
|
177
|
+
|
178
|
+
def reconfirmable=(reconfirmable)
|
179
|
+
app_set_configs << :reconfirmable
|
180
|
+
@@reconfirmable = reconfirmable
|
181
|
+
end
|
182
|
+
|
155
183
|
# Time interval to timeout the user session without activity.
|
156
184
|
mattr_accessor :timeout_in
|
157
185
|
@@timeout_in = 30.minutes
|
158
186
|
|
159
|
-
#
|
160
|
-
mattr_accessor :expire_auth_token_on_timeout
|
161
|
-
@@expire_auth_token_on_timeout = false
|
162
|
-
|
163
|
-
# Used to encrypt password. Please generate one with rake secret.
|
187
|
+
# Used to hash the password. Please generate one with rake secret.
|
164
188
|
mattr_accessor :pepper
|
165
189
|
@@pepper = nil
|
166
190
|
|
191
|
+
# Used to enable sending notification to user when their password is changed
|
192
|
+
mattr_accessor :send_password_change_notification
|
193
|
+
@@send_password_change_notification = false
|
194
|
+
|
167
195
|
# Scoped views. Since it relies on fallbacks to render default views, it's
|
168
196
|
# turned off by default.
|
169
197
|
mattr_accessor :scoped_views
|
@@ -176,7 +204,7 @@ module Devise
|
|
176
204
|
|
177
205
|
# Defines which key will be used when locking and unlocking an account
|
178
206
|
mattr_accessor :unlock_keys
|
179
|
-
@@unlock_keys = [
|
207
|
+
@@unlock_keys = [:email]
|
180
208
|
|
181
209
|
# Defines which strategy can be used to unlock an account.
|
182
210
|
# Values: :email, :time, :both
|
@@ -193,12 +221,16 @@ module Devise
|
|
193
221
|
|
194
222
|
# Defines which key will be used when recovering the password for an account
|
195
223
|
mattr_accessor :reset_password_keys
|
196
|
-
@@reset_password_keys = [
|
224
|
+
@@reset_password_keys = [:email]
|
197
225
|
|
198
226
|
# Time interval you can reset your password with a reset password key
|
199
227
|
mattr_accessor :reset_password_within
|
200
228
|
@@reset_password_within = 6.hours
|
201
229
|
|
230
|
+
# When set to false, resetting a password does not automatically sign in a user
|
231
|
+
mattr_accessor :sign_in_after_reset_password
|
232
|
+
@@sign_in_after_reset_password = true
|
233
|
+
|
202
234
|
# The default scope which is used by warden.
|
203
235
|
mattr_accessor :default_scope
|
204
236
|
@@default_scope = nil
|
@@ -208,9 +240,20 @@ module Devise
|
|
208
240
|
@@mailer_sender = nil
|
209
241
|
|
210
242
|
# Skip session storage for the following strategies
|
211
|
-
|
243
|
+
# TODO: 4.1 Do: @@skip_session_storage = [:http_auth]
|
244
|
+
mattr_reader :skip_session_storage
|
212
245
|
@@skip_session_storage = []
|
213
246
|
|
247
|
+
def self.skip_session_storage=(skip_session_storage)
|
248
|
+
app_set_configs << :skip_session_storage
|
249
|
+
@@skip_session_storage = skip_session_storage
|
250
|
+
end
|
251
|
+
|
252
|
+
def skip_session_storage=(skip_session_storage)
|
253
|
+
app_set_configs << :skip_session_storage
|
254
|
+
@@skip_session_storage = skip_session_storage
|
255
|
+
end
|
256
|
+
|
214
257
|
# Which formats should be treated as navigational.
|
215
258
|
mattr_accessor :navigational_formats
|
216
259
|
@@navigational_formats = ["*/*", :html]
|
@@ -220,9 +263,20 @@ module Devise
|
|
220
263
|
@@sign_out_all_scopes = true
|
221
264
|
|
222
265
|
# The default method used while signing out
|
223
|
-
|
266
|
+
# TODO: 4.1 Do: @@sign_out_via = :delete
|
267
|
+
mattr_reader :sign_out_via
|
224
268
|
@@sign_out_via = :get
|
225
269
|
|
270
|
+
def self.sign_out_via=(sign_out_via)
|
271
|
+
app_set_configs << :sign_out_via
|
272
|
+
@@sign_out_via = sign_out_via
|
273
|
+
end
|
274
|
+
|
275
|
+
def sign_out_via=(sign_out_via)
|
276
|
+
app_set_configs << :sign_out_via
|
277
|
+
@@sign_out_via = sign_out_via
|
278
|
+
end
|
279
|
+
|
226
280
|
# The parent controller all Devise controllers inherits from.
|
227
281
|
# Defaults to ApplicationController. This should be set early
|
228
282
|
# in the initialization process and should be set to a string.
|
@@ -241,7 +295,7 @@ module Devise
|
|
241
295
|
mattr_accessor :router_name
|
242
296
|
@@router_name = nil
|
243
297
|
|
244
|
-
# Set the
|
298
|
+
# Set the OmniAuth path prefix so it can be overridden when
|
245
299
|
# Devise is used in a mountable engine
|
246
300
|
mattr_accessor :omniauth_path_prefix
|
247
301
|
@@omniauth_path_prefix = nil
|
@@ -256,7 +310,7 @@ module Devise
|
|
256
310
|
mattr_reader :mappings
|
257
311
|
@@mappings = ActiveSupport::OrderedHash.new
|
258
312
|
|
259
|
-
#
|
313
|
+
# OmniAuth configurations.
|
260
314
|
mattr_reader :omniauth_configs
|
261
315
|
@@omniauth_configs = ActiveSupport::OrderedHash.new
|
262
316
|
|
@@ -268,7 +322,7 @@ module Devise
|
|
268
322
|
# Private methods to interface with Warden.
|
269
323
|
mattr_accessor :warden_config
|
270
324
|
@@warden_config = nil
|
271
|
-
@@
|
325
|
+
@@warden_config_blocks = []
|
272
326
|
|
273
327
|
# When true, enter in paranoid mode to avoid user enumeration.
|
274
328
|
mattr_accessor :paranoid
|
@@ -276,16 +330,42 @@ module Devise
|
|
276
330
|
|
277
331
|
# When true, warn user if they just used next-to-last attempt of authentication
|
278
332
|
mattr_accessor :last_attempt_warning
|
279
|
-
@@last_attempt_warning =
|
333
|
+
@@last_attempt_warning = true
|
280
334
|
|
281
335
|
# Stores the token generator
|
282
336
|
mattr_accessor :token_generator
|
283
337
|
@@token_generator = nil
|
284
338
|
|
285
|
-
# Default way to
|
339
|
+
# Default way to set up Devise. Run rails generate devise_install to create
|
286
340
|
# a fresh initializer with all configuration values.
|
287
341
|
def self.setup
|
288
342
|
yield self
|
343
|
+
|
344
|
+
warn_default_config_changed(:email_regexp, '/\A[^@\s]+@([^@\s]+\.)+[^@\W]+\z/', '/\A[^@\s]+@[^@\s]+\z/')
|
345
|
+
warn_default_config_changed(:reconfirmable, 'false', 'true')
|
346
|
+
warn_default_config_changed(:sign_out_via, ':get', ':delete')
|
347
|
+
warn_default_config_changed(:skip_session_storage, '[]', '[:http_auth]')
|
348
|
+
warn_default_config_changed(:strip_whitespace_keys, '[]', '[:email]')
|
349
|
+
end
|
350
|
+
|
351
|
+
def self.warn_default_config_changed(config, current_default, new_default)
|
352
|
+
unless app_set_configs.include?(config)
|
353
|
+
warn = <<-MESSAGE.strip_heredoc
|
354
|
+
[Devise] config.#{config} will have a new default on Devise 4.1
|
355
|
+
To keep the current behavior please set in your config/initializers/devise.rb the following:
|
356
|
+
|
357
|
+
Devise.setup do |config|
|
358
|
+
config.#{config} = #{current_default}
|
359
|
+
end
|
360
|
+
|
361
|
+
If you want to use the new default:
|
362
|
+
|
363
|
+
Devise.setup do |config|
|
364
|
+
config.#{config} = #{new_default}
|
365
|
+
end
|
366
|
+
MESSAGE
|
367
|
+
ActiveSupport::Deprecation.warn(warn)
|
368
|
+
end
|
289
369
|
end
|
290
370
|
|
291
371
|
class Getter
|
@@ -335,7 +415,12 @@ module Devise
|
|
335
415
|
mapping
|
336
416
|
end
|
337
417
|
|
338
|
-
#
|
418
|
+
# Register available devise modules. For the standard modules that Devise provides, this method is
|
419
|
+
# called from lib/devise/modules.rb. Third-party modules need to be added explicitly using this method.
|
420
|
+
#
|
421
|
+
# Note that adding a module using this method does not cause it to be used in the authentication
|
422
|
+
# process. That requires that the module be listed in the arguments passed to the 'devise' method
|
423
|
+
# in the model class definition.
|
339
424
|
#
|
340
425
|
# == Options:
|
341
426
|
#
|
@@ -343,6 +428,7 @@ module Devise
|
|
343
428
|
# +controller+ - Symbol representing the name of an existing or custom *controller* for this module.
|
344
429
|
# +route+ - Symbol representing the named *route* helper for this module.
|
345
430
|
# +strategy+ - Symbol representing if this module got a custom *strategy*.
|
431
|
+
# +insert_at+ - Integer representing the order in which this module's model will be included
|
346
432
|
#
|
347
433
|
# All values, except :model, accept also a boolean and will have the same name as the given module
|
348
434
|
# name.
|
@@ -352,10 +438,12 @@ module Devise
|
|
352
438
|
# Devise.add_module(:party_module)
|
353
439
|
# Devise.add_module(:party_module, strategy: true, controller: :sessions)
|
354
440
|
# Devise.add_module(:party_module, model: 'party_module/model')
|
441
|
+
# Devise.add_module(:party_module, insert_at: 0)
|
355
442
|
#
|
356
443
|
def self.add_module(module_name, options = {})
|
357
|
-
|
358
|
-
|
444
|
+
options.assert_valid_keys(:strategy, :model, :controller, :route, :no_input, :insert_at)
|
445
|
+
|
446
|
+
ALL.insert (options[:insert_at] || -1), module_name
|
359
447
|
|
360
448
|
if strategy = options[:strategy]
|
361
449
|
strategy = (strategy == true ? module_name : strategy)
|
@@ -400,7 +488,7 @@ module Devise
|
|
400
488
|
# Sets warden configuration using a block that will be invoked on warden
|
401
489
|
# initialization.
|
402
490
|
#
|
403
|
-
# Devise.
|
491
|
+
# Devise.setup do |config|
|
404
492
|
# config.allow_unconfirmed_access_for = 2.days
|
405
493
|
#
|
406
494
|
# config.warden do |manager|
|
@@ -409,10 +497,10 @@ module Devise
|
|
409
497
|
# end
|
410
498
|
# end
|
411
499
|
def self.warden(&block)
|
412
|
-
@@
|
500
|
+
@@warden_config_blocks << block
|
413
501
|
end
|
414
502
|
|
415
|
-
# Specify an
|
503
|
+
# Specify an OmniAuth provider.
|
416
504
|
#
|
417
505
|
# config.omniauth :github, APP_ID, APP_SECRET
|
418
506
|
#
|
@@ -440,8 +528,8 @@ module Devise
|
|
440
528
|
Devise::Controllers::UrlHelpers.generate_helpers!
|
441
529
|
end
|
442
530
|
|
443
|
-
# A method used internally to setup warden manager
|
444
|
-
#
|
531
|
+
# A method used internally to complete the setup of warden manager after routes are loaded.
|
532
|
+
# See lib/devise/rails/routes.rb - ActionDispatch::Routing::RouteSet#finalize_with_devise!
|
445
533
|
def self.configure_warden! #:nodoc:
|
446
534
|
@@warden_configured ||= begin
|
447
535
|
warden_config.failure_app = Devise::Delegator.new
|
@@ -463,14 +551,18 @@ module Devise
|
|
463
551
|
end
|
464
552
|
end
|
465
553
|
|
466
|
-
@@
|
554
|
+
@@warden_config_blocks.map { |block| block.call Devise.warden_config }
|
467
555
|
true
|
468
556
|
end
|
469
557
|
end
|
470
558
|
|
471
559
|
# Generate a friendly string randomly to be used as token.
|
472
|
-
|
473
|
-
|
560
|
+
# By default, length is 20 characters.
|
561
|
+
def self.friendly_token(length = 20)
|
562
|
+
# To calculate real characters, we must perform this operation.
|
563
|
+
# See SecureRandom.urlsafe_base64
|
564
|
+
rlength = (length * 3) / 4
|
565
|
+
SecureRandom.urlsafe_base64(rlength).tr('lIO0', 'sxyz')
|
474
566
|
end
|
475
567
|
|
476
568
|
# constant-time comparison algorithm to prevent timing attacks
|
@@ -11,9 +11,9 @@ module ActiveRecord
|
|
11
11
|
|
12
12
|
def copy_devise_migration
|
13
13
|
if (behavior == :invoke && model_exists?) || (behavior == :revoke && migration_exists?(table_name))
|
14
|
-
migration_template "migration_existing.rb", "db/migrate/add_devise_to_#{table_name}.rb"
|
14
|
+
migration_template "migration_existing.rb", "db/migrate/add_devise_to_#{table_name}.rb", migration_version: migration_version
|
15
15
|
else
|
16
|
-
migration_template "migration.rb", "db/migrate/devise_create_#{table_name}.rb"
|
16
|
+
migration_template "migration.rb", "db/migrate/devise_create_#{table_name}.rb", migration_version: migration_version
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -53,8 +53,8 @@ module ActiveRecord
|
|
53
53
|
t.integer :sign_in_count, default: 0, null: false
|
54
54
|
t.datetime :current_sign_in_at
|
55
55
|
t.datetime :last_sign_in_at
|
56
|
-
t
|
57
|
-
t
|
56
|
+
t.#{ip_column} :current_sign_in_ip
|
57
|
+
t.#{ip_column} :last_sign_in_ip
|
58
58
|
|
59
59
|
## Confirmable
|
60
60
|
# t.string :confirmation_token
|
@@ -68,6 +68,30 @@ module ActiveRecord
|
|
68
68
|
# t.datetime :locked_at
|
69
69
|
RUBY
|
70
70
|
end
|
71
|
+
|
72
|
+
def ip_column
|
73
|
+
# Padded with spaces so it aligns nicely with the rest of the columns.
|
74
|
+
"%-8s" % (inet? ? "inet" : "string")
|
75
|
+
end
|
76
|
+
|
77
|
+
def inet?
|
78
|
+
postgresql?
|
79
|
+
end
|
80
|
+
|
81
|
+
def rails5?
|
82
|
+
Rails.version.start_with? '5'
|
83
|
+
end
|
84
|
+
|
85
|
+
def postgresql?
|
86
|
+
config = ActiveRecord::Base.configurations[Rails.env]
|
87
|
+
config && config['adapter'] == 'postgresql'
|
88
|
+
end
|
89
|
+
|
90
|
+
def migration_version
|
91
|
+
if rails5?
|
92
|
+
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
93
|
+
end
|
94
|
+
end
|
71
95
|
end
|
72
96
|
end
|
73
97
|
end
|
@@ -1,13 +1,13 @@
|
|
1
|
-
class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration
|
1
|
+
class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
|
2
2
|
def change
|
3
|
-
create_table
|
3
|
+
create_table :<%= table_name %> do |t|
|
4
4
|
<%= migration_data -%>
|
5
5
|
|
6
6
|
<% attributes.each do |attribute| -%>
|
7
7
|
t.<%= attribute.type %> :<%= attribute.name %>
|
8
8
|
<% end -%>
|
9
9
|
|
10
|
-
t.timestamps
|
10
|
+
t.timestamps null: false
|
11
11
|
end
|
12
12
|
|
13
13
|
add_index :<%= table_name %>, :email, unique: true
|
@@ -1,6 +1,6 @@
|
|
1
|
-
class AddDeviseTo<%= table_name.camelize %> < ActiveRecord::Migration
|
1
|
+
class AddDeviseTo<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
|
2
2
|
def self.up
|
3
|
-
change_table
|
3
|
+
change_table :<%= table_name %> do |t|
|
4
4
|
<%= migration_data -%>
|
5
5
|
|
6
6
|
<% attributes.each do |attribute| -%>
|
@@ -8,7 +8,7 @@ class AddDeviseTo<%= table_name.camelize %> < ActiveRecord::Migration
|
|
8
8
|
<% end -%>
|
9
9
|
|
10
10
|
# Uncomment below if timestamps were not included in your original model.
|
11
|
-
# t.timestamps
|
11
|
+
# t.timestamps null: false
|
12
12
|
end
|
13
13
|
|
14
14
|
add_index :<%= table_name %>, :email, unique: true
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
module Devise
|
4
|
+
module Generators
|
5
|
+
class ControllersGenerator < Rails::Generators::Base
|
6
|
+
CONTROLLERS = %w(confirmations passwords registrations sessions unlocks omniauth_callbacks).freeze
|
7
|
+
|
8
|
+
desc <<-DESC.strip_heredoc
|
9
|
+
Create inherited Devise controllers in your app/controllers folder.
|
10
|
+
|
11
|
+
Use -c to specify which controller you want to overwrite.
|
12
|
+
If you do no specify a controller, all controllers will be created.
|
13
|
+
For example:
|
14
|
+
|
15
|
+
rails generate devise:controllers users -c=sessions
|
16
|
+
|
17
|
+
This will create a controller class at app/controllers/users/sessions_controller.rb like this:
|
18
|
+
|
19
|
+
class Users::ConfirmationsController < Devise::ConfirmationsController
|
20
|
+
content...
|
21
|
+
end
|
22
|
+
DESC
|
23
|
+
|
24
|
+
source_root File.expand_path("../../templates/controllers", __FILE__)
|
25
|
+
argument :scope, required: true,
|
26
|
+
desc: "The scope to create controllers in, e.g. users, admins"
|
27
|
+
class_option :controllers, aliases: "-c", type: :array,
|
28
|
+
desc: "Select specific controllers to generate (#{CONTROLLERS.join(', ')})"
|
29
|
+
|
30
|
+
def create_controllers
|
31
|
+
@scope_prefix = scope.blank? ? '' : (scope.camelize + '::')
|
32
|
+
controllers = options[:controllers] || CONTROLLERS
|
33
|
+
controllers.each do |name|
|
34
|
+
template "#{name}_controller.rb",
|
35
|
+
"app/controllers/#{scope}/#{name}_controller.rb"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def show_readme
|
40
|
+
readme "README" if behavior == :invoke
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|