Skip to content

Conversation

@NipuniBhagya
Copy link
Contributor

@NipuniBhagya NipuniBhagya commented Oct 1, 2025

This pull request introduces a new common module for credential management in the WSO2 Identity Server API, providing foundational interfaces, DTOs, constants, and exception handling for credential management operations. The changes establish a clear contract for handling different credential types (such as passkeys and push authentication), standardize error handling, and facilitate integration with relevant backend services.

Key additions and changes include:

Core Interfaces and DTOs

  • Added the CredentialManagementService and CredentialHandler interfaces, defining methods for retrieving and deleting user credentials, and introduced the CredentialDTO class for transferring credential data. [1] [2] [3]

Constants and Credential Types

  • Introduced CredentialManagementConstants, which defines supported credential types (e.g., passkey, push-auth) and standardized error messages for both server and client errors.

Exception Handling Framework

  • Implemented a hierarchy of custom exceptions for credential management, including a base CredentialMgtException and specialized client and server exceptions (CredentialMgtClientException, CredentialMgtServerException). [1] [2] [3]

Service Integration

  • Added CredentialManagementServiceDataHolder to provide access to backend services (e.g., WebAuthn and Push Device Handler) required for credential operations.

Build Configuration

  • Created a new Maven pom.xml for the common module, specifying dependencies on required WSO2 and test libraries.## Purpose

Describe the problems, issues, or needs driving this feature/fix and include links to related issues in the following format: Resolves issue1, issue2, etc.

Goals

Describe the solutions that this feature/fix will introduce to resolve the problems described above

Approach

Describe how you are implementing the solutions. Include an animated GIF or screenshot if the change affects the UI (email documentation@wso2.com to review all UI text). Include a link to a Markdown file or Google doc if the feature write-up is too long to paste here.

User stories

Summary of user stories addressed by this change>

Developer Checklist (Mandatory)

  • Complete the Developer Checklist in the related product-is issue to track any behavioral change or migration impact.

Release note

Brief description of the new feature or bug fix as it will appear in the release notes

Documentation

Link(s) to product documentation that addresses the changes of this PR. If no doc impact, enter “N/A” plus brief explanation of why there’s no doc impact

Training

Link to the PR for changes to the training content in https://github.com/wso2/WSO2-Training, if applicable

Certification

Type “Sent” when you have provided new/updated certification questions, plus four answers for each question (correct answer highlighted in bold), based on this change. Certification questions/answers should be sent to certification@wso2.com and NOT pasted in this PR. If there is no impact on certification exams, type “N/A” and explain why.

Marketing

Link to drafts of marketing content that will describe and promote this feature, including product page changes, technical articles, blog posts, videos, etc., if applicable

Automation tests

  • Unit tests

    Code coverage information

  • Integration tests

    Details about the test cases and coverage

Security checks

Samples

Provide high-level details about the samples related to this feature

Related PRs

List any other related PRs

Related Issues

wso2/product-is#25666

Migrations (if applicable)

Describe migration steps and platforms on which migration has been tested

Test environment

List all JDK versions, operating systems, databases, and browser/versions on which this feature/fix was tested

Learning

Describe the research phase and any blog posts, patterns, libraries, or add-ons you used to solve the problem.

Summary by CodeRabbit

  • New Features

    • REST endpoints to list and delete user credentials (GET, DELETE)
    • Support for passkey and push-auth credential types with handlers for each
  • Documentation

    • Added OpenAPI specification for the credential management API
  • Improvements

    • Centralized error handling, validation and normalized error codes
    • Aggregation service to collect credentials from multiple sources
  • Tests

    • Comprehensive unit tests covering listing, deletion and error scenarios
  • Chores

    • New multi-module packaging for credential management

✏️ Tip: You can customize this high-level summary in your review settings.

Comment on lines 67 to 69
CredentialMgtEndpointUtils.validateUserId(userId);
CredentialMgtEndpointUtils.validateCredentialId(credentialId);
CredentialMgtEndpointUtils.validateCredentialType(type);

Choose a reason for hiding this comment

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

Log Improvement Suggestion No: 18

Suggested change
CredentialMgtEndpointUtils.validateUserId(userId);
CredentialMgtEndpointUtils.validateCredentialId(credentialId);
CredentialMgtEndpointUtils.validateCredentialType(type);
CredentialMgtEndpointUtils.validateCredentialId(credentialId);
CredentialMgtEndpointUtils.validateCredentialType(type);
log.info("Deleting credential of type: {} for user: {}", type, userId);
adminCredentialManagementService.deleteCredentialForUser(userId, type, credentialId);

@NipuniBhagya NipuniBhagya force-pushed the credential-mgt branch 2 times, most recently from 42747b1 to f0f9713 Compare January 14, 2026 12:47
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In
`@components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/CredentialManagementServiceDataHolder.java`:
- Around line 46-50: The SERVICE field in the inner class RealmServiceHolder is
declared package-private; change its declaration to private static final to
match the visibility of WebAuthnServiceHolder and PushDeviceHandlerHolder.
Locate the RealmServiceHolder inner class and update the SERVICE field modifier
accordingly so it becomes private static final RealmService SERVICE (keeping the
existing initialization via PrivilegedCarbonContext unchanged).

