From f4b01307a5ab96ad9179fff66c832ca21a62d4d3 Mon Sep 17 00:00:00 2001 From: Aditi Tiwari Date: Mon, 2 Mar 2026 21:56:46 +0530 Subject: [PATCH] Add failed login attempt tracking and basic lock after 5 attempts --- .../java/com/iemr/common/data/users/User.java | 7 ++- .../users/IEMRAdminUserServiceImpl.java | 59 +++++++++++++++---- 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/iemr/common/data/users/User.java b/src/main/java/com/iemr/common/data/users/User.java index 275b0ec6..8874b12f 100644 --- a/src/main/java/com/iemr/common/data/users/User.java +++ b/src/main/java/com/iemr/common/data/users/User.java @@ -25,6 +25,7 @@ import java.sql.Timestamp; import java.util.List; import java.util.Set; +import java.time.LocalDateTime; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -82,7 +83,7 @@ public class User implements Serializable { @JoinColumn(updatable = false, insertable = false, name = "userID", referencedColumnName = "userID") private Set m_UserLangMappings; - @OneToMany(mappedBy = "mUser", fetch = FetchType.EAGER) + @OneToMany(mappedBy = "m_User", fetch = FetchType.EAGER) @Transient @Expose private Set feedbackDetails; @@ -209,6 +210,10 @@ public class User implements Serializable { @Column(name = "failed_attempt") private Integer failedAttempt; + /* @Expose + @Column(name="lock_until") + private LocalDateTime lockUntil; */ + @Expose @Column(name = "dhistoken") private String dhistoken; diff --git a/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java b/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java index 44bd2247..58d42946 100644 --- a/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java +++ b/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java @@ -386,29 +386,62 @@ public User superUserAuthenticate(String userName, String password) throws Excep return users.get(0); } + @Override - public LoginResponseModel userAuthenticateV1(LoginRequestModel loginRequest, String ipAddress, String hostName) - throws Exception { + + + public LoginResponseModel userAuthenticateV1(LoginRequestModel loginRequest, + String ipAddress, String hostName) throws Exception { + LoginResponseModel loginResponseModel = null; - List users = iEMRUserRepositoryCustom.findByUserName(loginRequest.getUserName()); + + List users = iEMRUserRepositoryCustom + .findByUserName(loginRequest.getUserName()); + if (users.size() == 1) { - User user = users.get(0); + + User user = users.get(0); // ✅ FIRST declare user + + // ✅ THEN check failed attempts + Integer failedAttempt = user.getFailedAttempt(); + + if (failedAttempt != null && failedAttempt >= 5) { + throw new IEMRException( + "Your account has been locked. You can try tomorrow or connect to the administrator." + ); + } + try { - if (!securePassword.validatePasswordExisting(loginRequest.getPassword(), user.getPassword())) { + if (!securePassword.validatePasswordExisting( + loginRequest.getPassword(), + user.getPassword())) { + + int currentAttempt = + user.getFailedAttempt() == null ? 0 : user.getFailedAttempt(); + + currentAttempt++; + user.setFailedAttempt(currentAttempt); + iEMRUserRepositoryCustom.save(user); + throw new IEMRException("Invalid username or password"); } + } catch (Exception e) { throw new IEMRException("Invalid username or password"); } + + // ✅ reset on success + user.setFailedAttempt(0); + iEMRUserRepositoryCustom.save(user); + loginResponseModel = userMapper.userDataToLoginResponse(user); - logger.info("Login response is " + loginResponseModel.toString()); - List userServiceRoleMappings = getUserServiceRoleMapping( - loginResponseModel.getUserID()); - loginResponseModel - .setUserServiceRoleMappings(userServiceRoleMapper.userRoleToLoginUserRole(userServiceRoleMappings)); - - // loginResponseModel.setHostName(hostName); - // loginResponseModel.setIpAddress(ipAddress); + + List userServiceRoleMappings = + getUserServiceRoleMapping(loginResponseModel.getUserID()); + + loginResponseModel.setUserServiceRoleMappings( + userServiceRoleMapper.userRoleToLoginUserRole(userServiceRoleMappings)); + } else { throw new IEMRException("Invalid username or password"); }