devise-security 0.14.1 → 0.18.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.
Files changed (170) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +3 -1
  3. data/README.md +136 -61
  4. data/app/controllers/devise/paranoid_verification_code_controller.rb +26 -12
  5. data/app/controllers/devise/password_expired_controller.rb +32 -10
  6. data/app/views/devise/paranoid_verification_code/show.html.erb +3 -3
  7. data/app/views/devise/password_expired/show.html.erb +5 -5
  8. data/config/locales/bg.yml +42 -0
  9. data/config/locales/by.yml +50 -0
  10. data/config/locales/cs.yml +46 -0
  11. data/config/locales/de.yml +16 -2
  12. data/config/locales/en.yml +15 -2
  13. data/config/locales/es.yml +22 -9
  14. data/config/locales/fa.yml +42 -0
  15. data/config/locales/fr.yml +15 -2
  16. data/config/locales/hi.yml +43 -0
  17. data/config/locales/it.yml +36 -4
  18. data/config/locales/ja.yml +14 -1
  19. data/config/locales/nl.yml +42 -0
  20. data/config/locales/pt.yml +42 -0
  21. data/config/locales/ru.yml +50 -0
  22. data/config/locales/tr.yml +26 -1
  23. data/config/locales/uk.yml +50 -0
  24. data/config/locales/zh_CN.yml +42 -0
  25. data/config/locales/zh_TW.yml +42 -0
  26. data/lib/devise-security/controllers/helpers.rb +72 -51
  27. data/lib/devise-security/hooks/expirable.rb +3 -3
  28. data/lib/devise-security/hooks/paranoid_verification.rb +1 -3
  29. data/lib/devise-security/hooks/password_expirable.rb +3 -3
  30. data/lib/devise-security/hooks/session_limitable.rb +29 -14
  31. data/lib/devise-security/models/compatibility/{active_record.rb → active_record_patch.rb} +14 -2
  32. data/lib/devise-security/models/compatibility/{mongoid.rb → mongoid_patch.rb} +12 -1
  33. data/lib/devise-security/models/compatibility.rb +2 -2
  34. data/lib/devise-security/models/database_authenticatable_patch.rb +18 -10
  35. data/lib/devise-security/models/expirable.rb +6 -5
  36. data/lib/devise-security/models/paranoid_verification.rb +2 -2
  37. data/lib/devise-security/models/password_archivable.rb +3 -3
  38. data/lib/devise-security/models/password_expirable.rb +5 -1
  39. data/lib/devise-security/models/secure_validatable.rb +62 -11
  40. data/lib/devise-security/models/session_limitable.rb +17 -2
  41. data/lib/devise-security/orm/mongoid.rb +1 -1
  42. data/lib/devise-security/patches.rb +14 -8
  43. data/lib/devise-security/routes.rb +2 -3
  44. data/lib/devise-security/validators/password_complexity_validator.rb +53 -24
  45. data/lib/devise-security/version.rb +1 -1
  46. data/lib/devise-security.rb +15 -6
  47. data/lib/generators/devise_security/install_generator.rb +4 -6
  48. data/lib/generators/templates/{devise-security.rb → devise_security.rb} +9 -1
  49. data/test/controllers/test_paranoid_verification_code_controller.rb +133 -0
  50. data/test/controllers/test_password_expired_controller.rb +164 -0
  51. data/test/{test_security_question_controller.rb → controllers/test_security_question_controller.rb} +19 -37
  52. data/test/dummy/app/assets/config/manifest.js +3 -0
  53. data/test/dummy/app/controllers/overrides/paranoid_verification_code_controller.rb +7 -0
  54. data/test/dummy/app/controllers/overrides/password_expired_controller.rb +17 -0
  55. data/test/dummy/app/controllers/widgets_controller.rb +9 -0
  56. data/test/dummy/app/models/application_user_record.rb +2 -1
  57. data/test/dummy/app/models/mongoid/confirmable_fields.rb +2 -0
  58. data/test/dummy/app/models/mongoid/database_authenticable_fields.rb +4 -3
  59. data/test/dummy/app/models/mongoid/expirable_fields.rb +2 -0
  60. data/test/dummy/app/models/mongoid/lockable_fields.rb +2 -0
  61. data/test/dummy/app/models/mongoid/mappings.rb +4 -2
  62. data/test/dummy/app/models/mongoid/omniauthable_fields.rb +2 -0
  63. data/test/dummy/app/models/mongoid/paranoid_verification_fields.rb +2 -0
  64. data/test/dummy/app/models/mongoid/password_archivable_fields.rb +2 -0
  65. data/test/dummy/app/models/mongoid/password_expirable_fields.rb +2 -0
  66. data/test/dummy/app/models/mongoid/recoverable_fields.rb +2 -0
  67. data/test/dummy/app/models/mongoid/registerable_fields.rb +4 -2
  68. data/test/dummy/app/models/mongoid/rememberable_fields.rb +2 -0
  69. data/test/dummy/app/models/mongoid/secure_validatable_fields.rb +2 -0
  70. data/test/dummy/app/models/mongoid/security_questionable_fields.rb +2 -0
  71. data/test/dummy/app/models/mongoid/session_limitable_fields.rb +2 -0
  72. data/test/dummy/app/models/mongoid/timeoutable_fields.rb +2 -0
  73. data/test/dummy/app/models/mongoid/trackable_fields.rb +2 -0
  74. data/test/dummy/app/models/mongoid/validatable_fields.rb +2 -0
  75. data/test/dummy/app/models/paranoid_verification_user.rb +26 -0
  76. data/test/dummy/app/models/password_expired_user.rb +26 -0
  77. data/test/dummy/app/models/user.rb +10 -2
  78. data/test/dummy/app/models/widget.rb +1 -3
  79. data/test/dummy/app/mongoid/one_user.rb +5 -5
  80. data/test/dummy/app/mongoid/user_on_engine.rb +2 -2
  81. data/test/dummy/app/mongoid/user_on_main_app.rb +2 -2
  82. data/test/dummy/app/mongoid/user_with_validations.rb +3 -3
  83. data/test/dummy/app/mongoid/user_without_email.rb +7 -4
  84. data/test/dummy/config/application.rb +3 -7
  85. data/test/dummy/config/boot.rb +1 -1
  86. data/test/dummy/config/environment.rb +1 -1
  87. data/test/dummy/config/environments/test.rb +4 -13
  88. data/test/dummy/config/initializers/devise.rb +1 -5
  89. data/test/dummy/config/initializers/migration_class.rb +1 -8
  90. data/test/dummy/config/locales/en.yml +10 -0
  91. data/test/dummy/config/mongoid.yml +1 -1
  92. data/test/dummy/config/routes.rb +6 -3
  93. data/test/dummy/config.ru +1 -1
  94. data/test/dummy/db/migrate/20120508165529_create_tables.rb +15 -6
  95. data/test/dummy/lib/shared_expirable_columns.rb +1 -0
  96. data/test/dummy/lib/shared_security_questions_fields.rb +1 -0
  97. data/test/dummy/lib/shared_user.rb +17 -6
  98. data/test/dummy/lib/shared_user_without_omniauth.rb +12 -3
  99. data/test/dummy/lib/shared_verification_fields.rb +1 -0
  100. data/test/dummy/log/test.log +45240 -0
  101. data/test/i18n_test.rb +22 -0
  102. data/test/integration/test_paranoid_verification_code_workflow.rb +53 -0
  103. data/test/integration/test_password_expirable_workflow.rb +53 -0
  104. data/test/integration/test_session_limitable_workflow.rb +69 -0
  105. data/test/orm/active_record.rb +7 -4
  106. data/test/orm/mongoid.rb +2 -1
  107. data/test/support/integration_helpers.rb +35 -0
  108. data/test/support/mongoid.yml +1 -1
  109. data/test/test_compatibility.rb +15 -0
  110. data/test/test_complexity_validator.rb +251 -29
  111. data/test/test_database_authenticatable_patch.rb +146 -0
  112. data/test/test_helper.rb +23 -8
  113. data/test/test_install_generator.rb +12 -2
  114. data/test/test_paranoid_verification.rb +8 -9
  115. data/test/test_password_archivable.rb +34 -11
  116. data/test/test_password_expirable.rb +27 -27
  117. data/test/test_secure_validatable.rb +284 -50
  118. data/test/test_secure_validatable_overrides.rb +185 -0
  119. data/test/test_session_limitable.rb +57 -0
  120. data/test/tmp/config/initializers/devise_security.rb +52 -0
  121. data/test/tmp/config/locales/devise.security_extension.by.yml +50 -0
  122. data/test/tmp/config/locales/devise.security_extension.cs.yml +46 -0
  123. data/test/tmp/config/locales/devise.security_extension.de.yml +42 -0
  124. data/test/tmp/config/locales/devise.security_extension.en.yml +42 -0
  125. data/test/tmp/config/locales/devise.security_extension.es.yml +42 -0
  126. data/test/tmp/config/locales/devise.security_extension.fa.yml +42 -0
  127. data/test/tmp/config/locales/devise.security_extension.fr.yml +42 -0
  128. data/test/tmp/config/locales/devise.security_extension.hi.yml +43 -0
  129. data/test/tmp/config/locales/devise.security_extension.it.yml +42 -0
  130. data/test/tmp/config/locales/devise.security_extension.ja.yml +42 -0
  131. data/test/tmp/config/locales/devise.security_extension.nl.yml +42 -0
  132. data/test/tmp/config/locales/devise.security_extension.pt.yml +42 -0
  133. data/test/tmp/config/locales/devise.security_extension.ru.yml +50 -0
  134. data/test/tmp/config/locales/devise.security_extension.tr.yml +42 -0
  135. data/test/tmp/config/locales/devise.security_extension.uk.yml +50 -0
  136. data/test/tmp/config/locales/devise.security_extension.zh_CN.yml +42 -0
  137. data/test/tmp/config/locales/devise.security_extension.zh_TW.yml +42 -0
  138. metadata +202 -138
  139. data/.codeclimate.yml +0 -63
  140. data/.document +0 -5
  141. data/.gitignore +0 -43
  142. data/.mdlrc +0 -1
  143. data/.rubocop.yml +0 -64
  144. data/.ruby-version +0 -1
  145. data/.travis.yml +0 -39
  146. data/Appraisals +0 -35
  147. data/Gemfile +0 -10
  148. data/Rakefile +0 -27
  149. data/devise-security.gemspec +0 -50
  150. data/gemfiles/rails_4.2_stable.gemfile +0 -16
  151. data/gemfiles/rails_5.0_stable.gemfile +0 -15
  152. data/gemfiles/rails_5.1_stable.gemfile +0 -15
  153. data/gemfiles/rails_5.2_stable.gemfile +0 -15
  154. data/gemfiles/rails_6.0_beta.gemfile +0 -15
  155. data/lib/devise-security/orm/active_record.rb +0 -20
  156. data/lib/devise-security/patches/confirmations_controller_captcha.rb +0 -23
  157. data/lib/devise-security/patches/confirmations_controller_security_question.rb +0 -26
  158. data/lib/devise-security/patches/passwords_controller_captcha.rb +0 -22
  159. data/lib/devise-security/patches/passwords_controller_security_question.rb +0 -25
  160. data/lib/devise-security/patches/registrations_controller_captcha.rb +0 -35
  161. data/lib/devise-security/patches/sessions_controller_captcha.rb +0 -26
  162. data/lib/devise-security/patches/unlocks_controller_captcha.rb +0 -22
  163. data/lib/devise-security/patches/unlocks_controller_security_question.rb +0 -25
  164. data/lib/devise-security/schema.rb +0 -66
  165. data/test/dummy/app/controllers/foos_controller.rb +0 -0
  166. data/test/dummy/app/models/.gitkeep +0 -0
  167. data/test/dummy/app/models/secure_user.rb +0 -9
  168. data/test/dummy/lib/shared_user_without_email.rb +0 -28
  169. data/test/test_password_expired_controller.rb +0 -46
  170. /data/test/{test_captcha_controller.rb → controllers/test_captcha_controller.rb} +0 -0
