devise-security 0.13.0 → 0.14.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +1 -1
- data/.gitignore +1 -0
- data/.ruby-version +1 -1
- data/.travis.yml +30 -12
- data/Appraisals +21 -5
- data/Gemfile +8 -1
- data/README.md +47 -7
- data/app/views/devise/paranoid_verification_code/show.html.erb +1 -1
- data/app/views/devise/password_expired/show.html.erb +1 -1
- data/config/locales/de.yml +11 -11
- data/config/locales/fr.yml +13 -13
- data/config/locales/ja.yml +29 -0
- data/devise-security.gemspec +12 -6
- data/gemfiles/rails_4.2_stable.gemfile +9 -1
- data/gemfiles/rails_5.0_stable.gemfile +8 -1
- data/gemfiles/rails_5.1_stable.gemfile +8 -1
- data/gemfiles/{rails_5.2.0.gemfile → rails_5.2_stable.gemfile} +8 -1
- data/gemfiles/rails_6.0_beta.gemfile +15 -0
- data/lib/devise-security.rb +2 -4
- data/lib/devise-security/models/{old_password.rb → active_record/old_password.rb} +1 -2
- data/lib/devise-security/models/compatibility.rb +6 -15
- data/lib/devise-security/models/compatibility/active_record.rb +29 -0
- data/lib/devise-security/models/compatibility/mongoid.rb +21 -0
- data/lib/devise-security/models/database_authenticatable_patch.rb +1 -1
- data/lib/devise-security/models/expirable.rb +6 -2
- data/lib/devise-security/models/mongoid/old_password.rb +21 -0
- data/lib/devise-security/models/password_archivable.rb +16 -7
- data/lib/devise-security/models/password_expirable.rb +5 -0
- data/lib/devise-security/models/secure_validatable.rb +2 -2
- data/lib/devise-security/orm/mongoid.rb +7 -0
- data/lib/devise-security/patches/controller_security_question.rb +1 -1
- data/lib/devise-security/version.rb +1 -1
- data/lib/generators/devise_security/install_generator.rb +1 -1
- data/test/dummy/app/models/application_record.rb +8 -2
- data/test/dummy/app/models/application_user_record.rb +11 -0
- data/test/dummy/app/models/captcha_user.rb +5 -2
- data/test/dummy/app/models/mongoid/confirmable_fields.rb +13 -0
- data/test/dummy/app/models/mongoid/database_authenticable_fields.rb +17 -0
- data/test/dummy/app/models/mongoid/expirable_fields.rb +11 -0
- data/test/dummy/app/models/mongoid/lockable_fields.rb +13 -0
- data/test/dummy/app/models/mongoid/mappings.rb +13 -0
- data/test/dummy/app/models/mongoid/omniauthable_fields.rb +11 -0
- data/test/dummy/app/models/mongoid/paranoid_verification_fields.rb +10 -0
- data/test/dummy/app/models/mongoid/password_archivable_fields.rb +9 -0
- data/test/dummy/app/models/mongoid/password_expirable_fields.rb +10 -0
- data/test/dummy/app/models/mongoid/recoverable_fields.rb +11 -0
- data/test/dummy/app/models/mongoid/registerable_fields.rb +19 -0
- data/test/dummy/app/models/mongoid/rememberable_fields.rb +10 -0
- data/test/dummy/app/models/mongoid/secure_validatable_fields.rb +11 -0
- data/test/dummy/app/models/mongoid/security_questionable_fields.rb +13 -0
- data/test/dummy/app/models/mongoid/session_limitable_fields.rb +10 -0
- data/test/dummy/app/models/mongoid/timeoutable_fields.rb +9 -0
- data/test/dummy/app/models/mongoid/trackable_fields.rb +14 -0
- data/test/dummy/app/models/mongoid/validatable_fields.rb +7 -0
- data/test/dummy/app/models/secure_user.rb +5 -1
- data/test/dummy/app/models/security_question_user.rb +7 -4
- data/test/dummy/app/models/user.rb +5 -0
- data/test/dummy/app/models/widget.rb +4 -0
- data/test/dummy/app/mongoid/admin.rb +31 -0
- data/test/dummy/app/mongoid/one_user.rb +58 -0
- data/test/dummy/app/mongoid/shim.rb +25 -0
- data/test/dummy/app/mongoid/user_on_engine.rb +41 -0
- data/test/dummy/app/mongoid/user_on_main_app.rb +41 -0
- data/test/dummy/app/mongoid/user_with_validations.rb +37 -0
- data/test/dummy/app/mongoid/user_without_email.rb +35 -0
- data/test/dummy/config/application.rb +10 -7
- data/test/dummy/config/environments/test.rb +2 -2
- data/test/dummy/config/initializers/devise.rb +3 -4
- data/test/dummy/config/initializers/migration_class.rb +8 -6
- data/test/dummy/config/mongoid.yml +6 -0
- data/test/dummy/lib/shared_expirable_columns.rb +14 -0
- data/test/dummy/lib/shared_security_questions_fields.rb +16 -0
- data/test/dummy/lib/shared_user.rb +32 -0
- data/test/dummy/lib/shared_user_with_password_verification.rb +13 -0
- data/test/dummy/lib/shared_user_without_email.rb +28 -0
- data/test/dummy/lib/shared_user_without_omniauth.rb +15 -0
- data/test/dummy/lib/shared_verification_fields.rb +15 -0
- data/test/orm/active_record.rb +12 -0
- data/test/orm/mongoid.rb +12 -0
- data/test/support/mongoid.yml +6 -0
- data/test/test_helper.rb +16 -9
- data/test/test_install_generator.rb +1 -0
- data/test/test_password_archivable.rb +6 -7
- data/test/test_password_expirable.rb +3 -1
- data/test/test_secure_validatable.rb +11 -10
- data/test/test_security_question_controller.rb +9 -11
- metadata +125 -16
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "shared_user_without_email"
|
4
|
+
|
5
|
+
class UserWithoutEmail
|
6
|
+
include Mongoid::Document
|
7
|
+
include Shim
|
8
|
+
include SharedUserWithoutEmail
|
9
|
+
|
10
|
+
field :username, type: String
|
11
|
+
field :facebook_token, type: String
|
12
|
+
|
13
|
+
## Database authenticatable
|
14
|
+
field :email, type: String, default: ""
|
15
|
+
field :encrypted_password, type: String, default: ""
|
16
|
+
|
17
|
+
## Recoverable
|
18
|
+
field :reset_password_token, type: String
|
19
|
+
field :reset_password_sent_at, type: Time
|
20
|
+
|
21
|
+
## Rememberable
|
22
|
+
field :remember_created_at, type: Time
|
23
|
+
|
24
|
+
## Trackable
|
25
|
+
field :sign_in_count, type: Integer, default: 0
|
26
|
+
field :current_sign_in_at, type: Time
|
27
|
+
field :last_sign_in_at, type: Time
|
28
|
+
field :current_sign_in_ip, type: String
|
29
|
+
field :last_sign_in_ip, type: String
|
30
|
+
|
31
|
+
## Lockable
|
32
|
+
field :failed_attempts, type: Integer, default: 0 # Only if lock strategy is :failed_attempts
|
33
|
+
field :unlock_token, type: String # Only if unlock strategy is :email or :both
|
34
|
+
field :locked_at, type: Time
|
35
|
+
end
|
@@ -2,22 +2,25 @@
|
|
2
2
|
|
3
3
|
require File.expand_path('../boot', __FILE__)
|
4
4
|
|
5
|
+
require 'action_mailer/railtie'
|
6
|
+
require "action_mailer/railtie"
|
7
|
+
require "rails/test_unit/railtie"
|
8
|
+
|
9
|
+
Bundler.require :default, DEVISE_ORM
|
10
|
+
require "#{DEVISE_ORM}/railtie"
|
11
|
+
|
5
12
|
require 'rails/all'
|
6
13
|
require 'devise-security'
|
7
14
|
|
8
|
-
if defined?(Bundler)
|
9
|
-
# If you precompile assets before deploying to production, use this line
|
10
|
-
Bundler.require(*Rails.groups(assets: %w[development test]))
|
11
|
-
# If you want your assets lazily compiled in production, use this line
|
12
|
-
# Bundler.require(:default, :assets, Rails.env)
|
13
|
-
end
|
14
|
-
|
15
15
|
module RailsApp
|
16
16
|
class Application < Rails::Application
|
17
17
|
config.encoding = 'utf-8'
|
18
18
|
|
19
19
|
config.filter_parameters += [:password]
|
20
20
|
|
21
|
+
config.autoload_paths += ["#{config.root}/app/#{DEVISE_ORM}"]
|
22
|
+
config.autoload_paths += ["#{config.root}/lib"]
|
23
|
+
|
21
24
|
config.assets.enabled = true
|
22
25
|
|
23
26
|
config.assets.version = '1.0'
|
@@ -27,10 +27,10 @@ RailsApp::Application.configure do
|
|
27
27
|
|
28
28
|
config.active_support.test_order = :sorted
|
29
29
|
config.log_level = :debug
|
30
|
-
if Rails.gem_version >= Gem::Version.new('4.2') && Rails.gem_version < Gem::Version.new('5.0')
|
30
|
+
if Rails.gem_version >= Gem::Version.new('4.2') && Rails.gem_version.release < Gem::Version.new('5.0')
|
31
31
|
config.active_record.raise_in_transactional_callbacks = true
|
32
32
|
end
|
33
|
-
if Rails.gem_version.release >= Gem::Version.new('5.2')
|
33
|
+
if Rails.gem_version.release >= Gem::Version.new('5.2') && Rails.gem_version.release < Gem::Version.new('6.0')
|
34
34
|
config.active_record.sqlite3.represent_boolean_as_integer = true
|
35
35
|
end
|
36
36
|
end
|
@@ -1,18 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rails_email_validator'
|
4
|
+
require "devise/orm/#{DEVISE_ORM}"
|
5
|
+
|
4
6
|
Devise.setup do |config|
|
5
7
|
config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
|
6
|
-
|
7
|
-
require 'devise/orm/active_record'
|
8
8
|
config.secret_key = 'f08cf11a38906f531d2dfc9a2c2d671aa0021be806c21255d4'
|
9
9
|
config.case_insensitive_keys = [:email]
|
10
|
-
|
11
10
|
config.strip_whitespace_keys = [:email]
|
12
|
-
|
13
11
|
config.password_complexity = {
|
14
12
|
digit: 1,
|
15
13
|
lower: 1,
|
16
14
|
upper: 1,
|
17
15
|
}
|
16
|
+
config.password_length = 7..128
|
18
17
|
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
if DEVISE_ORM == :active_record
|
4
|
+
MIGRATION_CLASS =
|
5
|
+
if Rails.gem_version >= Gem::Version.new('5.0')
|
6
|
+
ActiveRecord::Migration[Rails.version.to_f]
|
7
|
+
else
|
8
|
+
ActiveRecord::Migration
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'shared_user'
|
3
|
+
|
4
|
+
module SharedVerificationColumns
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
include SharedUser
|
9
|
+
devise :expirable
|
10
|
+
|
11
|
+
field :expired_at, type: Time
|
12
|
+
field :last_activity_at, type: Time
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'shared_user'
|
3
|
+
|
4
|
+
module SharedSecurityQuestionsFields
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
include SharedUser
|
9
|
+
devise :lockable, :security_questionable
|
10
|
+
|
11
|
+
field :locked_at, type: Time
|
12
|
+
field :unlock_token, type: String
|
13
|
+
field :security_question_id, type: Integer
|
14
|
+
field :security_question_answer, type: String
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SharedUser
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
devise :database_authenticatable, :confirmable, :lockable, :recoverable,
|
8
|
+
:registerable, :rememberable, :timeoutable,
|
9
|
+
:trackable, :secure_validatable, :omniauthable, :validatable, password_length: 7..72,
|
10
|
+
reconfirmable: false
|
11
|
+
|
12
|
+
attr_accessor :other_key
|
13
|
+
|
14
|
+
# They need to be included after Devise is called.
|
15
|
+
extend ExtendMethods
|
16
|
+
end
|
17
|
+
|
18
|
+
def raw_confirmation_token
|
19
|
+
@raw_confirmation_token
|
20
|
+
end
|
21
|
+
|
22
|
+
module ExtendMethods
|
23
|
+
def new_with_session(params, session)
|
24
|
+
super.tap do |user|
|
25
|
+
if data = session["devise.facebook_data"]
|
26
|
+
user.email = data["email"]
|
27
|
+
user.confirmed_at = Time.zone.now
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SharedUserWithoutEmail
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
# NOTE: This is missing :validatable and :confirmable, as they both require
|
8
|
+
# an email field at the moment. It is also missing :omniauthable because that
|
9
|
+
# adds unnecessary complexity to the setup
|
10
|
+
devise :database_authenticatable, :lockable, :recoverable,
|
11
|
+
:registerable, :rememberable, :timeoutable,
|
12
|
+
:trackable
|
13
|
+
end
|
14
|
+
|
15
|
+
# This test stub is a bit rubbish because it's tied very closely to the
|
16
|
+
# implementation where we care about this one case. However, completely
|
17
|
+
# removing the email field breaks "recoverable" tests completely, so we are
|
18
|
+
# just taking the approach here that "email" is something that is a not an
|
19
|
+
# ActiveRecord field.
|
20
|
+
def email_changed?
|
21
|
+
raise NoMethodError
|
22
|
+
end
|
23
|
+
|
24
|
+
def respond_to?(method_name, include_all=false)
|
25
|
+
return false if method_name.to_sym == :email_changed?
|
26
|
+
super(method_name, include_all)
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SharedUserWithoutOmniauth
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
devise :database_authenticatable, :confirmable, :lockable, :recoverable,
|
8
|
+
:registerable, :rememberable, :timeoutable,
|
9
|
+
:trackable, :validatable, reconfirmable: false
|
10
|
+
end
|
11
|
+
|
12
|
+
def raw_confirmation_token
|
13
|
+
@raw_confirmation_token
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'shared_user'
|
3
|
+
|
4
|
+
module SharedVerificationFields
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
include SharedUser
|
9
|
+
devise :paranoid_verification
|
10
|
+
|
11
|
+
field :paranoid_verified_at, type: Time
|
12
|
+
field :paranoid_verification_attempt, type: Integer, default: 0
|
13
|
+
field :paranoid_verification_code, type: String
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
ActiveRecord::Migration.verbose = false
|
4
|
+
ActiveRecord::Base.logger = Logger.new(nil)
|
5
|
+
if Rails.gem_version >= Gem::Version.new('5.2.0')
|
6
|
+
ActiveRecord::MigrationContext.new(File.expand_path('../../dummy/db/migrate', __FILE__)).migrate
|
7
|
+
else
|
8
|
+
ActiveRecord::Migrator.migrate(File.expand_path('../../dummy/db/migrate', __FILE__))
|
9
|
+
end
|
10
|
+
|
11
|
+
DatabaseCleaner[:active_record].strategy = :transaction
|
12
|
+
ORMInvalidRecordException = ActiveRecord::RecordInvalid
|
data/test/orm/mongoid.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mongoid/version'
|
4
|
+
|
5
|
+
Mongoid.configure do |config|
|
6
|
+
config.load!('test/support/mongoid.yml', Rails.env)
|
7
|
+
config.use_utc = true
|
8
|
+
config.include_root_in_json = true
|
9
|
+
end
|
10
|
+
|
11
|
+
DatabaseCleaner[:mongoid].strategy = :truncation
|
12
|
+
ORMInvalidRecordException = Mongoid::Errors::Validations
|
data/test/test_helper.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
ENV['RAILS_ENV'] ||= 'test'
|
4
|
+
DEVISE_ORM = ENV.fetch('DEVISE_ORM', 'active_record').to_sym
|
4
5
|
|
5
6
|
require 'simplecov'
|
6
7
|
SimpleCov.start do
|
7
8
|
add_filter 'gemfiles'
|
8
9
|
add_group 'Tests', 'test'
|
9
|
-
add_group 'Password
|
10
|
+
add_group 'Password Archivable', 'password_archivable'
|
11
|
+
add_group 'Password Expirable', 'password_expirable'
|
10
12
|
end
|
11
13
|
|
12
14
|
if ENV['CI']
|
@@ -15,17 +17,22 @@ if ENV['CI']
|
|
15
17
|
Coveralls.wear!
|
16
18
|
end
|
17
19
|
|
20
|
+
require 'pry'
|
18
21
|
require 'dummy/config/environment'
|
19
22
|
require 'minitest/autorun'
|
20
23
|
require 'rails/test_help'
|
21
|
-
|
22
24
|
require 'devise-security'
|
23
|
-
require '
|
25
|
+
require 'database_cleaner'
|
26
|
+
require "orm/#{DEVISE_ORM}"
|
24
27
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
class Minitest::Test
|
29
|
+
def before_setup
|
30
|
+
DatabaseCleaner.start
|
31
|
+
end
|
32
|
+
|
33
|
+
def after_teardown
|
34
|
+
DatabaseCleaner.clean
|
35
|
+
end
|
31
36
|
end
|
37
|
+
|
38
|
+
DatabaseCleaner.clean
|
@@ -17,6 +17,7 @@ class TestInstallGenerator < Rails::Generators::TestCase
|
|
17
17
|
assert_file 'config/locales/devise.security_extension.es.yml'
|
18
18
|
assert_file 'config/locales/devise.security_extension.fr.yml'
|
19
19
|
assert_file 'config/locales/devise.security_extension.it.yml'
|
20
|
+
assert_file 'config/locales/devise.security_extension.ja.yml'
|
20
21
|
assert_file 'config/locales/devise.security_extension.tr.yml'
|
21
22
|
end
|
22
23
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
5
5
|
class TestPasswordArchivable < ActiveSupport::TestCase
|
6
|
+
|
6
7
|
setup do
|
7
8
|
Devise.password_archiving_count = 2
|
8
9
|
end
|
@@ -19,7 +20,7 @@ class TestPasswordArchivable < ActiveSupport::TestCase
|
|
19
20
|
|
20
21
|
test 'cannot use same password' do
|
21
22
|
user = User.create email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
|
22
|
-
assert_raises(
|
23
|
+
assert_raises(ORMInvalidRecordException) { set_password(user, 'Password1') }
|
23
24
|
end
|
24
25
|
|
25
26
|
test 'indirectly saving associated user does not cause deprecation warning' do
|
@@ -37,17 +38,15 @@ class TestPasswordArchivable < ActiveSupport::TestCase
|
|
37
38
|
assert_equal 0, OldPassword.count
|
38
39
|
end
|
39
40
|
|
40
|
-
test 'cannot
|
41
|
+
test 'cannot reuse archived passwords' do
|
41
42
|
assert_equal 2, Devise.password_archiving_count
|
42
43
|
|
43
44
|
user = User.create! email: 'bob@microsoft.com', password: 'Password1', password_confirmation: 'Password1'
|
44
45
|
assert_equal 0, OldPassword.count
|
45
|
-
|
46
46
|
set_password(user, 'Password2')
|
47
47
|
assert_equal 1, OldPassword.count
|
48
48
|
|
49
|
-
assert_raises(
|
50
|
-
|
49
|
+
assert_raises(ORMInvalidRecordException) { set_password(user, 'Password1') }
|
51
50
|
set_password(user, 'Password3')
|
52
51
|
assert_equal 2, OldPassword.count
|
53
52
|
|
@@ -70,8 +69,8 @@ class TestPasswordArchivable < ActiveSupport::TestCase
|
|
70
69
|
|
71
70
|
assert set_password(user, 'Password2')
|
72
71
|
|
73
|
-
assert_raises(
|
72
|
+
assert_raises(ORMInvalidRecordException) { set_password(user, 'Password2') }
|
74
73
|
|
75
|
-
assert_raises(
|
74
|
+
assert_raises(ORMInvalidRecordException) { set_password(user, 'Password1') }
|
76
75
|
end
|
77
76
|
end
|
@@ -58,12 +58,14 @@ class TestPasswordArchivable < ActiveSupport::TestCase
|
|
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))
|
62
|
+
original_password_changed_at = user.password_changed_at
|
61
63
|
user.expire_password!
|
62
64
|
assert user.password_change_requested?
|
63
65
|
user.password = "NewPassword1"
|
64
66
|
user.password_confirmation = "NewPassword1"
|
65
67
|
user.save
|
66
|
-
assert user.
|
68
|
+
assert user.password_changed_at > original_password_changed_at
|
67
69
|
refute user.password_change_requested?
|
68
70
|
end
|
69
71
|
|
@@ -4,9 +4,10 @@ require 'test_helper'
|
|
4
4
|
require 'rails_email_validator'
|
5
5
|
|
6
6
|
class TestSecureValidatable < ActiveSupport::TestCase
|
7
|
-
class User <
|
7
|
+
class User < ApplicationRecord
|
8
8
|
devise :database_authenticatable, :password_archivable,
|
9
9
|
:paranoid_verification, :password_expirable, :secure_validatable
|
10
|
+
include ::Mongoid::Mappings if DEVISE_ORM == :mongoid
|
10
11
|
end
|
11
12
|
|
12
13
|
test 'email cannot be blank' do
|
@@ -15,7 +16,7 @@ class TestSecureValidatable < ActiveSupport::TestCase
|
|
15
16
|
|
16
17
|
assert_equal(false, user.valid?)
|
17
18
|
assert_equal([msg], user.errors.full_messages)
|
18
|
-
assert_raises(
|
19
|
+
assert_raises(ORMInvalidRecordException) do
|
19
20
|
user.save!
|
20
21
|
end
|
21
22
|
end
|
@@ -25,7 +26,7 @@ class TestSecureValidatable < ActiveSupport::TestCase
|
|
25
26
|
user = User.create email: 'bob', password: 'passWord1', password_confirmation: 'passWord1'
|
26
27
|
assert_equal(false, user.valid?)
|
27
28
|
assert_equal([msg], user.errors.full_messages)
|
28
|
-
assert_raises(
|
29
|
+
assert_raises(ORMInvalidRecordException) do
|
29
30
|
user.save!
|
30
31
|
end
|
31
32
|
end
|
@@ -35,7 +36,7 @@ class TestSecureValidatable < ActiveSupport::TestCase
|
|
35
36
|
user = User.create email: 'bob@@foo.tv', password: 'password1', password_confirmation: 'password1'
|
36
37
|
assert_equal(false, user.valid?)
|
37
38
|
assert_equal(msgs, user.errors.full_messages)
|
38
|
-
assert_raises(
|
39
|
+
assert_raises(ORMInvalidRecordException) { user.save! }
|
39
40
|
end
|
40
41
|
|
41
42
|
test 'password must have capital letter' do
|
@@ -43,7 +44,7 @@ class TestSecureValidatable < ActiveSupport::TestCase
|
|
43
44
|
user = User.create email: 'bob@microsoft.com', password: 'password1', password_confirmation: 'password1'
|
44
45
|
assert_equal(false, user.valid?)
|
45
46
|
assert_equal(msgs, user.errors.full_messages)
|
46
|
-
assert_raises(
|
47
|
+
assert_raises(ORMInvalidRecordException) { user.save! }
|
47
48
|
end
|
48
49
|
|
49
50
|
test 'password must have lowercase letter' do
|
@@ -51,7 +52,7 @@ class TestSecureValidatable < ActiveSupport::TestCase
|
|
51
52
|
user = User.create email: 'bob@microsoft.com', password: 'PASSWORD1', password_confirmation: 'PASSWORD1'
|
52
53
|
assert_equal(false, user.valid?)
|
53
54
|
assert_equal([msg], user.errors.full_messages)
|
54
|
-
assert_raises(
|
55
|
+
assert_raises(ORMInvalidRecordException) { user.save! }
|
55
56
|
end
|
56
57
|
|
57
58
|
test 'password must have number' do
|
@@ -59,15 +60,15 @@ class TestSecureValidatable < ActiveSupport::TestCase
|
|
59
60
|
user = User.create email: 'bob@microsoft.com', password: 'PASSword', password_confirmation: 'PASSword'
|
60
61
|
assert_equal(false, user.valid?)
|
61
62
|
assert_equal([msg], user.errors.full_messages)
|
62
|
-
assert_raises(
|
63
|
+
assert_raises(ORMInvalidRecordException) { user.save! }
|
63
64
|
end
|
64
65
|
|
65
66
|
test 'password must have minimum length' do
|
66
|
-
msg = 'Password is too short (minimum is
|
67
|
+
msg = 'Password is too short (minimum is 7 characters)'
|
67
68
|
user = User.create email: 'bob@microsoft.com', password: 'Pa3zZ', password_confirmation: 'Pa3zZ'
|
68
69
|
assert_equal(false, user.valid?)
|
69
70
|
assert_equal([msg], user.errors.full_messages)
|
70
|
-
assert_raises(
|
71
|
+
assert_raises(ORMInvalidRecordException) { user.save! }
|
71
72
|
end
|
72
73
|
|
73
74
|
test 'duplicate email validation message is added only once' do
|
@@ -79,6 +80,6 @@ class TestSecureValidatable < ActiveSupport::TestCase
|
|
79
80
|
SecureUser.create!(options)
|
80
81
|
user = SecureUser.new(options)
|
81
82
|
refute user.valid?
|
82
|
-
assert_equal ['Email has already been taken'], user.errors.full_messages
|
83
|
+
assert_equal DEVISE_ORM == :active_record ? ['Email has already been taken'] : ['Email is already taken'], user.errors.full_messages
|
83
84
|
end
|
84
85
|
end
|