devise 2.1.2 → 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.

Files changed (242) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +39 -10
  3. data/.yardopts +9 -0
  4. data/{CHANGELOG.rdoc → CHANGELOG.md} +445 -112
  5. data/CODE_OF_CONDUCT.md +22 -0
  6. data/CONTRIBUTING.md +16 -0
  7. data/Gemfile +10 -15
  8. data/Gemfile.lock +151 -129
  9. data/MIT-LICENSE +1 -1
  10. data/README.md +256 -96
  11. data/Rakefile +4 -2
  12. data/app/controllers/devise/confirmations_controller.rb +15 -7
  13. data/app/controllers/devise/omniauth_callbacks_controller.rb +6 -2
  14. data/app/controllers/devise/passwords_controller.rb +33 -9
  15. data/app/controllers/devise/registrations_controller.rb +66 -26
  16. data/app/controllers/devise/sessions_controller.rb +52 -21
  17. data/app/controllers/devise/unlocks_controller.rb +11 -6
  18. data/app/controllers/devise_controller.rb +65 -58
  19. data/app/helpers/devise_helper.rb +2 -2
  20. data/app/mailers/devise/mailer.rb +19 -10
  21. data/app/views/devise/confirmations/new.html.erb +8 -4
  22. data/app/views/devise/mailer/confirmation_instructions.html.erb +2 -2
  23. data/app/views/devise/mailer/password_change.html.erb +3 -0
  24. data/app/views/devise/mailer/reset_password_instructions.html.erb +2 -2
  25. data/app/views/devise/mailer/unlock_instructions.html.erb +2 -2
  26. data/app/views/devise/passwords/edit.html.erb +15 -6
  27. data/app/views/devise/passwords/new.html.erb +8 -4
  28. data/app/views/devise/registrations/edit.html.erb +29 -15
  29. data/app/views/devise/registrations/new.html.erb +19 -8
  30. data/app/views/devise/sessions/new.html.erb +17 -8
  31. data/app/views/devise/shared/{_links.erb → _links.html.erb} +4 -4
  32. data/app/views/devise/unlocks/new.html.erb +8 -4
  33. data/config/locales/en.yml +51 -47
  34. data/devise.gemspec +8 -6
  35. data/devise.png +0 -0
  36. data/gemfiles/Gemfile.rails-3.2-stable +29 -0
  37. data/gemfiles/Gemfile.rails-3.2-stable.lock +172 -0
  38. data/gemfiles/Gemfile.rails-4.0-stable +30 -0
  39. data/gemfiles/Gemfile.rails-4.0-stable.lock +166 -0
  40. data/gemfiles/Gemfile.rails-4.1-stable +30 -0
  41. data/gemfiles/Gemfile.rails-4.1-stable.lock +171 -0
  42. data/gemfiles/Gemfile.rails-4.2-stable +30 -0
  43. data/gemfiles/Gemfile.rails-4.2-stable.lock +193 -0
  44. data/lib/devise/controllers/helpers.rb +126 -108
  45. data/lib/devise/controllers/rememberable.rb +19 -17
  46. data/lib/devise/controllers/scoped_views.rb +1 -1
  47. data/lib/devise/controllers/sign_in_out.rb +96 -0
  48. data/lib/devise/controllers/store_location.rb +58 -0
  49. data/lib/devise/controllers/url_helpers.rb +7 -7
  50. data/lib/devise/encryptor.rb +22 -0
  51. data/lib/devise/failure_app.rb +85 -25
  52. data/lib/devise/hooks/activatable.rb +5 -6
  53. data/lib/devise/hooks/csrf_cleaner.rb +7 -0
  54. data/lib/devise/hooks/forgetable.rb +1 -1
  55. data/lib/devise/hooks/lockable.rb +2 -2
  56. data/lib/devise/hooks/proxy.rb +21 -0
  57. data/lib/devise/hooks/rememberable.rb +5 -4
  58. data/lib/devise/hooks/timeoutable.rb +16 -8
  59. data/lib/devise/hooks/trackable.rb +1 -1
  60. data/lib/devise/mailers/helpers.rb +27 -23
  61. data/lib/devise/mapping.rb +11 -7
  62. data/lib/devise/models/authenticatable.rb +82 -66
  63. data/lib/devise/models/confirmable.rb +142 -55
  64. data/lib/devise/models/database_authenticatable.rb +59 -15
  65. data/lib/devise/models/lockable.rb +41 -30
  66. data/lib/devise/models/omniauthable.rb +3 -3
  67. data/lib/devise/models/recoverable.rb +56 -41
  68. data/lib/devise/models/rememberable.rb +65 -27
  69. data/lib/devise/models/timeoutable.rb +2 -8
  70. data/lib/devise/models/trackable.rb +6 -4
  71. data/lib/devise/models/validatable.rb +9 -9
  72. data/lib/devise/models.rb +4 -13
  73. data/lib/devise/modules.rb +10 -11
  74. data/lib/devise/omniauth/url_helpers.rb +2 -2
  75. data/lib/devise/orm/active_record.rb +1 -1
  76. data/lib/devise/orm/mongoid.rb +1 -1
  77. data/lib/devise/{param_filter.rb → parameter_filter.rb} +10 -11
  78. data/lib/devise/parameter_sanitizer.rb +99 -0
  79. data/lib/devise/rails/routes.rb +173 -115
  80. data/lib/devise/rails/warden_compat.rb +10 -31
  81. data/lib/devise/rails.rb +14 -12
  82. data/lib/devise/strategies/authenticatable.rb +26 -26
  83. data/lib/devise/strategies/base.rb +1 -1
  84. data/lib/devise/strategies/database_authenticatable.rb +8 -4
  85. data/lib/devise/strategies/rememberable.rb +15 -5
  86. data/lib/devise/test_helpers.rb +7 -5
  87. data/lib/devise/time_inflector.rb +14 -0
  88. data/lib/devise/token_generator.rb +70 -0
  89. data/lib/devise/version.rb +1 -1
  90. data/lib/devise.rb +110 -52
  91. data/lib/generators/active_record/devise_generator.rb +34 -18
  92. data/lib/generators/active_record/templates/migration.rb +5 -6
  93. data/lib/generators/active_record/templates/migration_existing.rb +5 -6
  94. data/lib/generators/devise/controllers_generator.rb +44 -0
  95. data/lib/generators/devise/devise_generator.rb +5 -3
  96. data/lib/generators/devise/install_generator.rb +5 -0
  97. data/lib/generators/devise/orm_helpers.rb +25 -6
  98. data/lib/generators/devise/views_generator.rb +52 -22
  99. data/lib/generators/mongoid/devise_generator.rb +21 -26
  100. data/lib/generators/templates/README +9 -5
  101. data/lib/generators/templates/controllers/README +14 -0
  102. data/lib/generators/templates/controllers/confirmations_controller.rb +28 -0
  103. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +28 -0
  104. data/lib/generators/templates/controllers/passwords_controller.rb +32 -0
  105. data/lib/generators/templates/controllers/registrations_controller.rb +60 -0
  106. data/lib/generators/templates/controllers/sessions_controller.rb +25 -0
  107. data/lib/generators/templates/controllers/unlocks_controller.rb +28 -0
  108. data/lib/generators/templates/devise.rb +80 -43
  109. data/lib/generators/templates/markerb/confirmation_instructions.markerb +2 -2
  110. data/lib/generators/templates/markerb/password_change.markerb +3 -0
  111. data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
  112. data/lib/generators/templates/markerb/unlock_instructions.markerb +2 -2
  113. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +3 -2
  114. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +4 -4
  115. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +2 -2
  116. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +11 -6
  117. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +4 -4
  118. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +6 -6
  119. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +3 -2
  120. data/script/cached-bundle +49 -0
  121. data/script/s3-put +71 -0
  122. data/test/controllers/custom_registrations_controller_test.rb +40 -0
  123. data/test/controllers/helper_methods_test.rb +21 -0
  124. data/test/controllers/helpers_test.rb +95 -32
  125. data/test/controllers/inherited_controller_i18n_messages_test.rb +51 -0
  126. data/test/controllers/internal_helpers_test.rb +39 -14
  127. data/test/controllers/load_hooks_controller_test.rb +19 -0
  128. data/test/controllers/passwords_controller_test.rb +31 -0
  129. data/test/controllers/sessions_controller_test.rb +66 -6
  130. data/test/controllers/url_helpers_test.rb +10 -4
  131. data/test/delegator_test.rb +1 -1
  132. data/test/devise_test.rb +45 -10
  133. data/test/failure_app_test.rb +121 -27
  134. data/test/generators/active_record_generator_test.rb +48 -8
  135. data/test/generators/controllers_generator_test.rb +48 -0
  136. data/test/generators/devise_generator_test.rb +2 -2
  137. data/test/generators/mongoid_generator_test.rb +3 -3
  138. data/test/generators/views_generator_test.rb +54 -3
  139. data/test/helpers/devise_helper_test.rb +18 -20
  140. data/test/integration/authenticatable_test.rb +161 -65
  141. data/test/integration/confirmable_test.rb +146 -77
  142. data/test/integration/database_authenticatable_test.rb +43 -30
  143. data/test/integration/http_authenticatable_test.rb +30 -22
  144. data/test/integration/lockable_test.rb +64 -49
  145. data/test/integration/omniauthable_test.rb +17 -15
  146. data/test/integration/recoverable_test.rb +111 -70
  147. data/test/integration/registerable_test.rb +114 -79
  148. data/test/integration/rememberable_test.rb +87 -31
  149. data/test/integration/timeoutable_test.rb +77 -33
  150. data/test/integration/trackable_test.rb +5 -5
  151. data/test/mailers/confirmation_instructions_test.rb +28 -8
  152. data/test/mailers/reset_password_instructions_test.rb +21 -8
  153. data/test/mailers/unlock_instructions_test.rb +20 -6
  154. data/test/mapping_test.rb +12 -5
  155. data/test/models/authenticatable_test.rb +17 -1
  156. data/test/models/confirmable_test.rb +216 -62
  157. data/test/models/database_authenticatable_test.rb +129 -49
  158. data/test/models/lockable_test.rb +132 -45
  159. data/test/models/recoverable_test.rb +100 -54
  160. data/test/models/rememberable_test.rb +89 -94
  161. data/test/models/serializable_test.rb +12 -11
  162. data/test/models/timeoutable_test.rb +6 -1
  163. data/test/models/trackable_test.rb +28 -0
  164. data/test/models/validatable_test.rb +31 -21
  165. data/test/models_test.rb +22 -48
  166. data/test/omniauth/config_test.rb +4 -4
  167. data/test/omniauth/url_helpers_test.rb +7 -4
  168. data/test/orm/active_record.rb +1 -0
  169. data/test/orm/mongoid.rb +2 -3
  170. data/test/parameter_sanitizer_test.rb +81 -0
  171. data/test/rails_app/Rakefile +0 -4
  172. data/test/rails_app/app/active_record/shim.rb +1 -1
  173. data/test/rails_app/app/active_record/user_on_engine.rb +7 -0
  174. data/test/rails_app/app/active_record/user_on_main_app.rb +7 -0
  175. data/test/rails_app/app/active_record/user_without_email.rb +8 -0
  176. data/test/rails_app/app/controllers/admins/sessions_controller.rb +1 -1
  177. data/test/rails_app/app/controllers/admins_controller.rb +0 -5
  178. data/test/rails_app/app/controllers/application_controller.rb +6 -2
  179. data/test/rails_app/app/controllers/application_with_fake_engine.rb +30 -0
  180. data/test/rails_app/app/controllers/custom/registrations_controller.rb +31 -0
  181. data/test/rails_app/app/controllers/home_controller.rb +1 -1
  182. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +1 -1
  183. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +1 -1
  184. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +4 -4
  185. data/test/rails_app/app/controllers/users_controller.rb +12 -4
  186. data/test/rails_app/app/mailers/users/from_proc_mailer.rb +3 -0
  187. data/test/rails_app/app/mailers/users/mailer.rb +1 -1
  188. data/test/rails_app/app/mailers/users/reply_to_mailer.rb +4 -0
  189. data/test/rails_app/app/mongoid/admin.rb +12 -10
  190. data/test/rails_app/app/mongoid/shim.rb +4 -5
  191. data/test/rails_app/app/mongoid/user.rb +19 -22
  192. data/test/rails_app/app/mongoid/user_on_engine.rb +39 -0
  193. data/test/rails_app/app/mongoid/user_on_main_app.rb +39 -0
  194. data/test/rails_app/app/mongoid/user_without_email.rb +33 -0
  195. data/test/rails_app/app/views/admins/sessions/new.html.erb +1 -1
  196. data/test/rails_app/app/views/home/admin_dashboard.html.erb +1 -1
  197. data/test/rails_app/app/views/home/index.html.erb +1 -1
  198. data/test/rails_app/app/views/home/join.html.erb +1 -1
  199. data/test/rails_app/app/views/home/user_dashboard.html.erb +1 -1
  200. data/test/rails_app/app/views/layouts/application.html.erb +1 -1
  201. data/test/rails_app/app/views/users/edit_form.html.erb +1 -0
  202. data/test/rails_app/bin/bundle +3 -0
  203. data/test/rails_app/bin/rails +4 -0
  204. data/test/rails_app/bin/rake +4 -0
  205. data/test/rails_app/config/application.rb +4 -5
  206. data/test/rails_app/config/boot.rb +9 -3
  207. data/test/rails_app/config/environment.rb +2 -2
  208. data/test/rails_app/config/environments/development.rb +19 -7
  209. data/test/rails_app/config/environments/production.rb +68 -17
  210. data/test/rails_app/config/environments/test.rb +24 -16
  211. data/test/rails_app/config/initializers/devise.rb +22 -20
  212. data/test/rails_app/config/initializers/secret_token.rb +8 -2
  213. data/test/rails_app/config/initializers/session_store.rb +1 -0
  214. data/test/rails_app/config/routes.rb +71 -46
  215. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +9 -12
  216. data/test/rails_app/db/schema.rb +21 -18
  217. data/test/rails_app/lib/shared_admin.rb +7 -4
  218. data/test/rails_app/lib/shared_user.rb +6 -3
  219. data/test/rails_app/lib/shared_user_without_email.rb +26 -0
  220. data/test/rails_app/lib/shared_user_without_omniauth.rb +13 -0
  221. data/test/rails_test.rb +9 -0
  222. data/test/routes_test.rb +94 -78
  223. data/test/support/action_controller/record_identifier.rb +10 -0
  224. data/test/support/assertions.rb +2 -3
  225. data/test/support/helpers.rb +18 -32
  226. data/test/support/integration.rb +17 -16
  227. data/test/support/locale/en.yml +4 -0
  228. data/test/support/mongoid.yml +6 -0
  229. data/test/test_helper.rb +8 -1
  230. data/test/test_helpers_test.rb +64 -20
  231. data/test/test_models.rb +33 -0
  232. data/test/time_helpers.rb +137 -0
  233. metadata +172 -51
  234. data/app/views/devise/_links.erb +0 -3
  235. data/gemfiles/Gemfile.rails-3.1.x +0 -35
  236. data/gemfiles/Gemfile.rails-3.1.x.lock +0 -167
  237. data/lib/devise/models/token_authenticatable.rb +0 -77
  238. data/lib/devise/strategies/token_authenticatable.rb +0 -56
  239. data/test/indifferent_hash.rb +0 -33
  240. data/test/integration/token_authenticatable_test.rb +0 -161
  241. data/test/models/token_authenticatable_test.rb +0 -55
  242. data/test/rails_app/script/rails +0 -10
