devise 3.2.4 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

Files changed (178) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.travis.yml +33 -17
  4. data/CHANGELOG.md +57 -1033
  5. data/CODE_OF_CONDUCT.md +22 -0
  6. data/CONTRIBUTING.md +2 -0
  7. data/Gemfile +5 -5
  8. data/Gemfile.lock +138 -115
  9. data/MIT-LICENSE +1 -1
  10. data/README.md +124 -65
  11. data/Rakefile +2 -1
  12. data/app/controllers/devise/confirmations_controller.rb +7 -3
  13. data/app/controllers/devise/omniauth_callbacks_controller.rb +8 -4
  14. data/app/controllers/devise/passwords_controller.rb +16 -6
  15. data/app/controllers/devise/registrations_controller.rb +22 -10
  16. data/app/controllers/devise/sessions_controller.rb +42 -14
  17. data/app/controllers/devise/unlocks_controller.rb +5 -2
  18. data/app/controllers/devise_controller.rb +63 -29
  19. data/app/mailers/devise/mailer.rb +4 -0
  20. data/app/views/devise/confirmations/new.html.erb +7 -3
  21. data/app/views/devise/mailer/password_change.html.erb +3 -0
  22. data/app/views/devise/passwords/edit.html.erb +14 -5
  23. data/app/views/devise/passwords/new.html.erb +7 -3
  24. data/app/views/devise/registrations/edit.html.erb +19 -9
  25. data/app/views/devise/registrations/new.html.erb +18 -7
  26. data/app/views/devise/sessions/new.html.erb +16 -7
  27. data/app/views/devise/shared/{_links.erb → _links.html.erb} +2 -2
  28. data/app/views/devise/unlocks/new.html.erb +7 -3
  29. data/bin/test +13 -0
  30. data/config/locales/en.yml +19 -16
  31. data/devise.gemspec +3 -4
  32. data/gemfiles/{Gemfile.rails-3.2-stable → Gemfile.rails-4.1-stable} +6 -6
  33. data/gemfiles/Gemfile.rails-4.1-stable.lock +167 -0
  34. data/gemfiles/{Gemfile.rails-head → Gemfile.rails-4.2-stable} +6 -6
  35. data/gemfiles/Gemfile.rails-4.2-stable.lock +189 -0
  36. data/gemfiles/Gemfile.rails-5.0-beta +37 -0
  37. data/gemfiles/Gemfile.rails-5.0-beta.lock +199 -0
  38. data/lib/devise/controllers/helpers.rb +94 -27
  39. data/lib/devise/controllers/rememberable.rb +9 -2
  40. data/lib/devise/controllers/sign_in_out.rb +2 -9
  41. data/lib/devise/controllers/store_location.rb +11 -3
  42. data/lib/devise/controllers/url_helpers.rb +7 -7
  43. data/lib/devise/encryptor.rb +22 -0
  44. data/lib/devise/failure_app.rb +72 -23
  45. data/lib/devise/hooks/activatable.rb +3 -4
  46. data/lib/devise/hooks/csrf_cleaner.rb +3 -1
  47. data/lib/devise/hooks/timeoutable.rb +13 -8
  48. data/lib/devise/mailers/helpers.rb +1 -1
  49. data/lib/devise/mapping.rb +6 -2
  50. data/lib/devise/models/authenticatable.rb +32 -28
  51. data/lib/devise/models/confirmable.rb +55 -22
  52. data/lib/devise/models/database_authenticatable.rb +32 -19
  53. data/lib/devise/models/lockable.rb +5 -5
  54. data/lib/devise/models/recoverable.rb +44 -20
  55. data/lib/devise/models/rememberable.rb +54 -27
  56. data/lib/devise/models/timeoutable.rb +0 -6
  57. data/lib/devise/models/trackable.rb +5 -3
  58. data/lib/devise/models/validatable.rb +3 -3
  59. data/lib/devise/models.rb +1 -1
  60. data/lib/devise/omniauth/url_helpers.rb +62 -4
  61. data/lib/devise/parameter_sanitizer.rb +176 -61
  62. data/lib/devise/rails/routes.rb +76 -59
  63. data/lib/devise/rails/warden_compat.rb +1 -10
  64. data/lib/devise/rails.rb +2 -11
  65. data/lib/devise/strategies/authenticatable.rb +15 -6
  66. data/lib/devise/strategies/database_authenticatable.rb +5 -4
  67. data/lib/devise/strategies/rememberable.rb +13 -3
  68. data/lib/devise/test_helpers.rb +12 -7
  69. data/lib/devise/token_generator.rb +1 -41
  70. data/lib/devise/version.rb +1 -1
  71. data/lib/devise.rb +150 -58
  72. data/lib/generators/active_record/devise_generator.rb +28 -4
  73. data/lib/generators/active_record/templates/migration.rb +3 -3
  74. data/lib/generators/active_record/templates/migration_existing.rb +3 -3
  75. data/lib/generators/devise/controllers_generator.rb +44 -0
  76. data/lib/generators/devise/install_generator.rb +15 -0
  77. data/lib/generators/devise/orm_helpers.rb +1 -18
  78. data/lib/generators/devise/views_generator.rb +14 -3
  79. data/lib/generators/templates/README +1 -1
  80. data/lib/generators/templates/controllers/README +14 -0
  81. data/lib/generators/templates/controllers/confirmations_controller.rb +28 -0
  82. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +28 -0
  83. data/lib/generators/templates/controllers/passwords_controller.rb +32 -0
  84. data/lib/generators/templates/controllers/registrations_controller.rb +60 -0
  85. data/lib/generators/templates/controllers/sessions_controller.rb +25 -0
  86. data/lib/generators/templates/controllers/unlocks_controller.rb +28 -0
  87. data/lib/generators/templates/devise.rb +36 -28
  88. data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
  89. data/lib/generators/templates/markerb/password_change.markerb +3 -0
  90. data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
  91. data/lib/generators/templates/markerb/unlock_instructions.markerb +1 -1
  92. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +1 -1
  93. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +1 -1
  94. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +2 -2
  95. data/test/controllers/custom_registrations_controller_test.rb +40 -0
  96. data/test/controllers/custom_strategy_test.rb +7 -5
  97. data/test/controllers/helper_methods_test.rb +22 -0
  98. data/test/controllers/helpers_test.rb +41 -1
  99. data/test/controllers/inherited_controller_i18n_messages_test.rb +51 -0
  100. data/test/controllers/internal_helpers_test.rb +19 -15
  101. data/test/controllers/load_hooks_controller_test.rb +19 -0
  102. data/test/controllers/passwords_controller_test.rb +5 -4
  103. data/test/controllers/sessions_controller_test.rb +24 -21
  104. data/test/controllers/url_helpers_test.rb +7 -1
  105. data/test/devise_test.rb +48 -8
  106. data/test/failure_app_test.rb +107 -19
  107. data/test/generators/active_record_generator_test.rb +6 -26
  108. data/test/generators/controllers_generator_test.rb +48 -0
  109. data/test/generators/install_generator_test.rb +14 -3
  110. data/test/generators/views_generator_test.rb +8 -1
  111. data/test/helpers/devise_helper_test.rb +10 -12
  112. data/test/integration/authenticatable_test.rb +37 -21
  113. data/test/integration/confirmable_test.rb +54 -14
  114. data/test/integration/database_authenticatable_test.rb +12 -1
  115. data/test/integration/http_authenticatable_test.rb +4 -5
  116. data/test/integration/lockable_test.rb +10 -9
  117. data/test/integration/omniauthable_test.rb +13 -11
  118. data/test/integration/recoverable_test.rb +28 -15
  119. data/test/integration/registerable_test.rb +41 -33
  120. data/test/integration/rememberable_test.rb +51 -7
  121. data/test/integration/timeoutable_test.rb +23 -22
  122. data/test/integration/trackable_test.rb +3 -3
  123. data/test/mailers/confirmation_instructions_test.rb +10 -10
  124. data/test/mailers/reset_password_instructions_test.rb +8 -8
  125. data/test/mailers/unlock_instructions_test.rb +8 -8
  126. data/test/mapping_test.rb +7 -0
  127. data/test/models/authenticatable_test.rb +11 -1
  128. data/test/models/confirmable_test.rb +91 -42
  129. data/test/models/database_authenticatable_test.rb +26 -6
  130. data/test/models/lockable_test.rb +29 -17
  131. data/test/models/recoverable_test.rb +74 -7
  132. data/test/models/rememberable_test.rb +68 -94
  133. data/test/models/trackable_test.rb +28 -0
  134. data/test/models/validatable_test.rb +9 -17
  135. data/test/models_test.rb +15 -6
  136. data/test/omniauth/url_helpers_test.rb +4 -7
  137. data/test/orm/active_record.rb +6 -1
  138. data/test/parameter_sanitizer_test.rb +103 -53
  139. data/test/rails_app/app/active_record/user.rb +1 -0
  140. data/test/rails_app/app/active_record/user_on_engine.rb +7 -0
  141. data/test/rails_app/app/active_record/user_on_main_app.rb +7 -0
  142. data/test/rails_app/app/active_record/user_without_email.rb +8 -0
  143. data/test/rails_app/app/controllers/admins_controller.rb +1 -6
  144. data/test/rails_app/app/controllers/application_controller.rb +5 -2
  145. data/test/rails_app/app/controllers/application_with_fake_engine.rb +30 -0
  146. data/test/rails_app/app/controllers/custom/registrations_controller.rb +31 -0
  147. data/test/rails_app/app/controllers/home_controller.rb +5 -1
  148. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +3 -3
  149. data/test/rails_app/app/controllers/users_controller.rb +6 -6
  150. data/test/rails_app/app/mailers/users/from_proc_mailer.rb +3 -0
  151. data/test/rails_app/app/mailers/users/mailer.rb +0 -9
  152. data/test/rails_app/app/mailers/users/reply_to_mailer.rb +4 -0
  153. data/test/rails_app/app/mongoid/user_on_engine.rb +39 -0
  154. data/test/rails_app/app/mongoid/user_on_main_app.rb +39 -0
  155. data/test/rails_app/app/mongoid/user_without_email.rb +33 -0
  156. data/test/rails_app/config/application.rb +3 -3
  157. data/test/rails_app/config/boot.rb +4 -4
  158. data/test/rails_app/config/environments/production.rb +6 -2
  159. data/test/rails_app/config/environments/test.rb +13 -3
  160. data/test/rails_app/config/initializers/devise.rb +15 -16
  161. data/test/rails_app/config/initializers/secret_token.rb +1 -6
  162. data/test/rails_app/config/routes.rb +23 -3
  163. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +2 -2
  164. data/test/rails_app/lib/shared_user.rb +1 -1
  165. data/test/rails_app/lib/shared_user_without_email.rb +26 -0
  166. data/test/rails_app/lib/shared_user_without_omniauth.rb +13 -0
  167. data/test/rails_test.rb +9 -0
  168. data/test/routes_test.rb +33 -16
  169. data/test/support/assertions.rb +2 -3
  170. data/test/support/helpers.rb +13 -6
  171. data/test/support/http_method_compatibility.rb +51 -0
  172. data/test/support/integration.rb +4 -4
  173. data/test/support/webrat/integrations/rails.rb +9 -0
  174. data/test/test_helper.rb +7 -0
  175. data/test/test_helpers_test.rb +43 -38
  176. data/test/test_models.rb +3 -3
  177. metadata +77 -23
  178. data/gemfiles/Gemfile.rails-4.0-stable +0 -29
