Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 56
AMM-118: Add admin account lock controls#332
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
vanitha1822
merged 1 commit into
PSMRI:release-3.6.2
from
varundeepsaini:AMM-118-time-based-account-lockoutApr 15, 2026
Uh oh!
There was an error while loading. Please reload this page.
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
108 changes: 108 additions & 0 deletions
108 src/main/java/com/iemr/common/controller/users/IEMRAdminController.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -77,6 +77,7 @@ | ||
| @RequestMapping("/user") | ||
| @RestController | ||
| public class IEMRAdminController { | ||
| private static final String USER_ID_FIELD = "userId"; | ||
| private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); | ||
| private InputMapper inputMapper = new InputMapper(); | ||
| @@ -583,6 +584,13 @@ public String getLoginResponse(HttpServletRequest request) { | ||
| throw new IEMRException("Authentication failed. Please log in again."); | ||
| } | ||
| // Validate the token first | ||
| Claims claims = jwtUtil.validateToken(jwtToken); | ||
| if (claims == null) { | ||
| logger.warn("Authentication failed: invalid or expired token."); | ||
| throw new IEMRException("Authentication failed. Please log in again."); | ||
| } | ||
| // Extract user ID from the JWT token | ||
| String userId = jwtUtil.getUserIdFromToken(jwtToken); | ||
| @@ -1248,4 +1256,104 @@ public ResponseEntity<?> checkUserDetails(@PathVariable("userName") String userN | ||
| } | ||
| } | ||
| @Operation(summary = "Lock user account") | ||
| @PostMapping(value = "/lockUserAccount", produces = MediaType.APPLICATION_JSON, headers = "Authorization") | ||
| public String lockUserAccount(@RequestBody String request, HttpServletRequest httpRequest) { | ||
| OutputResponse response = new OutputResponse(); | ||
| try { | ||
| Long authenticatedUserId = getAuthenticatedUserId(httpRequest); | ||
| validateAdminPrivileges(authenticatedUserId); | ||
| Long userId = parseUserIdFromRequest(request); | ||
| boolean locked = iemrAdminUserServiceImpl.lockUserAccount(userId); | ||
| response.setResponse(locked ? "User account successfully locked" : "User account was already locked"); | ||
| } catch (Exception e) { | ||
| logger.error("Error locking user account: " + e.getMessage(), e); | ||
| response.setError(e); | ||
| } | ||
| return response.toString(); | ||
| } | ||
| @Operation(summary = "Unlock user account locked due to failed login attempts") | ||
| @PostMapping(value = "/unlockUserAccount", produces = MediaType.APPLICATION_JSON, headers = "Authorization") | ||
| public String unlockUserAccount(@RequestBody String request, HttpServletRequest httpRequest) { | ||
| OutputResponse response = new OutputResponse(); | ||
| try { | ||
| Long authenticatedUserId = getAuthenticatedUserId(httpRequest); | ||
| validateAdminPrivileges(authenticatedUserId); | ||
| Long userId = parseUserIdFromRequest(request); | ||
| boolean unlocked = iemrAdminUserServiceImpl.unlockUserAccount(userId); | ||
| response.setResponse(unlocked ? "User account successfully unlocked" : "User account was not locked"); | ||
| } catch (Exception e) { | ||
| logger.error("Error unlocking user account: " + e.getMessage(), e); | ||
| response.setError(e); | ||
| } | ||
| return response.toString(); | ||
| } | ||
| @Operation(summary = "Get user account lock status") | ||
| @PostMapping(value = "/getUserLockStatus", produces = MediaType.APPLICATION_JSON, headers = "Authorization") | ||
| public String getUserLockStatus(@RequestBody String request, HttpServletRequest httpRequest) { | ||
| OutputResponse response = new OutputResponse(); | ||
| try { | ||
| Long authenticatedUserId = getAuthenticatedUserId(httpRequest); | ||
| validateAdminPrivileges(authenticatedUserId); | ||
| Long userId = parseUserIdFromRequest(request); | ||
| String lockStatusJson = iemrAdminUserServiceImpl.getUserLockStatusJson(userId); | ||
| response.setResponse(lockStatusJson); | ||
| } catch (Exception e) { | ||
| logger.error("Error getting user lock status: " + e.getMessage(), e); | ||
| response.setError(e); | ||
| } | ||
| return response.toString(); | ||
| } | ||
| private Long parseUserIdFromRequest(String request) throws IEMRException { | ||
| try { | ||
| JsonObject requestObj = JsonParser.parseString(request).getAsJsonObject(); | ||
| if (!requestObj.has(USER_ID_FIELD) || requestObj.get(USER_ID_FIELD).isJsonNull()) { | ||
| throw new IEMRException(USER_ID_FIELD + " is required"); | ||
| } | ||
| JsonElement userIdElement = requestObj.get(USER_ID_FIELD); | ||
| if (!userIdElement.isJsonPrimitive() || !userIdElement.getAsJsonPrimitive().isNumber()) { | ||
| throw new IEMRException(USER_ID_FIELD + " must be a number"); | ||
| } | ||
| return userIdElement.getAsLong(); | ||
| } catch (IEMRException e) { | ||
| throw e; | ||
| } catch (Exception e) { | ||
| logger.error("Failed to parse {} from request: {}", USER_ID_FIELD, e.getMessage()); | ||
| throw new IEMRException("Invalid request body"); | ||
| } | ||
| } | ||
coderabbitai[bot] marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| private Long getAuthenticatedUserId(HttpServletRequest httpRequest) throws IEMRException { | ||
| String authorization = httpRequest.getHeader("Authorization"); | ||
| if (authorization != null && authorization.contains("Bearer ")) { | ||
| authorization = authorization.replace("Bearer ", ""); | ||
| } | ||
| if (authorization == null || authorization.isEmpty()) { | ||
| throw new IEMRException("Authentication required"); | ||
| } | ||
| try { | ||
| String sessionJson = sessionObject.getSessionObject(authorization); | ||
| if (sessionJson == null || sessionJson.isEmpty()) { | ||
| throw new IEMRException("Session expired. Please log in again."); | ||
| } | ||
| JSONObject session = new JSONObject(sessionJson); | ||
| return session.getLong("userID"); | ||
| } catch (IEMRException e) { | ||
| throw e; | ||
| } catch (Exception e) { | ||
| logger.error("Authentication failed while extracting user ID: {}", e.getMessage()); | ||
| throw new IEMRException("Authentication failed"); | ||
| } | ||
| } | ||
coderabbitai[bot] marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| private void validateAdminPrivileges(Long userId) throws IEMRException { | ||
| if (!iemrAdminUserServiceImpl.hasAdminPrivileges(userId)) { | ||
| logger.warn("Unauthorized access attempt by userId: {}", userId); | ||
| throw new IEMRException("Access denied. Admin privileges required."); | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2 src/main/java/com/iemr/common/repository/users/IEMRUserRepositoryCustom.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 7 additions & 1 deletion
8 src/main/java/com/iemr/common/service/users/IEMRAdminUserService.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.