devise 3.0.0 → 3.1.0

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.

Potentially problematic release.


This version of devise might be problematic. Click here for more details.

Files changed (68) hide show
  1. data/{CHANGELOG.rdoc → CHANGELOG.md} +67 -25
  2. data/Gemfile.lock +13 -12
  3. data/README.md +19 -17
  4. data/app/controllers/devise/confirmations_controller.rb +11 -3
  5. data/app/controllers/devise/registrations_controller.rb +9 -3
  6. data/app/controllers/devise/sessions_controller.rb +1 -1
  7. data/app/mailers/devise/mailer.rb +6 -3
  8. data/app/views/devise/mailer/confirmation_instructions.html.erb +1 -1
  9. data/app/views/devise/mailer/reset_password_instructions.html.erb +1 -1
  10. data/app/views/devise/mailer/unlock_instructions.html.erb +1 -1
  11. data/app/views/devise/shared/_links.erb +2 -2
  12. data/config/locales/en.yml +4 -3
  13. data/devise.gemspec +1 -0
  14. data/gemfiles/Gemfile.rails-3.2.x.lock +47 -44
  15. data/lib/devise/controllers/helpers.rb +1 -0
  16. data/lib/devise/controllers/rememberable.rb +1 -0
  17. data/lib/devise/hooks/csrf_cleaner.rb +5 -0
  18. data/lib/devise/hooks/lockable.rb +1 -1
  19. data/lib/devise/hooks/rememberable.rb +2 -1
  20. data/lib/devise/mailers/helpers.rb +0 -6
  21. data/lib/devise/models/authenticatable.rb +9 -16
  22. data/lib/devise/models/confirmable.rb +34 -43
  23. data/lib/devise/models/lockable.rb +15 -17
  24. data/lib/devise/models/recoverable.rb +21 -27
  25. data/lib/devise/models/rememberable.rb +6 -2
  26. data/lib/devise/models/timeoutable.rb +1 -1
  27. data/lib/devise/models/token_authenticatable.rb +4 -1
  28. data/lib/devise/models.rb +8 -12
  29. data/lib/devise/parameter_sanitizer.rb +49 -19
  30. data/lib/devise/rails/routes.rb +12 -9
  31. data/lib/devise/rails/warden_compat.rb +10 -2
  32. data/lib/devise/rails.rb +7 -11
  33. data/lib/devise/strategies/authenticatable.rb +0 -12
  34. data/lib/devise/token_generator.rb +70 -0
  35. data/lib/devise/version.rb +1 -1
  36. data/lib/devise.rb +23 -12
  37. data/lib/generators/active_record/devise_generator.rb +2 -5
  38. data/lib/generators/active_record/templates/migration.rb +0 -1
  39. data/lib/generators/active_record/templates/migration_existing.rb +0 -1
  40. data/lib/generators/devise/orm_helpers.rb +25 -6
  41. data/lib/generators/mongoid/devise_generator.rb +2 -2
  42. data/lib/generators/templates/devise.rb +21 -9
  43. data/test/controllers/helpers_test.rb +1 -1
  44. data/test/controllers/passwords_controller_test.rb +4 -5
  45. data/test/failure_app_test.rb +1 -1
  46. data/test/generators/active_record_generator_test.rb +31 -1
  47. data/test/integration/authenticatable_test.rb +15 -1
  48. data/test/integration/confirmable_test.rb +29 -42
  49. data/test/integration/http_authenticatable_test.rb +1 -1
  50. data/test/integration/lockable_test.rb +11 -14
  51. data/test/integration/recoverable_test.rb +23 -24
  52. data/test/integration/rememberable_test.rb +15 -13
  53. data/test/mailers/confirmation_instructions_test.rb +6 -2
  54. data/test/mailers/reset_password_instructions_test.rb +6 -2
  55. data/test/mailers/unlock_instructions_test.rb +6 -2
  56. data/test/models/confirmable_test.rb +38 -27
  57. data/test/models/lockable_test.rb +15 -5
  58. data/test/models/recoverable_test.rb +20 -48
  59. data/test/models/rememberable_test.rb +8 -0
  60. data/test/models/timeoutable_test.rb +5 -0
  61. data/test/models_test.rb +0 -19
  62. data/test/parameter_sanitizer_test.rb +23 -9
  63. data/test/rails_app/config/initializers/devise.rb +3 -0
  64. data/test/rails_app/lib/shared_admin.rb +3 -0
  65. data/test/rails_app/lib/shared_user.rb +4 -0
  66. data/test/support/helpers.rb +0 -21
  67. metadata +42 -26
  68. data/app/views/devise/_links.erb +0 -3
