package stirling.software.SPDF.config.security; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import jakarta.annotation.PostConstruct; import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.AttemptCounter; @Service public class LoginAttemptService { @Autowired ApplicationProperties applicationProperties; private static final Logger logger = LoggerFactory.getLogger(LoginAttemptService.class); private int MAX_ATTEMPT; private long ATTEMPT_INCREMENT_TIME; private ConcurrentHashMap attemptsCache; @PostConstruct public void init() { MAX_ATTEMPT = applicationProperties.getSecurity().getLoginAttemptCount(); ATTEMPT_INCREMENT_TIME = TimeUnit.MINUTES.toMillis( applicationProperties.getSecurity().getLoginResetTimeMinutes()); attemptsCache = new ConcurrentHashMap<>(); } public void loginSucceeded(String key) { if (key == null || key.trim().isEmpty()) { return; } attemptsCache.remove(key.toLowerCase()); } public void loginFailed(String key) { if (key == null || key.trim().isEmpty()) return; AttemptCounter attemptCounter = attemptsCache.get(key.toLowerCase()); if (attemptCounter == null) { attemptCounter = new AttemptCounter(); attemptsCache.put(key.toLowerCase(), attemptCounter); } else { if (attemptCounter.shouldReset(ATTEMPT_INCREMENT_TIME)) { attemptCounter.reset(); } attemptCounter.increment(); } } public boolean isBlocked(String key) { if (key == null || key.trim().isEmpty()) return false; AttemptCounter attemptCounter = attemptsCache.get(key.toLowerCase()); if (attemptCounter == null) { return false; } return attemptCounter.getAttemptCount() >= MAX_ATTEMPT; } public int getRemainingAttempts(String key) { if (key == null || key.trim().isEmpty()) return MAX_ATTEMPT; AttemptCounter attemptCounter = attemptsCache.get(key.toLowerCase()); if (attemptCounter == null) { return MAX_ATTEMPT; } return MAX_ATTEMPT - attemptCounter.getAttemptCount(); } }