In
`@components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/exception/CredentialMgtServerException.java`:
- Around line 26-36: Update the Javadoc for the
CredentialMgtServerException(String errorCode, String message, String
description, Throwable cause) constructor to match the actual parameter list and
include the missing cause: reorder the `@param` tags to errorCode, message,
description, cause; add a `@param` description for cause (e.g., throwable cause of
the exception); and update the main description to mention that a cause can be
provided. Ensure the comment text and tag order exactly reflect the constructor
signature.

In
`@components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/resources/credential-management.yaml`:
- Around line 110-136: The DELETE endpoint responses block in
credential-management.yaml is missing a 404 response for "credential or user not
found"; update the responses for the DELETE operation (the responses block
shown) to include a '404' entry with a description like "Not Found - Credential
or User Not Found" and the same application/json schema ref
('#/components/schemas/Error') used by the other error responses so the API
returns 404 when the credential or user does not exist.

In
`@components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/test/java/org/wso2/carbon/identity/api/server/credential/management/v1/impl/CredentialManagementServiceImplTest.java`:
- Around line 55-64: The test currently mocks the system under test
(userCredentialManagementService) which is wrong; remove the `@Mock` on
CredentialManagementServiceImpl, instantiate a real
CredentialManagementServiceImpl in setUp() and inject the mocked
CredentialHandler instances (passkeyHandler, pushAuthHandler) into its handler
map (e.g., via the existing handlerMap field or reflection), then update tests
to call real methods on userCredentialManagementService and remove
doCallRealMethod() usages so the real implementation is exercised with mocked
dependencies.

In
`@components/org.wso2.carbon.identity.api.server.credential.management/pom.xml`:
- Around line 23-28: The parent POM version in the <parent> block (artifactId
identity-api-server, groupId org.wso2.carbon.identity.server.api) is incorrect
(1.3.223-SNAPSHOT) and must match the root POM; update the <version> value to
1.3.231-SNAPSHOT so Maven can resolve the parent successfully.
♻️ Duplicate comments (8)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/CredentialManagementService.java (1)

29-40: Interface structure looks good; documentation concern already raised.

The interface design is clean with appropriate method signatures and DTO usage. The previous review comment comprehensively addresses the need for detailed JavaDoc including parameter descriptions, return value semantics, and exception documentation. Please ensure that feedback is addressed.

components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/dto/CredentialDeletionRequestDTO.java (1)

26-28: Declare fields as final for true immutability.

The fields should be final since the class uses a private constructor, no setters, and the builder pattern—all indicating immutability intent. This ensures thread safety and prevents accidental reassignment.

-    private String entityId;
-    private String credentialId;
-    private String type;
+    private final String entityId;
+    private final String credentialId;
+    private final String type;
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/CredentialManagementServiceDataHolder.java (1)

35-38: Direct instantiation of OSGi service is inconsistent with other holders.

This issue was already flagged in a previous review. The WebAuthnService is instantiated directly with new WebAuthnService(), while PushDeviceHandlerHolder and RealmServiceHolder retrieve services via PrivilegedCarbonContext. This inconsistency may lead to runtime failures if WebAuthnService depends on OSGi lifecycle management.

components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/test/java/org/wso2/carbon/identity/api/server/credential/management/v1/impl/CredentialManagementServiceImplTest.java (1)

251-258: Unused DataProvider edgeCaseInputs.

This DataProvider is defined but not consumed by any test method. Either add a test using @Test(dataProvider = "edgeCaseInputs") to validate trimming and mixed-case handling, or remove this dead code.

components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/resources/credential-management.yaml (1)

157-160: Verify error code example validity.

The example error code 'CM-60401' was previously flagged as potentially invalid since CredentialManagementConstants.ErrorMessages defines codes like CM-60001 through CM-60006 (client errors) and CM-65001 through CM-65004 (server errors). The previous review was marked as addressed, but the value appears unchanged.

Please confirm if CM-60401 is intentional (perhaps a new error code was added) or if it should be updated to match an existing constant like CM-60001.

components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/CredentialHandler.java (1)

27-29: Correct the interface Javadoc to match the interface name.

The Javadoc describes this as "Credential Management Service interface" but the interface is actually named CredentialHandler. This inconsistency can cause confusion for developers.