@@ -0,0 +1,146 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class TestDatabaseAuthenticatablePatch < ActiveSupport::TestCase
6
+ def create_user
7
+ User.create(
8
+ email: 'bob@microsoft.com',
9
+ password: 'Password1!',
10
+ password_confirmation: 'Password1!'
11
+ ) do |user|
12
+ user.extend(Devise::Models::DatabaseAuthenticatablePatch)
13
+ end
14
+ end
15
+
16
+ test 'updates if all params are present and valid' do
17
+ user = create_user
18
+
19
+ assert(
20
+ user.update_with_password(
21
+ {
22
+ current_password: 'Password1!',
23
+ password: 'Password2!',
24
+ password_confirmation: 'Password2!'
25
+ }
26
+ )
27
+ )
28
+ end
29
+
30
+ test 'does not update if current_password is missing' do
31
+ user = create_user
32
+
33
+ user.update_with_password(
34
+ {
35
+ password: 'Password2!',
36
+ password_confirmation: 'Password2!'
37
+ }
38
+ )
39
+
40
+ assert_equal(["Current password can't be blank"], user.errors.full_messages)
41
+ end
42
+
43
+ test 'does not update if current_password is incorrect' do
44
+ user = create_user
45
+
46
+ user.update_with_password(
47
+ {
48
+ current_password: 'Password2!',
49
+ password: 'Password2!',
50
+ password_confirmation: 'Password2!'
51
+ }
52
+ )
53
+
54
+ assert_equal(['Current password is invalid'], user.errors.full_messages)
55
+ end
56
+
57
+ test 'does not update if password is missing' do
58
+ user = create_user
59
+
60
+ user.update_with_password(
61
+ {
62
+ current_password: 'Password1!',
63
+ password: '',
64
+ password_confirmation: 'Password2!'
65
+ }
66
+ )
67
+
68
+ assert_equal(["Password can't be blank"], user.errors.full_messages)
69
+ end
70
+
71
+ test 'does not update if password is invalid and mismatches confirmation' do
72
+ user = create_user
73
+
74
+ user.update_with_password(
75
+ {
76
+ current_password: 'Password1!',
77
+ password: 'f',
78
+ password_confirmation: 'Password2!'
79
+ }
80
+ )
81
+
82
+ assert_equal(
83
+ [
84
+ "Password confirmation doesn't match Password",
85
+ 'Password is too short (minimum is 7 characters)',
86
+ 'Password must contain at least one digit',
87
+ 'Password must contain at least one upper-case letter'
88
+ ],
89
+ user.errors.full_messages
90
+ )
91
+ end
92
+
93
+ test 'does not update if password is invalid and matches confirmation' do
94
+ user = create_user
95
+
96
+ user.update_with_password(
97
+ {
98
+ current_password: 'Password1!',
99
+ password: 'f',
100
+ password_confirmation: 'f'
101
+ }
102
+ )
103
+
104
+ assert_equal(
105
+ [
106
+ 'Password is too short (minimum is 7 characters)',
107
+ 'Password must contain at least one digit',
108
+ 'Password must contain at least one upper-case letter'
109
+ ],
110
+ user.errors.full_messages
111
+ )
112
+ end
113
+
114
+ test 'does not update if password_confirmation is missing' do
115
+ user = create_user
116
+
117
+ user.update_with_password(
118
+ {
119
+ current_password: 'Password1!',
120
+ password: 'Password2!',
121
+ password_confirmation: ''
122
+ }
123
+ )
124
+
125
+ assert_equal(
126
+ ["Password confirmation can't be blank"], user.errors.full_messages
127
+ )
128
+ end
129
+
130
+ test 'does not update if password_confirmation is mismatched' do
131
+ user = create_user
132
+
133
+ user.update_with_password(
134
+ {
135
+ current_password: 'Password1!',
136
+ password: 'Password2!',
137
+ password_confirmation: 'Password3!'
138
+ }
139
+ )
140
+
141
+ assert_equal(
142
+ ["Password confirmation doesn't match Password"],
143
+ user.errors.full_messages
144
+ )
145
+ end
146
+ end
data/test/test_helper.rb CHANGED
@@ -3,17 +3,26 @@
3
3
  ENV['RAILS_ENV'] ||= 'test'
