Skip to content

Clear OAuth cache using persisted token scopes on revoke#3193

Open
KD23243 wants to merge 1 commit intowso2-extensions:masterfrom
KD23243:clearCachePersistedScopes
Open

Clear OAuth cache using persisted token scopes on revoke#3193
KD23243 wants to merge 1 commit intowso2-extensions:masterfrom
KD23243:clearCachePersistedScopes

Conversation

@KD23243
Copy link
Copy Markdown
Contributor

@KD23243 KD23243 commented Apr 10, 2026

Purpose

During token revocation, the in-memory accessTokenDO may have had its scopes mutated or filtered earlier in the request lifecycle. The existing cache-clearing path uses those (potentially mutated) scopes as part of the cache key, so entries originally cached under the persisted scopes can be left behind.

Related Issue

N/A

Implementation

  • Added OAuthUtil.clearOAuthCacheUsingPersistedScopes(...) which:
    • Returns early if OAuthServerConfiguration#getAllowedScopes is empty or the access token is blank.
    • Fetches the access token from OAuthTokenPersistenceFactory.getAccessTokenDAO().getAccessToken(token, true) to obtain the original persisted scopes.
    • Builds the scope string from the persisted scopes and calls clearOAuthCache for both the (consumerKey, authzUser, scope, tokenBindingReference) and (consumerKey, authzUser, scope) key variants.
    • Catches IdentityOAuth2Exception from the DAO and logs it without propagating.
  • Wired the new helper into OAuth2Service#revokeTokenByOAuthClient, called right after the existing clearOAuthCache invocations.
  • Added unit tests in OAuthUtilTest covering:
    • Empty allowedScopes short-circuit.
    • Blank access token short-circuit.
    • DB token lookup returning null.
    • DB token returning null scope array.
    • DB token returning empty scope array.
    • Happy path: cache cleared with persisted scopes for both key variants.
    • DAO throwing IdentityOAuth2Exception is swallowed and no cache clear is invoked.

Summary by CodeRabbit

  • New Features

    • Enhanced OAuth token revocation with improved cache clearing mechanism to ensure complete invalidation of revoked tokens.
  • Tests

    • Added comprehensive unit tests covering token revocation cache clearing scenarios, including edge cases and exception handling.

Adds a helper that fetches the original scopes from the access token DAO and clears the OAuth cache using those scope keys, so cache entries are removed even when the in-memory accessTokenDO scopes have been mutated during request processing. Wired into OAuth2Service.revokeTokenByOAuthClient and covered with unit tests for empty allowed-scopes, blank token, null/empty DB scopes, success path, and DAO failure path.
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 10, 2026

📝 Walkthrough

Walkthrough

The changes introduce a new utility method clearOAuthCacheUsingPersistedScopes in OAuthUtil to clear OAuth cache entries using scopes fetched from persisted access-token data. This method is invoked during token revocation in OAuth2Service and is covered by comprehensive unit tests with edge case coverage.

Changes

Cohort / File(s) Summary
Cache Clearing Enhancement
components/org.wso2.carbon.identity.oauth/src/main/java/.../OAuthUtil.java, components/org.wso2.carbon.identity.oauth/src/main/java/.../OAuth2Service.java
Added new public method clearOAuthCacheUsingPersistedScopes that retrieves persisted access-token data, converts scopes to string format, and clears both token-binding-aware and standard cache keys. Integrated into revokeTokenByOAuthClient during access-token revocation pipeline with exception handling for IdentityOAuth2Exception.
Test Coverage
components/org.wso2.carbon.identity.oauth/src/test/java/.../OAuthUtilTest.java
Comprehensive unit tests for the new method covering: empty configured scopes, blank/null access tokens, missing persisted token data, null/empty persisted scopes, positive path with valid scopes, and exception handling scenarios. Tests verify correct DAO calls and cache-clearing invocations with appropriate consumer keys.

Sequence Diagram

sequenceDiagram
    participant Client as Token Revocation<br/>Request Handler
    participant OAuthUtil as OAuthUtil
    participant TokenDAO as AccessTokenDAO
    participant Cache as OAuth Cache

    Client->>OAuthUtil: clearOAuthCacheUsingPersistedScopes(tokenBindingRef,<br/>accessTokenDO, revokeRequest)
    OAuthUtil->>OAuthUtil: Validate conditions<br/>(scopes, token, data)
    OAuthUtil->>TokenDAO: getAccessToken(tokenString,<br/>fromPersistence=true)
    TokenDAO-->>OAuthUtil: Returns persisted<br/>AccessTokenDO
    OAuthUtil->>OAuthUtil: Convert persisted scopes<br/>to string format
    OAuthUtil->>Cache: clearOAuthCache(consumerKey,<br/>scope)
    Cache-->>OAuthUtil: Cache cleared
    OAuthUtil->>Cache: clearOAuthCache(consumerKey,<br/>scope, tokenBindingRef)
    Cache-->>OAuthUtil: Cache cleared
    OAuthUtil-->>Client: Method completes
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested reviewers

  • piraveena
  • ashanthamara
  • ZiyamSanthosh

Poem

🐰 Hoppy caching, scopes persist,
Token bindings gently kissed,
Revocation flows so clean,
OAuth cache now serene! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

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.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: clearing OAuth cache using persisted token scopes during token revocation.
Description check ✅ Passed The description covers the main purpose, implementation details, and test coverage, addressing the key sections of the template.

✏️ 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.

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
#### Log Improvement Suggestion No: 3
#### Log Improvement Suggestion No: 4
#### Log Improvement Suggestion No: 5

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/OAuthUtilTest.java`:
- Around line 823-835: The test creates mockFactory and mockAccessTokenDAO but
never wires mockFactory.getAccessTokenDAO() to return mockAccessTokenDAO, so the
verify(mockAccessTokenDAO, never()) assertions are disconnected; update the test
to stub OAuthTokenPersistenceFactory.getInstance() to return mockFactory and
then stub mockFactory.getAccessTokenDAO() to return mockAccessTokenDAO (for the
same test blocks that call OAuthUtil.clearOAuthCacheUsingPersistedScopes),
ensuring verify(mockAccessTokenDAO, never()).getAccessToken(...) checks the
actual DAO returned in the call path.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: a6bc28ed-6581-405d-9620-5c4b7e259714

📥 Commits

Reviewing files that changed from the base of the PR and between 3ecff83 and 13abdd4.

📒 Files selected for processing (3)
  • components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthUtil.java
  • 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/oauth/OAuthUtilTest.java

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 10, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 59.67%. Comparing base (3ecff83) to head (13abdd4).

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #3193      +/-   ##
============================================
+ Coverage     59.18%   59.67%   +0.49%     
+ Complexity    10337    10253      -84     
============================================
  Files           711      711              
  Lines         56756    55930     -826     
  Branches      13685    13460     -225     
============================================
- Hits          33593    33379     -214     
+ Misses        18674    18163     -511     
+ Partials       4489     4388     -101     
Flag Coverage Δ
unit 42.79% <100.00%> (+0.02%) ⬆️

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.

@jenkins-is-staging
Copy link
Copy Markdown

@jenkins-is-staging
Copy link
Copy Markdown

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

Copy link
Copy Markdown

@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/24225608320

// mismatches, retrieve the original scopes from the database before clearing
// the OAuth cache.
AccessTokenDO dbTokenDO = OAuthTokenPersistenceFactory.getInstance()
.getAccessTokenDAO()
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.

use token provider if exists

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