@@ -1,37 +1,89 @@
1
1
  require 'test_helper'
2
+ require 'test_models'
2
3
  require 'digest/sha1'
3
4
 
4
5
  class DatabaseAuthenticatableTest < ActiveSupport::TestCase
6
+ def setup
7
+ setup_mailer
8
+ end
9
+
5
10
  test 'should downcase case insensitive keys when saving' do
6
11
  # case_insensitive_keys is set to :email by default.
7
12
  email = 'Foo@Bar.com'
8
- user = new_user(:email => email)
13
+ user = new_user(email: email)
9
14
 
10
15
  assert_equal email, user.email
11
16
  user.save!
12
17
  assert_equal email.downcase, user.email
13
18
  end
14
19
 
20
+ test 'should downcase case insensitive keys that refer to virtual attributes when saving' do
21
+ email = 'Foo@Bar1.com'
22
+ confirmation = 'Foo@Bar1.com'
23
+ attributes = valid_attributes(email: email, email_confirmation: confirmation)
24
+ user = UserWithVirtualAttributes.new(attributes)
25
+
26
+ assert_equal confirmation, user.email_confirmation
27
+ user.save!
28
+ assert_equal confirmation.downcase, user.email_confirmation
29
+ end
30
+
31
+ test 'should not mutate value assigned to case insensitive key' do
32
+ email = 'Foo@Bar.com'
33
+ original_email = email.dup
34
+ user = new_user(email: email)
35
+
36
+ user.save!
37
+ assert_equal original_email, email
38
+ end
39
+
15
40
  test 'should remove whitespace from strip whitespace keys when saving' do
