Skip to content

Add versioning support for pre-issue access token action and extend grant types#3000

Draft
Lashen1227 wants to merge 20 commits intowso2-extensions:masterfrom
Lashen1227:feat/pre-issue-access-token-action-token-exchange
Draft

Add versioning support for pre-issue access token action and extend grant types#3000
Lashen1227 wants to merge 20 commits intowso2-extensions:masterfrom
Lashen1227:feat/pre-issue-access-token-action-token-exchange

Conversation

@Lashen1227
Copy link
Copy Markdown
Member

@Lashen1227 Lashen1227 commented Dec 17, 2025

This pull request introduces a versioning mechanism for the "Pre Issue Access Token" action in the OAuth component, enabling support for multiple action versions and their corresponding execution logic. It adds new factories and handlers to determine the correct version-specific behavior.

Key changes include:

Versioning infrastructure for Pre Issue Access Token actions:

  • Added PreIssueAccessTokenActionConstants to define supported action versions (v1, v2).
  • Introduced PreIssueAccessTokenActionVersioningHandler, which determines if the pre-issue access token action can be executed based on version-specific logic.
  • Implemented ActionTriggerEvaluatorFactory and ActionTriggerEvaluatorForVersion to provide version-specific evaluators for action triggering, supporting both V1 and V2 behaviors.
  • Added PreIssueAccessTokenRequestBuilderFactory to instantiate the correct request builder based on action version.
  • New supported grant types - token_exchange, device_code, organization_switch, jwt_bearer & saml2_bearer.
  • Fixed inconsistencies identified in the existing action V1 by addressing them in the V2 ([Bug] Bugs/inconsistencies in Existing Pre Issue Access Token Action. wso2/product-is#26540).

Related PRs:

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
#### Log Improvement Suggestion No: 6
#### Log Improvement Suggestion No: 7
#### Log Improvement Suggestion No: 8
#### Log Improvement Suggestion No: 9
#### Log Improvement Suggestion No: 10
#### Log Improvement Suggestion No: 11
#### Log Improvement Suggestion No: 12
#### Log Improvement Suggestion No: 13
#### Log Improvement Suggestion No: 14
#### Log Improvement Suggestion No: 15
#### Log Improvement Suggestion No: 16
#### Log Improvement Suggestion No: 17
#### Log Improvement Suggestion No: 18

OAuthTokenReqMessageContext tokenMessageContext =
flowContext.getValue("tokenMessageContext", OAuthTokenReqMessageContext.class);
if (OAuthConstants.GrantTypes.TOKEN_EXCHANGE.equals(
tokenMessageContext.getOauth2AccessTokenReqDTO().getGrantType())) {
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.

Handle possible NPE cases


OAuthTokenReqMessageContext tokenMessageContext =
flowContext.getValue("tokenMessageContext", OAuthTokenReqMessageContext.class);
if (OAuthConstants.GrantTypes.TOKEN_EXCHANGE.equals(
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.

Can you explain how does this logic allows token exchange grant type in action version 2.0 ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

In v1 the evaluator checks the grant type and returns false for TOKEN_EXCHANGE, so the action is not triggered for token exchange. And in v2 this check is removed and isTriggerableForTokenExchangeGrant() always returns true, so the action is allowed for all grant types including token exchange

@ImalshaD ImalshaD requested a review from Copilot December 18, 2025 08:14
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request introduces a versioning mechanism for the "Pre Issue Access Token" action in the OAuth component, enabling support for multiple action versions (v1 and v2) and extending token exchange grant type support. The changes establish a factory pattern for version-specific request builders and evaluators, refactor the existing request builder to delegate to versioned implementations, and update grant type checking logic.

Key changes:

  • Introduced versioning infrastructure with V1 and V2 action implementations supporting different grant type behaviors
  • Extended pre-issue access token action support to include token exchange grant type
  • Refactored request builder to use factory pattern for version-specific delegation

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
ActionVersioningHandlerFactory.java New factory class to obtain action versioning handlers by action type and version
AbstractAuthorizationGrantHandler.java Added token exchange grant type to supported grant types and conditional audience setting
OAuthServiceComponent.java Registered new PreIssueAccessTokenActionVersioningHandler as OSGi service
PreIssueAccessTokenRequestBuilderV2.java New V2 request builder with enhanced audience handling for token exchange grant
ActionTriggerEvaluatorForVersionV2.java V2 evaluator that allows token exchange grant triggering
PreIssueAccessTokenRequestBuilderV1.java V1 request builder maintaining backward-compatible behavior
PreIssueAccessTokenRequestBuilderFactory.java Factory to instantiate correct request builder based on action version
ActionTriggerEvaluatorForVersion.java Base evaluator class blocking token exchange grant by default (V1 behavior)
ActionTriggerEvaluatorFactory.java Factory to obtain version-specific trigger evaluators
PreIssueAccessTokenRequestBuilder.java Refactored to delegate to versioned request builders via factory
PreIssueAccessTokenActionVersioningHandler.java Version handler for pre-issue access token action using trigger evaluators
PreIssueAccessTokenActionConstants.java Constants defining action version identifiers (v1, v2)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

public ActionVersioningHandler getVersionTriggerEvaluator(ActionType actionType, String actionVersion) {

// Delegate to the main OAuth ActionVersioningHandlerFactory to get the correct version handler.
return ActionVersioningHandlerFactory.getInstance().getVersionTriggerEvaluator(actionType, actionVersion);
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

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

This line creates infinite recursion: the factory calls its own getInstance() method and then calls a method that doesn't exist in this class. The intention appears to be delegating to a different factory class (possibly from the action.versioning package), but this will cause a stack overflow or compilation error.

Suggested change
return ActionVersioningHandlerFactory.getInstance().getVersionTriggerEvaluator(actionType, actionVersion);
return org.wso2.carbon.identity.action.versioning.ActionVersioningHandlerFactory
.getInstance().getVersionTriggerEvaluator(actionType, actionVersion);

Copilot uses AI. Check for mistakes.
boolean isAuthorizedForUser = isAccessTokenAuthorizedForUser(tokenReqDTO.getGrantType(), tokenMessageContext);
if (isAuthorizedForUser) {
setUserForEventBuilder(eventBuilder, authorizedUser, tokenReqDTO.getClientId(), tokenReqDTO.getGrantType());
eventBuilder.userStore(new UserStore(authorizedUser.getUserStoreDomain()));
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

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

Setting user store without checking if authorizedUser or authorizedUser.getUserStoreDomain() is null. In V2 (line 129-131 of PreIssueAccessTokenRequestBuilderV2), there's a null check for the user store domain. V1 should have the same null safety check to prevent potential NullPointerException.

Suggested change
eventBuilder.userStore(new UserStore(authorizedUser.getUserStoreDomain()));
if (authorizedUser != null && StringUtils.isNotBlank(authorizedUser.getUserStoreDomain())) {
eventBuilder.userStore(new UserStore(authorizedUser.getUserStoreDomain()));
}

Copilot uses AI. Check for mistakes.
Comment on lines +309 to +313
if (tokenMessageContext.isPreIssueAccessTokenActionsExecuted()) {
return tokenMessageContext.getAudiences();
} else {
return OAuth2Util.getOIDCAudience(oAuthAppDO.getOauthConsumerKey(), oAuthAppDO);
}
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

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

V1 uses isPreIssueAccessTokenActionsExecuted() to determine audience source, while V2 (lines 312-317 of PreIssueAccessTokenRequestBuilderV2) uses CollectionUtils.isNotEmpty() to prioritize context audiences. This inconsistency creates different behaviors between versions. Consider documenting why these versions have different audience resolution strategies, or ensure both use the same logic if the behavior should be consistent.

Copilot uses AI. Check for mistakes.
@codecov
Copy link
Copy Markdown

codecov bot commented Jan 14, 2026

Codecov Report

❌ Patch coverage is 51.70068% with 284 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.66%. Comparing base (f4e024f) to head (a743cfa).
⚠️ Report is 235 commits behind head on master.

Files with missing lines Patch % Lines
...ioning/v2/PreIssueAccessTokenRequestBuilderV2.java 67.95% 56 Missing and 27 partials ⚠️
...xecution/PreIssueAccessTokenResponseProcessor.java 0.00% 75 Missing ⚠️
...ioning/v1/PreIssueAccessTokenRequestBuilderV1.java 61.34% 61 Missing and 14 partials ⚠️
...n/versioning/ActionTriggerEvaluatorForVersion.java 0.00% 13 Missing ⚠️
...on/PreIssueAccessTokenActionVersioningHandler.java 0.00% 9 Missing ⚠️
...tion/versioning/ActionTriggerEvaluatorFactory.java 0.00% 7 Missing ⚠️
...dlers/grant/AbstractAuthorizationGrantHandler.java 14.28% 5 Missing and 1 partial ⚠️
...identity/oauth/internal/OAuthServiceComponent.java 0.00% 5 Missing ⚠️
...sioning/v2/ActionTriggerEvaluatorForVersionV2.java 0.00% 4 Missing ⚠️
...handlers/grant/ActionVersioningHandlerFactory.java 0.00% 4 Missing ⚠️
... and 1 more
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #3000      +/-   ##
============================================
- Coverage     58.77%   58.66%   -0.11%     
+ Complexity     9933     9892      -41     
============================================
  Files           701      709       +8     
  Lines         54577    54924     +347     
  Branches      12697    12735      +38     
============================================
+ Hits          32078    32223     +145     
- Misses        18256    18430     +174     
- Partials       4243     4271      +28     
Flag Coverage Δ
unit 42.52% <51.70%> (+0.07%) ⬆️

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.

@Lashen1227 Lashen1227 changed the title Enhance pre-issue access token action to token exchange grant type Enhance pre-issue access token action to token exchange grant type & pre-issue access token action versioning Jan 23, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 12, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@Lashen1227 Lashen1227 changed the title Enhance pre-issue access token action to token exchange grant type & pre-issue access token action versioning Add versioning support for pre-issue access token action and extend grant types Feb 16, 2026
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