@@ -62,11 +62,41 @@ if DEVISE_ORM == :active_record
62
62
  destination File.expand_path("../../tmp", __FILE__)
63
63
  setup :prepare_destination
64
64
 
65
- test "all files are properly created" do
65
+ test "all files are properly created in rails 4.0" do
66
+ ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:rails_3?).returns(false)
66
67
  simulate_inside_engine(RailsEngine::Engine, RailsEngine) do
67
68
  run_generator ["monster"]
68
69
 
69
70
  assert_file "app/models/rails_engine/monster.rb", /devise/
71
+ assert_file "app/models/rails_engine/monster.rb" do |content|
72
+ assert_no_match /attr_accessible :email/, content
73
+ end
74
+ end
75
+ end
76
+
77
+ test "all files are properly created in rails 3.2 when strong_parameters gem is not installed" do
78
+ ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:rails_3?).returns(true)
79
+ ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:strong_parameters_enabled?).returns(false)
80
+ simulate_inside_engine(RailsEngine::Engine, RailsEngine) do
81
+ run_generator ["monster"]
82
+
83
+ assert_file "app/models/rails_engine/monster.rb", /devise/
84
+ assert_file "app/models/rails_engine/monster.rb" do |content|
85
+ assert_match /attr_accessible :email/, content
86
+ end
87
+ end
88
+ end
89
+
90
+ test "all files are properly created in rails 3.2 when strong_parameters gem is installed" do
91
+ ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:rails_3?).returns(true)
92
+ ActiveRecord::Generators::DeviseGenerator.any_instance.stubs(:strong_parameters_enabled?).returns(true)
93
+ simulate_inside_engine(RailsEngine::Engine, RailsEngine) do
94
+ run_generator ["monster"]
95
+
96
+ assert_file "app/models/rails_engine/monster.rb", /devise/
97
+ assert_file "app/models/rails_engine/monster.rb" do |content|
98
+ assert_no_match /attr_accessible :email/, content
99
+ end
70
100
  end
71
101
  end
72
102
  end
@@ -327,6 +327,20 @@ class AuthenticationSessionTest < ActionDispatch::IntegrationTest
327
327
  assert_redirected_to new_user_session_path
328
328
  end
329
329
 
330
+ test 'refreshes _csrf_token' do
331
+ ApplicationController.allow_forgery_protection = true
332
+
333
+ begin
334
+ get new_user_session_path
335
+ token = request.session[:_csrf_token]
336
+
337
+ sign_in_as_user
338
+ assert_not_equal request.session[:_csrf_token], token
339
+ ensure
340
+ ApplicationController.allow_forgery_protection = false
341
+ end
342
+ end
343
+
330
344
  test 'allows session to be set for a given scope' do
331
345
  sign_in_as_user
332
346
  get '/users'
@@ -419,7 +433,7 @@ end
419
433
 
420
434
  class AuthenticationOthersTest < ActionDispatch::IntegrationTest
421
435
  test 'handles unverified requests gets rid of caches' do
422
- swap UsersController, :allow_forgery_protection => true do
436
+ swap ApplicationController, :allow_forgery_protection => true do
423
437
  post exhibit_user_url(1)
424
438
  assert_not warden.authenticated?(:user)
425
439
 
@@ -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.confirmation_token)
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,22 @@ 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.confirmation_token)
57
+ visit_user_confirmation_with_token(user.raw_confirmation_token)
70
58
 