16
41
  # strip_whitespace_keys is set to :email by default.
17
42
  email = ' foo@bar.com '
18
- user = new_user(:email => email)
43
+ user = new_user(email: email)
19
44
 
20
45
  assert_equal email, user.email
21
46
  user.save!
22
47
  assert_equal email.strip, user.email
23
48
  end
24
49
 
50
+ test 'should not mutate value assigned to string whitespace key' do
51
+ email = ' foo@bar.com '
52
+ original_email = email.dup
53
+ user = new_user(email: email)
54
+
55
+ user.save!
56
+ assert_equal original_email, email
57
+ end
58
+
59
+ test "doesn't throw exception when globally configured strip_whitespace_keys are not present on a model" do
60
+ swap Devise, strip_whitespace_keys: [:fake_key] do
61
+ assert_nothing_raised { create_user }
62
+ end
63
+ end
64
+
65
+ test "doesn't throw exception when globally configured case_insensitive_keys are not present on a model" do
66
+ swap Devise, case_insensitive_keys: [:fake_key] do
67
+ assert_nothing_raised { create_user }
68
+ end
69
+ end
70
+
25
71
  test "param filter should not convert booleans and integer to strings" do
26
- conditions = { 'login' => 'foo@bar.com', "bool1" => true, "bool2" => false, "fixnum" => 123, "will_be_converted" => (1..10) }
27
- conditions = Devise::ParamFilter.new([], []).filter(conditions)
28
- assert_equal( { 'login' => 'foo@bar.com', "bool1" => true, "bool2" => false, "fixnum" => 123, "will_be_converted" => "1..10" }, conditions)
72
+ conditions = { "login" => "foo@bar.com", "bool1" => true, "bool2" => false, "fixnum" => 123, "will_be_converted" => (1..10) }
73
+ conditions = Devise::ParameterFilter.new([], []).filter(conditions)
74
+ assert_equal( { "login" => "foo@bar.com", "bool1" => "true", "bool2" => "false", "fixnum" => "123", "will_be_converted" => "1..10" }, conditions)
75
+ end
76
+
77
+ test 'param filter should filter case_insensitive_keys as insensitive' do
78
+ conditions = {'insensitive' => 'insensitive_VAL', 'sensitive' => 'sensitive_VAL'}
79
+ conditions = Devise::ParameterFilter.new(['insensitive'], []).filter(conditions)
80
+ assert_equal( {'insensitive' => 'insensitive_val', 'sensitive' => 'sensitive_VAL'}, conditions )
29
81
  end
30
82
 
31
- test "param filter should not convert regular expressions to strings" do
32
- conditions = { "regexp" => /expression/ }
33
- conditions = Devise::ParamFilter.new([], []).filter(conditions)
34
- assert_equal( { "regexp" => /expression/ }, conditions)
83
+ test 'param filter should filter strip_whitespace_keys stripping whitespaces' do
84
+ conditions = {'strip_whitespace' => ' strip_whitespace_val ', 'do_not_strip_whitespace' => ' do_not_strip_whitespace_val '}
85
+ conditions = Devise::ParameterFilter.new([], ['strip_whitespace']).filter(conditions)
86
+ assert_equal( {'strip_whitespace' => 'strip_whitespace_val', 'do_not_strip_whitespace' => ' do_not_strip_whitespace_val '}, conditions )
35
87
  end
36
88
 
37
89
  test 'should respond to password and password confirmation' do
@@ -45,6 +97,11 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
45
97
  assert_present user.encrypted_password
46
98
  end
47
99
 
100
+ test 'should support custom encryption methods' do
101
+ user = UserWithCustomEncryption.new(password: '654321')
102
+ assert_equal user.encrypted_password, '123456'
103
+ end
104
+
48
105
  test 'allow authenticatable_salt to work even with nil encrypted password' do
49
106
  user = User.new
50
107
  user.encrypted_password = nil
@@ -52,8 +109,8 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
52
109
  end
53
110
 
54
111
  test 'should not generate encrypted password if password is blank' do
55
- assert_blank new_user(:password => nil).encrypted_password
56
- assert_blank new_user(:password => '').encrypted_password
112
+ assert_blank new_user(password: nil).encrypted_password
113
+ assert_blank new_user(password: '').encrypted_password
57
114
  end
58
115
 
59
116
  test 'should encrypt password again if password has changed' do
@@ -66,14 +123,14 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
66
123
 
67
124
  test 'should test for a valid password' do
68
125
  user = create_user
69
- assert user.valid_password?('123456')
126
+ assert user.valid_password?('12345678')
70
127
  assert_not user.valid_password?('654321')
71
128
  end
72
129
 
73
130
  test 'should not raise error with an empty password' do
74
131
  user = create_user
75
132
  user.encrypted_password = ''
76
- assert_nothing_raised { user.valid_password?('123456') }
133
+ assert_nothing_raised { user.valid_password?('12345678') }
77
134
  end
78
135
 
79
136
  test 'should be an invalid password if the user has an empty password' do
@@ -88,31 +145,24 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
88
145
 
89
146
  test 'should update password with valid current password' do
90
147
  user = create_user
91
- assert user.update_with_password(:current_password => '123456',
92
- :password => 'pass321', :password_confirmation => 'pass321')
93
- assert user.reload.valid_password?('pass321')
94
- end
95
-
96
- test 'should update password with valid current password and :as option' do
97
- user = create_user
98
- assert user.update_with_password(:current_password => '123456',
99
- :password => 'pass321', :password_confirmation => 'pass321', :as => :admin)
100
- assert user.reload.valid_password?('pass321')
148
+ assert user.update_with_password(current_password: '12345678',
149
+ password: 'pass4321', password_confirmation: 'pass4321')
150
+ assert user.reload.valid_password?('pass4321')
101
151
  end
102
152
 
103
153
  test 'should add an error to current password when it is invalid' do
104
154
  user = create_user
105
- assert_not user.update_with_password(:current_password => 'other',
106
- :password => 'pass321', :password_confirmation => 'pass321')
107
- assert user.reload.valid_password?('123456')
155
+ assert_not user.update_with_password(current_password: 'other',
156
+ password: 'pass4321', password_confirmation: 'pass4321')
157
+ assert user.reload.valid_password?('12345678')
108
158
  assert_match "is invalid", user.errors[:current_password].join
109
159
  end
110
160
 
111
161
  test 'should add an error to current password when it is blank' do
112
162
  user = create_user
113
- assert_not user.update_with_password(:password => 'pass321',
114
- :password_confirmation => 'pass321')
115
- assert user.reload.valid_password?('123456')
163
+ assert_not user.update_with_password(password: 'pass4321',
164
+ password_confirmation: 'pass4321')
165
+ assert user.reload.valid_password?('12345678')
116
166
  assert_match "can't be blank", user.errors[:current_password].join
117
167
  end
118
168
 
@@ -120,58 +170,88 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
120
170
  user = UserWithValidation.create!(valid_attributes)
121
171
  user.save
122
172
  assert user.persisted?
123
- assert_not user.update_with_password(:username => "")
173
+ assert_not user.update_with_password(username: "")
124
174
  assert_match "usertest", user.reload.username
125
175
  assert_match "can't be blank", user.errors[:username].join
126
176
  end
127
177
 
128
178
  test 'should ignore password and its confirmation if they are blank' do
129
179
  user = create_user
130
- assert user.update_with_password(:current_password => '123456', :email => "new@example.com")
180
+ assert user.update_with_password(current_password: '12345678', email: "new@example.com")
131
181
  assert_equal "new@example.com", user.email
132
182
  end
133
183
 
134
184
  test 'should not update password with invalid confirmation' do
135
185
  user = create_user
136
- assert_not user.update_with_password(:current_password => '123456',
137
- :password => 'pass321', :password_confirmation => 'other')
138
- assert user.reload.valid_password?('123456')
186
+ assert_not user.update_with_password(current_password: '12345678',
187
+ password: 'pass4321', password_confirmation: 'other')
188
+ assert user.reload.valid_password?('12345678')
139
189
  end
140
190
 
141
191
  test 'should clean up password fields on failure' do
142
192
  user = create_user
143
- assert_not user.update_with_password(:current_password => '123456',
144
- :password => 'pass321', :password_confirmation => 'other')
193
+ assert_not user.update_with_password(current_password: '12345678',
194
+ password: 'pass4321', password_confirmation: 'other')
145
195
  assert user.password.blank?
146
196
  assert user.password_confirmation.blank?
147
197
  end
148
198
 
149
199
  test 'should update the user without password' do
150
200
  user = create_user
