diff --git a/components/org.wso2.carbon.identity.oauth/pom.xml b/components/org.wso2.carbon.identity.oauth/pom.xml
index 26158431a6..cbbad0e5c8 100644
--- a/components/org.wso2.carbon.identity.oauth/pom.xml
+++ b/components/org.wso2.carbon.identity.oauth/pom.xml
@@ -111,6 +111,10 @@
org.wso2.carbon.identity.framework
org.wso2.carbon.identity.action.execution
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.rule.evaluation
+
org.wso2.carbon.identity.framework
org.wso2.carbon.identity.event
@@ -431,6 +435,10 @@
org.wso2.carbon.identity.application.common.*;version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.application.authentication.framework.*;version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.user.store.configuration.*;version="${carbon.identity.framework.imp.pkg.version.range}",
+ org.wso2.carbon.identity.rule.evaluation.model; version="${carbon.identity.framework.imp.pkg.version.range}",
+ org.wso2.carbon.identity.rule.evaluation.exception; version="${carbon.identity.framework.imp.pkg.version.range}",
+ org.wso2.carbon.identity.rule.evaluation.provider; version="${carbon.identity.framework.imp.pkg.version.range}",
+
org.wso2.carbon.identity.oauth.common.token.bindings.*;version="${identity.inbound.auth.oauth.imp.pkg.version.range}",
org.wso2.carbon.identity.oauth.common.*;version="${identity.inbound.auth.oauth.imp.pkg.version.range}",
org.wso2.carbon.identity.saml.common.util.*; version="${saml.common.util.version.range}",
diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/PreIssueAccessTokenRequestBuilder.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/execution/PreIssueAccessTokenRequestBuilder.java
similarity index 99%
rename from components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/PreIssueAccessTokenRequestBuilder.java
rename to components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/execution/PreIssueAccessTokenRequestBuilder.java
index 9f88024419..0cc016f424 100755
--- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/PreIssueAccessTokenRequestBuilder.java
+++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/execution/PreIssueAccessTokenRequestBuilder.java
@@ -16,7 +16,7 @@
* under the License.
*/
-package org.wso2.carbon.identity.oauth.action;
+package org.wso2.carbon.identity.oauth.action.execution;
import com.nimbusds.jwt.JWTClaimsSet;
import org.apache.commons.logging.Log;
diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/PreIssueAccessTokenResponseProcessor.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/execution/PreIssueAccessTokenResponseProcessor.java
similarity index 99%
rename from components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/PreIssueAccessTokenResponseProcessor.java
rename to components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/execution/PreIssueAccessTokenResponseProcessor.java
index b4bd8d1b67..1657577e7c 100644
--- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/PreIssueAccessTokenResponseProcessor.java
+++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/execution/PreIssueAccessTokenResponseProcessor.java
@@ -16,7 +16,7 @@
* under the License.
*/
-package org.wso2.carbon.identity.oauth.action;
+package org.wso2.carbon.identity.oauth.action.execution;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/rule/PreIssueAccessTokenRuleEvaluationDataProvider.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/rule/PreIssueAccessTokenRuleEvaluationDataProvider.java
new file mode 100644
index 0000000000..e7d23374a5
--- /dev/null
+++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/action/rule/PreIssueAccessTokenRuleEvaluationDataProvider.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
+ *
+ * WSO2 LLC. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.identity.oauth.action.rule;
+
+import org.wso2.carbon.identity.application.common.model.ServiceProvider;
+import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
+import org.wso2.carbon.identity.oauth2.dto.OAuth2AccessTokenReqDTO;
+import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;
+import org.wso2.carbon.identity.oauth2.util.OAuth2Util;
+import org.wso2.carbon.identity.rule.evaluation.exception.RuleEvaluationDataProviderException;
+import org.wso2.carbon.identity.rule.evaluation.model.Field;
+import org.wso2.carbon.identity.rule.evaluation.model.FieldValue;
+import org.wso2.carbon.identity.rule.evaluation.model.FlowContext;
+import org.wso2.carbon.identity.rule.evaluation.model.FlowType;
+import org.wso2.carbon.identity.rule.evaluation.model.RuleEvaluationContext;
+import org.wso2.carbon.identity.rule.evaluation.model.ValueType;
+import org.wso2.carbon.identity.rule.evaluation.provider.RuleEvaluationDataProvider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Rule evaluation data provider for pre issue access token flow.
+ * This class provides the data required for rule evaluation in pre issue access token flow.
+ */
+public class PreIssueAccessTokenRuleEvaluationDataProvider implements RuleEvaluationDataProvider {
+
+ private enum RuleField {
+ APPLICATION("application"),
+ GRANT_TYPE("grantType");
+
+ final String fieldName;
+
+ RuleField(String fieldName) {
+
+ this.fieldName = fieldName;
+ }
+
+ public String getFieldName() {
+
+ return fieldName;
+ }
+
+ public static RuleField valueOfFieldName(String fieldName) throws RuleEvaluationDataProviderException {
+
+ for (RuleField ruleField : RuleField.values()) {
+ if (ruleField.getFieldName().equals(fieldName)) {
+ return ruleField;
+ }
+ }
+
+ throw new RuleEvaluationDataProviderException("Unsupported field: " + fieldName);
+ }
+ }
+
+ @Override
+ public FlowType getSupportedFlowType() {
+
+ return FlowType.PRE_ISSUE_ACCESS_TOKEN;
+ }
+
+ @Override
+ public List getEvaluationData(RuleEvaluationContext ruleEvaluationContext,
+ FlowContext flowContext, String tenantDomain)
+ throws RuleEvaluationDataProviderException {
+
+ OAuthTokenReqMessageContext tokenMessageContext =
+ (OAuthTokenReqMessageContext) flowContext.getContextData().get("tokenMessageContext");
+
+ OAuth2AccessTokenReqDTO tokenReqDTO = tokenMessageContext.getOauth2AccessTokenReqDTO();
+ List fieldValueList = new ArrayList<>();
+
+ for (Field field : ruleEvaluationContext.getFields()) {
+ switch (RuleField.valueOfFieldName(field.getName())) {
+ case APPLICATION:
+ addApplicationFieldValue(fieldValueList, field, tokenReqDTO);
+ break;
+ case GRANT_TYPE:
+ fieldValueList.add(new FieldValue(field.getName(), tokenReqDTO.getGrantType(), ValueType.STRING));
+ break;
+ default:
+ throw new RuleEvaluationDataProviderException("Unsupported field: " + field.getName());
+ }
+ }
+
+ return fieldValueList;
+ }
+
+ private void addApplicationFieldValue(List fieldValueList, Field field,
+ OAuth2AccessTokenReqDTO tokenReqDTO)
+ throws RuleEvaluationDataProviderException {
+
+ try {
+ ServiceProvider application =
+ OAuth2Util.getServiceProvider(tokenReqDTO.getClientId(), tokenReqDTO.getTenantDomain());
+ if (application != null) {
+ fieldValueList.add(
+ new FieldValue(field.getName(), application.getApplicationResourceId(), ValueType.REFERENCE));
+ }
+ } catch (IdentityOAuth2Exception e) {
+ throw new RuleEvaluationDataProviderException("Error retrieving service provider", e);
+ }
+ }
+}
diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthServiceComponent.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthServiceComponent.java
index 3d24ba3dc9..c56215ab76 100644
--- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthServiceComponent.java
+++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/internal/OAuthServiceComponent.java
@@ -39,8 +39,9 @@
import org.wso2.carbon.identity.event.handler.AbstractEventHandler;
import org.wso2.carbon.identity.oauth.OAuthAdminServiceImpl;
import org.wso2.carbon.identity.oauth.OauthInboundAuthConfigHandler;
-import org.wso2.carbon.identity.oauth.action.PreIssueAccessTokenRequestBuilder;
-import org.wso2.carbon.identity.oauth.action.PreIssueAccessTokenResponseProcessor;
+import org.wso2.carbon.identity.oauth.action.execution.PreIssueAccessTokenRequestBuilder;
+import org.wso2.carbon.identity.oauth.action.execution.PreIssueAccessTokenResponseProcessor;
+import org.wso2.carbon.identity.oauth.action.rule.PreIssueAccessTokenRuleEvaluationDataProvider;
import org.wso2.carbon.identity.oauth.cache.OAuthCache;
import org.wso2.carbon.identity.oauth.common.OAuthConstants;
import org.wso2.carbon.identity.oauth.common.token.bindings.TokenBinderInfo;
@@ -58,6 +59,7 @@
import org.wso2.carbon.identity.organization.management.service.OrganizationManager;
import org.wso2.carbon.identity.organization.management.service.OrganizationUserResidentResolverService;
import org.wso2.carbon.identity.role.mgt.core.RoleManagementService;
+import org.wso2.carbon.identity.rule.evaluation.provider.RuleEvaluationDataProvider;
import org.wso2.carbon.idp.mgt.IdpManager;
import org.wso2.carbon.user.core.listener.UserOperationEventListener;
import org.wso2.carbon.user.core.service.RealmService;
@@ -118,6 +120,7 @@ protected void activate(ComponentContext context) {
authProtocolApplicationService, null);
registerActionRequestBuilderAndResponseProcessor(context);
+ registerRuleEvaluationDataProvider(context);
// Note : DO NOT add any activation related code below this point,
// to make sure the server doesn't start up if any activation failures occur
@@ -140,6 +143,13 @@ private void registerActionRequestBuilderAndResponseProcessor(ComponentContext c
null);
}
+ private void registerRuleEvaluationDataProvider(ComponentContext context) {
+
+ context.getBundleContext()
+ .registerService(RuleEvaluationDataProvider.class, new PreIssueAccessTokenRuleEvaluationDataProvider(),
+ null);
+ }
+
protected void deactivate(ComponentContext context) {
if (serviceRegistration != null) {
diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/action/PreIssueAccessTokenRequestBuilderTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/action/execution/PreIssueAccessTokenRequestBuilderTest.java
similarity index 99%
rename from components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/action/PreIssueAccessTokenRequestBuilderTest.java
rename to components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/action/execution/PreIssueAccessTokenRequestBuilderTest.java
index ff9f8bfc0b..fe8cf0a16c 100644
--- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/action/PreIssueAccessTokenRequestBuilderTest.java
+++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/action/execution/PreIssueAccessTokenRequestBuilderTest.java
@@ -16,7 +16,7 @@
* under the License.
*/
-package org.wso2.carbon.identity.oauth.action;
+package org.wso2.carbon.identity.oauth.action.execution;
import org.apache.commons.codec.binary.Base64;
import org.mockito.MockedStatic;
diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/action/rule/PreIssueAccessTokenRuleEvaluationDataProviderTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/action/rule/PreIssueAccessTokenRuleEvaluationDataProviderTest.java
new file mode 100644
index 0000000000..8f3fb2b767
--- /dev/null
+++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/action/rule/PreIssueAccessTokenRuleEvaluationDataProviderTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
+ *
+ * WSO2 LLC. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.identity.oauth.action.rule;
+
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.MockitoAnnotations;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.wso2.carbon.identity.application.common.model.ServiceProvider;
+import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
+import org.wso2.carbon.identity.oauth2.dto.OAuth2AccessTokenReqDTO;
+import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;
+import org.wso2.carbon.identity.oauth2.util.OAuth2Util;
+import org.wso2.carbon.identity.rule.evaluation.exception.RuleEvaluationDataProviderException;
+import org.wso2.carbon.identity.rule.evaluation.model.Field;
+import org.wso2.carbon.identity.rule.evaluation.model.FieldValue;
+import org.wso2.carbon.identity.rule.evaluation.model.FlowContext;
+import org.wso2.carbon.identity.rule.evaluation.model.FlowType;
+import org.wso2.carbon.identity.rule.evaluation.model.RuleEvaluationContext;
+import org.wso2.carbon.identity.rule.evaluation.model.ValueType;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
+
+public class PreIssueAccessTokenRuleEvaluationDataProviderTest {
+
+ @InjectMocks
+ private PreIssueAccessTokenRuleEvaluationDataProvider provider;
+ @Mock
+ private OAuthTokenReqMessageContext tokenMessageContext;
+ @Mock
+ private OAuth2AccessTokenReqDTO tokenReqDTO;
+ @Mock
+ private FlowContext flowContext;
+ @Mock
+ private RuleEvaluationContext ruleEvaluationContext;
+ @Mock
+ private ServiceProvider serviceProvider;
+ private MockedStatic oAuth2UtilMockedStatic;
+
+ @BeforeMethod
+ public void setUp() {
+
+ MockitoAnnotations.openMocks(this);
+ when(flowContext.getContextData()).thenReturn(
+ Collections.singletonMap("tokenMessageContext", tokenMessageContext));
+ when(tokenMessageContext.getOauth2AccessTokenReqDTO()).thenReturn(tokenReqDTO);
+
+ oAuth2UtilMockedStatic = mockStatic(OAuth2Util.class);
+ }
+
+ @AfterMethod
+ public void tearDown() {
+
+ oAuth2UtilMockedStatic.close();
+ }
+
+ @Test
+ public void testGetSupportedFlowType() {
+
+ assertEquals(provider.getSupportedFlowType(), FlowType.PRE_ISSUE_ACCESS_TOKEN);
+ }
+
+ @Test
+ public void testGetEvaluationDataWithValidFields() throws Exception {
+
+ Field applicationField = new Field("application", ValueType.REFERENCE);
+ Field grantTypeField = new Field("grantType", ValueType.STRING);
+ when(ruleEvaluationContext.getFields()).thenReturn(Arrays.asList(applicationField, grantTypeField));
+
+ when(tokenReqDTO.getClientId()).thenReturn("clientId");
+ when(tokenReqDTO.getTenantDomain()).thenReturn("tenantDomain");
+ when(tokenReqDTO.getGrantType()).thenReturn("authorization_code");
+
+ when(OAuth2Util.getServiceProvider(anyString(), anyString())).thenReturn(serviceProvider);
+ when(serviceProvider.getApplicationResourceId()).thenReturn("testapp");
+
+ List fieldValues = provider.getEvaluationData(ruleEvaluationContext, flowContext, null);
+
+ assertEquals(fieldValues.size(), 2);
+ assertEquals(fieldValues.get(0).getName(), "application");
+ assertEquals(fieldValues.get(0).getValue(), "testapp");
+ assertEquals(fieldValues.get(1).getName(), "grantType");
+ assertEquals(fieldValues.get(1).getValue(), "authorization_code");
+ }
+
+ @Test(expectedExceptions = RuleEvaluationDataProviderException.class, expectedExceptionsMessageRegExp =
+ "Unsupported field: unsupported")
+ public void testGetEvaluationDataWithUnsupportedField() throws Exception {
+
+ Field unsupportedField = new Field("unsupported", ValueType.STRING);
+ when(ruleEvaluationContext.getFields()).thenReturn(Collections.singletonList(unsupportedField));
+
+ provider.getEvaluationData(ruleEvaluationContext, flowContext, null);
+ }
+
+ @Test(expectedExceptions = RuleEvaluationDataProviderException.class)
+ public void testGetEvaluationDataWhenRetrievingServiceProviderFails() throws Exception {
+
+ Field applicationField = new Field("application", ValueType.REFERENCE);
+ when(ruleEvaluationContext.getFields()).thenReturn(Collections.singletonList(applicationField));
+
+ when(tokenReqDTO.getClientId()).thenReturn("clientId");
+ when(tokenReqDTO.getTenantDomain()).thenReturn("tenantDomain");
+
+ when(OAuth2Util.getServiceProvider(anyString(), anyString())).thenThrow(new IdentityOAuth2Exception("Error"));
+
+ provider.getEvaluationData(ruleEvaluationContext, flowContext, "tenantDomain");
+ }
+}
diff --git a/components/org.wso2.carbon.identity.oauth/src/test/resources/testng.xml b/components/org.wso2.carbon.identity.oauth/src/test/resources/testng.xml
index f1a5b35f9e..4ea7b033b9 100755
--- a/components/org.wso2.carbon.identity.oauth/src/test/resources/testng.xml
+++ b/components/org.wso2.carbon.identity.oauth/src/test/resources/testng.xml
@@ -212,6 +212,8 @@
+
+
diff --git a/pom.xml b/pom.xml
index 6951d0e3d5..8a62524cb1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -277,6 +277,11 @@
org.wso2.carbon.identity.action.execution
${carbon.identity.framework.version}
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.rule.evaluation
+ ${carbon.identity.framework.version}
+
@@ -962,7 +967,7 @@
[1.0.1, 2.0.0)
- 7.7.90
+ 7.7.112
[5.25.234, 8.0.0)
[2.0.0, 3.0.0)