71
- assert_contain 'Your account was successfully confirmed.'
72
- assert_current_url '/'
59
+ assert_contain 'Your account was successfully confirmed. Please sign in.'
60
+ assert_current_url '/users/sign_in'
61
+ assert user.reload.confirmed?
62
+ end
63
+ end
64
+
65
+ test 'user should be signed in after confirmation if allow_insecure_sign_in_after_confirmation is enabled' do
66
+ swap Devise, :confirm_within => 3.days, :allow_insecure_sign_in_after_confirmation => true do
67
+ user = create_user(:confirm => false, :confirmation_sent_at => 2.days.ago)
68
+ assert_not user.confirmed?
69
+ visit_user_confirmation_with_token(user.raw_confirmation_token)
70
+
71
+ assert_contain 'Your account was successfully confirmed. You are now signed in.'
72
+ assert_current_url root_url
73
73
  assert user.reload.confirmed?
74
74
  end
75
75
  end
@@ -78,7 +78,7 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
78
78
  Devise::ConfirmationsController.any_instance.stubs(:after_confirmation_path_for).returns("/?custom=1")
79
79
 
80
80
  user = create_user(:confirm => false)
81
- visit_user_confirmation_with_token(user.confirmation_token)
81
+ visit_user_confirmation_with_token(user.raw_confirmation_token)
82
82
 
83
83
  assert_current_url "/?custom=1"
84
84
  end
@@ -87,7 +87,7 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
87
87
  user = create_user(:confirm => false)
88
88
  user.confirmed_at = Time.now
89
89
  user.save
90
- visit_user_confirmation_with_token(user.confirmation_token)
90
+ visit_user_confirmation_with_token(user.raw_confirmation_token)
91
91
 
92
92
  assert_have_selector '#error_explanation'
93
93
  assert_contain 'already confirmed'
@@ -98,7 +98,7 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
98
98
  user.confirmed_at = Time.now
99
99
  user.save
100
100
 
101
- visit_user_confirmation_with_token(user.confirmation_token)
101
+ visit_user_confirmation_with_token(user.raw_confirmation_token)
102
102
  assert_contain 'already confirmed'
103
103
 
104
104
  fill_in 'email', :with => user.email
@@ -106,21 +106,6 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
106
106
  assert_contain 'already confirmed'
107
107
  end
108
108
 
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
109
  test 'not confirmed user with setup to block without confirmation should not be able to sign in' do
125
110
  swap Devise, :allow_unconfirmed_access_for => 0.days do
126
111
  sign_in_as_user(:confirm => false)
@@ -175,7 +160,7 @@ class ConfirmationTest < ActionDispatch::IntegrationTest
175
160
 
176
161
  test 'confirm account with valid confirmation token in XML format should return valid response' do
177
162
  user = create_user(:confirm => false)
178
- get user_confirmation_path(:confirmation_token => user.confirmation_token, :format => 'xml')
163
+ get user_confirmation_path(:confirmation_token => user.raw_confirmation_token, :format => 'xml')
179
164
  assert_response :success
180
165
  assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<user>)
181
166
  end
@@ -256,10 +241,10 @@ class ConfirmationOnChangeTest < ActionDispatch::IntegrationTest
256
241
  admin = create_admin
257
242
  admin.update_attributes(:email => 'new_test@example.com')
258
243
  assert_equal 'new_test@example.com', admin.unconfirmed_email
259
- visit_admin_confirmation_with_token(admin.confirmation_token)
244
+ visit_admin_confirmation_with_token(admin.raw_confirmation_token)
260
245
 
261
246
  assert_contain 'Your account was successfully confirmed.'
262
- assert_current_url '/admin_area/home'
247
+ assert_current_url '/admin_area/sign_in'
263
248
  assert admin.reload.confirmed?
264
249
  assert_not admin.reload.pending_reconfirmation?
265
250
  end
@@ -269,17 +254,19 @@ class ConfirmationOnChangeTest < ActionDispatch::IntegrationTest
269
254
  admin.update_attributes(:email => 'first_test@example.com')
270
255
  assert_equal 'first_test@example.com', admin.unconfirmed_email
271
256
 
272
- confirmation_token = admin.confirmation_token
257
+ raw_confirmation_token = admin.raw_confirmation_token
258
+ admin = Admin.find(admin.id)
259
+
273
260
  admin.update_attributes(:email => 'second_test@example.com')
274
261
  assert_equal 'second_test@example.com', admin.unconfirmed_email
275
262
 
276
- visit_admin_confirmation_with_token(confirmation_token)
263
+ visit_admin_confirmation_with_token(raw_confirmation_token)
277
264
  assert_have_selector '#error_explanation'
