devise 3.0.4 → 3.1.0.rc2
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.
- data/{CHANGELOG.rdoc → CHANGELOG.md} +41 -30
- data/Gemfile.lock +14 -13
- data/README.md +12 -11
- data/app/controllers/devise/confirmations_controller.rb +6 -2
- data/app/controllers/devise/registrations_controller.rb +2 -2
- data/app/controllers/devise/sessions_controller.rb +1 -1
- data/app/mailers/devise/mailer.rb +6 -3
- 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/mailer/unlock_instructions.html.erb +1 -1
- data/app/views/devise/shared/_links.erb +2 -2
- data/config/locales/en.yml +2 -2
- data/devise.gemspec +1 -0
- data/gemfiles/Gemfile.rails-3.2.x.lock +45 -42
- data/lib/devise.rb +20 -13
- data/lib/devise/controllers/helpers.rb +1 -0
- data/lib/devise/hooks/rememberable.rb +2 -1
- data/lib/devise/mailers/helpers.rb +0 -6
- data/lib/devise/models.rb +8 -12
- data/lib/devise/models/authenticatable.rb +8 -16
- data/lib/devise/models/confirmable.rb +27 -37
- data/lib/devise/models/lockable.rb +15 -17
- data/lib/devise/models/recoverable.rb +21 -27
- data/lib/devise/models/token_authenticatable.rb +4 -1
- data/lib/devise/parameter_sanitizer.rb +49 -19
- data/lib/devise/rails.rb +7 -11
- data/lib/devise/rails/routes.rb +12 -9
- data/lib/devise/rails/warden_compat.rb +1 -0
- data/lib/devise/strategies/authenticatable.rb +0 -12
- data/lib/devise/strategies/database_authenticatable.rb +3 -6
- data/lib/devise/token_generator.rb +70 -0
- data/lib/devise/version.rb +1 -1
- data/lib/generators/templates/devise.rb +14 -8
- data/test/controllers/passwords_controller_test.rb +3 -4
- data/test/failure_app_test.rb +1 -1
- data/test/integration/confirmable_test.rb +16 -41
- data/test/integration/lockable_test.rb +11 -14
- data/test/integration/recoverable_test.rb +23 -15
- data/test/mailers/confirmation_instructions_test.rb +6 -2
- data/test/mailers/reset_password_instructions_test.rb +6 -2
- data/test/mailers/unlock_instructions_test.rb +6 -2
- data/test/models/confirmable_test.rb +20 -30
- data/test/models/lockable_test.rb +15 -5
- data/test/models/recoverable_test.rb +20 -48
- data/test/models_test.rb +0 -19
- data/test/parameter_sanitizer_test.rb +23 -9
- data/test/rails_app/config/initializers/devise.rb +3 -0
- data/test/rails_app/lib/shared_admin.rb +3 -0
- data/test/rails_app/lib/shared_user.rb +4 -0
- data/test/support/helpers.rb +0 -21
- metadata +23 -7
- data/app/views/devise/_links.erb +0 -3
@@ -79,7 +79,10 @@ module Devise
|
|
79
79
|
|
80
80
|
# Generate a token checking if one does not already exist in the database.
|
81
81
|
def authentication_token
|
82
|
-
|
82
|
+
loop do
|
83
|
+
token = Devise.friendly_token
|
84
|
+
break token unless to_adapter.find_first({ :authentication_token => token })
|
85
|
+
end
|
83
86
|
end
|
84
87
|
|
85
88
|
Devise::Models.config(self, :token_authentication_key, :expire_auth_token_on_timeout)
|
@@ -13,14 +13,25 @@ module Devise
|
|
13
13
|
if block_given?
|
14
14
|
@blocks[kind] = block
|
15
15
|
else
|
16
|
-
|
17
|
-
|
16
|
+
default_for(kind)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def sanitize(kind)
|
21
|
+
if block = @blocks[kind]
|
22
|
+
block.call(default_params)
|
23
|
+
else
|
24
|
+
default_sanitize(kind)
|
18
25
|
end
|
19
26
|
end
|
20
27
|
|
21
28
|
private
|
22
29
|
|
23
|
-
def
|
30
|
+
def default_for(kind)
|
31
|
+
raise ArgumentError, "a block is expected in Devise base sanitizer"
|
32
|
+
end
|
33
|
+
|
34
|
+
def default_sanitize(kind)
|
24
35
|
default_params
|
25
36
|
end
|
26
37
|
|
@@ -30,34 +41,53 @@ module Devise
|
|
30
41
|
end
|
31
42
|
|
32
43
|
class ParameterSanitizer < BaseSanitizer
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
if respond_to?(kind, true)
|
37
|
-
send(kind)
|
38
|
-
else
|
39
|
-
raise NotImplementedError, "Devise Parameter Sanitizer doesn't know how to sanitize parameters for #{kind}"
|
40
|
-
end
|
44
|
+
def initialize(*)
|
45
|
+
super
|
46
|
+
@permitted = Hash.new { |h,k| h[k] = attributes_for(k) }
|
41
47
|
end
|
42
48
|
|
43
|
-
# These are the params used to sign in a user so we don't need to
|
44
|
-
# mass-assign the password param in order to authenticate. Excluding it
|
45
|
-
# here allows us to construct a new user without sensitive information if
|
46
|
-
# authentication fails.
|
47
49
|
def sign_in
|
48
|
-
default_params.permit(
|
50
|
+
default_params.permit self.for(:sign_in)
|
49
51
|
end
|
50
52
|
|
51
53
|
def sign_up
|
52
|
-
default_params.permit(
|
54
|
+
default_params.permit self.for(:sign_up)
|
53
55
|
end
|
54
56
|
|
55
57
|
def account_update
|
56
|
-
default_params.permit(
|
58
|
+
default_params.permit self.for(:account_update)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
# Change for(kind) to return the values in the @permitted
|
64
|
+
# hash, allowing the developer to customize at runtime.
|
65
|
+
def default_for(kind)
|
66
|
+
@permitted[kind] || raise("No sanitizer provided for #{kind}")
|
67
|
+
end
|
68
|
+
|
69
|
+
def default_sanitize(kind)
|
70
|
+
if respond_to?(kind, true)
|
71
|
+
send(kind)
|
72
|
+
else
|
73
|
+
raise NotImplementedError, "Devise doesn't know how to sanitize parameters for #{kind}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def attributes_for(kind)
|
78
|
+
case kind
|
79
|
+
when :sign_in
|
80
|
+
auth_keys + [:password, :remember_me]
|
81
|
+
when :sign_up
|
82
|
+
auth_keys + [:password, :password_confirmation]
|
83
|
+
when :account_update
|
84
|
+
auth_keys + [:password, :password_confirmation, :current_password]
|
85
|
+
end
|
57
86
|
end
|
58
87
|
|
59
88
|
def auth_keys
|
60
|
-
resource_class.authentication_keys.respond_to?(:keys) ?
|
89
|
+
@auth_keys ||= @resource_class.authentication_keys.respond_to?(:keys) ?
|
90
|
+
@resource_class.authentication_keys.keys : @resource_class.authentication_keys
|
61
91
|
end
|
62
92
|
end
|
63
93
|
end
|
data/lib/devise/rails.rb
CHANGED
@@ -29,21 +29,17 @@ module Devise
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
initializer "devise.
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
"its usual uniqueness and format validations for the email field. It is recommended " \
|
39
|
-
"that you upgrade to Mongoid 2.1+ for this and other fixes, but if for some reason you " \
|
40
|
-
"are unable to do so, you should add these validations manually.\n"
|
32
|
+
initializer "devise.secret_key" do
|
33
|
+
Devise.token_generator ||=
|
34
|
+
if secret_key = Devise.secret_key
|
35
|
+
Devise::TokenGenerator.new(
|
36
|
+
Devise::CachingKeyGenerator.new(Devise::KeyGenerator.new(secret_key))
|
37
|
+
)
|
41
38
|
end
|
42
|
-
end
|
43
39
|
end
|
44
40
|
|
45
41
|
initializer "devise.fix_routes_proxy_missing_respond_to_bug" do
|
46
|
-
#
|
42
|
+
# Deprecate: Remove once we move to Rails 4 only.
|
47
43
|
ActionDispatch::Routing::RoutesProxy.class_eval do
|
48
44
|
def respond_to?(method, include_private = false)
|
49
45
|
super || routes.url_helpers.respond_to?(method)
|
data/lib/devise/rails/routes.rb
CHANGED
@@ -80,7 +80,8 @@ module ActionDispatch::Routing
|
|
80
80
|
# * :path_names => configure different path names to overwrite defaults :sign_in, :sign_out, :sign_up,
|
81
81
|
# :password, :confirmation, :unlock.
|
82
82
|
#
|
83
|
-
# devise_for :users, :path_names => { :sign_in => 'login', :sign_out => 'logout',
|
83
|
+
# devise_for :users, :path_names => { :sign_in => 'login', :sign_out => 'logout',
|
84
|
+
# :password => 'secret', :confirmation => 'verification', registration: 'register }
|
84
85
|
#
|
85
86
|
# * :controllers => the controller which should be used. All routes by default points to Devise controllers.
|
86
87
|
# However, if you want them to point to custom controller, you should do:
|
@@ -191,6 +192,7 @@ module ActionDispatch::Routing
|
|
191
192
|
#
|
192
193
|
def devise_for(*resources)
|
193
194
|
@devise_finalized = false
|
195
|
+
raise_no_secret_key unless Devise.secret_key
|
194
196
|
options = resources.extract_options!
|
195
197
|
|
196
198
|
options[:as] ||= @scope[:as] if @scope[:as].present?
|
@@ -222,14 +224,6 @@ module ActionDispatch::Routing
|
|
222
224
|
routes = mapping.used_routes
|
223
225
|
|
224
226
|
devise_scope mapping.name do
|
225
|
-
if block_given?
|
226
|
-
ActiveSupport::Deprecation.warn "Passing a block to devise_for is deprecated. " \
|
227
|
-
"Please remove the block from devise_for (only the block, the call to " \
|
228
|
-
"devise_for must still exist) and call devise_scope :#{mapping.name} do ... end " \
|
229
|
-
"with the block instead", caller
|
230
|
-
yield
|
231
|
-
end
|
232
|
-
|
233
227
|
with_devise_exclusive_scope mapping.fullpath, mapping.name, options do
|
234
228
|
routes.each { |mod| send("devise_#{mod}", mapping, mapping.controllers) }
|
235
229
|
end
|
@@ -442,6 +436,15 @@ module ActionDispatch::Routing
|
|
442
436
|
end
|
443
437
|
end
|
444
438
|
|
439
|
+
def raise_no_secret_key #:nodoc:
|
440
|
+
raise <<-ERROR
|
441
|
+
Devise.secret_key was not set. Please add the following to your Devise initializer:
|
442
|
+
|
443
|
+
config.secret_key = '#{SecureRandom.hex(64)}'
|
444
|
+
|
445
|
+
ERROR
|
446
|
+
end
|
447
|
+
|
445
448
|
def raise_no_devise_method_error!(klass) #:nodoc:
|
446
449
|
raise "#{klass} does not respond to 'devise' method. This usually means you haven't " \
|
447
450
|
"loaded your ORM file or it's being loaded too late. To fix it, be sure to require 'devise/orm/YOUR_ORM' " \
|
@@ -3,6 +3,7 @@ module Warden::Mixins::Common
|
|
3
3
|
@request ||= ActionDispatch::Request.new(env)
|
4
4
|
end
|
5
5
|
|
6
|
+
# Deprecate: Remove this check once we move to Rails 4 only.
|
6
7
|
NULL_STORE =
|
7
8
|
defined?(ActionController::RequestForgeryProtection::ProtectionMethods::NullSession::NullSessionHash) ?
|
8
9
|
ActionController::RequestForgeryProtection::ProtectionMethods::NullSession::NullSessionHash : nil
|
@@ -26,20 +26,8 @@ module Devise
|
|
26
26
|
# In case the resource can't be validated, it will fail with the given
|
27
27
|
# unauthenticated_message.
|
28
28
|
def validate(resource, &block)
|
29
|
-
unless resource
|
30
|
-
ActiveSupport::Deprecation.warn "an empty resource was given to #{self.class.name}#validate. " \
|
31
|
-
"Please ensure the resource is not nil", caller
|
32
|
-
end
|
33
|
-
|
34
29
|
result = resource && resource.valid_for_authentication?(&block)
|
35
30
|
|
36
|
-
case result
|
37
|
-
when Symbol, String
|
38
|
-
ActiveSupport::Deprecation.warn "valid_for_authentication? should return a boolean value"
|
39
|
-
fail!(result)
|
40
|
-
return false
|
41
|
-
end
|
42
|
-
|
43
31
|
if result
|
44
32
|
decorate(resource)
|
45
33
|
true
|
@@ -5,16 +5,13 @@ module Devise
|
|
5
5
|
# Default strategy for signing in a user, based on his email and password in the database.
|
6
6
|
class DatabaseAuthenticatable < Authenticatable
|
7
7
|
def authenticate!
|
8
|
-
resource
|
9
|
-
|
8
|
+
resource = valid_password? && mapping.to.find_for_database_authentication(authentication_hash)
|
9
|
+
return fail(:not_found_in_database) unless resource
|
10
10
|
|
11
|
-
if validate(resource){
|
11
|
+
if validate(resource){ resource.valid_password?(password) }
|
12
12
|
resource.after_database_authentication
|
13
13
|
success!(resource)
|
14
14
|
end
|
15
|
-
|
16
|
-
mapping.to.new.password = password if !encrypted && Devise.paranoid
|
17
|
-
fail(:not_found_in_database) unless resource
|
18
15
|
end
|
19
16
|
end
|
20
17
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# Deprecate: Copied verbatim from Rails source, remove once we move to Rails 4 only.
|
2
|
+
require 'thread_safe'
|
3
|
+
require 'openssl'
|
4
|
+
require 'securerandom'
|
5
|
+
|
6
|
+
module Devise
|
7
|
+
class TokenGenerator
|
8
|
+
def initialize(key_generator, digest="SHA256")
|
9
|
+
@key_generator = key_generator
|
10
|
+
@digest = digest
|
11
|
+
end
|
12
|
+
|
13
|
+
def digest(klass, column, value)
|
14
|
+
value.present? && OpenSSL::HMAC.hexdigest(@digest, key_for(column), value.to_s)
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate(klass, column)
|
18
|
+
key = key_for(column)
|
19
|
+
|
20
|
+
loop do
|
21
|
+
raw = Devise.friendly_token
|
22
|
+
enc = OpenSSL::HMAC.hexdigest(@digest, key, raw)
|
23
|
+
break [raw, enc] unless klass.to_adapter.find_first({ column => enc })
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def key_for(column)
|
30
|
+
@key_generator.generate_key("Devise #{column}")
|
31
|
+
end
|
32
|
+
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
|
+
end
|
data/lib/devise/version.rb
CHANGED
@@ -1,13 +1,19 @@
|
|
1
1
|
# Use this hook to configure devise mailer, warden hooks and so forth.
|
2
2
|
# Many of these configuration options can be set straight in your model.
|
3
3
|
Devise.setup do |config|
|
4
|
+
# The secret key used by Devise. Devise uses this key to generate
|
5
|
+
# random tokens. Changing this key will render invalid all existing
|
6
|
+
# confirmation, reset password and unlock tokens in the database.
|
7
|
+
config.secret_key = '<%= SecureRandom.hex(64) %>'
|
8
|
+
|
4
9
|
# ==> Mailer Configuration
|
5
10
|
# Configure the e-mail address which will be shown in Devise::Mailer,
|
6
|
-
# note that it will be overwritten if you use your own mailer class
|
7
|
-
|
11
|
+
# note that it will be overwritten if you use your own mailer class
|
12
|
+
# with default "from" parameter.
|
13
|
+
config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
|
8
14
|
|
9
15
|
# Configure the class responsible to send e-mails.
|
10
|
-
# config.mailer =
|
16
|
+
# config.mailer = 'Devise::Mailer'
|
11
17
|
|
12
18
|
# ==> ORM configuration
|
13
19
|
# Load and configure the ORM. Supports :active_record (default) and
|
@@ -61,8 +67,8 @@ Devise.setup do |config|
|
|
61
67
|
# If http headers should be returned for AJAX requests. True by default.
|
62
68
|
# config.http_authenticatable_on_xhr = true
|
63
69
|
|
64
|
-
# The realm used in Http Basic Authentication.
|
65
|
-
# config.http_authentication_realm =
|
70
|
+
# The realm used in Http Basic Authentication. 'Application' by default.
|
71
|
+
# config.http_authentication_realm = 'Application'
|
66
72
|
|
67
73
|
# It will change confirmation, password recovery and other workflows
|
68
74
|
# to behave the same regardless if the e-mail provided was right or wrong.
|
@@ -217,7 +223,7 @@ Devise.setup do |config|
|
|
217
223
|
# should add them to the navigational formats lists.
|
218
224
|
#
|
219
225
|
# The "*/*" below is required to match Internet Explorer requests.
|
220
|
-
# config.navigational_formats = [
|
226
|
+
# config.navigational_formats = ['*/*', :html]
|
221
227
|
|
222
228
|
# The default HTTP method used to sign out a resource. Default is :delete.
|
223
229
|
config.sign_out_via = :delete
|
@@ -241,12 +247,12 @@ Devise.setup do |config|
|
|
241
247
|
# is mountable, there are some extra configurations to be taken into account.
|
242
248
|
# The following options are available, assuming the engine is mounted as:
|
243
249
|
#
|
244
|
-
# mount MyEngine, at:
|
250
|
+
# mount MyEngine, at: '/my_engine'
|
245
251
|
#
|
246
252
|
# The router that invoked `devise_for`, in the example above, would be:
|
247
253
|
# config.router_name = :my_engine
|
248
254
|
#
|
249
255
|
# When using omniauth, Devise cannot automatically set Omniauth path,
|
250
256
|
# so you need to do it manually. For the users scope, it would be:
|
251
|
-
# config.omniauth_path_prefix =
|
257
|
+
# config.omniauth_path_prefix = '/my_engine/users/auth'
|
252
258
|
end
|
@@ -4,16 +4,15 @@ class PasswordsControllerTest < ActionController::TestCase
|
|
4
4
|
tests Devise::PasswordsController
|
5
5
|
include Devise::TestHelpers
|
6
6
|
|
7
|
-
|
7
|
+
setup do
|
8
8
|
request.env["devise.mapping"] = Devise.mappings[:user]
|
9
|
-
|
10
9
|
@user = create_user.tap(&:confirm!)
|
11
|
-
@user.send_reset_password_instructions
|
10
|
+
@raw = @user.send_reset_password_instructions
|
12
11
|
end
|
13
12
|
|
14
13
|
def put_update_with_params
|
15
14
|
put :update, "user" => {
|
16
|
-
"reset_password_token" => @
|
15
|
+
"reset_password_token" => @raw, "password" => "123456", "password_confirmation" => "123456"
|
17
16
|
}
|
18
17
|
end
|
19
18
|
|
data/test/failure_app_test.rb
CHANGED
@@ -215,7 +215,7 @@ class FailureTest < ActiveSupport::TestCase
|
|
215
215
|
}
|
216
216
|
call_failure(env)
|
217
217
|
assert @response.third.body.include?('<h2>Sign in</h2>')
|
218
|
-
assert @response.third.body.include?('Your account
|
218
|
+
assert @response.third.body.include?('Your account is not activated yet.')
|
219
219
|
end
|
220
220
|
end
|
221
221
|
end
|
@@ -28,9 +28,7 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
|
|
28
28
|
|
29
29
|
test 'user should receive a confirmation from a custom mailer' do
|
30
30
|
User.any_instance.stubs(:devise_mailer).returns(Users::Mailer)
|
31
|
-
|
32
31
|
resend_confirmation
|
33
|
-
|
34
32
|
assert_equal ['custom@example.com'], ActionMailer::Base.deliveries.first.from
|
35
33
|
end
|
36
34
|
|
@@ -40,21 +38,11 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
|
|
40
38
|
assert_contain /Confirmation token(.*)invalid/
|
41
39
|
end
|
42
40
|
|
43
|
-
test 'user with valid confirmation token should be able to confirm an account' do
|
44
|
-
user = create_user(:confirm => false)
|
45
|
-
assert_not user.confirmed?
|
46
|
-
visit_user_confirmation_with_token(user.confirmation_token)
|
47
|
-
|
48
|
-
assert_contain 'Your account was successfully confirmed.'
|
49
|
-
assert_current_url '/'
|
50
|
-
assert user.reload.confirmed?
|
51
|
-
end
|
52
|
-
|
53
41
|
test 'user with valid confirmation token should not be able to confirm an account after the token has expired' do
|
54
42
|
swap Devise, :confirm_within => 3.days do
|
55
43
|
user = create_user(:confirm => false, :confirmation_sent_at => 4.days.ago)
|
56
44
|
assert_not user.confirmed?
|
57
|
-
visit_user_confirmation_with_token(user.
|
45
|
+
visit_user_confirmation_with_token(user.raw_confirmation_token)
|
58
46
|
|
59
47
|
assert_have_selector '#error_explanation'
|
60
48
|
assert_contain /needs to be confirmed within 3 days/
|
@@ -66,10 +54,10 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
|
|
66
54
|
swap Devise, :confirm_within => 3.days do
|
67
55
|
user = create_user(:confirm => false, :confirmation_sent_at => 2.days.ago)
|
68
56
|
assert_not user.confirmed?
|
69
|
-
visit_user_confirmation_with_token(user.
|
57
|
+
visit_user_confirmation_with_token(user.raw_confirmation_token)
|
70
58
|
|
71
59
|
assert_contain 'Your account was successfully confirmed.'
|
72
|
-
assert_current_url '/'
|
60
|
+
assert_current_url '/users/sign_in'
|
73
61
|
assert user.reload.confirmed?
|
74
62
|
end
|
75
63
|
end
|
@@ -78,7 +66,7 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
|
|
78
66
|
Devise::ConfirmationsController.any_instance.stubs(:after_confirmation_path_for).returns("/?custom=1")
|
79
67
|
|
80
68
|
user = create_user(:confirm => false)
|
81
|
-
visit_user_confirmation_with_token(user.
|
69
|
+
visit_user_confirmation_with_token(user.raw_confirmation_token)
|
82
70
|
|
83
71
|
assert_current_url "/?custom=1"
|
84
72
|
end
|
@@ -87,7 +75,7 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
|
|
87
75
|
user = create_user(:confirm => false)
|
88
76
|
user.confirmed_at = Time.now
|
89
77
|
user.save
|
90
|
-
visit_user_confirmation_with_token(user.
|
78
|
+
visit_user_confirmation_with_token(user.raw_confirmation_token)
|
91
79
|
|
92
80
|
assert_have_selector '#error_explanation'
|
93
81
|
assert_contain 'already confirmed'
|
@@ -98,7 +86,7 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
|
|
98
86
|
user.confirmed_at = Time.now
|
99
87
|
user.save
|
100
88
|
|
101
|
-
visit_user_confirmation_with_token(user.
|
89
|
+
visit_user_confirmation_with_token(user.raw_confirmation_token)
|
102
90
|
assert_contain 'already confirmed'
|
103
91
|
|
104
92
|
fill_in 'email', :with => user.email
|
@@ -106,21 +94,6 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
|
|
106
94
|
assert_contain 'already confirmed'
|
107
95
|
end
|
108
96
|
|
109
|
-
test 'sign in user automatically after confirming its email' do
|
110
|
-
user = create_user(:confirm => false)
|
111
|
-
visit_user_confirmation_with_token(user.confirmation_token)
|
112
|
-
|
113
|
-
assert warden.authenticated?(:user)
|
114
|
-
end
|
115
|
-
|
116
|
-
test 'increases sign count when signed in through confirmation' do
|
117
|
-
user = create_user(:confirm => false)
|
118
|
-
visit_user_confirmation_with_token(user.confirmation_token)
|
119
|
-
|
120
|
-
user.reload
|
121
|
-
assert_equal 1, user.sign_in_count
|
122
|
-
end
|
123
|
-
|
124
97
|
test 'not confirmed user with setup to block without confirmation should not be able to sign in' do
|
125
98
|
swap Devise, :allow_unconfirmed_access_for => 0.days do
|
126
99
|
sign_in_as_user(:confirm => false)
|
@@ -175,7 +148,7 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
|
|
175
148
|
|
176
149
|
test 'confirm account with valid confirmation token in XML format should return valid response' do
|
177
150
|
user = create_user(:confirm => false)
|
178
|
-
get user_confirmation_path(:confirmation_token => user.
|
151
|
+
get user_confirmation_path(:confirmation_token => user.raw_confirmation_token, :format => 'xml')
|
179
152
|
assert_response :success
|
180
153
|
assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<user>)
|
181
154
|
end
|
@@ -256,10 +229,10 @@ class ConfirmationOnChangeTest < ActionDispatch::IntegrationTest
|
|
256
229
|
admin = create_admin
|
257
230
|
admin.update_attributes(:email => 'new_test@example.com')
|
258
231
|
assert_equal 'new_test@example.com', admin.unconfirmed_email
|
259
|
-
visit_admin_confirmation_with_token(admin.
|
232
|
+
visit_admin_confirmation_with_token(admin.raw_confirmation_token)
|
260
233
|
|
261
234
|
assert_contain 'Your account was successfully confirmed.'
|
262
|
-
assert_current_url '/admin_area/
|
235
|
+
assert_current_url '/admin_area/sign_in'
|
263
236
|
assert admin.reload.confirmed?
|
264
237
|
assert_not admin.reload.pending_reconfirmation?
|
265
238
|
end
|
@@ -269,17 +242,19 @@ class ConfirmationOnChangeTest < ActionDispatch::IntegrationTest
|
|
269
242
|
admin.update_attributes(:email => 'first_test@example.com')
|
270
243
|
assert_equal 'first_test@example.com', admin.unconfirmed_email
|
271
244
|
|
272
|
-
|
245
|
+
raw_confirmation_token = admin.raw_confirmation_token
|
246
|
+
admin = Admin.find(admin.id)
|
247
|
+
|
273
248
|
admin.update_attributes(:email => 'second_test@example.com')
|
274
249
|
assert_equal 'second_test@example.com', admin.unconfirmed_email
|
275
250
|
|
276
|
-
visit_admin_confirmation_with_token(
|
251
|
+
visit_admin_confirmation_with_token(raw_confirmation_token)
|
277
252
|
assert_have_selector '#error_explanation'
|
278
253
|
assert_contain(/Confirmation token(.*)invalid/)
|
279
254
|
|
280
|
-
visit_admin_confirmation_with_token(admin.
|
255
|
+
visit_admin_confirmation_with_token(admin.raw_confirmation_token)
|
281
256
|
assert_contain 'Your account was successfully confirmed.'
|
282
|
-
assert_current_url '/admin_area/
|
257
|
+
assert_current_url '/admin_area/sign_in'
|
283
258
|
assert admin.reload.confirmed?
|
284
259
|
assert_not admin.reload.pending_reconfirmation?
|
285
260
|
end
|
@@ -291,7 +266,7 @@ class ConfirmationOnChangeTest < ActionDispatch::IntegrationTest
|
|
291
266
|
|
292
267
|
create_second_admin(:email => "new_admin_test@example.com")
|
293
268
|
|
294
|
-
visit_admin_confirmation_with_token(admin.
|
269
|
+
visit_admin_confirmation_with_token(admin.raw_confirmation_token)
|
295
270
|
assert_have_selector '#error_explanation'
|
296
271
|
assert_contain(/Email.*already.*taken/)
|
297
272
|
assert admin.reload.pending_reconfirmation?
|