4
4
 
5
5
  require 'simplecov'
6
+
7
+ if ENV['CI']
8
+ require 'simplecov-lcov'
9
+ SimpleCov.formatter = SimpleCov::Formatter::LcovFormatter
10
+ SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true
11
+ end
12
+
6
13
  SimpleCov.start do
7
14
  add_filter 'gemfiles'
15
+ add_filter 'test/dummy/db'
16
+ add_group 'ActiveRecord', 'active_record'
17
+ add_group 'Expirable', /(?<!password_)expirable/
18
+ add_group 'Mongoid', 'mongoid'
19
+ add_group 'Paranoid Verifiable', 'paranoid_verification'
20
+ add_group 'Password Archivable', /password_archivable|old_password/
21
+ add_group 'Password Expirable', /password_expirable|password_expired/
22
+ add_group 'Secure Validateable', 'secure_validatable'
23
+ add_group 'Security Questionable', 'security_question'
24
+ add_group 'Session Limitable', 'session_limitable'
8
25
  add_group 'Tests', 'test'
9
- add_group 'Password Archivable', 'password_archivable'
10
- add_group 'Password Expirable', 'password_expirable'
11
- end
12
-
13
- if ENV['CI']
14
- require 'coveralls'
15
- SimpleCov.formatter = Coveralls::SimpleCov::Formatter
16
- Coveralls.wear!
17
26
  end
