devise 3.3.0 → 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 +4 -4
- data/.travis.yml +29 -20
- data/CHANGELOG.md +219 -102
- data/CODE_OF_CONDUCT.md +22 -0
- data/CONTRIBUTING.md +2 -0
- data/Gemfile +3 -2
- data/Gemfile.lock +101 -80
- data/MIT-LICENSE +1 -1
- data/README.md +87 -43
- data/Rakefile +2 -1
- data/app/controllers/devise/confirmations_controller.rb +5 -1
- data/app/controllers/devise/omniauth_callbacks_controller.rb +4 -0
- data/app/controllers/devise/passwords_controller.rb +14 -4
- data/app/controllers/devise/registrations_controller.rb +10 -11
- data/app/controllers/devise/sessions_controller.rb +7 -2
- data/app/controllers/devise/unlocks_controller.rb +3 -0
- data/app/controllers/devise_controller.rb +44 -21
- 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 +15 -6
- data/app/views/devise/shared/{_links.erb → _links.html.erb} +1 -1
- data/app/views/devise/unlocks/new.html.erb +7 -3
- data/config/locales/en.yml +4 -2
- data/devise.gemspec +2 -2
- data/gemfiles/Gemfile.rails-3.2-stable.lock +54 -48
- data/gemfiles/Gemfile.rails-4.0-stable +1 -0
- data/gemfiles/Gemfile.rails-4.0-stable.lock +63 -59
- data/gemfiles/{Gemfile.rails-head → Gemfile.rails-4.1-stable} +3 -5
- 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 +12 -6
- data/lib/devise/controllers/rememberable.rb +9 -2
- data/lib/devise/controllers/sign_in_out.rb +2 -8
- data/lib/devise/controllers/store_location.rb +3 -1
- data/lib/devise/controllers/url_helpers.rb +7 -9
- data/lib/devise/encryptor.rb +22 -0
- data/lib/devise/failure_app.rb +56 -14
- data/lib/devise/hooks/timeoutable.rb +5 -7
- data/lib/devise/mapping.rb +2 -1
- data/lib/devise/models/authenticatable.rb +28 -28
- data/lib/devise/models/confirmable.rb +51 -17
- data/lib/devise/models/database_authenticatable.rb +17 -11
- data/lib/devise/models/lockable.rb +7 -3
- data/lib/devise/models/recoverable.rb +23 -15
- data/lib/devise/models/rememberable.rb +56 -22
- data/lib/devise/models/timeoutable.rb +0 -6
- data/lib/devise/models/trackable.rb +1 -2
- data/lib/devise/models/validatable.rb +3 -3
- data/lib/devise/models.rb +1 -1
- data/lib/devise/rails/routes.rb +33 -27
- data/lib/devise/rails.rb +1 -1
- data/lib/devise/strategies/authenticatable.rb +8 -6
- data/lib/devise/strategies/database_authenticatable.rb +2 -1
- data/lib/devise/strategies/rememberable.rb +13 -3
- data/lib/devise/test_helpers.rb +2 -2
- data/lib/devise/version.rb +1 -1
- data/lib/devise.rb +39 -37
- data/lib/generators/active_record/devise_generator.rb +2 -1
- data/lib/generators/active_record/templates/migration.rb +1 -1
- data/lib/generators/active_record/templates/migration_existing.rb +1 -1
- data/lib/generators/devise/controllers_generator.rb +44 -0
- data/lib/generators/devise/views_generator.rb +14 -3
- 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 +19 -13
- 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 +6 -1
- data/test/controllers/helper_methods_test.rb +21 -0
- data/test/controllers/helpers_test.rb +5 -0
- data/test/controllers/inherited_controller_i18n_messages_test.rb +51 -0
- data/test/controllers/internal_helpers_test.rb +10 -4
- data/test/controllers/load_hooks_controller_test.rb +19 -0
- data/test/controllers/passwords_controller_test.rb +1 -1
- data/test/controllers/sessions_controller_test.rb +3 -3
- data/test/controllers/url_helpers_test.rb +6 -0
- data/test/devise_test.rb +3 -3
- data/test/failure_app_test.rb +47 -0
- data/test/generators/controllers_generator_test.rb +48 -0
- data/test/generators/views_generator_test.rb +8 -1
- data/test/helpers/devise_helper_test.rb +9 -12
- data/test/integration/authenticatable_test.rb +1 -1
- data/test/integration/database_authenticatable_test.rb +11 -0
- data/test/integration/http_authenticatable_test.rb +1 -1
- data/test/integration/omniauthable_test.rb +12 -10
- data/test/integration/recoverable_test.rb +13 -0
- data/test/integration/rememberable_test.rb +50 -3
- data/test/integration/timeoutable_test.rb +13 -18
- data/test/mailers/confirmation_instructions_test.rb +1 -1
- data/test/mapping_test.rb +7 -0
- data/test/models/authenticatable_test.rb +10 -0
- data/test/models/confirmable_test.rb +99 -42
- data/test/models/database_authenticatable_test.rb +20 -0
- data/test/models/lockable_test.rb +45 -17
- data/test/models/recoverable_test.rb +62 -7
- data/test/models/rememberable_test.rb +68 -97
- data/test/models/validatable_test.rb +5 -5
- data/test/models_test.rb +15 -6
- data/test/rails_app/app/active_record/user_without_email.rb +8 -0
- data/test/rails_app/app/controllers/admins_controller.rb +0 -5
- data/test/rails_app/app/controllers/custom/registrations_controller.rb +10 -0
- 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_without_email.rb +33 -0
- data/test/rails_app/config/application.rb +1 -1
- data/test/rails_app/config/environments/production.rb +6 -2
- data/test/rails_app/config/environments/test.rb +7 -2
- data/test/rails_app/config/initializers/devise.rb +12 -15
- data/test/rails_app/config/routes.rb +6 -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_test.rb +9 -0
- data/test/support/helpers.rb +13 -6
- data/test/support/integration.rb +2 -2
- data/test/test_helper.rb +5 -0
- data/test/test_helpers_test.rb +22 -7
- data/test/test_models.rb +2 -2
- data/test/time_helpers.rb +137 -0
- metadata +58 -8
- data/gemfiles/Gemfile.rails-head.lock +0 -190
@@ -42,7 +42,7 @@ class HttpAuthenticationTest < ActionDispatch::IntegrationTest
|
|
42
42
|
sign_in_as_new_user_with_http("unknown")
|
43
43
|
assert_equal 401, status
|
44
44
|
assert_equal "application/xml; charset=utf-8", headers["Content-Type"]
|
45
|
-
assert_match "<error>Invalid email
|
45
|
+
assert_match "<error>Invalid email or password.</error>", response.body
|
46
46
|
end
|
47
47
|
|
48
48
|
test 'returns a custom response with www-authenticate and chosen realm' do
|
@@ -20,9 +20,11 @@ class OmniauthableIntegrationTest < ActionDispatch::IntegrationTest
|
|
20
20
|
"credentials" => {"token" => 'plataformatec'},
|
21
21
|
"extra" => {"user_hash" => FACEBOOK_INFO}
|
22
22
|
}
|
23
|
+
OmniAuth.config.add_camelization 'facebook', 'FaceBook'
|
23
24
|
end
|
24
25
|
|
25
26
|
teardown do
|
27
|
+
OmniAuth.config.camelizations.delete('facebook')
|
26
28
|
OmniAuth.config.test_mode = false
|
27
29
|
end
|
28
30
|
|
@@ -40,7 +42,7 @@ class OmniauthableIntegrationTest < ActionDispatch::IntegrationTest
|
|
40
42
|
|
41
43
|
test "can access omniauth.auth in the env hash" do
|
42
44
|
visit "/users/sign_in"
|
43
|
-
click_link "Sign in with
|
45
|
+
click_link "Sign in with FaceBook"
|
44
46
|
|
45
47
|
json = ActiveSupport::JSON.decode(response.body)
|
46
48
|
|
@@ -54,7 +56,7 @@ class OmniauthableIntegrationTest < ActionDispatch::IntegrationTest
|
|
54
56
|
test "cleans up session on sign up" do
|
55
57
|
assert_no_difference "User.count" do
|
56
58
|
visit "/users/sign_in"
|
57
|
-
click_link "Sign in with
|
59
|
+
click_link "Sign in with FaceBook"
|
58
60
|
end
|
59
61
|
|
60
62
|
assert session["devise.facebook_data"]
|
@@ -75,7 +77,7 @@ class OmniauthableIntegrationTest < ActionDispatch::IntegrationTest
|
|
75
77
|
test "cleans up session on cancel" do
|
76
78
|
assert_no_difference "User.count" do
|
77
79
|
visit "/users/sign_in"
|
78
|
-
click_link "Sign in with
|
80
|
+
click_link "Sign in with FaceBook"
|
79
81
|
end
|
80
82
|
|
81
83
|
assert session["devise.facebook_data"]
|
@@ -86,7 +88,7 @@ class OmniauthableIntegrationTest < ActionDispatch::IntegrationTest
|
|
86
88
|
test "cleans up session on sign in" do
|
87
89
|
assert_no_difference "User.count" do
|
88
90
|
visit "/users/sign_in"
|
89
|
-
click_link "Sign in with
|
91
|
+
click_link "Sign in with FaceBook"
|
90
92
|
end
|
91
93
|
|
92
94
|
assert session["devise.facebook_data"]
|
@@ -96,13 +98,13 @@ class OmniauthableIntegrationTest < ActionDispatch::IntegrationTest
|
|
96
98
|
|
97
99
|
test "sign in and send remember token if configured" do
|
98
100
|
visit "/users/sign_in"
|
99
|
-
click_link "Sign in with
|
101
|
+
click_link "Sign in with FaceBook"
|
100
102
|
assert_nil warden.cookies["remember_user_token"]
|
101
103
|
|
102
104
|
stub_action!(:sign_in_facebook) do
|
103
105
|
create_user
|
104
106
|
visit "/users/sign_in"
|
105
|
-
click_link "Sign in with
|
107
|
+
click_link "Sign in with FaceBook"
|
106
108
|
assert warden.authenticated?(:user)
|
107
109
|
assert warden.cookies["remember_user_token"]
|
108
110
|
end
|
@@ -118,16 +120,16 @@ class OmniauthableIntegrationTest < ActionDispatch::IntegrationTest
|
|
118
120
|
OmniAuth.config.mock_auth[:facebook] = :access_denied
|
119
121
|
visit "/users/auth/facebook/callback?error=access_denied"
|
120
122
|
assert_current_url "/users/sign_in"
|
121
|
-
assert_contain 'Could not authenticate you from
|
123
|
+
assert_contain 'Could not authenticate you from FaceBook because "Access denied".'
|
122
124
|
end
|
123
125
|
|
124
|
-
test "handles other exceptions from
|
126
|
+
test "handles other exceptions from OmniAuth" do
|
125
127
|
OmniAuth.config.mock_auth[:facebook] = :invalid_credentials
|
126
128
|
|
127
129
|
visit "/users/sign_in"
|
128
|
-
click_link "Sign in with
|
130
|
+
click_link "Sign in with FaceBook"
|
129
131
|
|
130
132
|
assert_current_url "/users/sign_in"
|
131
|
-
assert_contain 'Could not authenticate you from
|
133
|
+
assert_contain 'Could not authenticate you from FaceBook because "Invalid credentials".'
|
132
134
|
end
|
133
135
|
end
|
@@ -197,6 +197,19 @@ class PasswordTest < ActionDispatch::IntegrationTest
|
|
197
197
|
assert warden.authenticated?(:user)
|
198
198
|
end
|
199
199
|
|
200
|
+
test 'does not sign in user automatically after changing its password if config.sign_in_after_reset_password is false' do
|
201
|
+
swap Devise, sign_in_after_reset_password: false do
|
202
|
+
create_user
|
203
|
+
request_forgot_password
|
204
|
+
reset_password
|
205
|
+
|
206
|
+
assert_contain 'Your password has been changed successfully.'
|
207
|
+
assert_not_contain 'You are now signed in.'
|
208
|
+
assert_equal new_user_session_path, @request.path
|
209
|
+
assert !warden.authenticated?(:user)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
200
213
|
test 'does not sign in user automatically after changing its password if it\'s locked and unlock strategy is :none or :time' do
|
201
214
|
[:none, :time].each do |strategy|
|
202
215
|
swap Devise, unlock_strategy: strategy do
|
@@ -1,10 +1,15 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class RememberMeTest < ActionDispatch::IntegrationTest
|
4
|
+
if (Rails::VERSION::MAJOR < 4) || (Rails::VERSION::MAJOR >= 4 && Rails::VERSION::MINOR < 1)
|
5
|
+
require 'time_helpers'
|
6
|
+
include ActiveSupport::Testing::TimeHelpers
|
7
|
+
end
|
8
|
+
|
4
9
|
def create_user_and_remember(add_to_token='')
|
5
10
|
user = create_user
|
6
11
|
user.remember_me!
|
7
|
-
raw_cookie = User.serialize_into_cookie(user).tap { |a| a
|
12
|
+
raw_cookie = User.serialize_into_cookie(user).tap { |a| a[1] << add_to_token }
|
8
13
|
cookies['remember_user_token'] = generate_signed_cookie(raw_cookie)
|
9
14
|
user
|
10
15
|
end
|
@@ -92,7 +97,6 @@ class RememberMeTest < ActionDispatch::IntegrationTest
|
|
92
97
|
assert_response :success
|
93
98
|
assert warden.authenticated?(:user)
|
94
99
|
assert warden.user(:user) == user
|
95
|
-
assert_match /remember_user_token[^\n]*HttpOnly/, response.headers["Set-Cookie"], "Expected Set-Cookie header in response to set HttpOnly flag on remember_user_token cookie."
|
96
100
|
end
|
97
101
|
|
98
102
|
test 'remember the user before sign up and redirect them to their home' do
|
@@ -118,6 +122,40 @@ class RememberMeTest < ActionDispatch::IntegrationTest
|
|
118
122
|
end
|
119
123
|
end
|
120
124
|
|
125
|
+
test 'extends remember period when extend remember period config is true' do
|
126
|
+
swap Devise, extend_remember_period: true, remember_for: 1.year do
|
127
|
+
user = create_user_and_remember
|
128
|
+
old_remember_token = nil
|
129
|
+
|
130
|
+
travel_to 1.day.ago do
|
131
|
+
get root_path
|
132
|
+
old_remember_token = request.cookies['remember_user_token']
|
133
|
+
end
|
134
|
+
|
135
|
+
get root_path
|
136
|
+
current_remember_token = request.cookies['remember_user_token']
|
137
|
+
|
138
|
+
refute_equal old_remember_token, current_remember_token
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
test 'does not extend remember period when extend period config is false' do
|
143
|
+
swap Devise, extend_remember_period: false, remember_for: 1.year do
|
144
|
+
user = create_user_and_remember
|
145
|
+
old_remember_token = nil
|
146
|
+
|
147
|
+
travel_to 1.day.ago do
|
148
|
+
get root_path
|
149
|
+
old_remember_token = request.cookies['remember_user_token']
|
150
|
+
end
|
151
|
+
|
152
|
+
get root_path
|
153
|
+
current_remember_token = request.cookies['remember_user_token']
|
154
|
+
|
155
|
+
assert_equal old_remember_token, current_remember_token
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
121
159
|
test 'do not remember other scopes' do
|
122
160
|
create_user_and_remember
|
123
161
|
get root_path
|
@@ -135,7 +173,7 @@ class RememberMeTest < ActionDispatch::IntegrationTest
|
|
135
173
|
|
136
174
|
test 'do not remember with expired token' do
|
137
175
|
create_user_and_remember
|
138
|
-
swap Devise, remember_for: 0 do
|
176
|
+
swap Devise, remember_for: 0.days do
|
139
177
|
get users_path
|
140
178
|
assert_not warden.authenticated?(:user)
|
141
179
|
assert_redirected_to new_user_session_path
|
@@ -164,4 +202,13 @@ class RememberMeTest < ActionDispatch::IntegrationTest
|
|
164
202
|
get users_path
|
165
203
|
assert_not warden.authenticated?(:user)
|
166
204
|
end
|
205
|
+
|
206
|
+
test 'valid sign in calls after_remembered callback' do
|
207
|
+
user = create_user_and_remember
|
208
|
+
|
209
|
+
User.expects(:serialize_from_cookie).returns user
|
210
|
+
user.expects :after_remembered
|
211
|
+
|
212
|
+
get new_user_registration_path
|
213
|
+
end
|
167
214
|
end
|
@@ -24,6 +24,18 @@ class SessionTimeoutTest < ActionDispatch::IntegrationTest
|
|
24
24
|
assert_equal old_last_request, last_request_at
|
25
25
|
end
|
26
26
|
|
27
|
+
test 'does not set last request at in user session after each request if timeoutable is disabled' do
|
28
|
+
sign_in_as_user
|
29
|
+
old_last_request = last_request_at
|
30
|
+
assert_not_nil last_request_at
|
31
|
+
|
32
|
+
new_time = 2.seconds.from_now
|
33
|
+
Time.stubs(:now).returns(new_time)
|
34
|
+
|
35
|
+
get users_path, {}, 'devise.skip_timeoutable' => true
|
36
|
+
assert_equal old_last_request, last_request_at
|
37
|
+
end
|
38
|
+
|
27
39
|
test 'does not time out user session before default limit time' do
|
28
40
|
sign_in_as_user
|
29
41
|
assert_response :success
|
@@ -110,23 +122,6 @@ class SessionTimeoutTest < ActionDispatch::IntegrationTest
|
|
110
122
|
assert_contain 'You are signed in'
|
111
123
|
end
|
112
124
|
|
113
|
-
test 'admin does not explode on time out' do
|
114
|
-
admin = sign_in_as_admin
|
115
|
-
get expire_admin_path(admin)
|
116
|
-
|
117
|
-
Admin.send :define_method, :reset_authentication_token! do
|
118
|
-
nil
|
119
|
-
end
|
120
|
-
|
121
|
-
begin
|
122
|
-
get admins_path
|
123
|
-
assert_redirected_to admins_path
|
124
|
-
assert_not warden.authenticated?(:admin)
|
125
|
-
ensure
|
126
|
-
Admin.send(:remove_method, :reset_authentication_token!)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
125
|
test 'user configured timeout limit' do
|
131
126
|
swap Devise, timeout_in: 8.minutes do
|
132
127
|
user = sign_in_as_user
|
@@ -180,7 +175,7 @@ class SessionTimeoutTest < ActionDispatch::IntegrationTest
|
|
180
175
|
assert warden.authenticated?(:user)
|
181
176
|
end
|
182
177
|
|
183
|
-
test 'does not
|
178
|
+
test 'does not crash when the last_request_at is a String' do
|
184
179
|
user = sign_in_as_user
|
185
180
|
|
186
181
|
get edit_form_user_path(user, last_request_at: Time.now.utc.to_s)
|
@@ -86,7 +86,7 @@ class ConfirmationInstructionsTest < ActionMailer::TestCase
|
|
86
86
|
host, port = ActionMailer::Base.default_url_options.values_at :host, :port
|
87
87
|
|
88
88
|
if mail.body.encoded =~ %r{<a href=\"http://#{host}:#{port}/users/confirmation\?confirmation_token=([^"]+)">}
|
89
|
-
assert_equal
|
89
|
+
assert_equal $1, user.confirmation_token
|
90
90
|
else
|
91
91
|
flunk "expected confirmation url regex to match"
|
92
92
|
end
|
data/test/mapping_test.rb
CHANGED
@@ -62,6 +62,7 @@ class MappingTest < ActiveSupport::TestCase
|
|
62
62
|
test 'find scope for a given object' do
|
63
63
|
assert_equal :user, Devise::Mapping.find_scope!(User)
|
64
64
|
assert_equal :user, Devise::Mapping.find_scope!(:user)
|
65
|
+
assert_equal :user, Devise::Mapping.find_scope!("user")
|
65
66
|
assert_equal :user, Devise::Mapping.find_scope!(User.new)
|
66
67
|
end
|
67
68
|
|
@@ -70,6 +71,12 @@ class MappingTest < ActiveSupport::TestCase
|
|
70
71
|
assert_equal :user, Devise::Mapping.find_scope!(Class.new(User).new)
|
71
72
|
end
|
72
73
|
|
74
|
+
test 'find scope uses devise_scope' do
|
75
|
+
user = User.new
|
76
|
+
def user.devise_scope; :special_scope; end
|
77
|
+
assert_equal :special_scope, Devise::Mapping.find_scope!(user)
|
78
|
+
end
|
79
|
+
|
73
80
|
test 'find scope raises an error if cannot be found' do
|
74
81
|
assert_raise RuntimeError do
|
75
82
|
Devise::Mapping.find_scope!(String)
|
@@ -10,4 +10,14 @@ class AuthenticatableTest < ActiveSupport::TestCase
|
|
10
10
|
assert_equal User.find_first_by_auth_conditions({ email: "example@example.com" }), user
|
11
11
|
assert_nil User.find_first_by_auth_conditions({ email: "example@example.com" }, id: user.id.to_s.next)
|
12
12
|
end
|
13
|
+
|
14
|
+
if defined?(ActionController::Parameters)
|
15
|
+
test 'does not passes an ActionController::Parameters to find_first_by_auth_conditions through find_or_initialize_with_errors' do
|
16
|
+
user = create_user(email: 'example@example.com')
|
17
|
+
attributes = ActionController::Parameters.new(email: 'example@example.com')
|
18
|
+
|
19
|
+
User.expects(:find_first_by_auth_conditions).with('email' => 'example@example.com').returns(user)
|
20
|
+
User.find_or_initialize_with_errors([:email], attributes)
|
21
|
+
end
|
22
|
+
end
|
13
23
|
end
|
@@ -23,31 +23,24 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
23
23
|
test 'should confirm a user by updating confirmed at' do
|
24
24
|
user = create_user
|
25
25
|
assert_nil user.confirmed_at
|
26
|
-
assert user.confirm
|
26
|
+
assert user.confirm
|
27
27
|
assert_not_nil user.confirmed_at
|
28
28
|
end
|
29
29
|
|
30
|
-
test 'should clear confirmation token while confirming a user' do
|
31
|
-
user = create_user
|
32
|
-
assert_present user.confirmation_token
|
33
|
-
user.confirm!
|
34
|
-
assert_nil user.confirmation_token
|
35
|
-
end
|
36
|
-
|
37
30
|
test 'should verify whether a user is confirmed or not' do
|
38
31
|
assert_not new_user.confirmed?
|
39
32
|
user = create_user
|
40
33
|
assert_not user.confirmed?
|
41
|
-
user.confirm
|
34
|
+
user.confirm
|
42
35
|
assert user.confirmed?
|
43
36
|
end
|
44
37
|
|
45
38
|
test 'should not confirm a user already confirmed' do
|
46
39
|
user = create_user
|
47
|
-
assert user.confirm
|
40
|
+
assert user.confirm
|
48
41
|
assert_blank user.errors[:email]
|
49
42
|
|
50
|
-
assert_not user.confirm
|
43
|
+
assert_not user.confirm
|
51
44
|
assert_equal "was already confirmed, please try signing in", user.errors[:email].join
|
52
45
|
end
|
53
46
|
|
@@ -80,6 +73,16 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
80
73
|
assert_equal "was already confirmed, please try signing in", confirmed_user.errors[:email].join
|
81
74
|
end
|
82
75
|
|
76
|
+
test 'should show error when a token has already been used' do
|
77
|
+
user = create_user
|
78
|
+
raw = user.raw_confirmation_token
|
79
|
+
User.confirm_by_token(raw)
|
80
|
+
assert user.reload.confirmed?
|
81
|
+
|
82
|
+
confirmed_user = User.confirm_by_token(raw)
|
83
|
+
assert_equal "was already confirmed, please try signing in", confirmed_user.errors[:email].join
|
84
|
+
end
|
85
|
+
|
83
86
|
test 'should send confirmation instructions by email' do
|
84
87
|
assert_email_sent "mynewuser@example.com" do
|
85
88
|
create_user email: "mynewuser@example.com"
|
@@ -111,7 +114,7 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
111
114
|
|
112
115
|
assert_email_not_sent do
|
113
116
|
user.save!
|
114
|
-
|
117
|
+
assert_not user.confirmed?
|
115
118
|
end
|
116
119
|
end
|
117
120
|
|
@@ -165,18 +168,19 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
165
168
|
|
166
169
|
test 'should not reset confirmation status or token when updating email' do
|
167
170
|
user = create_user
|
168
|
-
user.
|
171
|
+
original_token = user.confirmation_token
|
172
|
+
user.confirm
|
169
173
|
user.email = 'new_test@example.com'
|
170
174
|
user.save!
|
171
175
|
|
172
176
|
user.reload
|
173
177
|
assert user.confirmed?
|
174
|
-
|
178
|
+
assert_equal original_token, user.confirmation_token
|
175
179
|
end
|
176
180
|
|
177
181
|
test 'should not be able to send instructions if the user is already confirmed' do
|
178
182
|
user = create_user
|
179
|
-
user.confirm
|
183
|
+
user.confirm
|
180
184
|
assert_not user.resend_confirmation_instructions
|
181
185
|
assert user.confirmed?
|
182
186
|
assert_equal 'was already confirmed, please try signing in', user.errors[:email].join
|
@@ -211,7 +215,7 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
211
215
|
assert_not user.confirmed?
|
212
216
|
assert_not user.active_for_authentication?
|
213
217
|
|
214
|
-
user.confirm
|
218
|
+
user.confirm
|
215
219
|
assert user.confirmed?
|
216
220
|
assert user.active_for_authentication?
|
217
221
|
end
|
@@ -219,15 +223,16 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
219
223
|
test 'should not be active when confirm in is zero' do
|
220
224
|
Devise.allow_unconfirmed_access_for = 0.days
|
221
225
|
user = create_user
|
222
|
-
user.confirmation_sent_at =
|
226
|
+
user.confirmation_sent_at = Time.zone.today
|
223
227
|
assert_not user.active_for_authentication?
|
224
228
|
end
|
225
229
|
|
226
230
|
test 'should be active when we set allow_unconfirmed_access_for to nil' do
|
227
|
-
Devise
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
+
swap Devise, allow_unconfirmed_access_for: nil do
|
232
|
+
user = create_user
|
233
|
+
user.confirmation_sent_at = Time.zone.today
|
234
|
+
assert user.active_for_authentication?
|
235
|
+
end
|
231
236
|
end
|
232
237
|
|
233
238
|
test 'should not be active without confirmation' do
|
@@ -245,6 +250,16 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
245
250
|
assert user.reload.active_for_authentication?
|
246
251
|
end
|
247
252
|
|
253
|
+
test 'should not break when a user tries to reset their password in the case where confirmation is not required and confirm_within is set' do
|
254
|
+
swap Devise, confirm_within: 3.days do
|
255
|
+
user = create_user
|
256
|
+
user.instance_eval { def confirmation_required?; false end }
|
257
|
+
user.confirmation_sent_at = nil
|
258
|
+
user.save
|
259
|
+
assert user.reload.confirm!
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
248
263
|
test 'should find a user to send email instructions for the user confirm its email by authentication_keys' do
|
249
264
|
swap Devise, authentication_keys: [:username, :email] do
|
250
265
|
user = create_user
|
@@ -286,12 +301,23 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
286
301
|
end
|
287
302
|
end
|
288
303
|
|
289
|
-
test '
|
304
|
+
test 'do not generate a new token on resend' do
|
290
305
|
user = create_user
|
291
306
|
old = user.confirmation_token
|
292
307
|
user = User.find(user.id)
|
293
308
|
user.resend_confirmation_instructions
|
294
|
-
|
309
|
+
assert_equal user.confirmation_token, old
|
310
|
+
end
|
311
|
+
|
312
|
+
test 'generate a new token after first has expired' do
|
313
|
+
swap Devise, confirm_within: 3.days do
|
314
|
+
user = create_user
|
315
|
+
old = user.confirmation_token
|
316
|
+
user.update_attribute(:confirmation_sent_at, 4.days.ago)
|
317
|
+
user = User.find(user.id)
|
318
|
+
user.resend_confirmation_instructions
|
319
|
+
assert_not_equal user.confirmation_token, old
|
320
|
+
end
|
295
321
|
end
|
296
322
|
|
297
323
|
test 'should call after_confirmation if confirmed' do
|
@@ -300,43 +326,52 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
300
326
|
self.username = self.username.to_s + 'updated'
|
301
327
|
end
|
302
328
|
old = user.username
|
303
|
-
assert user.confirm
|
329
|
+
assert user.confirm
|
304
330
|
assert_not_equal user.username, old
|
305
331
|
end
|
306
332
|
|
307
333
|
test 'should not call after_confirmation if not confirmed' do
|
308
334
|
user = create_user
|
309
|
-
assert user.confirm
|
335
|
+
assert user.confirm
|
310
336
|
user.define_singleton_method :after_confirmation do
|
311
337
|
self.username = self.username.to_s + 'updated'
|
312
338
|
end
|
313
339
|
old = user.username
|
314
|
-
assert_not user.confirm
|
340
|
+
assert_not user.confirm
|
315
341
|
assert_equal user.username, old
|
316
342
|
end
|
343
|
+
|
344
|
+
test 'should always perform validations upon confirm when ensure valid true' do
|
345
|
+
admin = create_admin
|
346
|
+
admin.stubs(:valid?).returns(false)
|
347
|
+
assert_not admin.confirm(ensure_valid: true)
|
348
|
+
end
|
317
349
|
end
|
318
350
|
|
319
351
|
class ReconfirmableTest < ActiveSupport::TestCase
|
320
352
|
test 'should not worry about validations on confirm even with reconfirmable' do
|
321
353
|
admin = create_admin
|
322
354
|
admin.reset_password_token = "a"
|
323
|
-
assert admin.confirm
|
355
|
+
assert admin.confirm
|
324
356
|
end
|
325
357
|
|
326
358
|
test 'should generate confirmation token after changing email' do
|
327
359
|
admin = create_admin
|
328
|
-
assert admin.confirm
|
329
|
-
|
360
|
+
assert admin.confirm
|
361
|
+
residual_token = admin.confirmation_token
|
330
362
|
assert admin.update_attributes(email: 'new_test@example.com')
|
331
|
-
|
363
|
+
assert_not_equal residual_token, admin.confirmation_token
|
332
364
|
end
|
333
365
|
|
334
|
-
test 'should not
|
366
|
+
test 'should not regenerate confirmation token or require reconfirmation if skipping reconfirmation after changing email' do
|
335
367
|
admin = create_admin
|
336
|
-
|
368
|
+
original_token = admin.confirmation_token
|
369
|
+
assert admin.confirm
|
337
370
|
admin.skip_reconfirmation!
|
338
371
|
assert admin.update_attributes(email: 'new_test@example.com')
|
339
|
-
|
372
|
+
assert admin.confirmed?
|
373
|
+
assert_not admin.pending_reconfirmation?
|
374
|
+
assert_equal original_token, admin.confirmation_token
|
340
375
|
end
|
341
376
|
|
342
377
|
test 'should skip sending reconfirmation email when email is changed and skip_confirmation_notification! is invoked' do
|
@@ -350,7 +385,7 @@ class ReconfirmableTest < ActiveSupport::TestCase
|
|
350
385
|
|
351
386
|
test 'should regenerate confirmation token after changing email' do
|
352
387
|
admin = create_admin
|
353
|
-
assert admin.confirm
|
388
|
+
assert admin.confirm
|
354
389
|
assert admin.update_attributes(email: 'old_test@example.com')
|
355
390
|
token = admin.confirmation_token
|
356
391
|
assert admin.update_attributes(email: 'new_test@example.com')
|
@@ -359,7 +394,15 @@ class ReconfirmableTest < ActiveSupport::TestCase
|
|
359
394
|
|
360
395
|
test 'should send confirmation instructions by email after changing email' do
|
361
396
|
admin = create_admin
|
362
|
-
assert admin.confirm
|
397
|
+
assert admin.confirm
|
398
|
+
assert_email_sent "new_test@example.com" do
|
399
|
+
assert admin.update_attributes(email: 'new_test@example.com')
|
400
|
+
end
|
401
|
+
assert_match "new_test@example.com", ActionMailer::Base.deliveries.last.body.encoded
|
402
|
+
end
|
403
|
+
|
404
|
+
test 'should send confirmation instructions by email after changing email from nil' do
|
405
|
+
admin = create_admin(email: nil)
|
363
406
|
assert_email_sent "new_test@example.com" do
|
364
407
|
assert admin.update_attributes(email: 'new_test@example.com')
|
365
408
|
end
|
@@ -368,7 +411,7 @@ class ReconfirmableTest < ActiveSupport::TestCase
|
|
368
411
|
|
369
412
|
test 'should not send confirmation by email after changing password' do
|
370
413
|
admin = create_admin
|
371
|
-
assert admin.confirm
|
414
|
+
assert admin.confirm
|
372
415
|
assert_email_not_sent do
|
373
416
|
assert admin.update_attributes(password: 'newpass', password_confirmation: 'newpass')
|
374
417
|
end
|
@@ -376,7 +419,7 @@ class ReconfirmableTest < ActiveSupport::TestCase
|
|
376
419
|
|
377
420
|
test 'should not send confirmation by email after changing to a blank email' do
|
378
421
|
admin = create_admin
|
379
|
-
assert admin.confirm
|
422
|
+
assert admin.confirm
|
380
423
|
assert_email_not_sent do
|
381
424
|
admin.email = ''
|
382
425
|
admin.save(validate: false)
|
@@ -385,23 +428,23 @@ class ReconfirmableTest < ActiveSupport::TestCase
|
|
385
428
|
|
386
429
|
test 'should stay confirmed when email is changed' do
|
387
430
|
admin = create_admin
|
388
|
-
assert admin.confirm
|
431
|
+
assert admin.confirm
|
389
432
|
assert admin.update_attributes(email: 'new_test@example.com')
|
390
433
|
assert admin.confirmed?
|
391
434
|
end
|
392
435
|
|
393
436
|
test 'should update email only when it is confirmed' do
|
394
437
|
admin = create_admin
|
395
|
-
assert admin.confirm
|
438
|
+
assert admin.confirm
|
396
439
|
assert admin.update_attributes(email: 'new_test@example.com')
|
397
440
|
assert_not_equal 'new_test@example.com', admin.email
|
398
|
-
assert admin.confirm
|
441
|
+
assert admin.confirm
|
399
442
|
assert_equal 'new_test@example.com', admin.email
|
400
443
|
end
|
401
444
|
|
402
445
|
test 'should not allow admin to get past confirmation email by resubmitting their new address' do
|
403
446
|
admin = create_admin
|
404
|
-
assert admin.confirm
|
447
|
+
assert admin.confirm
|
405
448
|
assert admin.update_attributes(email: 'new_test@example.com')
|
406
449
|
assert_not_equal 'new_test@example.com', admin.email
|
407
450
|
assert admin.update_attributes(email: 'new_test@example.com')
|
@@ -410,7 +453,7 @@ class ReconfirmableTest < ActiveSupport::TestCase
|
|
410
453
|
|
411
454
|
test 'should find a admin by send confirmation instructions with unconfirmed_email' do
|
412
455
|
admin = create_admin
|
413
|
-
assert admin.confirm
|
456
|
+
assert admin.confirm
|
414
457
|
assert admin.update_attributes(email: 'new_test@example.com')
|
415
458
|
confirmation_admin = Admin.send_confirmation_instructions(email: admin.unconfirmed_email)
|
416
459
|
assert_equal confirmation_admin, admin
|
@@ -451,4 +494,18 @@ class ReconfirmableTest < ActiveSupport::TestCase
|
|
451
494
|
:unconfirmed_email
|
452
495
|
]
|
453
496
|
end
|
497
|
+
|
498
|
+
test 'should not require reconfirmation after creating a record' do
|
499
|
+
admin = create_admin
|
500
|
+
assert !admin.pending_reconfirmation?
|
501
|
+
end
|
502
|
+
|
503
|
+
test 'should not require reconfirmation after creating a record with #save called in callback' do
|
504
|
+
class Admin::WithSaveInCallback < Admin
|
505
|
+
after_create :save
|
506
|
+
end
|
507
|
+
|
508
|
+
admin = Admin::WithSaveInCallback.create(valid_attributes.except(:username))
|
509
|
+
assert !admin.pending_reconfirmation?
|
510
|
+
end
|
454
511
|
end
|
@@ -3,6 +3,10 @@ require 'test_models'
|
|
3
3
|
require 'digest/sha1'
|
4
4
|
|
5
5
|
class DatabaseAuthenticatableTest < ActiveSupport::TestCase
|
6
|
+
def setup
|
7
|
+
setup_mailer
|
8
|
+
end
|
9
|
+
|
6
10
|
test 'should downcase case insensitive keys when saving' do
|
7
11
|
# case_insensitive_keys is set to :email by default.
|
8
12
|
email = 'Foo@Bar.com'
|
@@ -225,6 +229,22 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
|
|
225
229
|
assert_match "can't be blank", user.errors[:current_password].join
|
226
230
|
end
|
227
231
|
|
232
|
+
test 'should not email on password change' do
|
233
|
+
user = create_user
|
234
|
+
assert_email_not_sent do
|
235
|
+
assert user.update_attributes(password: 'newpass', password_confirmation: 'newpass')
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
test 'should email on password change when configured' do
|
240
|
+
swap Devise, send_password_change_notification: true do
|
241
|
+
user = create_user
|
242
|
+
assert_email_sent user.email do
|
243
|
+
assert user.update_attributes(password: 'newpass', password_confirmation: 'newpass')
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
228
248
|
test 'downcase_keys with validation' do
|
229
249
|
User.create(email: "HEllO@example.com", password: "123456")
|
230
250
|
user = User.create(email: "HEllO@example.com", password: "123456")
|