From 640cd4a146f35746fb8f0334902dfa278a2eb237 Mon Sep 17 00:00:00 2001 From: Anntorkot Date: Sat, 8 Feb 2025 17:57:14 +0000 Subject: [PATCH] 08.02 PasswordLockout RQ3 --- PasswordLockoutRequirement.java | 66 +++++++++++++++++++++++++++++++++ PasswordMinimumLength.java | 2 +- PasswordPolicy.java | 4 +- 3 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 PasswordLockoutRequirement.java diff --git a/PasswordLockoutRequirement.java b/PasswordLockoutRequirement.java new file mode 100644 index 0000000..9316d81 --- /dev/null +++ b/PasswordLockoutRequirement.java @@ -0,0 +1,66 @@ +import java.util.HashMap; +import java.util.Map; + +public class PasswordLockoutRequirement extends Requirement { + private final String user; + private final Map users = new HashMap<>(); + + private static final long LOCK_TIME = 12 * 1 * 1000; // 12 minutes + private static final int MAX_ATTEMPTS = 5; + + public PasswordLockoutRequirement(String user) { + this.user = user; + users.putIfAbsent(user, new UserStatus()); + } + + public void recordFailedAttempt() { + users.get(user).increaseFailedAttempts(); + } + + public void resetFailedAttempts() { + users.get(user).clearAttempts(); + } + + @Override + public Checkable.CheckStatus check() { + UserStatus status = users.get(user); + if (status.isLocked()) { + if (System.currentTimeMillis() - status.getLockoutStartTime() > LOCK_TIME) { + status.clearLock(); + return Checkable.CheckStatus.PASS; + } else { + return Checkable.CheckStatus.FAIL; + } + } + return Checkable.CheckStatus.INCOMPLETE; + } + + private static class UserStatus { + private int failedAttempts = 0; + private long lockStart = 0; + + public long getLockoutStartTime() { + return lockStart; + } + + public void increaseFailedAttempts() { + failedAttempts++; + if (failedAttempts >= MAX_ATTEMPTS) { + lockStart = System.currentTimeMillis(); + } + } + + public void clearAttempts() { + failedAttempts = 0; + lockStart = 0; + } + + public boolean isLocked() { + return lockStart > 0; + } + + public void clearLock() { + lockStart = 0; + } + } +} diff --git a/PasswordMinimumLength.java b/PasswordMinimumLength.java index e3262ca..7d5eeca 100644 --- a/PasswordMinimumLength.java +++ b/PasswordMinimumLength.java @@ -1,5 +1,5 @@ -import rqcode.concepts.Requirement; + public class PasswordMinimumLength extends Requirement { private static final int MIN_LENGTH = 8; diff --git a/PasswordPolicy.java b/PasswordPolicy.java index 251ba3b..ad60228 100644 --- a/PasswordPolicy.java +++ b/PasswordPolicy.java @@ -1,6 +1,4 @@ -package rqcode.tutorial.tutorial_new; -import rqcode.concepts.CombinedRequirements; -import rqcode.concepts.Requirement; + import java.util.Arrays; import java.util.List;