18
27
 
19
28
  require 'pry'
@@ -24,6 +33,12 @@ require 'devise-security'
24
33
  require 'database_cleaner'
25
34
  require "orm/#{DEVISE_ORM}"
26
35
 
36
+ # Controller testing is the way that Devise itself tests the functionality of
37
+ # controller, even though it has been deprecated in favor of request tests.
38
+ require 'rails-controller-testing'
39
+ Rails::Controller::Testing.install
40
+ require 'support/integration_helpers'
41
+
27
42
  class Minitest::Test
28
43
  def before_setup
29
44
  DatabaseCleaner.start
@@ -6,18 +6,28 @@ require 'generators/devise_security/install_generator'
6
6
 
7
7
  class TestInstallGenerator < Rails::Generators::TestCase
8
8
  tests DeviseSecurity::Generators::InstallGenerator
9
- destination File.expand_path('../tmp', __FILE__)
9
+ destination File.expand_path('tmp', __dir__)
10
10
  setup :prepare_destination
11
11
 
12
12
  test 'Assert all files are properly created' do
13
13
  run_generator
14
- assert_file 'config/initializers/devise-security.rb'
14
+ assert_file 'config/initializers/devise_security.rb'
15
+ assert_file 'config/locales/devise.security_extension.by.yml'
16
+ assert_file 'config/locales/devise.security_extension.cs.yml'
15
17
  assert_file 'config/locales/devise.security_extension.de.yml'
