Skip to content

PreferredLanguage changes - #45

Merged
devikasuresh20 merged 1 commit into
PSMRI:developfrom
ravishanigarapu:develop
Nov 8, 2024
Merged

PreferredLanguage changes#45
devikasuresh20 merged 1 commit into
PSMRI:developfrom
ravishanigarapu:develop

Conversation

@ravishanigarapu

@ravishanigarapu ravishanigarapu commented Nov 8, 2024

Copy link
Copy Markdown
Contributor

📋 Description

JIRA ID: AMM-922

Preferred Language Changes


✅ Type of Change

  • 🐞 Bug fix (non-breaking change which resolves an issue)
  • New feature (non-breaking change which adds functionality)
  • 🔥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 🛠 Refactor (change that is neither a fix nor a new feature)
  • ⚙️ Config change (configuration file or build script updates)
  • 📚 Documentation (updates to docs or readme)
  • 🧪 Tests (adding new or updating existing tests)
  • 🎨 UI/UX (changes that affect the user interface)
  • 🚀 Performance (improves performance)
  • 🧹 Chore (miscellaneous changes that don't modify src or test files)

ℹ️ Additional Information

Please describe how the changes were tested, and include any relevant screenshots, logs, or other information that provides additional context.

Summary by CodeRabbit

  • New Features

    • Added functionality to update phone numbers for both child and mother records.
    • Enhanced authorization validation in the request interceptor for improved security.
  • Bug Fixes

    • Streamlined logic for updating phone numbers and handling call attempts.
  • Documentation

    • Improved error handling and logging mechanisms for authorization checks.

@coderabbitai

coderabbitai Bot commented Nov 8, 2024

Copy link
Copy Markdown

Walkthrough

The changes in this pull request introduce new methods for updating phone numbers in both the ChildRecordRepo and MotherRecordRepo interfaces. The CallClosureImpl class has been modified to streamline the logic for updating phone numbers and resetting call attempt numbers based on certain conditions. Additionally, the HttpInterceptor class has been enhanced with new validation checks for authorization keys, improving error handling and security.

Changes

File Change Summary
src/main/java/com/iemr/ecd/repo/call_conf_allocation/ChildRecordRepo.java Added method updateCorrectPhoneNumber(String correctPhoneNumber, Long childId) for updating child phone numbers.
src/main/java/com/iemr/ecd/repo/call_conf_allocation/MotherRecordRepo.java Added method updateCorrectPhoneNumber(String correctPhoneNumber, Long motherId) for updating mother phone numbers.
src/main/java/com/iemr/ecd/service/associate/CallClosureImpl.java Modified closeCall method to update phone numbers and adjust call attempt logic based on conditions.
src/main/java/com/iemr/ecd/utils/http_request_interceptor/HttpInterceptor.java Enhanced preHandle method to validate authorization keys against Redis session data and improved error handling.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant HttpInterceptor
    participant CallClosureImpl
    participant ChildRecordRepo
    participant MotherRecordRepo

    Client->>HttpInterceptor: Send request with Authorization
    HttpInterceptor->>HttpInterceptor: Validate Authorization key
    alt Invalid key
        HttpInterceptor-->>Client: Return error response
    else Valid key
        HttpInterceptor->>CallClosureImpl: Call closeCall()
        CallClosureImpl->>ChildRecordRepo: updateCorrectPhoneNumber()
        CallClosureImpl->>MotherRecordRepo: updateCorrectPhoneNumber()
        CallClosureImpl-->>HttpInterceptor: Process complete
        HttpInterceptor-->>Client: Return success response
    end
Loading

🐇 In the land of code, where changes abound,
New methods for numbers, in repos are found.
With calls that now close, and checks that are tight,
Our system grows stronger, all feels just right!
Let's hop with delight, for progress we see,
In the world of our code, as bright as can be!
🐇

Warning

Tool Failures:

Tool Failure Count:


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@sonarqubecloud

sonarqubecloud Bot commented Nov 8, 2024

Copy link
Copy Markdown

@devikasuresh20
devikasuresh20 merged commit 8c86b30 into PSMRI:develop Nov 8, 2024

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Outside diff range and nitpick comments (4)
src/main/java/com/iemr/ecd/utils/http_request_interceptor/HttpInterceptor.java (2)

88-90: Add performance optimization for token validation.

The current implementation performs a Redis lookup for every request. Consider adding a local cache with a short TTL to reduce Redis load.

Consider implementing:

  1. A local cache (e.g., Caffeine) with a short TTL (e.g., 1 minute)
  2. Batch prefetching of session data
  3. Redis connection pooling if not already implemented

Line range hint 47-90: Improve token extraction and validation logic.

The current token extraction and validation process has several areas for improvement:

  1. Inconsistent Bearer token handling
  2. No validation of token format
  3. Generic exception handling

Consider implementing these security improvements:

-    String authorization = null;
-    String preAuth = request.getHeader("Authorization");
-    if(null != preAuth && preAuth.contains("Bearer "))
-        authorization=preAuth.replace("Bearer ", "");
-    else
-        authorization = preAuth;
+    String authorization = extractAndValidateToken(request);
+    
+    private String extractAndValidateToken(HttpServletRequest request) throws SecurityException {
+        String authHeader = request.getHeader("Authorization");
+        if (authHeader == null || authHeader.isBlank()) {
+            throw new SecurityException("Missing authorization header");
+        }
+        
+        if (!authHeader.startsWith("Bearer ")) {
+            throw new SecurityException("Invalid authorization header format");
+        }
+        
+        String token = authHeader.substring(7);
+        if (!token.matches("^[a-zA-Z0-9-._~+/]+=*$")) {
+            throw new SecurityException("Invalid token format");
+        }
+        
+        return token;
+    }
src/main/java/com/iemr/ecd/repo/call_conf_allocation/ChildRecordRepo.java (1)

96-99: Consider adding transaction isolation level and parameter validation.

The method could benefit from:

  1. Explicit transaction isolation level for concurrent updates
  2. Parameter validation to prevent null/empty phone numbers
  3. Index hints for optimal query performance

Consider these improvements:

 @Modifying
-@Transactional
+@Transactional(isolation = Isolation.READ_COMMITTED)
 @Query(" UPDATE ChildRecord SET phoneNo = :correctPhoneNumber WHERE ecdIdNoChildId = :childId ")
 public int updateCorrectPhoneNumber(@Param("correctPhoneNumber") String correctPhoneNumber,@Param("childId") Long childId);
src/main/java/com/iemr/ecd/repo/call_conf_allocation/MotherRecordRepo.java (1)

99-102: Consider adding Javadoc for the new method.

Adding documentation would help other developers understand:

  • The purpose of this method
  • When it should be used
  • Parameter descriptions

Add documentation like this:

+    /**
+     * Updates the phone number for a mother record.
+     * 
+     * @param correctPhoneNumber The verified/corrected phone number to update
+     * @param motherId The unique identifier of the mother record
+     */
     @Modifying
     @Transactional
     @Query(" UPDATE MotherRecord SET phoneNo = :correctPhoneNumber WHERE ecdIdNo = :motherId ")
     public void updateCorrectPhoneNumber(@Param("correctPhoneNumber") String correctPhoneNumber, @Param("motherId") Long motherId);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between b3ab749 and 4bc7a66.

📒 Files selected for processing (4)
  • src/main/java/com/iemr/ecd/repo/call_conf_allocation/ChildRecordRepo.java (1 hunks)
  • src/main/java/com/iemr/ecd/repo/call_conf_allocation/MotherRecordRepo.java (1 hunks)
  • src/main/java/com/iemr/ecd/service/associate/CallClosureImpl.java (5 hunks)
  • src/main/java/com/iemr/ecd/utils/http_request_interceptor/HttpInterceptor.java (1 hunks)
🔇 Additional comments (6)
src/main/java/com/iemr/ecd/utils/http_request_interceptor/HttpInterceptor.java (1)

88-90: Verify security configuration and integration.

Let's verify the security configuration and integration with other components.

✅ Verification successful

Security configuration and Redis session integration are properly configured

Based on the verification results:

  1. The HttpInterceptor is properly registered in HttpInterceptorConfig and applies to all endpoints
  2. Redis session storage is configured with:
    • Redis host and port settings in application.properties
    • Session expiry time of 7200 seconds
  3. All REST endpoints require Authorization header
  4. Redis session validation is integrated into the security flow

The interceptor's Redis session validation is a valid security measure, working alongside Spring's session management and properly integrated into the application's security architecture.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for security configuration and dependencies
echo "Checking security configuration..."
rg -l "WebSecurityConfigurerAdapter|SecurityFilterChain|SecurityContextHolder" 

echo "Checking for other interceptors and filters..."
fd -e java -x grep -l "implements.*Filter\|implements.*Interceptor" {}

echo "Checking for Redis configuration..."
rg -l "RedisTemplate|RedisConnectionFactory"

Length of output: 546


Script:

#!/bin/bash
# Let's check for Redis configuration and usage patterns
echo "Checking Redis configuration files..."
fd -e java -e xml -e properties -e yml -x grep -l "redis|Redis" {}

echo "Checking Redis session storage implementation..."
rg -A 5 "class.*RedisStorage" 

echo "Checking WebMvc configuration for interceptor registration..."
rg -A 5 "implements.*WebMvcConfigurer|extends.*WebMvcConfigurerAdapter" 

echo "Checking Spring security annotations..."
rg "@Security|@Secured|@PreAuthorize"

Length of output: 2151


Script:

#!/bin/bash
# Let's check the interceptor configuration and Redis session implementation
echo "Checking HttpInterceptorConfig implementation..."
rg -A 10 "public class HttpInterceptorConfig" 

echo "Checking Redis session storage methods..."
rg -A 5 "getSessionObject|setSessionObject" src/main/java/com/iemr/ecd/utils/redis/RedisStorage.java

echo "Checking application properties for Redis configuration..."
fd -e properties -e yml -x cat {}

echo "Checking for authentication/security related endpoints..."
rg -A 5 "@RestController|@Controller" 

Length of output: 20980

src/main/java/com/iemr/ecd/repo/call_conf_allocation/ChildRecordRepo.java (1)

96-99: Verify the impact on existing phone number update flows.

Since this method is part of a larger change involving phone number updates, we should verify:

  1. Integration with CallClosureImpl
  2. Existing phone number validation logic
  3. Impact on reporting/auditing
✅ Verification successful

Phone number update implementation is properly integrated

The verification shows that the updateCorrectPhoneNumber method is:

  • Correctly integrated with CallClosureImpl which handles both mother and child record updates
  • Part of a consistent pattern across ChildRecordRepo and MotherRecordRepo
  • Used within a transaction that includes proper success logging

The implementation aligns with existing phone number update flows and maintains consistency with the codebase's patterns.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for existing phone number update implementations
echo "Searching for phone number update patterns..."
rg -t java "UPDATE.*SET.*phone.*=" --type java

# Look for related validation logic
echo "Searching for phone number validation..."
rg -t java "validatePhoneNumber|phoneNumberValidation" --type java

Length of output: 2464


Script:

#!/bin/bash
# Let's check for phone number related service implementations and validations
echo "Searching for phone number related service implementations..."
rg -t java -A 5 "updateCorrectPhoneNumber|updatePhoneNumber" --type java

# Look for call closure implementations
echo "Searching for CallClosureImpl..."
rg -t java -A 10 "class CallClosureImpl" --type java

# Check for any phone number related audit or logging
echo "Searching for audit/logging related to phone numbers..."
rg -t java "phone.*log|audit.*phone" --type java

Length of output: 3140

src/main/java/com/iemr/ecd/repo/call_conf_allocation/MotherRecordRepo.java (2)

99-102: LGTM! The implementation follows best practices.

The method is properly annotated with @Modifying and @transactional, and uses parameterized queries for safe database operations.


99-102: Verify the integration with CallClosureImpl.

The method appears to be part of a larger change involving phone number updates. Let's verify the integration points.

✅ Verification successful

Let me check the actual integration in CallClosureImpl.java to verify how updateCorrectPhoneNumber is being used.


Integration with CallClosureImpl is properly implemented

The integration is correctly implemented in CallClosureImpl.java where:

  • The method is called within appropriate null checks for motherId
  • It's used alongside childRecordRepo's similar method for consistent phone number updates
  • The implementation follows the same pattern as other updates (like preferredLanguage)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usage of updateCorrectPhoneNumber to verify proper integration
rg -l "updateCorrectPhoneNumber" | grep -i "CallClosure"

Length of output: 120


Script:

#!/bin/bash
# Get the context of updateCorrectPhoneNumber usage in CallClosureImpl
rg -A 5 -B 5 "updateCorrectPhoneNumber" "src/main/java/com/iemr/ecd/service/associate/CallClosureImpl.java"

Length of output: 809

src/main/java/com/iemr/ecd/service/associate/CallClosureImpl.java (2)

52-52: LGTM: Constants import added appropriately

The addition of Constants import aligns with best practices for maintaining string literals as constants.


182-188: Verify ANM role handling logic

The special handling for ANM role resets the call attempt counter and reopens allocation. This could have significant workflow implications.

Consider adding a comment explaining why ANM role requires this special handling for better maintainability.

✅ Verification successful

ANM role handling is consistent with special allocation workflow

The special handling for ANM role in call closure is consistent with the broader system design. The codebase shows ANM (Auxiliary Nurse Midwife) has dedicated allocation paths for both mother and child records that specifically consider preferred language:

  • Separate allocation methods allocateMotherRecordsToANM and allocateChildRecordsToANM
  • Special database queries like getMotherRecordsForANM and getChildRecordsForANM
  • Distinct record counting methods for ANM users that factor in language preference

The call attempt reset and reopening behavior aligns with this specialized workflow where ANM users handle language-specific allocations.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other ANM role-specific handling to ensure consistency
rg -l "Constants.ANM" | xargs rg -A 5 -B 5 "ANM"

Length of output: 21004

Comment on lines +88 to +90
String userRespFromRedis = redisStorage.getSessionObject(authorization);
if(userRespFromRedis == null)
throw new Exception("invalid Authorization key, please pass a valid key to proceed further. ");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider security hardening improvements.

While the Redis validation is a good addition, consider these security improvements:

  1. Use constant-time comparison for token validation to prevent timing attacks
  2. Make error messages generic to avoid information disclosure
  3. Add rate limiting for failed attempts

Apply this diff to implement the suggestions:

-    String userRespFromRedis = redisStorage.getSessionObject(authorization);
-    if(userRespFromRedis == null)
-        throw new Exception("invalid Authorization key, please pass a valid key to proceed further. ");
+    try {
+        String userRespFromRedis = redisStorage.getSessionObject(authorization);
+        if (!MessageDigest.isEqual(
+            userRespFromRedis.getBytes(),
+            redisStorage.getSessionObject(authorization).getBytes())) {
+            throw new SecurityException("Authentication failed");
+        }
+    } catch (Exception e) {
+        throw new SecurityException("Authentication failed");
+    }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +96 to +99
@Modifying
@Transactional
@Query(" UPDATE ChildRecord SET phoneNo = :correctPhoneNumber WHERE ecdIdNoChildId = :childId ")
public void updateCorrectPhoneNumber(@Param("correctPhoneNumber") String correctPhoneNumber,@Param("childId") Long childId);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Return type should be consistent with other update methods.

The method should return int to indicate the number of rows affected, consistent with other update methods in this repository (e.g., updatePreferredLanguage, updateIsAllocatedStatus).

Apply this change:

-public void updateCorrectPhoneNumber(@Param("correctPhoneNumber") String correctPhoneNumber,@Param("childId") Long childId);
+public int updateCorrectPhoneNumber(@Param("correctPhoneNumber") String correctPhoneNumber,@Param("childId") Long childId);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Modifying
@Transactional
@Query(" UPDATE ChildRecord SET phoneNo = :correctPhoneNumber WHERE ecdIdNoChildId = :childId ")
public void updateCorrectPhoneNumber(@Param("correctPhoneNumber") String correctPhoneNumber,@Param("childId") Long childId);
@Modifying
@Transactional
@Query(" UPDATE ChildRecord SET phoneNo = :correctPhoneNumber WHERE ecdIdNoChildId = :childId ")
public int updateCorrectPhoneNumber(@Param("correctPhoneNumber") String correctPhoneNumber,@Param("childId") Long childId);

if(!StringUtil.isNullOrEmpty(request.getCorrectPhoneNumber())) {
obj.setPhoneNo(request.getCorrectPhoneNumber());
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve error handling robustness

The current error handling could be more specific and robust:

  1. Generic exception handling masks specific errors
  2. Inconsistent null checks could lead to NPEs

Consider:

  1. Adding specific exception handling for different error scenarios
  2. Consistent null checks before operations
  3. Proper error messages for each failure case
 try {
     // ... existing code ...
+} catch (InvalidRequestException e) {
+    logger.error("Invalid request data: {}", e.getMessage());
+    throw e;
+} catch (IllegalStateException e) {
+    logger.error("Invalid state: {}", e.getMessage());
+    throw new ECDException("Failed to process call closure: " + e.getMessage());
 } catch (Exception e) {
+    logger.error("Unexpected error during call closure: {}", e.getMessage());
     throw new ECDException(e);
 }

Also applies to: 224-231

Comment on lines +224 to +231
if(!StringUtil.isNullOrEmpty(request.getCorrectPhoneNumber())) {
if (null != callObj.getMotherId() && callObj.getChildId() == null) {
motherRecordRepo.updateCorrectPhoneNumber(request.getCorrectPhoneNumber(), callObj.getMotherId());
}
if (callObj.getMotherId() != null && callObj.getChildId() != null) {
childRecordRepo.updateCorrectPhoneNumber(request.getCorrectPhoneNumber(), callObj.getChildId());
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add phone number format validation

The phone number update logic lacks format validation before updating the records. This could lead to invalid phone numbers being stored.

Consider:

  1. Adding phone number format validation
  2. Logging the phone number changes for audit purposes
  3. Adding a comment explaining the business logic for updating both mother and child records

Example validation:

 if(!StringUtil.isNullOrEmpty(request.getCorrectPhoneNumber())) {
+    if (!request.getCorrectPhoneNumber().matches("^\\d{10}$")) {
+        throw new InvalidRequestException("Invalid phone number format");
+    }
     if (null != callObj.getMotherId() && callObj.getChildId() == null) {
+        logger.info("Updating mother's phone number for motherId: {}", callObj.getMotherId());
         motherRecordRepo.updateCorrectPhoneNumber(request.getCorrectPhoneNumber(), callObj.getMotherId());
     }
     if (callObj.getMotherId() != null && callObj.getChildId() != null) {
+        logger.info("Updating child's phone number for childId: {}", callObj.getChildId());
         childRecordRepo.updateCorrectPhoneNumber(request.getCorrectPhoneNumber(), callObj.getChildId());
     }
 }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +162 to +166
if (request.getIsHrp() != null) {
callObj.setIsHighRisk(request.getIsHrp());
}
// else {
// callObj.setIsHrni(request.getIsHrni());
// }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance high-risk status change handling

Changes to high-risk status (HRP/HRNI) should be tracked for medical audit purposes.

Consider adding:

  1. Logging of risk status changes
  2. Reason for risk status change
  3. Audit trail
 if (request.getIsHrp() != null) {
+    logger.info("Updating HRP status for motherId: {} to: {}", callObj.getMotherId(), request.getIsHrp());
     callObj.setIsHighRisk(request.getIsHrp());
 }

 if (request.getIsHrni() != null) {
+    logger.info("Updating HRNI status for childId: {} to: {}", callObj.getChildId(), request.getIsHrni());
     callObj.setIsHrni(request.getIsHrni());
 }

Committable suggestion skipped: line range outside the PR's diff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants