Skip to content

Improve error message for invalid client in org context#3169

Open
ThaminduR wants to merge 1 commit intowso2-extensions:masterfrom
ThaminduR:fix/patch-oauth
Open

Improve error message for invalid client in org context#3169
ThaminduR wants to merge 1 commit intowso2-extensions:masterfrom
ThaminduR:fix/patch-oauth

Conversation

@ThaminduR
Copy link
Copy Markdown
Contributor

@ThaminduR ThaminduR commented Apr 5, 2026

Summary

  • Returns a more descriptive error message ("Application is not available in the organization.") when an OAuth client is not found in an organization context, instead of the generic "Invalid Client" message.
  • Adds unit test to verify the org-context-specific error message behavior.

Fixes wso2/product-is#27163

Test plan

  • Unit test added for org context error message
  • Verify with a multi-org setup that the improved error message is returned when accessing an app not shared to the organization

🤖 Generated with Claude Code

Return a more descriptive error message when an OAuth client is not
found in an organization context, instead of the generic "Invalid Client"
message.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment on lines 463 to +464
tokenRespDTO.setErrorCode(OAuth2ErrorCodes.INVALID_CLIENT);
tokenRespDTO.setErrorMsg("Invalid Client");
String errorMessage = "Invalid Client";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Log Improvement Suggestion No: 1

Suggested change
tokenRespDTO.setErrorCode(OAuth2ErrorCodes.INVALID_CLIENT);
tokenRespDTO.setErrorMsg("Invalid Client");
String errorMessage = "Invalid Client";
tokenRespDTO.setErrorCode(OAuth2ErrorCodes.INVALID_CLIENT);
log.error("Invalid client detected. Error code: {}", OAuth2ErrorCodes.INVALID_CLIENT);
String errorMessage = "Invalid Client";

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 5, 2026

📝 Walkthrough

Walkthrough

The OAuth2 error handling in the issueAccessToken method now dynamically determines error messages based on organization context. When an organization ID is present in the thread-local context, the error message is customized to indicate application unavailability within that organization instead of using a generic "Invalid Client" message.

Changes