278
265
  assert_contain(/Confirmation token(.*)invalid/)
279
266
 
280
- visit_admin_confirmation_with_token(admin.confirmation_token)
267
+ visit_admin_confirmation_with_token(admin.raw_confirmation_token)
281
268
  assert_contain 'Your account was successfully confirmed.'
282
- assert_current_url '/admin_area/home'
269
+ assert_current_url '/admin_area/sign_in'
283
270
  assert admin.reload.confirmed?
284
271
  assert_not admin.reload.pending_reconfirmation?
285
272
  end
@@ -291,7 +278,7 @@ class ConfirmationOnChangeTest < ActionDispatch::IntegrationTest
291
278
 
292
279
  create_second_admin(:email => "new_admin_test@example.com")
293
280
 
294
- visit_admin_confirmation_with_token(admin.confirmation_token)
281
+ visit_admin_confirmation_with_token(admin.raw_confirmation_token)
295
282
  assert_have_selector '#error_explanation'
296
283
  assert_contain(/Email.*already.*taken/)
297
284
  assert admin.reload.pending_reconfirmation?
@@ -2,7 +2,7 @@ require 'test_helper'
2
2
 
3
3
  class HttpAuthenticationTest < ActionDispatch::IntegrationTest
4
4
  test 'handles unverified requests gets rid of caches but continues signed in' do
5
- swap UsersController, :allow_forgery_protection => true do
5
+ swap ApplicationController, :allow_forgery_protection => true do
6
6
  create_user
7
7
  post exhibit_user_url(1), {}, "HTTP_AUTHORIZATION" => "Basic #{Base64.encode64("user@test.com:12345678")}"
8
8
  assert warden.authenticated?(:user)
@@ -13,6 +13,7 @@ class LockTest < ActionDispatch::IntegrationTest
13
13
  visit new_user_session_path
14
14
  click_link "Didn't receive unlock instructions?"
15
15
 
16
+ Devise.stubs(:friendly_token).returns("abcdef")
16
17
  fill_in 'email', :with => user.email
17
18
  click_button 'Resend unlock instructions'
18
19
  end
@@ -22,8 +23,11 @@ class LockTest < ActionDispatch::IntegrationTest
22
23
 
23
24
  assert_template 'sessions/new'
24
25
  assert_contain 'You will receive an email with instructions about how to unlock your account in a few minutes'
26
+
27
+ mail = ActionMailer::Base.deliveries.last
25
28
  assert_equal 1, ActionMailer::Base.deliveries.size
26
- assert_equal ['please-change-me@config-initializers-devise.com'], ActionMailer::Base.deliveries.first.from
29
+ assert_equal ['please-change-me@config-initializers-devise.com'], mail.from
30
+ assert_match user_unlock_path(unlock_token: 'abcdef'), mail.body.encoded
27
31
  end
28
32
 
29
33
  test 'user should receive the instructions from a custom mailer' do
@@ -75,23 +79,15 @@ class LockTest < ActionDispatch::IntegrationTest
75
79
  end
76
80
 
77
81
  test "locked user should be able to unlock account" do
78
- user = create_user(:locked => true)
79
- assert user.access_locked?
80
-
81
- visit_user_unlock_with_token(user.unlock_token)
82
+ user = create_user
83
+ raw = user.lock_access!
84
+ visit_user_unlock_with_token(raw)
82
85
 
83
86
  assert_current_url "/users/sign_in"
84
87
  assert_contain 'Your account has been unlocked successfully. Please sign in to continue.'
85
-
86
88
  assert_not user.reload.access_locked?
87
89
  end
88
90
 
89
- test "redirect user to sign in page after unlocking its account" do
90
- user = create_user(:locked => true)
91
- visit_user_unlock_with_token(user.unlock_token)
92
- assert_not warden.authenticated?(:user)
93
- end
94
-
95
91
  test "user should not send a new e-mail if already locked" do
96
92
  user = create_user(:locked => true)
97
93
  user.failed_attempts = User.maximum_attempts + 1
@@ -153,9 +149,10 @@ class LockTest < ActionDispatch::IntegrationTest
153
149
  end
154
150
 
155
151
  test 'user with valid unlock token should be able to unlock account via XML request' do