@@ -39,30 +39,30 @@ class ResetPasswordInstructionsTest < ActionMailer::TestCase
39
39
  assert_equal [user.email], mail.to
40
40
  end
41
41
 
42
- test 'setup sender from configuration' do
42
+ test 'set up sender from configuration' do
43
43
  assert_equal ['test@example.com'], mail.from
44
44
  end
45
45
 
46
- test 'setup sender from custom mailer defaults' do
46
+ test 'set up sender from custom mailer defaults' do
47
47
  Devise.mailer = 'Users::Mailer'
48
48
  assert_equal ['custom@example.com'], mail.from
49
49
  end
50
50
 
51
- test 'setup sender from custom mailer defaults with proc' do
51
+ test 'set up sender from custom mailer defaults with proc' do
52
52
  Devise.mailer = 'Users::FromProcMailer'
53
53
  assert_equal ['custom@example.com'], mail.from
54
54
  end
55
55
 
56
56
  test 'custom mailer renders parent mailer template' do
57
57
  Devise.mailer = 'Users::Mailer'
58
- assert_not_blank mail.body.encoded
58
+ assert_present mail.body.encoded
59
59
  end
60
60
 
61
- test 'setup reply to as copy from sender' do
61
+ test 'set up reply to as copy from sender' do
62
62
  assert_equal ['test@example.com'], mail.reply_to
