loyal_devise 2.1.2 → 2.1.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.
- data/.gitignore +2 -0
- data/.travis.yml +14 -9
- data/.yardopts +9 -0
- data/CHANGELOG.rdoc +60 -5
- data/CONTRIBUTING.md +4 -2
- data/Gemfile +7 -7
- data/Gemfile.lock +107 -101
- data/MIT-LICENSE +1 -1
- data/README.md +110 -48
- data/Rakefile +1 -0
- data/app/controllers/devise/confirmations_controller.rb +2 -4
- data/app/controllers/devise/omniauth_callbacks_controller.rb +0 -1
- data/app/controllers/devise/passwords_controller.rb +16 -5
- data/app/controllers/devise/registrations_controller.rb +13 -7
- data/app/controllers/devise/sessions_controller.rb +6 -6
- data/app/controllers/devise/unlocks_controller.rb +3 -4
- data/app/controllers/devise_controller.rb +12 -33
- data/app/helpers/devise_helper.rb +0 -1
- data/app/mailers/devise/mailer.rb +7 -8
- data/app/views/devise/mailer/confirmation_instructions.html.erb +1 -1
- data/app/views/devise/mailer/reset_password_instructions.html.erb +1 -1
- data/app/views/devise/registrations/edit.html.erb +5 -1
- data/config/locales/en.yml +48 -48
- data/devise.gemspec +6 -6
- data/devise.png +0 -0
- data/gemfiles/{Gemfile.rails-3.1.x → Gemfile.rails-3.2.x} +8 -12
- data/gemfiles/Gemfile.rails-3.2.x.lock +156 -0
- data/lib/devise.rb +34 -11
- data/lib/devise/controllers/helpers.rb +33 -7
- data/lib/devise/controllers/rememberable.rb +6 -3
- data/lib/devise/controllers/scoped_views.rb +1 -2
- data/lib/devise/controllers/url_helpers.rb +0 -1
- data/lib/devise/delegator.rb +0 -1
- data/lib/devise/failure_app.rb +8 -2
- data/lib/devise/hooks/activatable.rb +1 -2
- data/lib/devise/hooks/forgetable.rb +0 -1
- data/lib/devise/hooks/lockable.rb +1 -2
- data/lib/devise/hooks/rememberable.rb +1 -2
- data/lib/devise/hooks/timeoutable.rb +0 -1
- data/lib/devise/hooks/trackable.rb +0 -1
- data/lib/devise/mailers/helpers.rb +18 -14
- data/lib/devise/mapping.rb +6 -7
- data/lib/devise/models.rb +0 -1
- data/lib/devise/models/authenticatable.rb +50 -27
- data/lib/devise/models/confirmable.rb +37 -16
- data/lib/devise/models/database_authenticatable.rb +17 -3
- data/lib/devise/models/lockable.rb +1 -2
- data/lib/devise/models/omniauthable.rb +1 -2
- data/lib/devise/models/recoverable.rb +10 -6
- data/lib/devise/models/registerable.rb +0 -1
- data/lib/devise/models/rememberable.rb +1 -2
- data/lib/devise/models/timeoutable.rb +1 -2
- data/lib/devise/models/token_authenticatable.rb +0 -1
- data/lib/devise/models/trackable.rb +0 -1
- data/lib/devise/models/validatable.rb +0 -1
- data/lib/devise/modules.rb +1 -2
- data/lib/devise/omniauth.rb +0 -1
- data/lib/devise/omniauth/config.rb +0 -1
- data/lib/devise/omniauth/url_helpers.rb +0 -1
- data/lib/devise/orm/active_record.rb +1 -2
- data/lib/devise/orm/mongoid.rb +1 -2
- data/lib/devise/{param_filter.rb → parameter_filter.rb} +10 -12
- data/lib/devise/parameter_sanitizer.rb +59 -0
- data/lib/devise/rails.rb +0 -1
- data/lib/devise/rails/routes.rb +22 -18
- data/lib/devise/rails/warden_compat.rb +0 -30
- data/lib/devise/strategies/authenticatable.rb +8 -6
- data/lib/devise/strategies/base.rb +1 -2
- data/lib/devise/strategies/database_authenticatable.rb +1 -2
- data/lib/devise/strategies/rememberable.rb +1 -2
- data/lib/devise/strategies/token_authenticatable.rb +38 -4
- data/lib/devise/test_helpers.rb +0 -1
- data/lib/devise/time_inflector.rb +1 -2
- data/lib/devise/version.rb +1 -2
- data/lib/generators/active_record/devise_generator.rb +1 -5
- data/lib/generators/active_record/templates/migration.rb +0 -1
- data/lib/generators/active_record/templates/migration_existing.rb +0 -1
- data/lib/generators/devise/devise_generator.rb +0 -1
- data/lib/generators/devise/install_generator.rb +0 -1
- data/lib/generators/devise/orm_helpers.rb +1 -2
- data/lib/generators/devise/views_generator.rb +8 -3
- data/lib/generators/mongoid/devise_generator.rb +1 -2
- data/lib/generators/templates/README +1 -1
- data/lib/generators/templates/devise.rb +10 -5
- data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
- data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +1 -0
- data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +6 -1
- data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +1 -0
- data/loyal_devise.gemspec +27 -0
- data/test/controllers/custom_strategy_test.rb +0 -1
- data/test/controllers/helpers_test.rb +0 -1
- data/test/controllers/internal_helpers_test.rb +13 -4
- data/test/controllers/passwords_controller_test.rb +32 -0
- data/test/controllers/sessions_controller_test.rb +28 -1
- data/test/controllers/url_helpers_test.rb +0 -1
- data/test/delegator_test.rb +0 -1
- data/test/devise_test.rb +12 -2
- data/test/failure_app_test.rb +3 -4
- data/test/generators/active_record_generator_test.rb +1 -4
- data/test/generators/devise_generator_test.rb +0 -1
- data/test/generators/install_generator_test.rb +0 -1
- data/test/generators/mongoid_generator_test.rb +0 -1
- data/test/generators/views_generator_test.rb +16 -2
- data/test/helpers/devise_helper_test.rb +1 -2
- data/test/integration/authenticatable_test.rb +92 -27
- data/test/integration/confirmable_test.rb +7 -7
- data/test/integration/database_authenticatable_test.rb +8 -7
- data/test/integration/http_authenticatable_test.rb +19 -2
- data/test/integration/lockable_test.rb +1 -2
- data/test/integration/omniauthable_test.rb +2 -3
- data/test/integration/recoverable_test.rb +40 -12
- data/test/integration/registerable_test.rb +17 -14
- data/test/integration/rememberable_test.rb +16 -10
- data/test/integration/timeoutable_test.rb +11 -2
- data/test/integration/token_authenticatable_test.rb +45 -2
- data/test/integration/trackable_test.rb +1 -2
- data/test/mailers/confirmation_instructions_test.rb +11 -3
- data/test/mailers/reset_password_instructions_test.rb +11 -3
- data/test/mailers/unlock_instructions_test.rb +11 -2
- data/test/mapping_test.rb +0 -1
- data/test/models/authenticatable_test.rb +6 -1
- data/test/models/confirmable_test.rb +53 -2
- data/test/models/database_authenticatable_test.rb +57 -21
- data/test/models/lockable_test.rb +1 -2
- data/test/models/omniauthable_test.rb +0 -1
- data/test/models/recoverable_test.rb +21 -5
- data/test/models/registerable_test.rb +0 -1
- data/test/models/rememberable_test.rb +4 -4
- data/test/models/serializable_test.rb +8 -8
- data/test/models/timeoutable_test.rb +0 -1
- data/test/models/token_authenticatable_test.rb +0 -1
- data/test/models/trackable_test.rb +0 -1
- data/test/models/validatable_test.rb +16 -6
- data/test/models_test.rb +7 -24
- data/test/omniauth/config_test.rb +1 -2
- data/test/omniauth/url_helpers_test.rb +4 -2
- data/test/orm/active_record.rb +1 -1
- data/test/orm/mongoid.rb +2 -4
- data/test/parameter_sanitizer_test.rb +51 -0
- data/test/rails_app/Rakefile +0 -4
- data/test/rails_app/app/active_record/admin.rb +0 -1
- data/test/rails_app/app/active_record/shim.rb +1 -2
- data/test/rails_app/app/active_record/user.rb +0 -1
- data/test/rails_app/app/controllers/admins/sessions_controller.rb +1 -2
- data/test/rails_app/app/controllers/admins_controller.rb +0 -1
- data/test/rails_app/app/controllers/application_controller.rb +1 -1
- data/test/rails_app/app/controllers/home_controller.rb +0 -1
- data/test/rails_app/app/controllers/publisher/registrations_controller.rb +1 -2
- data/test/rails_app/app/controllers/publisher/sessions_controller.rb +1 -2
- data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +1 -2
- data/test/rails_app/app/controllers/users_controller.rb +8 -1
- data/test/rails_app/app/helpers/application_helper.rb +0 -1
- data/test/rails_app/app/mailers/users/mailer.rb +4 -1
- data/test/rails_app/app/mongoid/admin.rb +4 -3
- data/test/rails_app/app/mongoid/shim.rb +3 -5
- data/test/rails_app/app/mongoid/user.rb +2 -3
- 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 +1 -3
- data/test/rails_app/config/boot.rb +3 -4
- data/test/rails_app/config/environment.rb +2 -3
- data/test/rails_app/config/environments/development.rb +23 -8
- data/test/rails_app/config/environments/production.rb +68 -18
- data/test/rails_app/config/environments/test.rb +18 -16
- data/test/rails_app/config/initializers/backtrace_silencers.rb +0 -1
- data/test/rails_app/config/initializers/devise.rb +0 -1
- data/test/rails_app/config/initializers/inflections.rb +0 -1
- data/test/rails_app/config/initializers/secret_token.rb +8 -3
- data/test/rails_app/config/initializers/session_store.rb +1 -0
- data/test/rails_app/config/routes.rb +20 -17
- data/test/rails_app/db/migrate/20100401102949_create_tables.rb +0 -1
- data/test/rails_app/db/schema.rb +0 -1
- data/test/rails_app/lib/shared_admin.rb +0 -1
- data/test/rails_app/lib/shared_user.rb +0 -2
- data/test/routes_test.rb +22 -21
- data/test/support/assertions.rb +0 -1
- data/test/support/helpers.rb +1 -2
- data/test/support/integration.rb +0 -1
- data/test/support/webrat/integrations/rails.rb +0 -1
- data/test/test_helper.rb +8 -2
- data/test/test_helpers_test.rb +0 -1
- data/test/test_models.rb +26 -0
- metadata +65 -27
- data/gemfiles/Gemfile.rails-3.1.x.lock +0 -167
- data/test/indifferent_hash.rb +0 -34
- data/test/rails_app/script/rails +0 -10
data/lib/devise/delegator.rb
CHANGED
data/lib/devise/failure_app.rb
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
|
2
1
|
require "action_controller/metal"
|
|
3
2
|
|
|
4
3
|
module Devise
|
|
@@ -79,7 +78,14 @@ module Devise
|
|
|
79
78
|
def redirect_url
|
|
80
79
|
if warden_message == :timeout
|
|
81
80
|
flash[:timedout] = true
|
|
82
|
-
|
|
81
|
+
|
|
82
|
+
path = if request.get?
|
|
83
|
+
attempted_path
|
|
84
|
+
else
|
|
85
|
+
request.referrer
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
path || scope_path
|
|
83
89
|
else
|
|
84
90
|
scope_path
|
|
85
91
|
end
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
|
2
1
|
# Deny user access whenever his account is not active yet. All strategies that inherits from
|
|
3
2
|
# Devise::Strategies::Authenticatable and uses the validate already check if the user is active_for_authentication?
|
|
4
3
|
# before actively signing him in. However, we need this as hook to validate the user activity
|
|
@@ -9,4 +8,4 @@ Warden::Manager.after_set_user do |record, warden, options|
|
|
|
9
8
|
warden.logout(scope)
|
|
10
9
|
throw :warden, :scope => scope, :message => record.inactive_message
|
|
11
10
|
end
|
|
12
|
-
end
|
|
11
|
+
end
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
|
2
1
|
# After each sign in, if resource responds to failed_attempts, sets it to 0
|
|
3
2
|
# This is only triggered when the user is explicitly set (with set_user)
|
|
4
3
|
Warden::Manager.after_set_user :except => :fetch do |record, warden, options|
|
|
5
4
|
if record.respond_to?(:failed_attempts) && warden.authenticated?(options[:scope])
|
|
6
|
-
record.update_attribute(:failed_attempts, 0)
|
|
5
|
+
record.update_attribute(:failed_attempts, 0) unless record.failed_attempts.zero?
|
|
7
6
|
end
|
|
8
7
|
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
|
2
1
|
Warden::Manager.after_set_user :except => :fetch do |record, warden, options|
|
|
3
2
|
scope = options[:scope]
|
|
4
3
|
if record.respond_to?(:remember_me) && record.remember_me && warden.authenticated?(scope)
|
|
5
4
|
Devise::Controllers::Rememberable::Proxy.new(warden).remember_me(record)
|
|
6
5
|
end
|
|
7
|
-
end
|
|
6
|
+
end
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
|
2
1
|
module Devise
|
|
3
2
|
module Mailers
|
|
4
3
|
module Helpers
|
|
@@ -12,9 +11,9 @@ module Devise
|
|
|
12
11
|
protected
|
|
13
12
|
|
|
14
13
|
# Configure default email options
|
|
15
|
-
def devise_mail(record, action)
|
|
14
|
+
def devise_mail(record, action, opts={})
|
|
16
15
|
initialize_from_record(record)
|
|
17
|
-
mail headers_for(action)
|
|
16
|
+
mail headers_for(action, opts)
|
|
18
17
|
end
|
|
19
18
|
|
|
20
19
|
def initialize_from_record(record)
|
|
@@ -26,33 +25,38 @@ module Devise
|
|
|
26
25
|
@devise_mapping ||= Devise.mappings[scope_name]
|
|
27
26
|
end
|
|
28
27
|
|
|
29
|
-
def headers_for(action)
|
|
28
|
+
def headers_for(action, opts)
|
|
30
29
|
headers = {
|
|
31
|
-
:subject =>
|
|
30
|
+
:subject => subject_for(action),
|
|
32
31
|
:to => resource.email,
|
|
33
32
|
:from => mailer_sender(devise_mapping),
|
|
34
33
|
:reply_to => mailer_reply_to(devise_mapping),
|
|
35
|
-
:template_path => template_paths
|
|
36
|
-
|
|
34
|
+
:template_path => template_paths,
|
|
35
|
+
:template_name => action
|
|
36
|
+
}.merge(opts)
|
|
37
37
|
|
|
38
38
|
if resource.respond_to?(:headers_for)
|
|
39
|
+
ActiveSupport::Deprecation.warn "Calling headers_for in the model is no longer supported. " <<
|
|
40
|
+
"Please customize your mailer instead."
|
|
39
41
|
headers.merge!(resource.headers_for(action))
|
|
40
42
|
end
|
|
41
43
|
|
|
44
|
+
@email = headers[:to]
|
|
42
45
|
headers
|
|
43
46
|
end
|
|
44
47
|
|
|
45
48
|
def mailer_reply_to(mapping)
|
|
46
49
|
mailer_sender(mapping, :reply_to)
|
|
47
50
|
end
|
|
48
|
-
|
|
51
|
+
|
|
49
52
|
def mailer_from(mapping)
|
|
50
53
|
mailer_sender(mapping, :from)
|
|
51
54
|
end
|
|
52
55
|
|
|
53
56
|
def mailer_sender(mapping, sender = :from)
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
default_sender = default_params[sender]
|
|
58
|
+
if default_sender.present?
|
|
59
|
+
default_sender.respond_to?(:to_proc) ? instance_eval(&default_sender) : default_sender
|
|
56
60
|
elsif Devise.mailer_sender.is_a?(Proc)
|
|
57
61
|
Devise.mailer_sender.call(mapping.name)
|
|
58
62
|
else
|
|
@@ -61,12 +65,12 @@ module Devise
|
|
|
61
65
|
end
|
|
62
66
|
|
|
63
67
|
def template_paths
|
|
64
|
-
template_path =
|
|
68
|
+
template_path = _prefixes.dup
|
|
65
69
|
template_path.unshift "#{@devise_mapping.scoped_path}/mailer" if self.class.scoped_views?
|
|
66
70
|
template_path
|
|
67
71
|
end
|
|
68
72
|
|
|
69
|
-
# Setup a subject doing an I18n lookup. At first, it
|
|
73
|
+
# Setup a subject doing an I18n lookup. At first, it attempts to set a subject
|
|
70
74
|
# based on the current mapping:
|
|
71
75
|
#
|
|
72
76
|
# en:
|
|
@@ -83,8 +87,8 @@ module Devise
|
|
|
83
87
|
# confirmation_instructions:
|
|
84
88
|
# subject: '...'
|
|
85
89
|
#
|
|
86
|
-
def
|
|
87
|
-
I18n.t(:"#{
|
|
90
|
+
def subject_for(key)
|
|
91
|
+
I18n.t(:"#{devise_mapping.name}_subject", :scope => [:devise, :mailer, key],
|
|
88
92
|
:default => [:subject, key.to_s.humanize])
|
|
89
93
|
end
|
|
90
94
|
end
|
data/lib/devise/mapping.rb
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
|
2
1
|
module Devise
|
|
3
2
|
# Responsible for handling devise mappings and routes configuration. Each
|
|
4
3
|
# resource configured by devise_for in routes is actually creating a mapping
|
|
@@ -30,17 +29,17 @@ module Devise
|
|
|
30
29
|
|
|
31
30
|
# Receives an object and find a scope for it. If a scope cannot be found,
|
|
32
31
|
# raises an error. If a symbol is given, it's considered to be the scope.
|
|
33
|
-
def self.find_scope!(
|
|
34
|
-
case
|
|
32
|
+
def self.find_scope!(obj)
|
|
33
|
+
case obj
|
|
35
34
|
when String, Symbol
|
|
36
|
-
return
|
|
35
|
+
return obj
|
|
37
36
|
when Class
|
|
38
|
-
Devise.mappings.each_value { |m| return m.name if
|
|
37
|
+
Devise.mappings.each_value { |m| return m.name if obj <= m.to }
|
|
39
38
|
else
|
|
40
|
-
Devise.mappings.each_value { |m| return m.name if
|
|
39
|
+
Devise.mappings.each_value { |m| return m.name if obj.is_a?(m.to) }
|
|
41
40
|
end
|
|
42
41
|
|
|
43
|
-
raise "Could not find a valid mapping for #{
|
|
42
|
+
raise "Could not find a valid mapping for #{obj.inspect}"
|
|
44
43
|
end
|
|
45
44
|
|
|
46
45
|
def self.find_by_path!(path, path_type=:fullpath)
|
data/lib/devise/models.rb
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
|
2
1
|
require 'devise/hooks/activatable'
|
|
3
2
|
|
|
4
3
|
module Devise
|
|
@@ -11,15 +10,18 @@ module Devise
|
|
|
11
10
|
#
|
|
12
11
|
# * +authentication_keys+: parameters used for authentication. By default [:email].
|
|
13
12
|
#
|
|
13
|
+
# * +http_authentication_key+: map the username passed via HTTP Auth to this parameter. Defaults to
|
|
14
|
+
# the first element in +authentication_keys+.
|
|
15
|
+
#
|
|
14
16
|
# * +request_keys+: parameters from the request object used for authentication.
|
|
15
17
|
# By specifying a symbol (which should be a request method), it will automatically be
|
|
16
18
|
# passed to find_for_authentication method and considered in your model lookup.
|
|
17
19
|
#
|
|
18
20
|
# For instance, if you set :request_keys to [:subdomain], :subdomain will be considered
|
|
19
|
-
# as key on authentication. This can also be a hash where the value is a boolean
|
|
21
|
+
# as key on authentication. This can also be a hash where the value is a boolean specifying
|
|
20
22
|
# if the value is required or not.
|
|
21
23
|
#
|
|
22
|
-
# * +http_authenticatable+: if this model allows http authentication. By default
|
|
24
|
+
# * +http_authenticatable+: if this model allows http authentication. By default false.
|
|
23
25
|
# It also accepts an array specifying the strategies that should allow http.
|
|
24
26
|
#
|
|
25
27
|
# * +params_authenticatable+: if this model allows authentication through request params. By default true.
|
|
@@ -33,7 +35,7 @@ module Devise
|
|
|
33
35
|
# == active_for_authentication?
|
|
34
36
|
#
|
|
35
37
|
# After authenticating a user and in each request, Devise checks if your model is active by
|
|
36
|
-
# calling model.active_for_authentication?. This method is
|
|
38
|
+
# calling model.active_for_authentication?. This method is overwritten by other devise modules. For instance,
|
|
37
39
|
# :confirmable overwrites .active_for_authentication? to only return true if your model was confirmed.
|
|
38
40
|
#
|
|
39
41
|
# You overwrite this method yourself, but if you do, don't forget to call super:
|
|
@@ -94,10 +96,6 @@ module Devise
|
|
|
94
96
|
def authenticatable_salt
|
|
95
97
|
end
|
|
96
98
|
|
|
97
|
-
def headers_for(name)
|
|
98
|
-
{}
|
|
99
|
-
end
|
|
100
|
-
|
|
101
99
|
array = %w(serializable_hash)
|
|
102
100
|
# to_xml does not call serializable_hash on 3.1
|
|
103
101
|
array << "to_xml" if Rails::VERSION::STRING[0,3] == "3.1"
|
|
@@ -145,14 +143,26 @@ module Devise
|
|
|
145
143
|
#
|
|
146
144
|
# protected
|
|
147
145
|
#
|
|
148
|
-
# def send_devise_notification(notification)
|
|
149
|
-
#
|
|
146
|
+
# def send_devise_notification(notification, opts = {})
|
|
147
|
+
# # if the record is new or changed then delay the
|
|
148
|
+
# # delivery until the after_commit callback otherwise
|
|
149
|
+
# # send now because after_commit will not be called.
|
|
150
|
+
# if new_record? || changed?
|
|
151
|
+
# pending_notifications << [notification, opts]
|
|
152
|
+
# else
|
|
153
|
+
# devise_mailer.send(notification, self, opts).deliver
|
|
154
|
+
# end
|
|
150
155
|
# end
|
|
151
156
|
#
|
|
152
157
|
# def send_pending_notifications
|
|
153
|
-
# pending_notifications.each do |n|
|
|
154
|
-
# devise_mailer.send(n, self).deliver
|
|
158
|
+
# pending_notifications.each do |n, opts|
|
|
159
|
+
# devise_mailer.send(n, self, opts).deliver
|
|
155
160
|
# end
|
|
161
|
+
#
|
|
162
|
+
# # Empty the pending notifications array because the
|
|
163
|
+
# # after_commit hook can be called multiple times which
|
|
164
|
+
# # could cause multiple emails to be sent.
|
|
165
|
+
# pending_notifications.clear
|
|
156
166
|
# end
|
|
157
167
|
#
|
|
158
168
|
# def pending_notifications
|
|
@@ -160,21 +170,35 @@ module Devise
|
|
|
160
170
|
# end
|
|
161
171
|
# end
|
|
162
172
|
#
|
|
163
|
-
def send_devise_notification(notification)
|
|
164
|
-
devise_mailer.send(notification, self).deliver
|
|
173
|
+
def send_devise_notification(notification, opts={})
|
|
174
|
+
devise_mailer.send(notification, self, opts).deliver
|
|
165
175
|
end
|
|
166
176
|
|
|
167
177
|
def downcase_keys
|
|
168
|
-
self.class.case_insensitive_keys.each { |k|
|
|
178
|
+
self.class.case_insensitive_keys.each { |k| apply_to_attribute_or_variable(k, :downcase!) }
|
|
169
179
|
end
|
|
170
180
|
|
|
171
181
|
def strip_whitespace
|
|
172
|
-
self.class.strip_whitespace_keys.each { |k|
|
|
182
|
+
self.class.strip_whitespace_keys.each { |k| apply_to_attribute_or_variable(k, :strip!) }
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def apply_to_attribute_or_variable(attr, method)
|
|
186
|
+
if self[attr]
|
|
187
|
+
self[attr].try(method)
|
|
188
|
+
|
|
189
|
+
# Use respond_to? here to avoid a regression where globally
|
|
190
|
+
# configured strip_whitespace_keys or case_insensitive_keys were
|
|
191
|
+
# attempting to strip! or downcase! when a model didn't have the
|
|
192
|
+
# globally configured key.
|
|
193
|
+
elsif respond_to?(attr)
|
|
194
|
+
send(attr).try(method)
|
|
195
|
+
end
|
|
173
196
|
end
|
|
174
197
|
|
|
175
198
|
module ClassMethods
|
|
176
199
|
Devise::Models.config(self, :authentication_keys, :request_keys, :strip_whitespace_keys,
|
|
177
|
-
:case_insensitive_keys, :http_authenticatable, :params_authenticatable, :skip_session_storage
|
|
200
|
+
:case_insensitive_keys, :http_authenticatable, :params_authenticatable, :skip_session_storage,
|
|
201
|
+
:http_authentication_key)
|
|
178
202
|
|
|
179
203
|
def serialize_into_session(record)
|
|
180
204
|
[record.to_key, record.authenticatable_salt]
|
|
@@ -200,27 +224,26 @@ module Devise
|
|
|
200
224
|
# it may be wrapped as well. For instance, database authenticatable
|
|
201
225
|
# provides a `find_for_database_authentication` that wraps a call to
|
|
202
226
|
# this method. This allows you to customize both database authenticatable
|
|
203
|
-
# or the whole authenticate stack by customize `find_for_authentication.`
|
|
227
|
+
# or the whole authenticate stack by customize `find_for_authentication.`
|
|
204
228
|
#
|
|
205
229
|
# Overwrite to add customized conditions, create a join, or maybe use a
|
|
206
230
|
# namedscope to filter records while authenticating.
|
|
207
231
|
# Example:
|
|
208
232
|
#
|
|
209
|
-
# def self.find_for_authentication(
|
|
210
|
-
#
|
|
211
|
-
# super
|
|
233
|
+
# def self.find_for_authentication(tainted_conditions)
|
|
234
|
+
# find_first_by_auth_conditions(tainted_conditions, :active => true)
|
|
212
235
|
# end
|
|
213
236
|
#
|
|
214
237
|
# Finally, notice that Devise also queries for users in other scenarios
|
|
215
238
|
# besides authentication, for example when retrieving an user to send
|
|
216
239
|
# an e-mail for password reset. In such cases, find_for_authentication
|
|
217
240
|
# is not called.
|
|
218
|
-
def find_for_authentication(
|
|
219
|
-
find_first_by_auth_conditions(
|
|
241
|
+
def find_for_authentication(tainted_conditions)
|
|
242
|
+
find_first_by_auth_conditions(tainted_conditions)
|
|
220
243
|
end
|
|
221
244
|
|
|
222
|
-
def find_first_by_auth_conditions(
|
|
223
|
-
to_adapter.find_first
|
|
245
|
+
def find_first_by_auth_conditions(tainted_conditions, opts={})
|
|
246
|
+
to_adapter.find_first(devise_parameter_filter.filter(tainted_conditions).merge(opts))
|
|
224
247
|
end
|
|
225
248
|
|
|
226
249
|
# Find an initialize a record setting an error if it can't be found.
|
|
@@ -252,8 +275,8 @@ module Devise
|
|
|
252
275
|
|
|
253
276
|
protected
|
|
254
277
|
|
|
255
|
-
def
|
|
256
|
-
@
|
|
278
|
+
def devise_parameter_filter
|
|
279
|
+
@devise_parameter_filter ||= Devise::ParameterFilter.new(case_insensitive_keys, strip_whitespace_keys)
|
|
257
280
|
end
|
|
258
281
|
|
|
259
282
|
# Generate a token by looping and ensuring does not already exist.
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
|
2
1
|
module Devise
|
|
3
2
|
module Models
|
|
4
3
|
# Confirmable is responsible to verify if an account is already confirmed to
|
|
@@ -35,11 +34,18 @@ module Devise
|
|
|
35
34
|
|
|
36
35
|
included do
|
|
37
36
|
before_create :generate_confirmation_token, :if => :confirmation_required?
|
|
38
|
-
after_create :send_on_create_confirmation_instructions, :if => :
|
|
37
|
+
after_create :send_on_create_confirmation_instructions, :if => :send_confirmation_notification?
|
|
39
38
|
before_update :postpone_email_change_until_confirmation, :if => :postpone_email_change?
|
|
40
39
|
after_update :send_confirmation_instructions, :if => :reconfirmation_required?
|
|
41
40
|
end
|
|
42
41
|
|
|
42
|
+
def initialize(*args, &block)
|
|
43
|
+
@bypass_postpone = false
|
|
44
|
+
@reconfirmation_required = false
|
|
45
|
+
@skip_confirmation_notification = false
|
|
46
|
+
super
|
|
47
|
+
end
|
|
48
|
+
|
|
43
49
|
def self.required_fields(klass)
|
|
44
50
|
required_methods = [:confirmation_token, :confirmed_at, :confirmation_sent_at]
|
|
45
51
|
required_methods << :unconfirmed_email if klass.reconfirmable
|
|
@@ -87,8 +93,10 @@ module Devise
|
|
|
87
93
|
self.confirmation_token = nil if reconfirmation_required?
|
|
88
94
|
@reconfirmation_required = false
|
|
89
95
|
|
|
90
|
-
|
|
91
|
-
|
|
96
|
+
ensure_confirmation_token!
|
|
97
|
+
|
|
98
|
+
opts = pending_reconfirmation? ? { :to => unconfirmed_email } : { }
|
|
99
|
+
send_devise_notification(:confirmation_instructions, opts)
|
|
92
100
|
end
|
|
93
101
|
|
|
94
102
|
# Resend confirmation token. This method does not need to generate a new token.
|
|
@@ -98,6 +106,11 @@ module Devise
|
|
|
98
106
|
send_confirmation_instructions
|
|
99
107
|
end
|
|
100
108
|
end
|
|
109
|
+
|
|
110
|
+
# Generate a confirmation token unless already exists and save the record.
|
|
111
|
+
def ensure_confirmation_token!
|
|
112
|
+
generate_confirmation_token! if should_generate_confirmation_token?
|
|
113
|
+
end
|
|
101
114
|
|
|
102
115
|
# Overwrites active_for_authentication? for confirmation
|
|
103
116
|
# by verifying whether a user is active to sign in or not. If the user
|
|
@@ -118,21 +131,22 @@ module Devise
|
|
|
118
131
|
self.confirmed_at = Time.now.utc
|
|
119
132
|
end
|
|
120
133
|
|
|
134
|
+
# Skips sending the confirmation notification email after_create. Unlike
|
|
135
|
+
# #skip_confirmation!, record still requires confirmation.
|
|
136
|
+
def skip_confirmation_notification!
|
|
137
|
+
@skip_confirmation_notification = true
|
|
138
|
+
end
|
|
139
|
+
|
|
121
140
|
# If you don't want reconfirmation to be sent, neither a code
|
|
122
141
|
# to be generated, call skip_reconfirmation!
|
|
123
142
|
def skip_reconfirmation!
|
|
124
143
|
@bypass_postpone = true
|
|
125
144
|
end
|
|
126
145
|
|
|
127
|
-
def headers_for(action)
|
|
128
|
-
headers = super
|
|
129
|
-
if action == :confirmation_instructions && pending_reconfirmation?
|
|
130
|
-
headers[:to] = unconfirmed_email
|
|
131
|
-
end
|
|
132
|
-
headers
|
|
133
|
-
end
|
|
134
|
-
|
|
135
146
|
protected
|
|
147
|
+
def should_generate_confirmation_token?
|
|
148
|
+
confirmation_token.nil? || confirmation_period_expired?
|
|
149
|
+
end
|
|
136
150
|
|
|
137
151
|
# A callback method used to deliver confirmation
|
|
138
152
|
# instructions on creation. This can be overriden
|
|
@@ -165,8 +179,11 @@ module Devise
|
|
|
165
179
|
# # allow_unconfirmed_access_for = 0.days
|
|
166
180
|
# confirmation_period_valid? # will always return false
|
|
167
181
|
#
|
|
182
|
+
# # allow_unconfirmed_access_for = nil
|
|
183
|
+
# confirmation_period_valid? # will always return true
|
|
184
|
+
#
|
|
168
185
|
def confirmation_period_valid?
|
|
169
|
-
confirmation_sent_at && confirmation_sent_at.utc >= self.class.allow_unconfirmed_access_for.ago
|
|
186
|
+
self.class.allow_unconfirmed_access_for.nil? || (confirmation_sent_at && confirmation_sent_at.utc >= self.class.allow_unconfirmed_access_for.ago)
|
|
170
187
|
end
|
|
171
188
|
|
|
172
189
|
# Checks if the user confirmation happens before the token becomes invalid
|
|
@@ -218,13 +235,17 @@ module Devise
|
|
|
218
235
|
end
|
|
219
236
|
|
|
220
237
|
def postpone_email_change?
|
|
221
|
-
postpone = self.class.reconfirmable && email_changed? && !@bypass_postpone
|
|
222
|
-
@bypass_postpone =
|
|
238
|
+
postpone = self.class.reconfirmable && email_changed? && !@bypass_postpone && !self.email.blank?
|
|
239
|
+
@bypass_postpone = false
|
|
223
240
|
postpone
|
|
224
241
|
end
|
|
225
242
|
|
|
226
243
|
def reconfirmation_required?
|
|
227
|
-
self.class.reconfirmable && @reconfirmation_required
|
|
244
|
+
self.class.reconfirmable && @reconfirmation_required && !self.email.blank?
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def send_confirmation_notification?
|
|
248
|
+
confirmation_required? && !@skip_confirmation_notification && !self.email.blank?
|
|
228
249
|
end
|
|
229
250
|
|
|
230
251
|
module ClassMethods
|