16
18
  assert_file 'config/locales/devise.security_extension.en.yml'
17
19
  assert_file 'config/locales/devise.security_extension.es.yml'
20
+ assert_file 'config/locales/devise.security_extension.fa.yml'
18
21
  assert_file 'config/locales/devise.security_extension.fr.yml'
22
+ assert_file 'config/locales/devise.security_extension.hi.yml'
19
23
  assert_file 'config/locales/devise.security_extension.it.yml'
20
24
  assert_file 'config/locales/devise.security_extension.ja.yml'
25
+ assert_file 'config/locales/devise.security_extension.nl.yml'
26
+ assert_file 'config/locales/devise.security_extension.pt.yml'
27
+ assert_file 'config/locales/devise.security_extension.ru.yml'
21
28
  assert_file 'config/locales/devise.security_extension.tr.yml'
29
+ assert_file 'config/locales/devise.security_extension.uk.yml'
30
+ assert_file 'config/locales/devise.security_extension.zh_CN.yml'
31
+ assert_file 'config/locales/devise.security_extension.zh_TW.yml'
22
32
  end
23
33
  end
@@ -6,12 +6,12 @@ class TestParanoidVerification < ActiveSupport::TestCase
6
6
  test 'need to paranoid verify if code present' do
7
7
  user = User.new