156
- user = create_user(:locked => true)
152
+ user = create_user()
153
+ raw = user.lock_access!
157
154
  assert user.access_locked?
158
- get user_unlock_path(:format => 'xml', :unlock_token => user.unlock_token)
155
+ get user_unlock_path(:format => 'xml', :unlock_token => raw)
159
156
  assert_response :success
160
157
  assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<user>)
161
158
  end
@@ -14,12 +14,16 @@ class PasswordTest < ActionDispatch::IntegrationTest
14
14
 
15
15
  fill_in 'email', :with => 'user@test.com'
16
16
  yield if block_given?
17
+
18
+ Devise.stubs(:friendly_token).returns("abcdef")
17
19
  click_button 'Send me reset password instructions'
18
20
  end
19
21
 
20
22
  def reset_password(options={}, &block)
21
- visit edit_user_password_path(:reset_password_token => options[:reset_password_token]) unless options[:visit] == false
22
- assert_response :success
23
+ unless options[:visit] == false
24
+ visit edit_user_password_path(:reset_password_token => options[:reset_password_token] || "abcdef")
25
+ assert_response :success
26
+ end
23
27
 
24
28
  fill_in 'New password', :with => '987654321'
25
29
  fill_in 'Confirm new password', :with => '987654321'
@@ -45,7 +49,10 @@ class PasswordTest < ActionDispatch::IntegrationTest
45
49
  request_forgot_password do
46
50
  fill_in 'email', :with => 'foo@bar.com'
47
51
  end
48
- assert_equal ['custom@example.com'], ActionMailer::Base.deliveries.last.from
52
+
53
+ mail = ActionMailer::Base.deliveries.last
54
+ assert_equal ['custom@example.com'], mail.from
55
+ assert_match edit_user_password_path(reset_password_token: 'abcdef'), mail.body.encoded
49
56
  end
50
57
 
51
58
  test 'reset password with email of different case should fail when email is NOT the list of case insensitive keys' do
@@ -146,7 +153,7 @@ class PasswordTest < ActionDispatch::IntegrationTest
146
153
  test 'not authenticated user with valid reset password token but invalid password should not be able to change his password' do
147
154
  user = create_user
148
155
  request_forgot_password
149
- reset_password :reset_password_token => user.reload.reset_password_token do
156
+ reset_password do
150
157
  fill_in 'Confirm new password', :with => 'other_password'
151
158
  end
152
159
 
@@ -161,7 +168,7 @@ class PasswordTest < ActionDispatch::IntegrationTest
161
168
  test 'not authenticated user with valid data should be able to change his password' do
162
169
  user = create_user
163
170
  request_forgot_password
164
- reset_password :reset_password_token => user.reload.reset_password_token
171
+ reset_password
165
172
 
166
173
  assert_current_url '/'
167
174
  assert_contain 'Your password was changed successfully. You are now signed in.'
@@ -171,14 +178,13 @@ class PasswordTest < ActionDispatch::IntegrationTest
171
178
  test 'after entering invalid data user should still be able to change his password' do
172
179
  user = create_user
173
180
  request_forgot_password
174
- reset_password :reset_password_token => user.reload.reset_password_token do
175
- fill_in 'Confirm new password', :with => 'other_password'
176
- end
181
+
182
+ reset_password { fill_in 'Confirm new password', :with => 'other_password' }
177
183
  assert_response :success
178
184
  assert_have_selector '#error_explanation'
179
185
  assert_not user.reload.valid_password?('987654321')
180
186
 
181
- reset_password :reset_password_token => user.reload.reset_password_token, :visit => false
187
+ reset_password :visit => false
182
188
  assert_contain 'Your password was changed successfully.'
183
189
  assert user.reload.valid_password?('987654321')
184
190
  end
@@ -186,7 +192,7 @@ class PasswordTest < ActionDispatch::IntegrationTest
186
192
  test 'sign in user automatically after changing its password' do
187
193
  user = create_user
188
194
  request_forgot_password
189
- reset_password :reset_password_token => user.reload.reset_password_token
195
+ reset_password
190
196
 
191
197
  assert warden.authenticated?(:user)
192
198
  end
