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,13 @@
|
|
1
|
+
Dir[File.expand_path("*_fields.rb", __dir__)].each { |f| require_relative f }
|
2
|
+
|
3
|
+
module Mongoid
|
4
|
+
module Mappings
|
5
|
+
extend ::ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
self.devise_modules.each do |devise_module_name|
|
9
|
+
include "#{devise_module_name.to_s.classify}Fields".constantize
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module ParanoidVerificationFields
|
2
|
+
extend ::ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
include Mongoid::Document
|
6
|
+
field :paranoid_verification_code, type: String
|
7
|
+
field :paranoid_verified_at, type: Time
|
8
|
+
field :paranoid_verification_attempt, type: Integer, default: 0
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RegisterableFields
|
2
|
+
extend ::ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
include Mongoid::Document
|
6
|
+
|
7
|
+
## Database authenticatable
|
8
|
+
field :email, type: String, default: ""
|
9
|
+
validates_presence_of :email
|
10
|
+
|
11
|
+
field :encrypted_password, type: String, default: ""
|
12
|
+
validates_presence_of :encrypted_password
|
13
|
+
|
14
|
+
field :password_changed_at, type: Time
|
15
|
+
index({ password_changed_at: 1 }, {})
|
16
|
+
index({ email: 1 }, {})
|
17
|
+
include Mongoid::Timestamps
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module SecurityQuestionableFields
|
2
|
+
extend ::ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
include Mongoid::Document
|
6
|
+
|
7
|
+
## Security Questionable
|
8
|
+
field :locked_at, type: Time
|
9
|
+
field :unlock_token, type: String
|
10
|
+
field :security_question_id, type: Integer
|
11
|
+
field :security_question_answer, type: String
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module TrackableFields
|
2
|
+
extend ::ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
include Mongoid::Document
|
6
|
+
|
7
|
+
## Trackable
|
8
|
+
field :sign_in_count, type: Integer, default: 0
|
9
|
+
field :current_sign_in_at, type: Time
|
10
|
+
field :last_sign_in_at, type: Time
|
11
|
+
field :current_sign_in_ip, type: String
|
12
|
+
field :last_sign_in_ip, type: String
|
13
|
+
end
|
14
|
+
end
|
@@ -1,5 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class SecureUser <
|
3
|
+
class SecureUser < ApplicationUserRecord
|
4
4
|
devise :database_authenticatable, :secure_validatable, email_validation: false
|
5
|
+
if DEVISE_ORM == :mongoid
|
6
|
+
require './test/dummy/app/models/mongoid/mappings'
|
7
|
+
include ::Mongoid::Mappings
|
8
|
+
end
|
5
9
|
end
|
@@ -1,7 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class SecurityQuestionUser <
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
class SecurityQuestionUser < ApplicationUserRecord
|
4
|
+
devise :database_authenticatable, :lockable, :security_questionable
|
5
|
+
if DEVISE_ORM == :mongoid
|
6
|
+
require './test/dummy/app/models/mongoid/mappings'
|
7
|
+
include ::Mongoid::Mappings
|
8
|
+
field :security_question_answer, type: String
|
9
|
+
end
|
7
10
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'shared_admin'
|
4
|
+
|
5
|
+
class Admin
|
6
|
+
include Mongoid::Document
|
7
|
+
include Shim
|
8
|
+
include SharedAdmin
|
9
|
+
|
10
|
+
## Database authenticatable
|
11
|
+
field :email, type: String
|
12
|
+
field :encrypted_password, type: String
|
13
|
+
|
14
|
+
## Recoverable
|
15
|
+
field :reset_password_token, type: String
|
16
|
+
field :reset_password_sent_at, type: Time
|
17
|
+
|
18
|
+
## Rememberable
|
19
|
+
field :remember_created_at, type: Time
|
20
|
+
|
21
|
+
## Confirmable
|
22
|
+
field :confirmation_token, type: String
|
23
|
+
field :confirmed_at, type: Time
|
24
|
+
field :confirmation_sent_at, type: Time
|
25
|
+
field :unconfirmed_email, type: String # Only if using reconfirmable
|
26
|
+
|
27
|
+
## Lockable
|
28
|
+
field :locked_at, type: Time
|
29
|
+
|
30
|
+
field :active, type: Boolean, default: false
|
31
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'shared_user_with_password_verification'
|
4
|
+
|
5
|
+
class OneUser
|
6
|
+
include Mongoid::Document
|
7
|
+
include Shim
|
8
|
+
include SharedUserWithPasswordVerification
|
9
|
+
include SharedSecurityQuestionsFields
|
10
|
+
|
11
|
+
field :password_changed_at, type: Time
|
12
|
+
index({ password_changed_at: 1 }, {})
|
13
|
+
|
14
|
+
#field :paranoid_verification_code, type: String
|
15
|
+
#field :paranoid_verified_at, type: Time
|
16
|
+
#field :paranoid_verification_attempt, type: Integer, default: 0
|
17
|
+
|
18
|
+
field :username, type: String
|
19
|
+
field :facebook_token, type: String
|
20
|
+
|
21
|
+
## Database authenticatable
|
22
|
+
field :email, type: String, default: ""
|
23
|
+
field :encrypted_password, type: String, default: ""
|
24
|
+
|
25
|
+
## Recoverable
|
26
|
+
field :reset_password_token, type: String
|
27
|
+
field :reset_password_sent_at, type: Time
|
28
|
+
|
29
|
+
## Rememberable
|
30
|
+
field :remember_created_at, type: Time
|
31
|
+
|
32
|
+
## Trackable
|
33
|
+
field :sign_in_count, type: Integer, default: 0
|
34
|
+
field :current_sign_in_at, type: Time
|
35
|
+
field :last_sign_in_at, type: Time
|
36
|
+
field :current_sign_in_ip, type: String
|
37
|
+
field :last_sign_in_ip, type: String
|
38
|
+
|
39
|
+
## Confirmable
|
40
|
+
field :confirmation_token, type: String
|
41
|
+
field :confirmed_at, type: Time
|
42
|
+
field :confirmation_sent_at, type: Time
|
43
|
+
# field :unconfirmed_email, type: String # Only if using reconfirmable
|
44
|
+
|
45
|
+
## Lockable
|
46
|
+
field :failed_attempts, type: Integer, default: 0 # Only if lock strategy is :failed_attempts
|
47
|
+
field :unlock_token, type: String # Only if unlock strategy is :email or :both
|
48
|
+
field :locked_at, type: Time
|
49
|
+
|
50
|
+
cattr_accessor :validations_performed
|
51
|
+
|
52
|
+
after_validation :after_validation_callback
|
53
|
+
|
54
|
+
def after_validation_callback
|
55
|
+
# used to check in our test if the validations were called
|
56
|
+
@@validations_performed = true
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shim
|
4
|
+
extend ::ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
include ::Mongoid::Timestamps
|
8
|
+
field :created_at, type: DateTime
|
9
|
+
end
|
10
|
+
|
11
|
+
class_methods do
|
12
|
+
def order(attribute)
|
13
|
+
asc(attribute)
|
14
|
+
end
|
15
|
+
|
16
|
+
def find_by_email(email)
|
17
|
+
find_by(email: email)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# overwrite equality (because some devise tests use this for asserting model equality)
|
22
|
+
def ==(other)
|
23
|
+
other.is_a?(self.class) && _id == other._id
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'shared_user_without_omniauth'
|
4
|
+
|
5
|
+
class UserOnEngine
|
6
|
+
include Mongoid::Document
|
7
|
+
include Shim
|
8
|
+
include SharedUserWithoutOmniauth
|
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
|
+
## Confirmable
|
32
|
+
field :confirmation_token, type: String
|
33
|
+
field :confirmed_at, type: Time
|
34
|
+
field :confirmation_sent_at, type: Time
|
35
|
+
# field :unconfirmed_email, type: String # Only if using reconfirmable
|
36
|
+
|
37
|
+
## Lockable
|
38
|
+
field :failed_attempts, type: Integer, default: 0 # Only if lock strategy is :failed_attempts
|
39
|
+
field :unlock_token, type: String # Only if unlock strategy is :email or :both
|
40
|
+
field :locked_at, type: Time
|
41
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'shared_user_without_omniauth'
|
4
|
+
|
5
|
+
class UserOnMainApp
|
6
|
+
include Mongoid::Document
|
7
|
+
include Shim
|
8
|
+
include SharedUserWithoutOmniauth
|
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
|
+
## Confirmable
|
32
|
+
field :confirmation_token, type: String
|
33
|
+
field :confirmed_at, type: Time
|
34
|
+
field :confirmation_sent_at, type: Time
|
35
|
+
# field :unconfirmed_email, type: String # Only if using reconfirmable
|
36
|
+
|
37
|
+
## Lockable
|
38
|
+
field :failed_attempts, type: Integer, default: 0 # Only if lock strategy is :failed_attempts
|
39
|
+
field :unlock_token, type: String # Only if unlock strategy is :email or :both
|
40
|
+
field :locked_at, type: Time
|
41
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "shared_user"
|
4
|
+
|
5
|
+
class UserWithValidations
|
6
|
+
include Mongoid::Document
|
7
|
+
include Shim
|
8
|
+
include SharedUser
|
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
|
+
|
36
|
+
validates :email, presence: true
|
37
|
+
end
|