8
8
  user.generate_paranoid_code
9
- assert_equal(true, user.need_paranoid_verification?)
9
+ assert(user.need_paranoid_verification?)
10
10
  end
11
11
 
12
12
  test 'no need to paranoid verify if no code' do
13
13
  user = User.new
14
- assert_equal(false, user.need_paranoid_verification?)
14
+ assert_not(user.need_paranoid_verification?)
15
15
  end
16
16
 
17
17
  test 'generate code' do
@@ -29,23 +29,23 @@ class TestParanoidVerification < ActiveSupport::TestCase
29
29
  user.generate_paranoid_code
30
30
  # default generator generates 5 char string
31
31
  assert_equal(user.paranoid_verification_code.class, String)
32
- assert_equal(user.paranoid_verification_code.length, 5)
32
+ assert_equal(5, user.paranoid_verification_code.length)
33
33
  end
34
34
 
35
35
  test 'when code match upon verify code, should mark record that it\'s no loger needed to verify' do
36
36
  user = User.new(paranoid_verification_code: 'abcde')
37
37
 
38
- assert_equal(true, user.need_paranoid_verification?)
38
+ assert(user.need_paranoid_verification?)
39
39
  user.verify_code('abcde')
40
- assert_equal(false, user.need_paranoid_verification?)
40
+ assert_not(user.need_paranoid_verification?)
41
41
  end
42
42
 
43
43
  test 'when code match upon verify code, should no longer need verification' do
44
44
  user = User.new(paranoid_verification_code: 'abcde')
45
45
 
46
- assert_equal(true, user.need_paranoid_verification?)
46
+ assert(user.need_paranoid_verification?)
47
47
  user.verify_code('abcde')
48
- assert_equal(false, user.need_paranoid_verification?)
48
+ assert_not(user.need_paranoid_verification?)
49
49
  end
50
50
 
51
51
  test 'when code match upon verification code, should set when verification was accepted' do
@@ -57,7 +57,7 @@ class TestParanoidVerification < ActiveSupport::TestCase
57
57
  test 'when code not match upon verify code, should still need verification' do
58
58
  user = User.new(paranoid_verification_code: 'abcde')
59
59
  user.verify_code('wrong')
60
- assert_equal(true, user.need_paranoid_verification?)
60
+ assert(user.need_paranoid_verification?)
61
61
  end
62
62
 
63
63
  test 'when code not match upon verification code, should not set paranoid_verified_at' do
@@ -94,7 +94,6 @@ class TestParanoidVerification < ActiveSupport::TestCase
94
94
  Devise.paranoid_code_regenerate_after_attempt = original_regenerate
95
95
  end
96
96
 
97
-
98
97
  test 'by default paranoid code regenerate should have 10 attempts' do
99
98
  user = User.new(paranoid_verification_code: 'abcde')
100
99
  assert_equal 10, user.paranoid_attempts_remaining
@@ -3,7 +3,6 @@
3
3
  require 'test_helper'
4
4
 