63
63
  end
64
64
 
65
- test 'setup subject from I18n' do
65
+ test 'set up subject from I18n' do
66
66
  store_translations :en, devise: { mailer: { reset_password_instructions: { subject: 'Reset instructions' } } } do
67
67
  assert_equal 'Reset instructions', mail.subject
68
68
  end
@@ -79,9 +79,9 @@ class ResetPasswordInstructionsTest < ActionMailer::TestCase
79
79
  end
80
80
 
81
81
  test 'body should have link to confirm the account' do
82
- host = ActionMailer::Base.default_url_options[:host]
82
+ host, port = ActionMailer::Base.default_url_options.values_at :host, :port
83
83
 
84
- if mail.body.encoded =~ %r{<a href=\"http://#{host}/users/password/edit\?reset_password_token=([^"]+)">}
84
+ if mail.body.encoded =~ %r{<a href=\"http://#{host}:#{port}/users/password/edit\?reset_password_token=([^"]+)">}
85
85
  assert_equal Devise.token_generator.digest(user.class, :reset_password_token, $1), user.reset_password_token
86
86
  else
87
87
  flunk "expected reset password url regex to match"
@@ -40,30 +40,30 @@ class UnlockInstructionsTest < ActionMailer::TestCase
40
40
  assert_equal [user.email], mail.to
