Allow define maximum_attemps and unlock_in

This commit is contained in:
taitus
2023-10-09 09:54:42 +02:00
parent 873ec84b52
commit d54a5c2ae0
5 changed files with 89 additions and 3 deletions

View File

@@ -425,6 +425,14 @@ class User < ApplicationRecord
end
end
def self.maximum_attempts
(Tenant.current_secrets.dig(:security, :lockable, :maximum_attempts) || 20).to_i
end
def self.unlock_in
(Tenant.current_secrets.dig(:security, :lockable, :unlock_in) || 1).to_f.hours
end
private
def clean_document_number

View File

@@ -181,10 +181,10 @@ Devise.setup do |config|
# Number of authentication tries before locking an account if lock_strategy
# is failed attempts.
config.maximum_attempts = 20
config.maximum_attempts = 20 # Overwritten in User model
# Time interval to unlock the account if :time is enabled as unlock_strategy.
config.unlock_in = 1.hour
config.unlock_in = 1.hour # Overwritten in User model
# Warn on the last attempt before the account is locked.
config.last_attempt_warning = false

View File

@@ -23,6 +23,9 @@ development:
security:
last_sign_in: false
password_complexity: false
# lockable:
# maximum_attempts: 20
# unlock_in: 1 # In hours
secret_key_base: 56792feef405a59b18ea7db57b4777e855103882b926413d4afdfb8c0ea8aa86ea6649da4e729c5f5ae324c0ab9338f789174cf48c544173bc18fdc3b14262e4
<<: *maps
@@ -58,6 +61,9 @@ staging:
security:
last_sign_in: false
password_complexity: false
# lockable:
# maximum_attempts: 20
# unlock_in: 1 # In hours
tenants:
# If you've enabled multitenancy, you can overwrite secrets for a
# specific tenant with:
@@ -98,6 +104,9 @@ preproduction:
security:
last_sign_in: false
password_complexity: false
# lockable:
# maximum_attempts: 20
# unlock_in: 1 # In hours
tenants:
# If you've enabled multitenancy, you can overwrite secrets for a
# specific tenant with:
@@ -143,6 +152,9 @@ production:
security:
last_sign_in: false
password_complexity: false
# lockable:
# maximum_attempts: 20
# unlock_in: 1 # In hours
tenants:
# If you've enabled multitenancy, you can overwrite secrets for a
# specific tenant with:

View File

@@ -8,7 +8,7 @@ describe Users::SessionsController do
describe "Devise lock" do
context "when devise sign in maximum_attempts reached", :with_frozen_time do
it "locks the user account and sends an email to the account with an unlock link" do
user.update(failed_attempts: 19)
allow(User).to receive(:maximum_attempts).and_return(1)
expect do
post :create, params: { user: { login: "citizen@consul.org", password: "wrongpassword" }}

View File

@@ -882,4 +882,70 @@ describe User do
end
end
end
describe ".maximum_attempts" do
it "returns 20 as default when the secrets aren't configured" do
expect(User.maximum_attempts).to eq 20
end
context "when secrets are configured" do
before do
allow(Rails.application).to receive(:secrets).and_return(ActiveSupport::OrderedOptions.new.merge(
security: {
lockable: { maximum_attempts: "14" }
},
tenants: {
superstrict: {
security: {
lockable: { maximum_attempts: "1" }
}
}
}
))
end
it "uses the general secrets for the main tenant" do
expect(User.maximum_attempts).to eq 14
end
it "uses the tenant secrets for a tenant" do
allow(Tenant).to receive(:current_schema).and_return("superstrict")
expect(User.maximum_attempts).to eq 1
end
end
end
describe ".unlock_in" do
it "returns 1 as default when the secrets aren't configured" do
expect(User.unlock_in).to eq 1.hour
end
context "when secrets are configured" do
before do
allow(Rails.application).to receive(:secrets).and_return(ActiveSupport::OrderedOptions.new.merge(
security: {
lockable: { unlock_in: "2" }
},
tenants: {
superstrict: {
security: {
lockable: { unlock_in: "50" }
}
}
}
))
end
it "uses the general secrets for the main tenant" do
expect(User.unlock_in).to eq 2.hours
end
it "uses the tenant secrets for a tenant" do
allow(Tenant).to receive(:current_schema).and_return("superstrict")
expect(User.unlock_in).to eq 50.hours
end
end
end
end