📝 Suggested fix
 /**
- * Credential Management Service interface.
+ * Interface for handling credential operations for a specific credential type.
  */
 public interface CredentialHandler {
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/java/org/wso2/carbon/identity/api/server/credential/management/v1/impl/CredentialManagementServiceImpl.java (1)

78-86: Potential NPE if handler is not registered for a valid credential type.

After validateCredentialType passes, CredentialTypes.fromString will return a valid enum value. However, handlerMap.get(credentialType) could still return null if no handler is registered for that type, causing an NPE on line 83.

🐛 Proposed fix
         try {
             CredentialMgtEndpointUtils.validateCredentialId(credentialDeletionRequest.getCredentialId());
             CredentialMgtEndpointUtils.validateCredentialType(credentialDeletionRequest.getType());
             CredentialTypes credentialType = CredentialTypes.fromString(credentialDeletionRequest.getType());
             CredentialHandler handler = handlerMap.get(credentialType);
+            if (handler == null) {
+                throw new CredentialMgtException(
+                        "No handler registered for credential type: " + credentialType,
+                        CredentialManagementConstants.ErrorMessages.ERROR_CODE_INVALID_CREDENTIAL_TYPE.getCode(),
+                        "Handler not available for the specified credential type.");
+            }
             handler.deleteCredential(credentialDeletionRequest);
         } catch (CredentialMgtException e) {

Note: You'll need to add the import for CredentialMgtException and CredentialManagementConstants if not already present.

components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/core/PasskeyCredentialHandler.java (1)

141-156: Potential null username and duplicate exception handling.

Two issues remain from previous review:

  1. Null username risk (line 148): getUserNameFromUserID(userId) could return null, resulting in "null@tenantDomain" being returned, which could cause downstream issues.

  2. Duplicate catch blocks (lines 149-155): The two UserStoreException catch blocks have identical handling and can be combined using multi-catch syntax.

🐛 Proposed fix
     private String resolveUsernameFromUserId(String userId) throws CredentialMgtException {

         try {
             RealmService userRealm = CredentialManagementServiceDataHolder.getRealmService();
             String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
             AbstractUserStoreManager userStoreManager = (AbstractUserStoreManager) userRealm
                     .getTenantUserRealm(IdentityTenantUtil.getTenantId(tenantDomain)).getUserStoreManager();
-            return userStoreManager.getUserNameFromUserID(userId) + "@" + tenantDomain;
-        } catch (UserStoreException e) {
-            throw CredentialManagementUtils.handleServerException(
-                    CredentialManagementConstants.ErrorMessages.ERROR_CODE_GET_USERNAME_FROM_USERID, e, userId);
-        } catch (org.wso2.carbon.user.api.UserStoreException e) {
+            String username = userStoreManager.getUserNameFromUserID(userId);
+            if (username == null) {
+                throw CredentialManagementUtils.handleClientException(
+                        CredentialManagementConstants.ErrorMessages.ERROR_CODE_ENTITY_NOT_FOUND, null, userId);
+            }
+            return username + "@" + tenantDomain;
+        } catch (UserStoreException | org.wso2.carbon.user.api.UserStoreException e) {
             throw CredentialManagementUtils.handleServerException(
                     CredentialManagementConstants.ErrorMessages.ERROR_CODE_GET_USERNAME_FROM_USERID, e, userId);
         }
     }
🧹 Nitpick comments (8)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/dto/CredentialDeletionRequestDTO.java (1)

79-82: Add validation for required fields in build() method.

The build() method creates the DTO without validating that essential fields (entityId, credentialId, type) are non-null. This could allow invalid deletion requests to propagate, causing runtime failures downstream when the service attempts to delete a credential.

♻️ Suggested validation
         public CredentialDeletionRequestDTO build() {

+            if (entityId == null || entityId.isEmpty()) {
+                throw new IllegalArgumentException("entityId is required");
+            }
+            if (credentialId == null || credentialId.isEmpty()) {
+                throw new IllegalArgumentException("credentialId is required");
+            }
+            if (type == null || type.isEmpty()) {
+                throw new IllegalArgumentException("type is required");
+            }
             return new CredentialDeletionRequestDTO(entityId, credentialId, type);
         }
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/exception/CredentialMgtClientException.java (1)

58-61: Consider supporting formatted descriptions in the ErrorMessages constructor.

The ErrorMessages enum has description templates with %s placeholders (e.g., "Entity with ID %s not found..."), but this constructor uses error.getDescription() directly without formatting. Callers using this constructor won't be able to substitute placeholders.

If template substitution is needed, consider adding an overload:

💡 Suggested enhancement
/**
 * Constructor with {`@code` error} parameter and format arguments.
 *
 * `@param` error Error message.
 * `@param` args  Arguments to format the description.
 */
public CredentialMgtClientException(ErrorMessages error, Object... args) {

    super(error.getMessage(), error.getCode(), String.format(error.getDescription(), args));
}
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/CredentialManagementConstants.java (2)

73-80: Consider caching the Collator instance for better performance.

A new Collator instance is created on every call to fromString(). While not critical for low-volume usage, this could be optimized by caching it as a static field.

♻️ Suggested optimization
 public enum CredentialTypes {
 
     PASSKEY("passkey"),
     PUSH_AUTH("push-auth");
 
     private final String apiValue;
+    private static final Collator COLLATOR;
+
+    static {
+        COLLATOR = Collator.getInstance(Locale.ROOT);
+        COLLATOR.setStrength(Collator.PRIMARY);
+    }
 
     // ... constructor and getApiValue ...
 
     public static CredentialTypes fromString(String value) {
 
         if (value == null) {
             return null;
         }
 
         String candidate = value.trim();
         if (candidate.isEmpty()) {
             return null;
         }
 
-        Collator collator = Collator.getInstance(Locale.ROOT);
-        collator.setStrength(Collator.PRIMARY);
-
         return Arrays.stream(values())
-                .filter(type -> collator.compare(type.name(), candidate) == 0
-                        || collator.compare(type.getApiValue(), candidate) == 0)
+                .filter(type -> COLLATOR.compare(type.name(), candidate) == 0
+                        || COLLATOR.compare(type.getApiValue(), candidate) == 0)
                 .findFirst()
                 .orElse(null);
     }
 }

117-117: Relocate ERROR_CODE_PUSH_AUTH_DEVICE_NOT_FOUND outside the ErrorMessages enum.

This constant uses a different prefix (PDH- vs CM-) and isn't an enum member—it appears to be an external error code from the Push Device Handler used for comparison. Placing it inside the ErrorMessages enum is misleading.

♻️ Suggested relocation
 public class CredentialManagementConstants {
 
     private CredentialManagementConstants() {
 
     }
+
+    /**
+     * Error code from Push Device Handler indicating device not found.
+     */
+    public static final String ERROR_CODE_PUSH_AUTH_DEVICE_NOT_FOUND = "PDH-15010";
 
     // ... CredentialTypes enum ...
 
     public enum ErrorMessages {
         // ... enum values ...
 
         private static final String ERROR_PREFIX = "CM";
-        public static final String ERROR_CODE_PUSH_AUTH_DEVICE_NOT_FOUND = "PDH-15010";
         private final String code;
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/exception/CredentialMgtException.java (1)

26-27: Consider making exception fields immutable.

The errorCode and description fields are non-final with protected setters, allowing mutation after construction. Exceptions are conventionally immutable, and mutable exception state can lead to subtle bugs if the exception is caught, modified, and re-thrown or logged at different points.

If post-construction modification isn't required by subclasses, consider making the fields final and removing the setters.

♻️ Suggested change for immutability
 public class CredentialMgtException extends Exception {
 
-    private String errorCode;
-    private String description;
+    private final String errorCode;
+    private final String description;
 
     // ... constructors unchanged ...
 
-    /**
-     * Set the {`@code` errorCode}.
-     *
-     * `@param` errorCode The value to be set as the {`@code` errorCode}.
-     */
-    protected void setErrorCode(String errorCode) {
-
-        this.errorCode = errorCode;
-    }
-
-    /**
-     * Set the {`@code` description}.
-     *
-     * `@param` description The value to be set as the {`@code` description}.
-     */
-    protected void setDescription(String description) {
-
-        this.description = description;
-    }
 }

Also applies to: 83-96

components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/test/java/org/wso2/carbon/identity/api/server/credential/management/v1/impl/CredentialManagementServiceImplTest.java (1)

174-181: Test assumes handler invocation order.

Line 179 asserts pushAuthHandler is never called, assuming passkeyHandler throws first. This relies on EnumMap iteration order (which follows enum declaration order). If CredentialTypes enum is reordered, this test could fail or produce false positives.

Consider documenting this assumption or making the test order-agnostic by verifying that at least one handler was called before the exception.

components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/resources/credential-management.yaml (2)

48-51: Consider adding maxItems to the array response.

Static analysis flagged that the array response lacks a maximum bound. Adding maxItems improves API documentation and sets clear expectations for consumers about response size limits.

📝 Suggested improvement
              schema:
                type: array
+               maxItems: 100
                items:
                  $ref: '#/components/schemas/Credential'

104-109: Minor: Description refers to "device" instead of "credential".

Line 106 describes credential-id as "The unique identifier of the device to be deleted" but this API manages credentials, not specifically devices. Consider updating for consistency.

📝 Suggested fix
        - name: credential-id
          in: path
-         description: The unique identifier of the device to be deleted.
+         description: The unique identifier of the credential to be deleted.
          required: true
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7730fee and 541396e.

⛔ Files ignored due to path filters (5)
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/credential/management/v1/Credential.java is excluded by !**/gen/**
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/credential/management/v1/Error.java is excluded by !**/gen/**
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/credential/management/v1/UsersApi.java is excluded by !**/gen/**
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/credential/management/v1/UsersApiService.java is excluded by !**/gen/**
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/gen/java/org/wso2/carbon/identity/api/server/credential/management/v1/factories/UsersApiServiceFactory.java is excluded by !**/gen/**
📒 Files selected for processing (24)
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/pom.xml
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/CredentialHandler.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/CredentialManagementConstants.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/CredentialManagementService.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/CredentialManagementServiceDataHolder.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/core/PasskeyCredentialHandler.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/core/PushCredentialHandler.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/dto/CredentialDTO.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/dto/CredentialDeletionRequestDTO.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/exception/CredentialMgtClientException.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/exception/CredentialMgtException.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/exception/CredentialMgtServerException.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/utils/CredentialManagementUtils.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/pom.xml
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/java/org/wso2/carbon/identity/api/server/credential/management/v1/constants/CredentialMgtEndpointConstants.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/java/org/wso2/carbon/identity/api/server/credential/management/v1/factories/CredentialManagementServiceFactory.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/java/org/wso2/carbon/identity/api/server/credential/management/v1/impl/CredentialManagementServiceImpl.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/java/org/wso2/carbon/identity/api/server/credential/management/v1/impl/UsersCredentialApiServiceImpl.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/java/org/wso2/carbon/identity/api/server/credential/management/v1/utils/CredentialMgtEndpointUtils.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/resources/credential-management.yaml
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/test/java/org/wso2/carbon/identity/api/server/credential/management/v1/impl/CredentialManagementServiceImplTest.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/test/resources/testng.xml
  • components/org.wso2.carbon.identity.api.server.credential.management/pom.xml
  • pom.xml
🚧 Files skipped from review as they are similar to previous changes (9)
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/pom.xml
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/java/org/wso2/carbon/identity/api/server/credential/management/v1/factories/CredentialManagementServiceFactory.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/test/resources/testng.xml
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/pom.xml
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/dto/CredentialDTO.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/core/PushCredentialHandler.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/java/org/wso2/carbon/identity/api/server/credential/management/v1/utils/CredentialMgtEndpointUtils.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/java/org/wso2/carbon/identity/api/server/credential/management/v1/impl/UsersCredentialApiServiceImpl.java
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/utils/CredentialManagementUtils.java
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-10T02:37:06.312Z
Learnt from: mpmadhavig
Repo: wso2/identity-api-server PR: 1042
File: components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java:515-534
Timestamp: 2025-12-10T02:37:06.312Z
Learning: In the file `components/org.wso2.carbon.identity.api.server.idp/org.wso2.carbon.identity.api.server.idp.v1/src/main/java/org/wso2/carbon/identity/api/server/idp/v1/core/ServerIdpManagementService.java`, the `createIDPImportRequest` method intentionally supports only JSON format for the new certificate export/import structure when the `SupportMultipleCertificateExport` feature flag is enabled. XML and YAML format support for the new certificate structure is deferred as future work.

Applied to files:

  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/resources/credential-management.yaml
🧬 Code graph analysis (6)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/core/PasskeyCredentialHandler.java (6)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/CredentialManagementConstants.java (1)
  • CredentialManagementConstants (28-150)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/CredentialManagementServiceDataHolder.java (1)
  • CredentialManagementServiceDataHolder (29-81)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/dto/CredentialDTO.java (1)
  • CredentialDTO (24-84)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/dto/CredentialDeletionRequestDTO.java (1)
  • CredentialDeletionRequestDTO (24-84)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/exception/CredentialMgtException.java (1)
  • CredentialMgtException (24-97)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/utils/CredentialManagementUtils.java (1)
  • CredentialManagementUtils (29-70)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/exception/CredentialMgtClientException.java (1)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/CredentialManagementConstants.java (1)
  • CredentialManagementConstants (28-150)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/CredentialManagementService.java (2)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/dto/CredentialDTO.java (1)
  • CredentialDTO (24-84)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/dto/CredentialDeletionRequestDTO.java (1)
  • CredentialDeletionRequestDTO (24-84)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/dto/CredentialDeletionRequestDTO.java (1)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/dto/CredentialDTO.java (1)
  • Builder (55-83)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/java/org/wso2/carbon/identity/api/server/credential/management/v1/impl/CredentialManagementServiceImpl.java (5)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/CredentialManagementConstants.java (1)
  • CredentialManagementConstants (28-150)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/dto/CredentialDTO.java (1)
  • CredentialDTO (24-84)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/dto/CredentialDeletionRequestDTO.java (1)
  • CredentialDeletionRequestDTO (24-84)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/exception/CredentialMgtException.java (1)
  • CredentialMgtException (24-97)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/java/org/wso2/carbon/identity/api/server/credential/management/v1/utils/CredentialMgtEndpointUtils.java (1)
  • CredentialMgtEndpointUtils (43-185)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/CredentialHandler.java (3)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/dto/CredentialDTO.java (1)
  • CredentialDTO (24-84)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/dto/CredentialDeletionRequestDTO.java (1)
  • CredentialDeletionRequestDTO (24-84)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/exception/CredentialMgtException.java (1)
  • CredentialMgtException (24-97)
🪛 Checkov (3.2.334)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/resources/credential-management.yaml

[medium] 49-53: Ensure that arrays have a maximum number of items

(CKV_OPENAPI_21)

🔇 Additional comments (27)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/exception/CredentialMgtServerException.java (1)

1-24: LGTM!

License header, package declaration, and class design are appropriate for a server-side exception in the credential management hierarchy.

components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/java/org/wso2/carbon/identity/api/server/credential/management/v1/constants/CredentialMgtEndpointConstants.java (2)

36-67: LGTM!

The ErrorMessages enum follows a clean pattern for managing error codes with the prefix applied in getCode(). The structure is extensible for adding additional error codes as the module evolves.


30-31: > Likely an incorrect or invalid review comment.

components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/exception/CredentialMgtException.java (1)

36-56: LGTM!

The constructors are well-structured with proper delegation to the parent Exception class and consistent field initialization. The Javadoc accurately reflects the parameter order.

components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/CredentialManagementServiceDataHolder.java (1)

1-33: LGTM!

License header, imports, and class structure with private constructor follow standard patterns for a non-instantiable service holder class.

components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/test/java/org/wso2/carbon/identity/api/server/credential/management/v1/impl/CredentialManagementServiceImplTest.java (6)

66-78: Reflection injection is acceptable but ensure the SUT is a real instance.

The reflection-based handler injection is a valid approach for testing when constructors don't expose dependencies. However, this becomes meaningful only when userCredentialManagementService is a real instance rather than a mock.


83-103: Test logic is correct.

The test properly verifies that credentials from both handlers are aggregated. Once the SUT is changed to a real instance, remove the doCallRealMethod() call on line 92.


108-143: Good coverage of empty and partial result scenarios.

These tests effectively cover edge cases where handlers return empty lists or only one handler has credentials.


183-215: Well-structured data-driven test for credential type handling.

Good coverage of case-insensitive type matching and hyphen/underscore variations.


220-249: Good negative test coverage.

Tests properly validate error handling for invalid credential types and handler exceptions.


263-283: Helper methods are well-structured.

Clean factoring of mock DTO creation improves test readability.

components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/resources/credential-management.yaml (2)

1-14: LGTM!

The API metadata is well-structured with clear description of purpose, required admin scopes (internal_user_mgt_view and internal_user_mgt_delete), and proper licensing information.


16-18: Security schemes are referenced but not defined.

The OAuth2 and BasicAuth security schemes are referenced in the global security section but are not defined in components/securitySchemes. This may cause OpenAPI validation warnings and confusion for API consumers.

Please verify whether these security schemes are injected during build/generation or if they should be explicitly defined:

components:
  securitySchemes:
    OAuth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://localhost:9443/oauth2/authorize
          tokenUrl: https://localhost:9443/oauth2/token
          scopes:
            internal_user_mgt_view: View user details
            internal_user_mgt_delete: Delete user details
    BasicAuth:
      type: http
      scheme: basic
components/org.wso2.carbon.identity.api.server.credential.management/pom.xml (1)

33-36: LGTM!

The multi-module structure follows the project's established pattern for API modules (common + versioned implementation).

pom.xml (6)

842-847: LGTM!

The mockito-testng dependency is properly added with test scope and version managed via property.


893-898: LGTM!

The credential management common dependency is correctly added with provided scope, consistent with other common module dependencies in this POM.


1042-1043: LGTM!

Version properties are properly defined for the new dependencies.


1064-1064: LGTM!

Version property correctly defined for mockito-testng.


1112-1112: LGTM!

The credential management module is correctly added to the modules list.


899-908: Verify fido2 dependency version; 5.4.31 does not appear published.

Regarding the provided scope recommendation: While the suggestion to align with similar backend service dependencies is reasonable, I cannot verify the current scope values in other dependencies without direct repository access.

However, the version claim requires attention: Search results indicate that org.wso2.carbon.identity.application.authenticator.fido2 version 5.4.31 is not published in Maven repositories. Available versions include 5.4.30, 5.4.18, and earlier 5.3.x releases. If the pom.xml declares version 5.4.31, this will fail to resolve. Update to an available version (e.g., 5.4.30) before merging.

Regarding the provided scope: Please verify the scope declarations in similar backend service dependencies (identity.governance, identity.event.handler) to confirm whether adding provided scope is consistent with the project's dependency management strategy.

components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/CredentialHandler.java (1)

30-41: LGTM!

The interface methods are well-defined with appropriate signatures. The contract clearly defines operations for retrieving and deleting credentials with proper exception handling.

components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/java/org/wso2/carbon/identity/api/server/credential/management/v1/impl/CredentialManagementServiceImpl.java (2)

48-67: LGTM!

The getCredentials method correctly aggregates credentials from all registered handlers with proper exception handling and debug logging.


87-92: LGTM!

The logging has been correctly updated to use LOG.debug within the LOG.isDebugEnabled() check.

components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/core/PasskeyCredentialHandler.java (4)

46-58: LGTM!

The class structure is clean with appropriate constructor injection pattern for the WebAuthnService dependency.


60-88: LGTM!

The getCredentials method has proper exception handling that distinguishes between server errors (FIDO2AuthenticatorServerException) and client errors (IdentityRuntimeException for entity not found). Debug logging is correctly implemented.


90-117: LGTM!

The deleteCredential method has comprehensive exception handling covering client errors, server errors, and entity-not-found scenarios. Debug logging is correctly implemented.


125-132: Consider adding null safety for credential field access.

The method chain credential.getCredential().getCredentialId().getBase64Url() could throw NPE if any intermediate value is null. Consider adding null checks or defensive handling if the upstream FIDO2CredentialRegistration contract doesn't guarantee non-null values.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines 26 to 36
/**
* Constructor with {@code message}, {@code errorCode} and {@code description} parameters.
*
* @param message Message to be included in the exception.
* @param errorCode Error code of the exception.
* @param description Description of the exception.
*/
public CredentialMgtServerException(String errorCode, String message, String description, Throwable cause) {

super(message, errorCode, description, cause);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Javadoc is inconsistent with the constructor signature.

The Javadoc has the following issues:

  1. The description omits the cause parameter.
  2. The @param tag order doesn't match the actual parameter order (errorCode, message, description, cause).
  3. Missing @param for cause.
📝 Proposed fix for the Javadoc
     /**
-     * Constructor with {`@code` message}, {`@code` errorCode} and {`@code` description} parameters.
+     * Constructor with {`@code` errorCode}, {`@code` message}, {`@code` description} and {`@code` cause} parameters.
      *
-     * `@param` message     Message to be included in the exception.
      * `@param` errorCode   Error code of the exception.
+     * `@param` message     Message to be included in the exception.
      * `@param` description Description of the exception.
+     * `@param` cause       Throwable cause of the exception.
      */
     public CredentialMgtServerException(String errorCode, String message, String description, Throwable cause) {

         super(message, errorCode, description, cause);
     }
📝 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
/**
* Constructor with {@code message}, {@code errorCode} and {@code description} parameters.
*
* @param message Message to be included in the exception.
* @param errorCode Error code of the exception.
* @param description Description of the exception.
*/
public CredentialMgtServerException(String errorCode, String message, String description, Throwable cause) {
super(message, errorCode, description, cause);
}
/**
* Constructor with {`@code` errorCode}, {`@code` message}, {`@code` description} and {`@code` cause} parameters.
*
* `@param` errorCode Error code of the exception.
* `@param` message Message to be included in the exception.
* `@param` description Description of the exception.
* `@param` cause Throwable cause of the exception.
*/
public CredentialMgtServerException(String errorCode, String message, String description, Throwable cause) {
super(message, errorCode, description, cause);
}
🤖 Prompt for AI Agents
In
`@components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/src/main/java/org/wso2/carbon/identity/api/server/credential/management/common/exception/CredentialMgtServerException.java`
around lines 26 - 36, Update the Javadoc for the
CredentialMgtServerException(String errorCode, String message, String
description, Throwable cause) constructor to match the actual parameter list and
include the missing cause: reorder the `@param` tags to errorCode, message,
description, cause; add a `@param` description for cause (e.g., throwable cause of
the exception); and update the main description to mention that a cause can be
provided. Ensure the comment text and tag order exactly reflect the constructor
signature.

Comment on lines +110 to +136
responses:
'204':
description: User Credential Deleted.
'400':
description: Bad Request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Unauthorized.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Forbidden.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Internal Server Error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add 404 response for credential or user not found.

The DELETE endpoint is missing a 404 response, which is inconsistent with the GET endpoint that includes 404 for "User Not Found". When deleting a non-existent credential or for a non-existent user, the API should return 404.

📝 Suggested addition
        '403':
          description: Forbidden.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
+       '404':
+         description: User or Credential Not Found.
+         content:
+           application/json:
+             schema:
+               $ref: '#/components/schemas/Error'
        '500':
          description: Internal Server Error.
🤖 Prompt for AI Agents
In
`@components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/main/resources/credential-management.yaml`
around lines 110 - 136, The DELETE endpoint responses block in
credential-management.yaml is missing a 404 response for "credential or user not
found"; update the responses for the DELETE operation (the responses block
shown) to include a '404' entry with a description like "Not Found - Credential
or User Not Found" and the same application/json schema ref
('#/components/schemas/Error') used by the other error responses so the API
returns 404 when the credential or user does not exist.

Comment on lines +55 to +64
@Mock
private CredentialHandler passkeyHandler;

@Mock
private CredentialHandler pushAuthHandler;

@Mock
private CredentialManagementServiceImpl userCredentialManagementService;

private static final String TEST_USER_ID = "test-user-123";
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Avoid mocking the class under test.

userCredentialManagementService is the system under test (SUT), but it's declared as a @Mock. This anti-pattern leads to fragile tests that rely on doCallRealMethod() and may not accurately validate real implementation behavior.

Instantiate a real CredentialManagementServiceImpl and inject the mocked handlers directly.

♻️ Suggested refactor
     `@Mock`
     private CredentialHandler passkeyHandler;
 
     `@Mock`
     private CredentialHandler pushAuthHandler;
 
-    `@Mock`
-    private CredentialManagementServiceImpl userCredentialManagementService;
+    private CredentialManagementServiceImpl userCredentialManagementService;
 
     private static final String TEST_USER_ID = "test-user-123";

Then in setUp(), instantiate the real service:

userCredentialManagementService = new CredentialManagementServiceImpl();
// Inject the handlerMap via reflection into the real instance
🤖 Prompt for AI Agents
In
`@components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/src/test/java/org/wso2/carbon/identity/api/server/credential/management/v1/impl/CredentialManagementServiceImplTest.java`
around lines 55 - 64, The test currently mocks the system under test
(userCredentialManagementService) which is wrong; remove the `@Mock` on
CredentialManagementServiceImpl, instantiate a real
CredentialManagementServiceImpl in setUp() and inject the mocked
CredentialHandler instances (passkeyHandler, pushAuthHandler) into its handler
map (e.g., via the existing handlerMap field or reflection), then update tests
to call real methods on userCredentialManagementService and remove
doCallRealMethod() usages so the real implementation is exercised with mocked
dependencies.

@jenkins-is-staging
Copy link

PR builder started
Link: https://github.com/wso2/product-is/actions/runs/21033768213

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@pom.xml`:
- Around line 1042-1043: The pom property identity.notification.push.version is
set to the non-existent 1.0.9 and will break the build; change the property
value to the latest published release 1.0.6 (or point to a repository that
actually hosts 1.0.9) by updating the identity.notification.push.version
property in the POM so it matches an available artifact, then re-run the build
to confirm resolution.
🧹 Nitpick comments (3)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/pom.xml (2)

162-180: Consider updating build-helper-maven-plugin version.

Version 1.8 of build-helper-maven-plugin is quite dated. Consider updating to a more recent version (e.g., 3.4.0 or later) for better compatibility and bug fixes, or align with the version used elsewhere in the project.

🔧 Suggested update
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                 <artifactId>build-helper-maven-plugin</artifactId>
-                <version>1.8</version>
+                <version>3.4.0</version>
                 <executions>

145-145: Inconsistent dateLibrary in commented OpenAPI generator config.

The commented dateLibrary is set to java17, but the project's compiler targets Java 1.8 (line 119-120). If the OpenAPI generator is run, this mismatch could cause compatibility issues. Consider updating to java8 if this generator config is intended to be used.

pom.xml (1)

899-908: Consider adding explicit scope to external dependencies.

The push.device.handler and fido2 dependencies lack explicit scope declarations, defaulting to compile. Most other external dependencies in this POM use provided scope. Verify whether these should also be provided to match the pattern used for similar dependencies (e.g., lines 112-117, 148-159).

🔧 Suggested fix
             <dependency>
                 <groupId>org.wso2.carbon.identity.notification.push</groupId>
                 <artifactId>org.wso2.carbon.identity.notification.push.device.handler</artifactId>
                 <version>${identity.notification.push.version}</version>
+                <scope>provided</scope>
             </dependency>
             <dependency>
                 <groupId>org.wso2.carbon.identity.local.auth.fido</groupId>
                 <artifactId>org.wso2.carbon.identity.application.authenticator.fido2</artifactId>
                 <version>${identity.local.auth.fido.version}</version>
+                <scope>provided</scope>
             </dependency>
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 541396e and 7ec8883.

📒 Files selected for processing (4)
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/pom.xml
  • components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/pom.xml
  • components/org.wso2.carbon.identity.api.server.credential.management/pom.xml
  • pom.xml
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/org.wso2.carbon.identity.api.server.credential.management/pom.xml
🔇 Additional comments (4)
components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.v1/pom.xml (1)

36-111: Dependencies are properly configured.

The dependency declarations follow the project conventions with appropriate scopes. The exclusions on swagger-jaxrs are correctly configured to avoid transitive dependency conflicts. Test dependencies are properly test-scoped.

components/org.wso2.carbon.identity.api.server.credential.management/org.wso2.carbon.identity.api.server.credential.management.common/pom.xml (1)

35-52: LGTM!

The common module POM is well-structured with appropriate dependencies for credential management functionality. Version management is correctly delegated to the parent POM's dependencyManagement section.

pom.xml (2)

842-847: LGTM - Test dependency addition.

The mockito-testng dependency is properly declared with test scope and a dedicated version property.


1112-1112: LGTM - Module registration.

The new credential management module is correctly registered in the modules section.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +1042 to +1043
<identity.local.auth.fido.version>5.4.31</identity.local.auth.fido.version>
<identity.notification.push.version>1.0.9</identity.notification.push.version>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

org.wso2.carbon.identity.application.authenticator.fido2 5.4.31 Maven Central

💡 Result:

Yes — version 5.4.31 is available on Maven Central.

Maven coordinates:

  • groupId: org.wso2.carbon.identity.local.auth.fido
  • artifactId: org.wso2.carbon.identity.application.authenticator.fido2
  • version: 5.4.31. [1]

[1] Maven Central package page (org.wso2.carbon.identity.application.authenticator.fido2, v5.4.31).


🌐 Web query:

org.wso2.carbon.identity.notification.push 1.0.9 WSO2 repository

💡 Result:

I couldn't find org.wso2.carbon.identity.notification.push version 1.0.9 in the WSO2 public/release repositories. The latest published release I can find is 1.0.6 (published Feb 20, 2025) — see the WSO2/Maven listings. [1][2]

Sources:

  • mvnrepository listings for the group (shows available artifacts/versions). [1]
  • specific artifact release (example: push feature 1.0.6). [2]

🌐 Web query:

WSO2 Maven repository FIDO2 authenticator 5.4.31 release

💡 Result:

Do you want the Maven coordinates (groupId/artifactId/version) and repository URL for the WSO2 FIDO2 Authenticator 5.4.31 artifact, or do you want me to check whether version 5.4.31 exists and provide download links?


Update identity.notification.push.version to an available release.

The FIDO2 authenticator version 5.4.31 is confirmed available on Maven Central. However, identity.notification.push.version is set to 1.0.9, which does not exist in WSO2 repositories—the latest published release is 1.0.6. This will cause a build failure. Update to version 1.0.6 or verify if 1.0.9 is available in a different repository.

🤖 Prompt for AI Agents
In `@pom.xml` around lines 1042 - 1043, The pom property
identity.notification.push.version is set to the non-existent 1.0.9 and will
break the build; change the property value to the latest published release 1.0.6
(or point to a repository that actually hosts 1.0.9) by updating the
identity.notification.push.version property in the POM so it matches an
available artifact, then re-run the build to confirm resolution.

@jenkins-is-staging
Copy link

PR builder completed
Link: https://github.com/wso2/product-is/actions/runs/21033768213
Status: success

Copy link

@jenkins-is-staging jenkins-is-staging left a comment

Choose a reason for hiding this comment

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

Approving the pull request based on the successful pr build https://github.com/wso2/product-is/actions/runs/21033768213

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@pom.xml`:
- Around line 941-948: The Maven pom's compilerArgs section currently injects
JVM --add-opens flags (the <compilerArgs> block and its <arg> entries) which are
only valid on JDK 9+, so remove those unguarded --add-opens lines or relocate
them into a JDK9+ specific Maven profile; alternatively adjust the build matrix
to drop OpenJDK8. Update the <compilerArgs> block by either deleting the
<arg>-J--add-opens=...</arg> entries or wrap them in a profile activated for JDK
9+ (e.g., a profile keyed to a property or toolchain) so that functions/builds
that run on openjdk8 won't receive these flags.
♻️ Duplicate comments (1)
pom.xml (1)

1050-1051: Ensure identity.notification.push.version points to a published artifact.

Please verify that 1.0.9 is actually available in your repositories; otherwise the build will fail. If it’s not published, update to a known released version or add the correct repo.

🔧 Possible adjustment (if 1.0.9 isn’t published)
-        <identity.notification.push.version>1.0.9</identity.notification.push.version>
+        <identity.notification.push.version>1.0.6</identity.notification.push.version>

@NipuniBhagya NipuniBhagya merged commit 1622d96 into wso2:master Jan 20, 2026
5 checks passed
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.

3 participants