41
41
  end
42
42
 
43
- test 'setup sender from configuration' do
43
+ test 'set up sender from configuration' do
44
44
  assert_equal ['test@example.com'], mail.from
45
45
  end
46
46
 
47
- test 'setup sender from custom mailer defaults' do
47
+ test 'set up sender from custom mailer defaults' do
48
48
  Devise.mailer = 'Users::Mailer'
49
49
  assert_equal ['custom@example.com'], mail.from
50
50
  end
51
51
 
52
- test 'setup sender from custom mailer defaults with proc' do
52
+ test 'set up sender from custom mailer defaults with proc' do
53
53
  Devise.mailer = 'Users::FromProcMailer'
54
54
  assert_equal ['custom@example.com'], mail.from
55
55
  end
56
56
 
57
57
  test 'custom mailer renders parent mailer template' do
58
58
  Devise.mailer = 'Users::Mailer'
59
- assert_not_blank mail.body.encoded
59
+ assert_present mail.body.encoded
60
60
  end
61
61
 
62
- test 'setup reply to as copy from sender' do
62
+ test 'set up reply to as copy from sender' do
63
63
  assert_equal ['test@example.com'], mail.reply_to
64
64
  end
65
65
 
66
- test 'setup subject from I18n' do
66
+ test 'set up subject from I18n' do
67
67
  store_translations :en, devise: { mailer: { unlock_instructions: { subject: 'Yo unlock instructions' } } } do
68
68
  assert_equal 'Yo unlock instructions', mail.subject
69
69
  end
