Add CredentialManagementService to user credential API v2#299
Conversation
| } catch (PushDeviceHandlerClientException e) { | ||
| if (ERROR_CODE_PUSH_AUTH_DEVICE_NOT_FOUND.equals(e.getErrorCode())) { | ||
| if (ERROR_CODE_DEVICE_NOT_FOUND_FOR_USER_ID.getCode().equals(e.getErrorCode())) { | ||
| if (LOG.isDebugEnabled()) { |
There was a problem hiding this comment.
Log Improvement Suggestion No: 1
| } catch (PushDeviceHandlerClientException e) { | |
| if (ERROR_CODE_PUSH_AUTH_DEVICE_NOT_FOUND.equals(e.getErrorCode())) { | |
| if (ERROR_CODE_DEVICE_NOT_FOUND_FOR_USER_ID.getCode().equals(e.getErrorCode())) { | |
| if (LOG.isDebugEnabled()) { | |
| } catch (PushDeviceHandlerClientException e) { | |
| if (ERROR_CODE_DEVICE_NOT_FOUND_FOR_USER_ID.getCode().equals(e.getErrorCode())) { | |
| LOG.info("No push authentication devices found for user ID: " + userId); |
| * @return true if the user exists, false otherwise. | ||
| * @throws CredentialMgtServerException if an error occurs while validating the user ID. | ||
| */ | ||
| public static boolean validateUserId(String userId) throws CredentialMgtServerException { |
There was a problem hiding this comment.
Log Improvement Suggestion No: 2
| public static boolean validateUserId(String userId) throws CredentialMgtServerException { | |
| public static boolean validateUserId(String userId) throws CredentialMgtServerException { | |
| if (LOG.isDebugEnabled()) { | |
| LOG.debug("Validating user ID: " + userId); | |
| } |
| return false; | ||
| } | ||
| return ((UniqueIDUserStoreManager) userStoreManager).isExistingUserWithID(userId); |
There was a problem hiding this comment.
Log Improvement Suggestion No: 3
| return false; | |
| } | |
| return ((UniqueIDUserStoreManager) userStoreManager).isExistingUserWithID(userId); | |
| return false; | |
| } | |
| boolean userExists = ((UniqueIDUserStoreManager) userStoreManager).isExistingUserWithID(userId); | |
| if (LOG.isDebugEnabled()) { | |
| LOG.debug("User validation result for user ID " + userId + ": " + userExists); | |
| } | |
| return userExists; |
| */ | ||
| public CredentialCreationResponseDTO createUserCredential(String userId, String type) { |
There was a problem hiding this comment.
Log Improvement Suggestion No: 4
| */ | |
| public CredentialCreationResponseDTO createUserCredential(String userId, String type) { | |
| validateUserId(userId); | |
| LOG.info("Creating credential for user: " + userId + ", type: " + type); | |
| try { |
| break; | ||
| default: | ||
| LOG.warn("No response mapping for credential type: " + entry.getKey() + ". Skipping."); |
There was a problem hiding this comment.
Log Improvement Suggestion No: 5
| break; | |
| default: | |
| LOG.warn("No response mapping for credential type: " + entry.getKey() + ". Skipping."); | |
| throw CredentialMgtEndpointUtils.handleCredentialMgtException(e); | |
| } catch (Exception e) { | |
| LOG.error("Unexpected error while retrieving credentials for user: " + userId + ", type: " + entry.getKey() + ". Error: " + e.getMessage()); | |
| throw CredentialMgtEndpointUtils.handleCredentialMgtException(new CredentialMgtServerException("Unexpected error occurred", e)); | |
| } |
| import org.wso2.carbon.identity.api.user.credential.common.exception.CredentialMgtClientException; | ||
| import org.wso2.carbon.identity.api.user.credential.common.exception.CredentialMgtException; | ||
| import org.wso2.carbon.identity.api.user.credential.common.exception.CredentialMgtServerException; | ||
| import org.wso2.carbon.identity.rest.api.user.credential.v2.UsersApiService; |
There was a problem hiding this comment.
Log Improvement Suggestion No: 6
| import org.wso2.carbon.identity.rest.api.user.credential.v2.UsersApiService; | |
| import org.apache.commons.logging.Log; | |
| import org.apache.commons.logging.LogFactory; | |
| import org.wso2.carbon.identity.rest.api.user.credential.v2.UsersApiService; |
| */ | ||
| public class UsersCredentialApiServiceImpl implements UsersApiService { | ||
|
|
There was a problem hiding this comment.
Log Improvement Suggestion No: 7
| */ | |
| public class UsersCredentialApiServiceImpl implements UsersApiService { | |
| */ | |
| public class UsersCredentialApiServiceImpl implements UsersApiService { | |
| private static final Log LOG = LogFactory.getLog(UsersCredentialApiServiceImpl.class); | |
| private final CredentialManagementService credentialManagementService; |
There was a problem hiding this comment.
AI Agent Log Improvement Checklist
- The log-related comments and suggestions in this review were generated by an AI tool to assist with identifying potential improvements. Purpose of reviewing the code for log improvements is to improve the troubleshooting capabilities of our products.
- Please make sure to manually review and validate all suggestions before applying any changes. Not every code suggestion would make sense or add value to our purpose. Therefore, you have the freedom to decide which of the suggestions are helpful.
✅ Before merging this pull request:
- Review all AI-generated comments for accuracy and relevance.
- Complete and verify the table below. We need your feedback to measure the accuracy of these suggestions and the value they add. If you are rejecting a certain code suggestion, please mention the reason briefly in the suggestion for us to capture it.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (6)
💤 Files with no reviewable changes (1)
🚧 Files skipped from review as they are similar to previous changes (4)
📝 WalkthroughOverviewThis PR introduces a new Key ChangesNew Core Service:
Improved Error Handling:
Refactored REST Layer:
Simplified Utilities:
Test CoverageThe PR includes test plan items covering:
WalkthroughThis pull request refactors the credential management API by introducing a new CredentialManagementService core layer that centralizes credential operation orchestration. The changes standardize user ID validation, consolidate error handling, and simplify the API endpoint implementation through delegation. Five files are modified: error constants are added and standardized in handlers, user validation logic is centralized in utilities, a new service class coordinates all credential operations, the API implementation is simplified to delegate to the service, and endpoint utilities are cleaned up to remove now-redundant methods. Sequence DiagramsequenceDiagram
participant APIEndpoint as UsersCredentialApiServiceImpl
participant Service as CredentialManagementService
participant Handler as CredentialHandler
participant UserStore as UserStoreManager
participant DTO as DTO Layer
APIEndpoint->>Service: createUserCredential(userId, type)
Service->>Service: validateUserId(userId)
Service->>UserStore: isExistingUserWithID(userId)
UserStore-->>Service: boolean
Service->>Service: resolveCredentialHandler(type)
Service->>Handler: createCredential(userId)
Handler-->>Service: CredentialDTO
Service->>DTO: toEntryDTOs(credentials)
DTO-->>Service: List<CredentialEntryDTO>
Service-->>APIEndpoint: CredentialCreationResponseDTO
APIEndpoint-->>Client: 201 Created
Suggested reviewers
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@components/org.wso2.carbon.identity.api.user.credential/org.wso2.carbon.identity.api.user.credential.common/src/main/java/org/wso2/carbon/identity/api/user/credential/common/utils/CredentialManagementUtils.java`:
- Around line 113-119: Replace the current false return in the UniqueID support
check in CredentialManagementUtils (the branch that tests "if
(!(userStoreManager instanceof UniqueIDUserStoreManager))") with throwing a
server-side exception instead of returning false; specifically, throw an
appropriate runtime/server exception (e.g., IdentityServerException or
CarbonException used in this project) with a clear message that unique-ID
validation is unsupported for the current user store, include the userId and log
the condition (use LOG.debug/info/error as appropriate) so downstream code does
not interpret the result as USER_NOT_FOUND.
In
`@components/org.wso2.carbon.identity.api.user.credential/org.wso2.carbon.identity.api.user.credential.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/credential/v2/core/CredentialManagementService.java`:
- Around line 84-85: The response currently echoes the raw input `type` (the
.type(type) call in CredentialManagementService) which can preserve
case/whitespace variants; instead normalize to the canonical API enum value
before setting the response. Locate the .type(type) assignment in
CredentialManagementService and replace the raw value with a normalized form
derived from the API enum (e.g., trim the input, map/parse it to the canonical
enum constant using the credential enum/parsing helper, then use the enum's
canonical string/value) so the response always returns the enum's canonical API
value.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b8d1e861-ea38-43a3-9529-6addb79cc901
⛔ Files ignored due to path filters (2)
components/org.wso2.carbon.identity.api.user.credential/org.wso2.carbon.identity.api.user.credential.v2/src/gen/java/org/wso2/carbon/identity/rest/api/user/credential/v2/dto/ErrorDTO.javais excluded by!**/gen/**components/org.wso2.carbon.identity.api.user.credential/org.wso2.carbon.identity.api.user.credential.v2/src/gen/java/org/wso2/carbon/identity/rest/api/user/credential/v2/factories/UsersApiServiceFactory.javais excluded by!**/gen/**
📒 Files selected for processing (6)
components/org.wso2.carbon.identity.api.user.credential/org.wso2.carbon.identity.api.user.credential.common/src/main/java/org/wso2/carbon/identity/api/user/credential/common/CredentialManagementConstants.javacomponents/org.wso2.carbon.identity.api.user.credential/org.wso2.carbon.identity.api.user.credential.common/src/main/java/org/wso2/carbon/identity/api/user/credential/common/core/PushCredentialHandler.javacomponents/org.wso2.carbon.identity.api.user.credential/org.wso2.carbon.identity.api.user.credential.common/src/main/java/org/wso2/carbon/identity/api/user/credential/common/utils/CredentialManagementUtils.javacomponents/org.wso2.carbon.identity.api.user.credential/org.wso2.carbon.identity.api.user.credential.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/credential/v2/core/CredentialManagementService.javacomponents/org.wso2.carbon.identity.api.user.credential/org.wso2.carbon.identity.api.user.credential.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/credential/v2/impl/UsersCredentialApiServiceImpl.javacomponents/org.wso2.carbon.identity.api.user.credential/org.wso2.carbon.identity.api.user.credential.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/credential/v2/utils/CredentialMgtEndpointUtils.java
💤 Files with no reviewable changes (1)
- components/org.wso2.carbon.identity.api.user.credential/org.wso2.carbon.identity.api.user.credential.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/credential/v2/utils/CredentialMgtEndpointUtils.java
| if (!(userStoreManager instanceof UniqueIDUserStoreManager)) { | ||
| if (LOG.isDebugEnabled()) { | ||
| LOG.debug("User store manager does not support unique user IDs. " + | ||
| "Cannot validate user ID: " + userId); | ||
| } | ||
| return false; | ||
| } |
There was a problem hiding this comment.
Return a server error when unique-ID validation is unsupported.
At Line 113-119, returning false causes downstream code to treat this as USER_NOT_FOUND, which can misreport valid users when the store cannot validate unique IDs. Throw a server exception on this branch instead.
Suggested fix
if (!(userStoreManager instanceof UniqueIDUserStoreManager)) {
if (LOG.isDebugEnabled()) {
LOG.debug("User store manager does not support unique user IDs. " +
"Cannot validate user ID: " + userId);
}
- return false;
+ throw handleServerException(ErrorMessages.ERROR_CODE_VALIDATE_USER_ID_FAILURE,
+ new IllegalStateException("Unique ID user store is not supported for tenant: " +
+ tenantDomain), userId);
}📝 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.
| if (!(userStoreManager instanceof UniqueIDUserStoreManager)) { | |
| if (LOG.isDebugEnabled()) { | |
| LOG.debug("User store manager does not support unique user IDs. " + | |
| "Cannot validate user ID: " + userId); | |
| } | |
| return false; | |
| } | |
| if (!(userStoreManager instanceof UniqueIDUserStoreManager)) { | |
| if (LOG.isDebugEnabled()) { | |
| LOG.debug("User store manager does not support unique user IDs. " + | |
| "Cannot validate user ID: " + userId); | |
| } | |
| throw handleServerException(ErrorMessages.ERROR_CODE_VALIDATE_USER_ID_FAILURE, | |
| new IllegalStateException("Unique ID user store is not supported for tenant: " + | |
| tenantDomain), userId); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@components/org.wso2.carbon.identity.api.user.credential/org.wso2.carbon.identity.api.user.credential.common/src/main/java/org/wso2/carbon/identity/api/user/credential/common/utils/CredentialManagementUtils.java`
around lines 113 - 119, Replace the current false return in the UniqueID support
check in CredentialManagementUtils (the branch that tests "if
(!(userStoreManager instanceof UniqueIDUserStoreManager))") with throwing a
server-side exception instead of returning false; specifically, throw an
appropriate runtime/server exception (e.g., IdentityServerException or
CarbonException used in this project) with a clear message that unique-ID
validation is unsupported for the current user store, include the userId and log
the condition (use LOG.debug/info/error as appropriate) so downstream code does
not interpret the result as USER_NOT_FOUND.
| .type(type) | ||
| .credentials(dto.getCredentials()); |
There was a problem hiding this comment.
Normalize the response type to canonical API value.
At Line 84, the response echoes raw input type. If input includes case/whitespace variants, output becomes inconsistent despite successful normalized resolution. Return the canonical enum API value instead.
Suggested fix
return new CredentialCreationResponseDTO()
- .type(type)
+ .type(CredentialTypes.fromString(type).apiValue())
.credentials(dto.getCredentials());🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@components/org.wso2.carbon.identity.api.user.credential/org.wso2.carbon.identity.api.user.credential.v2/src/main/java/org/wso2/carbon/identity/rest/api/user/credential/v2/core/CredentialManagementService.java`
around lines 84 - 85, The response currently echoes the raw input `type` (the
.type(type) call in CredentialManagementService) which can preserve
case/whitespace variants; instead normalize to the canonical API enum value
before setting the response. Locate the .type(type) assignment in
CredentialManagementService and replace the raw value with a normalized form
derived from the API enum (e.g., trim the input, map/parse it to the canonical
enum constant using the credential enum/parsing helper, then use the enum's
canonical string/value) so the response always returns the enum's canonical API
value.
81d27e5 to
1d3044a
Compare
Summary
CredentialManagementServiceas a dedicated core service layer (mirroring theSessionManagementServicepattern) responsible for user ID validation, credential handler resolution, and translating handler results to API response DTOsUsersCredentialApiServiceImplto a thin delegation layer that only buildsResponseobjectsCredentialManagementUtils.validateUserId: handleUserStoreExceptionfromisExistingUserWithID, add a proper debug log and earlyreturn falsewhen the user store manager does not support unique IDs (instead of falling through to an unsafe cast), and replaceRuntimeExceptionwith a typedCredentialMgtServerExceptionCredentialManagementServiceand clean up now-unused methods fromCredentialMgtEndpointUtils