151
- user.update_without_password(:email => 'new@example.com')
201
+ user.update_without_password(email: 'new@example.com')
152
202
  assert_equal 'new@example.com', user.email
153
203
  end
154
204
 
155
- test 'should update the user without password with :as option' do
205
+ test 'should not update password without password' do
156
206
  user = create_user
157
- user.update_without_password(:email => 'new@example.com', :as => :admin)
158
- assert_equal 'new@example.com', user.email
207
+ user.update_without_password(password: 'pass4321', password_confirmation: 'pass4321')
208
+ assert !user.reload.valid_password?('pass4321')
209
+ assert user.valid_password?('12345678')
159
210
  end
160
211
 
161
- test 'should not update password without password' do
212
+ test 'should destroy user if current password is valid' do
162
213
  user = create_user
163
- user.update_without_password(:password => 'pass321', :password_confirmation => 'pass321')
164
- assert !user.reload.valid_password?('pass321')
165
- assert user.valid_password?('123456')
214
+ assert user.destroy_with_password('12345678')
215
+ assert !user.persisted?
216
+ end
217
+
218
+ test 'should not destroy user with invalid password' do
219
+ user = create_user
220
+ assert_not user.destroy_with_password('other')
221
+ assert user.persisted?
222
+ assert_match "is invalid", user.errors[:current_password].join
223
+ end
224
+
225
+ test 'should not destroy user with blank password' do
226
+ user = create_user
227
+ assert_not user.destroy_with_password(nil)
228
+ assert user.persisted?
229
+ assert_match "can't be blank", user.errors[:current_password].join
230
+ end
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
166
246
  end
167
247
 
168
248
  test 'downcase_keys with validation' do
169
- user = User.create(:email => "HEllO@example.com", :password => "123456")
170
- user = User.create(:email => "HEllO@example.com", :password => "123456")
249
+ User.create(email: "HEllO@example.com", password: "123456")
250
+ user = User.create(email: "HEllO@example.com", password: "123456")
171
251
  assert !user.valid?
172
252
  end
173
253
 