@@ -80,9 +80,9 @@ class UnlockInstructionsTest < ActionMailer::TestCase
80
80
  end
81
81
 
82
82
  test 'body should have link to unlock the account' do
83
- host = ActionMailer::Base.default_url_options[:host]
83
+ host, port = ActionMailer::Base.default_url_options.values_at :host, :port
84
84
 
85
- if mail.body.encoded =~ %r{<a href=\"http://#{host}/users/unlock\?unlock_token=([^"]+)">}
85
+ if mail.body.encoded =~ %r{<a href=\"http://#{host}:#{port}/users/unlock\?unlock_token=([^"]+)">}
86
86
  assert_equal Devise.token_generator.digest(user.class, :unlock_token, $1), user.unlock_token
87
87
  else
88
88
  flunk "expected unlock url regex to match"
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)
@@ -6,8 +6,18 @@ class AuthenticatableTest < ActiveSupport::TestCase
6
6
  end
7
7
 
8
8
  test 'find_first_by_auth_conditions allows custom filtering parameters' do
9
- user = User.create!(email: "example@example.com", password: "123456")
9
+ user = User.create!(email: "example@example.com", password: "1234567")
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"
@@ -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.confirm!
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
- assert_nil user.confirmation_token
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
@@ -184,7 +188,7 @@ class ConfirmableTest < ActiveSupport::TestCase
184
188
 
185
189
  test 'confirm time should fallback to devise confirm in default configuration' do
186
190
  swap Devise, allow_unconfirmed_access_for: 1.day do
187
- user = new_user
191
+ user = create_user
188
192
  user.confirmation_sent_at = 2.days.ago
189
193
  assert_not user.active_for_authentication?
190
194
 
@@ -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 = Date.today
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.allow_unconfirmed_access_for = nil
228
- user = create_user
229
- user.confirmation_sent_at = Date.today
230
- assert user.active_for_authentication?
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 'always generate a new token on resend' do
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
- assert_not_equal user.confirmation_token, old
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
- assert_nil admin.confirmation_token
360
+ assert admin.confirm
361
+ residual_token = admin.confirmation_token
330
362
  assert admin.update_attributes(email: 'new_test@example.com')
331
- assert_not_nil admin.confirmation_token
363
+ assert_not_equal residual_token, admin.confirmation_token
332
364
  end
333
365
 
334
- test 'should not generate confirmation token if skipping reconfirmation after changing email' do
366
+ test 'should not regenerate confirmation token or require reconfirmation if skipping reconfirmation after changing email' do
335
367
  admin = create_admin
336
- assert admin.confirm!
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
- assert_nil admin.confirmation_token
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,7 @@ 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
363
398
  assert_email_sent "new_test@example.com" do
364
399
  assert admin.update_attributes(email: 'new_test@example.com')
365
400
  end
@@ -368,7 +403,7 @@ class ReconfirmableTest < ActiveSupport::TestCase
368
403
 
369
404
  test 'should not send confirmation by email after changing password' do
370
405
  admin = create_admin
371
- assert admin.confirm!
406
+ assert admin.confirm
372
407
  assert_email_not_sent do
373
408
  assert admin.update_attributes(password: 'newpass', password_confirmation: 'newpass')
374
409
  end
@@ -376,7 +411,7 @@ class ReconfirmableTest < ActiveSupport::TestCase
376
411
 
377
412
  test 'should not send confirmation by email after changing to a blank email' do
378
413
  admin = create_admin
379
- assert admin.confirm!
414
+ assert admin.confirm
380
415
  assert_email_not_sent do
381
416
  admin.email = ''
382
417
  admin.save(validate: false)
@@ -385,23 +420,23 @@ class ReconfirmableTest < ActiveSupport::TestCase
385
420
 
386
421
  test 'should stay confirmed when email is changed' do
387
422
  admin = create_admin
388
- assert admin.confirm!
423
+ assert admin.confirm
389
424
  assert admin.update_attributes(email: 'new_test@example.com')
390
425
  assert admin.confirmed?
391
426
  end
392
427
 