@@ -196,7 +202,7 @@ class PasswordTest < ActionDispatch::IntegrationTest
196
202
  swap Devise, :unlock_strategy => strategy do
197
203
  user = create_user(:locked => true)
198
204
  request_forgot_password
199
- reset_password :reset_password_token => user.reload.reset_password_token
205
+ reset_password
200
206
 
201
207
  assert_contain 'Your password was changed successfully.'
202
208
  assert_not_contain 'You are now signed in.'
@@ -210,7 +216,7 @@ class PasswordTest < ActionDispatch::IntegrationTest
210
216
  swap Devise, :unlock_strategy => :email do
211
217
  user = create_user(:locked => true)
212
218
  request_forgot_password
213
- reset_password :reset_password_token => user.reload.reset_password_token
219
+ reset_password
214
220
 
215
221
  assert_contain 'Your password was changed successfully.'
216
222
  assert !user.reload.access_locked?
@@ -222,7 +228,7 @@ class PasswordTest < ActionDispatch::IntegrationTest
222
228
  swap Devise, :unlock_strategy => :both do
223
229
  user = create_user(:locked => true)
224
230
  request_forgot_password
225
- reset_password :reset_password_token => user.reload.reset_password_token
231
+ reset_password
226
232
 
227
233
  assert_contain 'Your password was changed successfully.'
228
234
  assert !user.reload.access_locked?
@@ -230,15 +236,6 @@ class PasswordTest < ActionDispatch::IntegrationTest
230
236
  end
231
237
  end
232
238
 
233
- test 'sign in user automatically and confirm after changing its password if it\'s not confirmed' do
234
- user = create_user(:confirm => false)
235
- request_forgot_password
236
- reset_password :reset_password_token => user.reload.reset_password_token
237
-
238
- assert warden.authenticated?(:user)
239
- assert user.reload.confirmed?
240
- end
241
-
242
239
  test 'reset password request with valid E-Mail in XML format should return valid response' do
243
240
  create_user
244
241
  post user_password_path(:format => 'xml'), :user => {:email => "user@test.com"}
@@ -265,7 +262,9 @@ class PasswordTest < ActionDispatch::IntegrationTest
265
262
  test 'change password with valid parameters in XML format should return valid response' do
266
263
  user = create_user
267
264
  request_forgot_password
268
- put user_password_path(:format => 'xml'), :user => {:reset_password_token => user.reload.reset_password_token, :password => '987654321', :password_confirmation => '987654321'}
265
+ put user_password_path(:format => 'xml'), :user => {
266
+ :reset_password_token => 'abcdef', :password => '987654321', :password_confirmation => '987654321'
267
+ }
269
268
  assert_response :success
270
269
  assert warden.authenticated?(:user)
271
270
  end
@@ -326,7 +325,7 @@ class PasswordTest < ActionDispatch::IntegrationTest
326
325
 
327
326
  assert_equal 10, user.failed_attempts
328
327
  request_forgot_password
329
- reset_password :reset_password_token => user.reload.reset_password_token
328
+ reset_password
330
329
 
331
330
  assert warden.authenticated?(:user)
332
331
  user.reload
@@ -30,8 +30,8 @@ class RememberMeTest < ActionDispatch::IntegrationTest
30
30
  assert_nil request.cookies["remember_user_cookie"]
31
31
  end
32
32
 
33
- test 'handles unverified requests gets rid of caches' do
34
- swap UsersController, :allow_forgery_protection => true do
33
+ test 'handle unverified requests gets rid of caches' do
34
+ swap ApplicationController, :allow_forgery_protection => true do
35
35
  post exhibit_user_url(1)
36
36
  assert_not warden.authenticated?(:user)
37
37
 
@@ -42,9 +42,21 @@ class RememberMeTest < ActionDispatch::IntegrationTest
42
42
  end
43
43
  end
44
44
 
45
+ test 'handle unverified requests does not create cookies on sign in' do
46
+ swap ApplicationController, :allow_forgery_protection => true do
47
+ get new_user_session_path
48
+ assert request.session[:_csrf_token]
49
+
50
+ post user_session_path, :authenticity_token => "oops", :user =>
51
+ { email: "jose.valim@gmail.com", password: "123456", :remember_me => "1" }
52
+ assert_not warden.authenticated?(:user)
53
+ assert_not request.cookies['remember_user_token']
54
+ end
55
+ end
56
+
45
57
  test 'generate remember token after sign in' do