174
- test 'required_fiels should be encryptable_password and the email field by default' do
254
+ test 'required_fields should be encryptable_password and the email field by default' do
175
255
  assert_same_content Devise::Models::DatabaseAuthenticatable.required_fields(User), [
176
256
  :email,
177
257
  :encrypted_password
@@ -179,11 +259,11 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
179
259
  end
180
260
 
181
261
  test 'required_fields should be encryptable_password and the login when the login is on authentication_keys' do
182
- swap Devise, :authentication_keys => [:login] do
262
+ swap Devise, authentication_keys: [:login] do
183
263
  assert_same_content Devise::Models::DatabaseAuthenticatable.required_fields(User), [
184
264
  :encrypted_password,
185
265
  :login
186
266
  ]
187
267
  end
188
268
  end
189
- end
269
+ end
@@ -7,30 +7,30 @@ class LockableTest < ActiveSupport::TestCase
7
7
 
8
8
  test "should respect maximum attempts configuration" do
9
9
  user = create_user
10
- user.confirm!
11
- swap Devise, :maximum_attempts => 2 do
12
- 3.times { user.valid_for_authentication?{ false } }
10
+ user.confirm
11
+ swap Devise, maximum_attempts: 2 do
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
- swap Devise, :maximum_attempts => 2 do
22
- 3.times { user.valid_for_authentication?{ false } }
21
+ swap Devise, maximum_attempts: 2 do
22
+ 2.times { user.valid_for_authentication?{ false } }
23
23
  assert user.reload.access_locked?
24
24
  end
25
25
 
26
26
  user.valid_for_authentication?{ true }
27
- assert_equal 4, user.reload.failed_attempts
27
+ assert_equal 3, user.reload.failed_attempts
28
28
  end
29
29
 
30
30
  test "should not touch failed_attempts if lock_strategy is none" do
31
31
  user = create_user
32
- user.confirm!
33
- swap Devise, :lock_strategy => :none, :maximum_attempts => 2 do
32
+ user.confirm
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?
36
36
  assert_equal 0, user.failed_attempts
@@ -53,13 +53,13 @@ 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?
60
60
  end
61
61
 
62
- test "should unlock a user by cleaning locked_at, falied_attempts and unlock_token" do
62
+ test "should unlock a user by cleaning locked_at, failed_attempts and unlock_token" do
63
63
  user = create_user
64
64
  user.lock_access!
65
65
  assert_not_nil user.reload.locked_at
@@ -77,7 +77,7 @@ class LockableTest < ActiveSupport::TestCase
77
77
  end
78
78
 
79
79
  test "should unlock user after unlock_in period" do
80
- swap Devise, :unlock_in => 3.hours do
80
+ swap Devise, unlock_in: 3.hours do
81
81
  user = new_user
82
82
  user.locked_at = 2.hours.ago
83
83
  assert user.access_locked?
@@ -88,7 +88,7 @@ class LockableTest < ActiveSupport::TestCase
88
88
  end
89
89
 
90
90
  test "should not unlock in 'unlock_in' if :time unlock strategy is not set" do
91
- swap Devise, :unlock_strategy => :email do
91
+ swap Devise, unlock_strategy: :email do
92
92
  user = new_user
93
93
  user.locked_at = 2.hours.ago
94
94
  assert user.access_locked?
@@ -114,7 +114,7 @@ class LockableTest < ActiveSupport::TestCase
114
114
  end
115
115
 
116
116
  test "should not generate unlock_token when :email is not an unlock strategy" do
117
- swap Devise, :unlock_strategy => :time do
117
+ swap Devise, unlock_strategy: :time do
118
118
  user = create_user
119
119
  user.lock_access!
120
120
  assert_nil user.unlock_token
@@ -122,7 +122,7 @@ class LockableTest < ActiveSupport::TestCase
122
122
  end
123
123
 
124
124
  test "should send email with unlock instructions when :email is an unlock strategy" do
125
- swap Devise, :unlock_strategy => :email do
125
+ swap Devise, unlock_strategy: :email do
126
126
  user = create_user
127
127
  assert_email_sent do
128
128
  user.lock_access!
@@ -130,8 +130,26 @@ class LockableTest < ActiveSupport::TestCase
130
130
  end
131
131
  end
132
132
 
133
+ test "doesn't send email when you pass option send_instructions to false" do
134
+ swap Devise, unlock_strategy: :email do
135
+ user = create_user
136
+ assert_email_not_sent do
137
+ user.lock_access! send_instructions: false
138
+ end
139
+ end
140
+ end
141
+
142
+ test "sends email when you pass options other than send_instructions" do
143
+ swap Devise, unlock_strategy: :email do
144
+ user = create_user
145
+ assert_email_sent do
146
+ user.lock_access! foo: :bar, bar: :foo
147
+ end
148
+ end
149
+ end
150
+
133
151
  test "should not send email with unlock instructions when :email is not an unlock strategy" do
134
- swap Devise, :unlock_strategy => :time do
152
+ swap Devise, unlock_strategy: :time do
135
153
  user = create_user
136
154
  assert_email_not_sent do
137
155
  user.lock_access!
@@ -139,10 +157,10 @@ class LockableTest < ActiveSupport::TestCase
139
157
  end
140
158
  end
141
159
 
142
- test 'should find and unlock a user automatically' do
160
+ test 'should find and unlock a user automatically based on raw token' do
143
161
  user = create_user
144
- user.lock_access!
145
- locked_user = User.unlock_access_by_token(user.unlock_token)
162
+ raw = user.send_unlock_instructions
163
+ locked_user = User.unlock_access_by_token(raw)
146
164
  assert_equal locked_user, user
147
165
  assert_not user.reload.access_locked?
148
166
  end
@@ -162,48 +180,57 @@ class LockableTest < ActiveSupport::TestCase
162
180
  test 'should find a user to send unlock instructions' do
163
181
  user = create_user
164
182
  user.lock_access!
165
- unlock_user = User.send_unlock_instructions(:email => user.email)
183
+ unlock_user = User.send_unlock_instructions(email: user.email)
166
184
  assert_equal unlock_user, user
167
185
  end
168
186
 
169
187
  test 'should return a new user if no email was found' do
170
- unlock_user = User.send_unlock_instructions(:email => "invalid@example.com")
188
+ unlock_user = User.send_unlock_instructions(email: "invalid@example.com")
171
189
  assert_not unlock_user.persisted?
172
190
  end
173
191
 
174
192
  test 'should add error to new user email if no email was found' do
175
- unlock_user = User.send_unlock_instructions(:email => "invalid@example.com")
193
+ unlock_user = User.send_unlock_instructions(email: "invalid@example.com")
176
194
  assert_equal 'not found', unlock_user.errors[:email].join
177
195
  end
178
196
 
179
197
  test 'should find a user to send unlock instructions by authentication_keys' do
180
- swap Devise, :authentication_keys => [:username, :email] do
198
+ swap Devise, authentication_keys: [:username, :email] do
181
199
  user = create_user
182
- unlock_user = User.send_unlock_instructions(:email => user.email, :username => user.username)
200
+ unlock_user = User.send_unlock_instructions(email: user.email, username: user.username)
183
201
  assert_equal unlock_user, user
184
202
  end
185
203
  end
186
204
 
187
205
  test 'should require all unlock_keys' do
188
- swap Devise, :unlock_keys => [:username, :email] do
189
- user = create_user
190
- unlock_user = User.send_unlock_instructions(:email => user.email)
191
- assert_not unlock_user.persisted?
192
- assert_equal "can't be blank", unlock_user.errors[:username].join
193
- end
206
+ swap Devise, unlock_keys: [:username, :email] do
207
+ user = create_user
208
+ unlock_user = User.send_unlock_instructions(email: user.email)
209
+ assert_not unlock_user.persisted?
210
+ assert_equal "can't be blank", unlock_user.errors[:username].join
211
+ end
194
212
  end
195
213
 
196
214
  test 'should not be able to send instructions if the user is not locked' do
197
215
  user = create_user
198
- assert_not user.resend_unlock_token
216
+ assert_not user.resend_unlock_instructions
199
217
  assert_not user.access_locked?
200
218
  assert_equal 'was not locked', user.errors[:email].join
201
219
  end
202
220
 
221
+ test 'should not be able to send instructions if the user if not locked and have username as unlock key' do
222
+ swap Devise, unlock_keys: [:username] do
223
+ user = create_user
224
+ assert_not user.resend_unlock_instructions
225
+ assert_not user.access_locked?
226
+ assert_equal 'was not locked', user.errors[:username].join
227
+ end
228
+ end
229
+
203
230
  test 'should unlock account if lock has expired and increase attempts on failure' do
204
- swap Devise, :unlock_in => 1.minute do
231
+ swap Devise, unlock_in: 1.minute do
205
232
  user = create_user
206
- user.confirm!
233
+ user.confirm
207
234
 
208
235
  user.failed_attempts = 2
209
236
  user.locked_at = 2.minutes.ago
@@ -214,9 +241,9 @@ class LockableTest < ActiveSupport::TestCase
214
241
  end
215
242
 
216
243
  test 'should unlock account if lock has expired on success' do
217
- swap Devise, :unlock_in => 1.minute do
244
+ swap Devise, unlock_in: 1.minute do
218
245
  user = create_user
219
- user.confirm!
246
+ user.confirm
220
247
 
221
248
  user.failed_attempts = 2
222
249
  user.locked_at = 2.minutes.ago
@@ -228,31 +255,31 @@ class LockableTest < ActiveSupport::TestCase
228
255
  end
229
256
 
230
257
  test 'required_fields should contain the all the fields when all the strategies are enabled' do
231
- swap Devise, :unlock_strategy => :both do
232
- swap Devise, :lock_strategy => :failed_attempts do
258
+ swap Devise, unlock_strategy: :both do
259
+ swap Devise, lock_strategy: :failed_attempts do
233
260
  assert_same_content Devise::Models::Lockable.required_fields(User), [
234
261
  :failed_attempts,
235
- :unlock_at,
262
+ :locked_at,
236
263
  :unlock_token
237
264
  ]
238
265
  end
239
266
  end
240
267
  end
241
268
 
242
- test 'required_fields should contain only failed_attempts and unlock_at when the strategies are time and failed_attempts are enabled' do
243
- swap Devise, :unlock_strategy => :time do
244
- swap Devise, :lock_strategy => :failed_attempts do
269
+ test 'required_fields should contain only failed_attempts and locked_at when the strategies are time and failed_attempts are enabled' do
270
+ swap Devise, unlock_strategy: :time do
271
+ swap Devise, lock_strategy: :failed_attempts do
245
272
  assert_same_content Devise::Models::Lockable.required_fields(User), [
246
273
  :failed_attempts,
247
- :unlock_at
274
+ :locked_at
248
275
  ]
249
276
  end
250
277
  end
251
278
  end
252
279
 
253
280
  test 'required_fields should contain only failed_attempts and unlock_token when the strategies are token and failed_attempts are enabled' do
254
- swap Devise, :unlock_strategy => :email do
255
- swap Devise, :lock_strategy => :failed_attempts do
281
+ swap Devise, unlock_strategy: :email do
282
+ swap Devise, lock_strategy: :failed_attempts do
256
283
  assert_same_content Devise::Models::Lockable.required_fields(User), [
257
284
  :failed_attempts,
258
285
  :unlock_token
@@ -260,4 +287,64 @@ class LockableTest < ActiveSupport::TestCase
260
287
  end
261
288
  end
262
289
  end
290
+
291
+ test 'should not return a locked unauthenticated message if in paranoid mode' do
292
+ swap Devise, paranoid: :true do
293
+ user = create_user
294
+ user.failed_attempts = Devise.maximum_attempts + 1
295
+ user.lock_access!
296
+
297
+ assert_equal :invalid, user.unauthenticated_message
298
+ end
299
+ end
300
+
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, lock_strategy: :failed_attempts do
303
+ user = create_user
304
+ user.failed_attempts = Devise.maximum_attempts - 2
305
+ assert_equal :invalid, user.unauthenticated_message
306
+
307
+ user.failed_attempts = Devise.maximum_attempts - 1
308
+ assert_equal :last_attempt, user.unauthenticated_message
309
+
310
+ user.failed_attempts = Devise.maximum_attempts
311
+ assert_equal :locked, user.unauthenticated_message
312
+ end
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
328
+
329
+ test 'unlock_strategy_enabled? should return true for both, email, and time strategies if :both is used' do
330
+ swap Devise, unlock_strategy: :both do
331
+ user = create_user
332
+ assert_equal true, user.unlock_strategy_enabled?(:both)
333
+ assert_equal true, user.unlock_strategy_enabled?(:time)
334
+ assert_equal true, user.unlock_strategy_enabled?(:email)
335
+ assert_equal false, user.unlock_strategy_enabled?(:none)
336
+ assert_equal false, user.unlock_strategy_enabled?(:an_undefined_strategy)
337
+ end
338
+ end
339
+
340
+ test 'unlock_strategy_enabled? should return true only for the configured strategy' do
341
+ swap Devise, unlock_strategy: :email do
342
+ user = create_user
343
+ assert_equal false, user.unlock_strategy_enabled?(:both)
344
+ assert_equal false, user.unlock_strategy_enabled?(:time)
345
+ assert_equal true, user.unlock_strategy_enabled?(:email)
346
+ assert_equal false, user.unlock_strategy_enabled?(:none)
347
+ assert_equal false, user.unlock_strategy_enabled?(:an_undefined_strategy)
348
+ end
349
+ end
263
350
  end