5
5
  class TestPasswordArchivable < ActiveSupport::TestCase
6
-
7
6
  setup do
8
7
  Devise.password_archiving_count = 2
9
8
  end
@@ -20,7 +19,7 @@ class TestPasswordArchivable < ActiveSupport::TestCase
20
19
 
21
20
  test 'cannot use same password' do
22
21
  user = User.create email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
23
- assert_raises(ORMInvalidRecordException) { set_password(user, 'Password1') }
22
+ assert_raises(ORMInvalidRecordException) { set_password(user, 'Password1') }
24
23
  end
25
24
 
26
25
  test 'indirectly saving associated user does not cause deprecation warning' do
@@ -43,19 +42,19 @@ class TestPasswordArchivable < ActiveSupport::TestCase
43
42
 
44
43
  user = User.create! email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
45
44
  assert_equal 0, OldPassword.count
46
- set_password(user, 'Password2')
45
+ set_password(user, 'Password2')
47
46
  assert_equal 1, OldPassword.count
48
47
 
49
- assert_raises(ORMInvalidRecordException) { set_password(user, 'Password1') }
50
- set_password(user, 'Password3')
48
+ assert_raises(ORMInvalidRecordException) { set_password(user, 'Password1') }
49
+ set_password(user, 'Password3')
51
50
  assert_equal 2, OldPassword.count
52
51
 
53
52
  # rotate first password out of archive
54
- assert set_password(user, 'Password4')
53
+ assert set_password(user, 'Password4')
55
54
 
56
55
  # archive count was 2, so first password should work again
57
- assert set_password(user, 'Password1')
58
- assert set_password(user, 'Password2')
56
+ assert set_password(user, 'Password1')
57
+ assert set_password(user, 'Password2')
59
58
  end
60
59
 
61
60
  test 'the option should be dynamic during runtime' do
@@ -67,10 +66,34 @@ class TestPasswordArchivable < ActiveSupport::TestCase
67
66
 
68
67
  user = User.create email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
69
68
 
70
- assert set_password(user, 'Password2')
69
+ assert set_password(user, 'Password2')
70
+
71
+ assert_raises(ORMInvalidRecordException) { set_password(user, 'Password2') }
72
+
73
+ assert_raises(ORMInvalidRecordException) { set_password(user, 'Password1') }
74
+ end
75
+
76
+ test 'default sort orders do not affect archiving' do
77
+ class ::OldPassword
78
+ default_scope { order(created_at: :asc) }
79
+ end
80
+
81
+ assert_equal 2, Devise.password_archiving_count
82
+
83
+ user = User.create! email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
84
+ assert_equal 0, OldPassword.count
85
+ set_password(user, 'Password2')
86
+ assert_equal 1, OldPassword.count
87
+
88
+ assert_raises(ORMInvalidRecordException) { set_password(user, 'Password1') }
89
+ set_password(user, 'Password3')
90
+ assert_equal 2, OldPassword.count
71
91
 
72
- assert_raises(ORMInvalidRecordException) { set_password(user, 'Password2') }
92
+ # rotate first password out of archive
93
+ assert set_password(user, 'Password4')
73
94
 
74
- assert_raises(ORMInvalidRecordException) { set_password(user, 'Password1') }
95
+ # archive count was 2, so first password should work again
96
+ assert set_password(user, 'Password1')
97
+ assert set_password(user, 'Password2')
75
98
  end
76
99
  end
@@ -14,59 +14,59 @@ class TestPasswordArchivable < ActiveSupport::TestCase
14
14
  test 'does nothing if disabled' do
15
15
  Devise.expire_password_after = false
16
16
  user = User.create email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
17
- refute user.need_change_password?
18
- refute user.password_expired?
17
+ assert_not user.need_change_password?
18
+ assert_not user.password_expired?
19
19
  user.need_change_password!
20
- refute user.need_change_password?
21
- refute user.password_expired?
20
+ assert_not user.need_change_password?
21
+ assert_not user.password_expired?
22
22
  end