46
58
  sign_in_as_user :remember_me => true
47
- assert request.cookies["remember_user_token"]
59
+ assert request.cookies['remember_user_token']
48
60
  end
49
61
 
50
62
  test 'generate remember token after sign in setting cookie options' do
@@ -90,16 +102,6 @@ class RememberMeTest < ActionDispatch::IntegrationTest
90
102
  assert_redirected_to root_path
91
103
  end
92
104
 
93
- test 'cookies are destroyed on unverified requests' do
94
- swap ApplicationController, :allow_forgery_protection => true do
95
- create_user_and_remember
96
- get users_path
97
- assert warden.authenticated?(:user)
98
- post root_path, :authenticity_token => 'INVALID'
99
- assert_not warden.authenticated?(:user)
100
- end
101
- end
102
-
103
105
  test 'does not extend remember period through sign in' do
104
106
  swap Devise, :extend_remember_period => true, :remember_for => 1.year do
105
107
  user = create_user
@@ -84,8 +84,12 @@ class ConfirmationInstructionsTest < ActionMailer::TestCase
84
84
 
85
85
  test 'body should have link to confirm the account' do
86
86
  host = ActionMailer::Base.default_url_options[:host]
87
- confirmation_url_regexp = %r{<a href=\"http://#{host}/users/confirmation\?confirmation_token=#{user.confirmation_token}">}
88
- assert_match confirmation_url_regexp, mail.body.encoded
87
+
88
+ if mail.body.encoded =~ %r{<a href=\"http://#{host}/users/confirmation\?confirmation_token=([^"]+)">}
89
+ assert_equal Devise.token_generator.digest(user.class, :confirmation_token, $1), user.confirmation_token
90
+ else
91
+ flunk "expected confirmation url regex to match"
92
+ end
89
93
  end
90
94
 
91
95
  test 'renders a scoped if scoped_views is set to true' do
@@ -80,8 +80,12 @@ class ResetPasswordInstructionsTest < ActionMailer::TestCase
80
80
 
81
81
  test 'body should have link to confirm the account' do
82
82
  host = ActionMailer::Base.default_url_options[:host]
83
- reset_url_regexp = %r{<a href=\"http://#{host}/users/password/edit\?reset_password_token=#{user.reset_password_token}">}
84
- assert_match reset_url_regexp, mail.body.encoded
83
+
84
+ if mail.body.encoded =~ %r{<a href=\"http://#{host}/users/password/edit\?reset_password_token=([^"]+)">}
85
+ assert_equal Devise.token_generator.digest(user.class, :reset_password_token, $1), user.reset_password_token
86
+ else
87
+ flunk "expected reset password url regex to match"
88
+ end
85
89
  end
86
90
 
87
91
  test 'mailer sender accepts a proc' do
@@ -81,7 +81,11 @@ class UnlockInstructionsTest < ActionMailer::TestCase
81
81
 
82
82
  test 'body should have link to unlock the account' do
83
83
  host = ActionMailer::Base.default_url_options[:host]
84
- unlock_url_regexp = %r{<a href=\"http://#{host}/users/unlock\?unlock_token=#{user.unlock_token}">}
85
- assert_match unlock_url_regexp, mail.body.encoded
84
+
85
+ if mail.body.encoded =~ %r{<a href=\"http://#{host}/users/unlock\?unlock_token=([^"]+)">}
86
+ assert_equal Devise.token_generator.digest(user.class, :unlock_token, $1), user.unlock_token
87
+ else
88
+ flunk "expected unlock url regex to match"
89
+ end
86
90
  end
87
91
  end
@@ -51,9 +51,19 @@ class ConfirmableTest < ActiveSupport::TestCase
51
51
  assert_equal "was already confirmed, please try signing in", user.errors[:email].join
52
52
  end
53
53
 
54
- test 'should find and confirm a user automatically' do
54
+ test 'DEPRECATED: should find and confirm a user automatically' do
55
+ swap Devise, allow_insecure_token_lookup: true do
56
+ user = create_user
57
+ confirmed_user = User.confirm_by_token(user.confirmation_token)
58
+ assert_equal confirmed_user, user
59
+ assert user.reload.confirmed?
60
+ end
61
+ end
62
+
63
+ test 'should find and confirm a user automatically based on the raw token' do
55
64
  user = create_user