393
428
  test 'should update email only when it is confirmed' do
394
429
  admin = create_admin
395
- assert admin.confirm!
430
+ assert admin.confirm
396
431
  assert admin.update_attributes(email: 'new_test@example.com')
397
432
  assert_not_equal 'new_test@example.com', admin.email
398
- assert admin.confirm!
433
+ assert admin.confirm
399
434
  assert_equal 'new_test@example.com', admin.email
400
435
  end
401
436
 
402
437
  test 'should not allow admin to get past confirmation email by resubmitting their new address' do
403
438
  admin = create_admin
404
- assert admin.confirm!
439
+ assert admin.confirm
405
440
  assert admin.update_attributes(email: 'new_test@example.com')
406
441
  assert_not_equal 'new_test@example.com', admin.email
407
442
  assert admin.update_attributes(email: 'new_test@example.com')
@@ -410,7 +445,7 @@ class ReconfirmableTest < ActiveSupport::TestCase
410
445
 
411
446
  test 'should find a admin by send confirmation instructions with unconfirmed_email' do
412
447
  admin = create_admin
413
- assert admin.confirm!
448
+ assert admin.confirm
414
449
  assert admin.update_attributes(email: 'new_test@example.com')
415
450
  confirmation_admin = Admin.send_confirmation_instructions(email: admin.unconfirmed_email)
416
451
  assert_equal confirmation_admin, admin
@@ -451,4 +486,18 @@ class ReconfirmableTest < ActiveSupport::TestCase
451
486
  :unconfirmed_email
452
487
  ]
453
488
  end
489
+
490
+ test 'should not require reconfirmation after creating a record' do
491
+ user = create_admin
492
+ assert !user.pending_reconfirmation?
493
+ end
494
+
495
+ test 'should not require reconfirmation after creating a record with #save called in callback' do
496
+ class Admin::WithSaveInCallback < Admin
497
+ after_create :save
498
+ end
499
+
500
+ user = Admin::WithSaveInCallback.create(valid_attributes.except(:username))
501
+ assert !user.pending_reconfirmation?
502
+ end
454
503
  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'
@@ -88,28 +92,28 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
88
92
  assert user.respond_to?(:password_confirmation)
89
93
  end
90
94
 
91
- test 'should generate encrypted password while setting password' do
95
+ test 'should generate a hashed password while setting password' do
92
96
  user = new_user
93
97
  assert_present user.encrypted_password
94
98
  end
95
99
 
96
- test 'should support custom encryption methods' do
97
- user = UserWithCustomEncryption.new(password: '654321')
100
+ test 'should support custom hashing methods' do
101
+ user = UserWithCustomHashing.new(password: '654321')
98
102
  assert_equal user.encrypted_password, '123456'
99
103
  end
100
104
 
101
- test 'allow authenticatable_salt to work even with nil encrypted password' do
105
+ test 'allow authenticatable_salt to work even with nil hashed password' do
102
106
  user = User.new
103
107
  user.encrypted_password = nil
104
108
  assert_nil user.authenticatable_salt
105
109
  end
106
110
 
107
- test 'should not generate encrypted password if password is blank' do
111
+ test 'should not generate a hashed password if password is blank' do
108
112
  assert_blank new_user(password: nil).encrypted_password
109
113
  assert_blank new_user(password: '').encrypted_password
110
114
  end
111
115
 
112
- test 'should encrypt password again if password has changed' do
116
+ test 'should hash password again if password has changed' do
113
117
  user = create_user
114
118
  encrypted_password = user.encrypted_password
115
119
  user.password = user.password_confirmation = 'new_password'
@@ -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")
@@ -7,16 +7,16 @@ class LockableTest < ActiveSupport::TestCase
7
7
 
8
8
  test "should respect maximum attempts configuration" do
9
9
  user = create_user
10
- user.confirm!
10
+ user.confirm
11
11
  swap Devise, maximum_attempts: 2 do
12
12
  2.times { user.valid_for_authentication?{ false } }
13
13
  assert user.reload.access_locked?