23
23
 
24
24
  test 'password change can be requested' do
25
25
  Devise.expire_password_after = true
26
26
  user = User.create email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
27
- refute user.need_change_password?
28
- refute user.password_expired?
29
- refute user.password_change_requested?
27
+ assert_not user.need_change_password?
28
+ assert_not user.password_expired?
29
+ assert_not user.password_change_requested?
30
30
  user.need_change_password!
31
31
  assert user.need_change_password?
32
- refute user.password_expired? # it's not too old because it's not set at all
32
+ assert_not user.password_expired? # it's not too old because it's not set at all
33
33
  assert user.password_change_requested?
34
34
  end
35
35
 
36
36
  test 'password expires' do
37
37
  user = User.create email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
38
- refute user.need_change_password?
39
- refute user.password_expired?
40
- refute user.password_too_old?
41
- user.update(password_changed_at: Time.now.ago(3.months))
38
+ assert_not user.need_change_password?
39
+ assert_not user.password_expired?
40
+ assert_not user.password_too_old?
41
+ user.update(password_changed_at: Time.zone.now.ago(3.months))
42
42
  assert user.password_too_old?
43
43
  assert user.need_change_password?
44
44
  assert user.password_expired?
45
- refute user.password_change_requested?
45
+ assert_not user.password_change_requested?
46
46
  end
47
47
 
48
48
  test 'saving a record records the time the password was changed' do
49
49
  user = User.new email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
50
- assert user.password_changed_at.nil?
51
- refute user.password_change_requested?
52
- refute user.password_expired?
50
+ assert_nil user.password_changed_at
51
+ assert_not user.password_change_requested?
52
+ assert_not user.password_expired?
53
53
  user.save
54
54
  assert user.password_changed_at.present?
55
- refute user.password_change_requested?
56
- refute user.password_expired?
55
+ assert_not user.password_change_requested?
56
+ assert_not user.password_expired?
57
57
  end
58
58
 
59
59
  test 'updating a record updates the time the password was changed if the password is changed' do
60
60
  user = User.create email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
61
- user.update(password_changed_at: Time.now.ago(3.months))
61
+ user.update(password_changed_at: Time.zone.now.ago(3.months))
62
62
  original_password_changed_at = user.password_changed_at
63
63
  user.expire_password!
64
64
  assert user.password_change_requested?
65
- user.password = "NewPassword1"
66
- user.password_confirmation = "NewPassword1"
65
+ user.password = 'NewPassword1'
66
+ user.password_confirmation = 'NewPassword1'
67
67
  user.save
68
68
  assert user.password_changed_at > original_password_changed_at
69
- refute user.password_change_requested?
69
+ assert_not user.password_change_requested?
70
70
  end
71
71
 
72
72
  test 'updating a record does not updates the time the password was changed if the password was not changed' do
@@ -74,7 +74,7 @@ class TestPasswordArchivable < ActiveSupport::TestCase
74
74
  user.expire_password!
75
75
  assert user.password_change_requested?
76
76
  user.save
77
- refute user.previous_changes.key?(:password_changed_at)
77
+ assert_not user.previous_changes.key?(:password_changed_at)
78
78
  assert user.password_change_requested?
79
79
  end
80
80
 
@@ -85,10 +85,10 @@ class TestPasswordArchivable < ActiveSupport::TestCase
85
85
  4.months
86
86
  end
87
87
  end
88
- user.password_changed_at = Time.now.ago(3.months)
89
- refute user.need_change_password?
90
- refute user.password_expired?
91
- user.password_changed_at = Time.now.ago(5.months)
88
+ user.password_changed_at = Time.zone.now.ago(3.months)
89
+ assert_not user.need_change_password?
90
+ assert_not user.password_expired?
91
+ user.password_changed_at = Time.zone.now.ago(5.months)
92
92
  assert user.need_change_password?
93
93
  assert user.password_expired?
94
94
  end