Cohort / File(s) Summary
OAuth2 Error Message Customization
components/org.wso2.carbon.identity.oauth/src/main/java/.../OAuth2Service.java, components/org.wso2.carbon.identity.oauth/src/test/java/.../OAuth2ServiceTest.java
Modified exception handling to provide organization-aware error messages when accessing the application resident organization ID from the privileged context. Added corresponding unit test to verify error messaging behavior when organization context is present.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 In org-land where apps reside,
Our errors now show local pride,
No generic "Invalid" here to stay—
Context-aware messages light the way!
A hop, a test, a message refined,
Organization clarity by design! 🌱

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The PR description is incomplete relative to the repository's template. It lacks most required sections including Goals, Approach, User stories, Release note, Documentation, Training, Certification, Marketing, Automation tests details, Security checks, and other required fields. Complete the PR description by filling in all required template sections. At minimum, add Goals, User stories, Release note, Documentation impact, Security checks confirmation, and Automation tests coverage details.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: improving the error message for invalid OAuth clients in an organization context.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment on lines +467 to +468
if (StringUtils.isNotEmpty(appOrgId)) {
errorMessage = "Application is not available in the organization.";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Log Improvement Suggestion No: 2

Suggested change
if (StringUtils.isNotEmpty(appOrgId)) {
errorMessage = "Application is not available in the organization.";
if (StringUtils.isNotEmpty(appOrgId)) {
log.warn("Application not available in organization. OrgId: {}", appOrgId);
errorMessage = "Application is not available in the organization.";

Copy link
Copy Markdown
Contributor

@wso2-engineering wso2-engineering bot left a comment

Choose a reason for hiding this comment

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

AI Agent Log Improvement Checklist

⚠️ Warning: AI-Generated Review Comments

  • 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.
Comment Accepted (Y/N) Reason
#### Log Improvement Suggestion No: 1
#### Log Improvement Suggestion No: 2

Copy link
Copy Markdown

@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.

🧹 Nitpick comments (1)
components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/OAuth2ServiceTest.java (1)

602-625: Add a companion non-org regression test for the default message.

This test covers the org path well, but adding the no-org path assertion will lock in the "Invalid Client" fallback and prevent regressions.

Proposed test addition
+    `@Test`
+    public void testIssueAccessTokenWithoutOrgContextReturnsDefaultInvalidClientMessage() throws IdentityException {
+
+        try (MockedStatic<IdentityTenantUtil> identityTenantUtil = mockStatic(IdentityTenantUtil.class);
+             MockedStatic<AccessTokenIssuer> accessTokenIssuer = mockStatic(AccessTokenIssuer.class)) {
+            identityTenantUtil.when(() -> IdentityTenantUtil.getTenantId(anyString())).thenReturn(-1234);
+            identityTenantUtil.when(() -> IdentityTenantUtil.getTenantDomain(-1234)).thenReturn("carbon.super");
+            AccessTokenIssuer mockAccessTokenIssuer = mock(AccessTokenIssuer.class);
+            accessTokenIssuer.when(AccessTokenIssuer::getInstance).thenReturn(mockAccessTokenIssuer);
+            when(mockAccessTokenIssuer.issue(any(OAuth2AccessTokenReqDTO.class)))
+                    .thenThrow(new InvalidOAuthClientException("application.not.found"));
+
+            PrivilegedCarbonContext.getThreadLocalCarbonContext().setApplicationResidentOrganizationId(null);
+            OAuth2AccessTokenRespDTO respDTO = oAuth2Service.issueAccessToken(new OAuth2AccessTokenReqDTO());
+            assertEquals(respDTO.getErrorCode(), OAuth2ErrorCodes.INVALID_CLIENT);
+            assertEquals(respDTO.getErrorMsg(), "Invalid Client");
+        }
+    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/OAuth2ServiceTest.java`
around lines 602 - 625, Add a companion regression test to verify the
non-org/default message path: create a new test (e.g.,
testIssueAccessTokenWithoutOrgReturnsDefaultError) that mocks IdentityTenantUtil
and AccessTokenIssuer the same way as
testIssueAccessTokenWithOrgContextReturnsOrgSpecificError, have
mockAccessTokenIssuer.issue(...) throw new
InvalidOAuthClientException("application.not.found"), ensure
PrivilegedCarbonContext.getThreadLocalCarbonContext().setApplicationResidentOrganizationId(null)
(or leave unset), call oAuth2Service.issueAccessToken(new
OAuth2AccessTokenReqDTO()), and assert the returned OAuth2AccessTokenRespDTO has
errorCode OAuth2ErrorCodes.INVALID_CLIENT and the default errorMsg ("Invalid
Client" or the current non-org message used in production) to lock in the
fallback behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/OAuth2ServiceTest.java`:
- Around line 602-625: Add a companion regression test to verify the
non-org/default message path: create a new test (e.g.,
testIssueAccessTokenWithoutOrgReturnsDefaultError) that mocks IdentityTenantUtil
and AccessTokenIssuer the same way as
testIssueAccessTokenWithOrgContextReturnsOrgSpecificError, have
mockAccessTokenIssuer.issue(...) throw new
InvalidOAuthClientException("application.not.found"), ensure
PrivilegedCarbonContext.getThreadLocalCarbonContext().setApplicationResidentOrganizationId(null)
(or leave unset), call oAuth2Service.issueAccessToken(new
OAuth2AccessTokenReqDTO()), and assert the returned OAuth2AccessTokenRespDTO has
errorCode OAuth2ErrorCodes.INVALID_CLIENT and the default errorMsg ("Invalid
Client" or the current non-org message used in production) to lock in the
fallback behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 685f68e3-fe0b-4f74-b2d6-31bb36718258

📥 Commits

Reviewing files that changed from the base of the PR and between 44e381e and e897f26.

📒 Files selected for processing (2)
  • components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/OAuth2Service.java
  • components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/OAuth2ServiceTest.java

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 56.93%. Comparing base (f3e9621) to head (e897f26).
⚠️ Report is 16 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #3169      +/-   ##
============================================
- Coverage     57.03%   56.93%   -0.11%     
- Complexity    10851    10904      +53     
============================================
  Files           709      710       +1     
  Lines         61497    61937     +440     
  Branches      15042    15171     +129     
============================================
+ Hits          35075    35261     +186     
- Misses        21731    21962     +231     
- Partials       4691     4714      +23     
Flag Coverage Δ
unit 42.71% <100.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

Improve "error_description" of token response of directly obtaining M2M token for a sub org when the app is not shared to that sub org

1 participant