56
- confirmed_user = User.confirm_by_token(user.confirmation_token)
65
+ raw = user.raw_confirmation_token
66
+ confirmed_user = User.confirm_by_token(raw)
57
67
  assert_equal confirmed_user, user
58
68
  assert user.reload.confirmed?
59
69
  end
@@ -74,7 +84,7 @@ class ConfirmableTest < ActiveSupport::TestCase
74
84
  user = create_user
75
85
  user.confirmed_at = Time.now
76
86
  user.save
77
- confirmed_user = User.confirm_by_token(user.confirmation_token)
87
+ confirmed_user = User.confirm_by_token(user.raw_confirmation_token)
78
88
  assert confirmed_user.confirmed?
79
89
  assert_equal "was already confirmed, please try signing in", confirmed_user.errors[:email].join
80
90
  end
@@ -176,7 +186,7 @@ class ConfirmableTest < ActiveSupport::TestCase
176
186
  test 'should not be able to send instructions if the user is already confirmed' do
177
187
  user = create_user
178
188
  user.confirm!
179
- assert_not user.resend_confirmation_token
189
+ assert_not user.resend_confirmation_instructions
180
190
  assert user.confirmed?
181
191
  assert_equal 'was already confirmed, please try signing in', user.errors[:email].join
182
192
  end
@@ -264,7 +274,7 @@ class ConfirmableTest < ActiveSupport::TestCase
264
274
  def confirm_user_by_token_with_confirmation_sent_at(confirmation_sent_at)
265
275
  user = create_user
266
276
  user.update_attribute(:confirmation_sent_at, confirmation_sent_at)
267
- confirmed_user = User.confirm_by_token(user.confirmation_token)
277
+ confirmed_user = User.confirm_by_token(user.raw_confirmation_token)
268
278
  assert_equal confirmed_user, user
269
279
  user.reload.confirmed?
270
280
  end
@@ -285,32 +295,33 @@ class ConfirmableTest < ActiveSupport::TestCase
285
295
  end
286
296
  end
287
297
 
288
- test 'should generate a new token if the previous one has expired' do
289
- swap Devise, :confirm_within => 3.days do
290
- user = create_user
291
- user.update_attribute(:confirmation_sent_at, 4.days.ago)
292
- old = user.confirmation_token
293
- user.resend_confirmation_token
294
- assert_not_equal user.confirmation_token, old
295
- end
298
+ test 'always generate a new token on resend' do
299
+ user = create_user
300
+ old = user.confirmation_token
301
+ user = User.find(user.id)
302
+ user.resend_confirmation_instructions
303
+ assert_not_equal user.confirmation_token, old
296
304
  end
297
-
298
- test 'should generate a new token when a valid one does not exist' do
299
- swap Devise, :confirm_within => 3.days do
300
- user = create_user
301
- user.update_attribute(:confirmation_sent_at, 4.days.ago)
302
- old = user.confirmation_token
303
- user.ensure_confirmation_token!
304
- assert_not_equal user.confirmation_token, old
305
+
306
+ test 'should call after_confirmation if confirmed' do
307
+ user = create_user
308
+ user.define_singleton_method :after_confirmation do
309
+ self.username = self.username.to_s + 'updated'
305
310
  end
311
+ old = user.username
312
+ assert user.confirm!
313
+ assert_not_equal user.username, old
306
314
  end
307
-
308
- test 'should not generate a new token when a valid one exists' do
315
+
316
+ test 'should not call after_confirmation if not confirmed' do
309
317
  user = create_user
310
- assert_not_nil user.confirmation_token
311
- old = user.confirmation_token
312
- user.ensure_confirmation_token!
313
- assert_equal user.confirmation_token, old
318
+ assert user.confirm!
319
+ user.define_singleton_method :after_confirmation do
320
+ self.username = self.username.to_s + 'updated'
321
+ end
322
+ old = user.username
323
+ assert_not user.confirm!
324
+ assert_equal user.username, old
314
325
  end
315
326
  end
316
327