14
14
  end
15
15
  end
16
16
 
17
- test "should increment failed_attempts on successfull validation if the user is already locked" do
17
+ test "should increment failed_attempts on successful validation if the user is already locked" do
18
18
  user = create_user
19
- user.confirm!
19
+ user.confirm
20
20
 
21
21
  swap Devise, maximum_attempts: 2 do
22
22
  2.times { user.valid_for_authentication?{ false } }
@@ -29,7 +29,7 @@ class LockableTest < ActiveSupport::TestCase
29
29
 
30
30
  test "should not touch failed_attempts if lock_strategy is none" do
31
31
  user = create_user
32
- user.confirm!
32
+ user.confirm
33
33
  swap Devise, lock_strategy: :none, maximum_attempts: 2 do
34
34
  3.times { user.valid_for_authentication?{ false } }
35
35
  assert !user.access_locked?
@@ -53,7 +53,7 @@ class LockableTest < ActiveSupport::TestCase
53
53
 
54
54
  test "active_for_authentication? should be the opposite of locked?" do
55
55
  user = create_user
56
- user.confirm!
56
+ user.confirm
57
57
  assert user.active_for_authentication?
58
58
  user.lock_access!
59
59
  assert_not user.active_for_authentication?
@@ -230,7 +230,7 @@ class LockableTest < ActiveSupport::TestCase
230
230
  test 'should unlock account if lock has expired and increase attempts on failure' do
231
231
  swap Devise, unlock_in: 1.minute do
232
232
  user = create_user
233
- user.confirm!
233
+ user.confirm
234
234
 
235
235
  user.failed_attempts = 2
236
236
  user.locked_at = 2.minutes.ago
@@ -243,7 +243,7 @@ class LockableTest < ActiveSupport::TestCase
243
243
  test 'should unlock account if lock has expired on success' do
244
244
  swap Devise, unlock_in: 1.minute do
245
245
  user = create_user
246
- user.confirm!
246
+ user.confirm
247
247
 
248
248
  user.failed_attempts = 2
249
249
  user.locked_at = 2.minutes.ago
@@ -299,18 +299,30 @@ class LockableTest < ActiveSupport::TestCase
299
299
  end
300
300
 
301
301
  test 'should return last attempt message if user made next-to-last attempt of password entering' do
302
- swap Devise, last_attempt_warning: :true do
303
- swap Devise, lock_strategy: :failed_attempts do
304
- user = create_user
305
- user.failed_attempts = Devise.maximum_attempts - 2
306
- assert_equal :invalid, user.unauthenticated_message
302
+ swap Devise, last_attempt_warning: true, lock_strategy: :failed_attempts do
303
+ user = create_user
304
+ user.failed_attempts = Devise.maximum_attempts - 2
305
+ assert_equal :invalid, user.unauthenticated_message
307
306
 
308
- user.failed_attempts = Devise.maximum_attempts - 1
309
- assert_equal :last_attempt, user.unauthenticated_message
307
+ user.failed_attempts = Devise.maximum_attempts - 1
308
+ assert_equal :last_attempt, user.unauthenticated_message
310
309
 
311
- user.failed_attempts = Devise.maximum_attempts
312
- assert_equal :locked, user.unauthenticated_message
313
- end
310
+ user.failed_attempts = Devise.maximum_attempts
311
+ assert_equal :locked, user.unauthenticated_message
314
312
  end
315
313
  end
314
+
315
+ test 'should not return last attempt message if last_attempt_warning is disabled' do
316
+ swap Devise, last_attempt_warning: false, lock_strategy: :failed_attempts do
317
+ user = create_user
318
+ user.failed_attempts = Devise.maximum_attempts - 1
319
+ assert_equal :invalid, user.unauthenticated_message
320
+ end
321
+ end
322
+
323
+ test 'should return locked message if user was programatically locked' do
324
+ user = create_user
325
+ user.lock_access!
326
+ assert_equal :locked, user.unauthenticated_message
327
+ end
316
328
  end