diff --git a/components/org.wso2.carbon.identity.oauth/pom.xml b/components/org.wso2.carbon.identity.oauth/pom.xml
index e8e1a2cf88a..55f2a1216da 100644
--- a/components/org.wso2.carbon.identity.oauth/pom.xml
+++ b/components/org.wso2.carbon.identity.oauth/pom.xml
@@ -605,7 +605,7 @@
org.apache.maven.plugins
maven-checkstyle-plugin
- **/IdentityOathEventListenerTest.java,**/AccessTokenIssuerTest.java,
+ **/IdentityOathEventListenerTest.java,**/DeprecatedAccessTokenIssuerTest.java,
**/OAuthUserStoreConfigListenerImplTest.java,**/NTLMAuthenticationGrantHandlerWithHandshakeTest.java,
**/AuthorizationCodeGrantHandlerTest.java,**/OAuthTenantMgtListenerImplTest.java
diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java
index 3f5d4bfb266..8ce1ede27e3 100644
--- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java
+++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuer.java
@@ -90,6 +90,7 @@
import org.wso2.carbon.identity.oauth2.validators.JDBCPermissionBasedInternalScopeValidator;
import org.wso2.carbon.identity.oauth2.validators.RoleBasedInternalScopeValidator;
import org.wso2.carbon.identity.openidconnect.IDTokenBuilder;
+import org.wso2.carbon.identity.openidconnect.OIDCConstants;
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.core.common.AbstractUserStoreManager;
@@ -128,6 +129,7 @@
import static org.wso2.carbon.identity.oauth2.util.OAuth2Util.EXTENDED_REFRESH_TOKEN_DEFAULT_TIME;
import static org.wso2.carbon.identity.oauth2.util.OAuth2Util.INTERNAL_LOGIN_SCOPE;
import static org.wso2.carbon.identity.oauth2.util.OAuth2Util.validateRequestTenantDomain;
+import static org.wso2.carbon.identity.openidconnect.OIDCConstants.EXISTING_TOKEN_USED;
import static org.wso2.carbon.identity.openidconnect.OIDCConstants.ID_TOKEN_USER_CLAIMS_PROP_KEY;
/**
@@ -141,6 +143,7 @@ public class AccessTokenIssuer {
public static final String OAUTH_APP_DO = "OAuthAppDO";
private static final String SERVICE_PROVIDERS_SUB_CLAIM = "ServiceProviders.UseUsernameAsSubClaim";
private final AuthorizationDetailsValidator authorizationDetailsValidator;
+ private static final String ENABLE_POST_TOKEN_ISSUE_EVENT = "PostTokenIssueEvent.Enable";
/**
* Private constructor which will not allow to create objects of this class from outside
@@ -417,7 +420,7 @@ private AuthorizationGrantCacheEntry getAuthzGrantCacheEntryFromDeviceCode(OAuth
}
private void persistImpersonationInfoToTokenReqCtx(AuthorizationGrantCacheEntry authorizationGrantCacheEntry,
- OAuthTokenReqMessageContext tokReqMsgCtx) {
+ OAuthTokenReqMessageContext tokReqMsgCtx) {
boolean isUserSessionImpersonationEnabled = OAuthServerConfiguration.getInstance()
.isUserSessionImpersonationEnabled();
@@ -1364,6 +1367,11 @@ private void triggerPostListeners(OAuth2AccessTokenReqDTO tokenReqDTO,
OAuthEventInterceptor oAuthEventInterceptorProxy = OAuthComponentServiceHolder.getInstance()
.getOAuthEventInterceptorProxy();
+ try {
+ triggerPostIssueTokenEvent(tokenReqDTO, tokenRespDTO, tokReqMsgCtx);
+ } catch (IdentityOAuth2Exception | OrganizationManagementException e) {
+ log.error("Error while triggering post issue token event.", e);
+ }
if (isRefresh) {
if (oAuthEventInterceptorProxy != null && oAuthEventInterceptorProxy.isEnabled()) {
@@ -1394,6 +1402,65 @@ private void triggerPostListeners(OAuth2AccessTokenReqDTO tokenReqDTO,
}
}
+ private static void triggerPostIssueTokenEvent(OAuth2AccessTokenReqDTO tokenReqDTO,
+ OAuth2AccessTokenRespDTO tokenRespDTO,
+ OAuthTokenReqMessageContext tokReqMsgCtx)
+ throws IdentityOAuth2Exception, OrganizationManagementException {
+
+ if (!Boolean.parseBoolean(IdentityUtil.getProperty(ENABLE_POST_TOKEN_ISSUE_EVENT))) {
+ if (log.isDebugEnabled()) {
+ log.debug("Token event publishing is disabled. Hence skipping the post issue token event.");
+ }
+ return;
+ }
+ if (tokenReqDTO == null || tokenRespDTO == null || tokReqMsgCtx == null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Token request DTO, token response DTO or token request message context is null. " +
+ "Skipping the post issue token event.");
+ }
+ return;
+ }
+ if (tokenRespDTO.isError()) {
+ if (log.isDebugEnabled()) {
+ log.debug("Token response DTO is in error state. Hence skipping the post issue token event.");
+ }
+ return;
+ }
+
+ String tenantDomain = tokReqMsgCtx.getOauth2AccessTokenReqDTO().getTenantDomain();
+ String organizationId = OAuthComponentServiceHolder.getInstance().getOrganizationManager()
+ .resolveOrganizationId(tenantDomain);
+ String accessingOrganizationId = StringUtils.EMPTY;
+ if (tokReqMsgCtx.getAuthorizedUser() != null
+ && tokReqMsgCtx.getAuthorizedUser().getAccessingOrganization() != null) {
+ accessingOrganizationId = tokReqMsgCtx.getAuthorizedUser().getAccessingOrganization();
+ }
+
+ Map eventProperties = new HashMap<>();
+ eventProperties.put(OIDCConstants.Event.TOKEN_ID, tokenRespDTO.getTokenId());
+ eventProperties.put(OIDCConstants.Event.TENANT_DOMAIN, tenantDomain);
+ eventProperties.put(OIDCConstants.Event.USER_TYPE, tokReqMsgCtx.getProperty(OAuthConstants.UserType.USER_TYPE));
+ eventProperties.put(OIDCConstants.Event.CLIENT_ID, tokReqMsgCtx.getOauth2AccessTokenReqDTO().getClientId());
+ eventProperties.put(OIDCConstants.Event.GRANT_TYPE, tokenReqDTO.getGrantType());
+ eventProperties.put(OIDCConstants.Event.ISSUED_TIME, String.valueOf(tokReqMsgCtx.getAccessTokenIssuedTime()));
+ eventProperties.put(OIDCConstants.Event.ISSUER_ORGANIZATION_ID, organizationId);
+ eventProperties.put(OIDCConstants.Event.ACCESSING_ORGANIZATION_ID, accessingOrganizationId);
+ eventProperties.put(OIDCConstants.Event.APP_RESIDENT_TENANT_ID, IdentityTenantUtil.getLoginTenantId());
+ eventProperties.put(OIDCConstants.Event.EXISTING_TOKEN_USED, String.valueOf(existingTokenUsed(tokReqMsgCtx)));
+ eventProperties.put(OIDCConstants.Event.SERVICE_PROVIDER, OAuth2Util.getServiceProvider(
+ tokReqMsgCtx.getOauth2AccessTokenReqDTO().getClientId(), tenantDomain).getApplicationName());
+ OAuth2TokenUtil.postIssueToken(eventProperties);
+ }
+
+ private static Boolean existingTokenUsed(OAuthTokenReqMessageContext tokReqMsgCtx) {
+
+ Boolean existingTokenUsed = (Boolean) tokReqMsgCtx.getProperty(EXISTING_TOKEN_USED);
+ if (existingTokenUsed == null) {
+ existingTokenUsed = false;
+ }
+ return existingTokenUsed;
+ }
+
/**
* Copies the cache entry against the authorization code/device code and adds an entry against the access token.
* This is done to reuse the calculated user claims for subsequent usages such as user info calls.
@@ -1474,8 +1541,8 @@ private void persistCustomizedAccessTokenAttributesForRefreshToken(OAuth2AccessT
AuthorizationGrantCache.getInstance().addToCacheByToken(newCacheKey, authorizationGrantCacheEntry);
log.debug("Customized audience list and access token attributes from pre issue access token actions " +
- "are persisted in the AuthorizationGrantCache against the token id: " +
- tokenRespDTO.getTokenId());
+ "are persisted in the AuthorizationGrantCache against the token id: " +
+ tokenRespDTO.getTokenId());
}
}
diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2TokenUtil.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2TokenUtil.java
index c9a2d1c0742..a3de16caece 100644
--- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2TokenUtil.java
+++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2TokenUtil.java
@@ -39,6 +39,7 @@
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import static org.wso2.carbon.identity.openidconnect.OIDCConstants.Event.IS_REQUEST_OBJECT_FLOW;
import static org.wso2.carbon.identity.openidconnect.OIDCConstants.Event.NEW_ACCESS_TOKEN;
@@ -82,6 +83,31 @@ public static void postIssueAccessToken(String tokenId, String sessionDataKey) t
}
}
+ /**
+ * Uses to publish token issuance details.
+ *
+ * @param eventProperties Map containing token issuance details.
+ * @throws IdentityOAuth2Exception when an error occurs while publishing the event.
+ */
+ public static void postIssueToken(Map eventProperties) throws IdentityOAuth2Exception {
+
+ String eventName = OIDCConstants.Event.POST_ISSUE_ACCESS_TOKEN_V2;
+ Event postIssueTokenEvent = new Event(eventName, eventProperties);
+ IdentityEventService identityEventService = OpenIDConnectServiceComponentHolder.getIdentityEventService();
+ try {
+ if (identityEventService != null) {
+ identityEventService.handleEvent(postIssueTokenEvent);
+ if (log.isDebugEnabled()) {
+ log.debug("The event " + eventName + " triggered after the token "
+ + eventProperties.get(OIDCConstants.Event.TOKEN_ID) + " is issued.");
+ }
+ }
+ } catch (IdentityEventException e) {
+ throw new IdentityOAuth2Exception("Error while invoking the request object persistence handler when " +
+ "issuing the access token id: " + eventProperties.get(OIDCConstants.Event.TOKEN_ID));
+ }
+ }
+
/**
* Uses to revoke access tokens from the request object related tables after token revocation
* happens from access token related tables.
diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/openidconnect/OIDCConstants.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/openidconnect/OIDCConstants.java
index dc5ce098854..14a59ac4509 100644
--- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/openidconnect/OIDCConstants.java
+++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/openidconnect/OIDCConstants.java
@@ -28,6 +28,7 @@ public class OIDCConstants {
public static final String IDN_OIDC_REQ_OBJECT_CLAIMS = "STORE_IDN_OIDC_REQ_OBJECT_CLAIMS";
public static final String HAS_NON_OIDC_CLAIMS = "hasNonOIDCClaims";
public static final String ID_TOKEN_USER_CLAIMS_PROP_KEY = "IDTokenUserClaims";
+ public static final String EXISTING_TOKEN_USED = "existingTokenUsed";
/**
* This class is used to define constants related to OIDC event specific features.
@@ -39,6 +40,7 @@ public class Event {
public static final String SESSION_DATA_KEY = "SESSION_DATA_KEY";
public static final String POST_ISSUE_CODE = "POST_ISSUE_CODE";
public static final String POST_ISSUE_ACCESS_TOKEN = "POST_ISSUE_ACCESS_TOKEN";
+ public static final String POST_ISSUE_ACCESS_TOKEN_V2 = "POST_ISSUE_ACCESS_TOKEN_V2";
public static final String HANDLE_REQUEST_OBJECT = "handleRequestObject";
public static final String POST_REVOKE_ACESS_TOKEN = "POST_REVOKE_ACESS_TOKEN";
public static final String POST_REVOKE_ACESS_TOKEN_BY_ID = "POST_REVOKE_ACESS_TOKEN_BY_ID";
@@ -47,10 +49,19 @@ public class Event {
public static final String ACEESS_TOKENS = "ACEESS_TOKENS";
public static final String CODES = "CODES";
public static final String TOKEN_STATE = "TOKEN_STATE";
+ public static final String GRANT_TYPE = "GRANT_TYPE";
+ public static final String CLIENT_ID = "CLIENT_ID";
+ public static final String TENANT_DOMAIN = "TENANT_DOMAIN";
+ public static final String USER_TYPE = "USER_TYPE";
public static final String NEW_ACCESS_TOKEN = "NEW_ACCESS_TOKEN";
public static final String OLD_ACCESS_TOKEN = "OLD_ACCESS_TOKEN";
public static final String POST_REFRESH_TOKEN = "POST_REFRESH_TOKEN";
public static final String IS_REQUEST_OBJECT_FLOW = "IS_REQUEST_OBJECT_FLOW";
+ public static final String APP_RESIDENT_TENANT_ID = "APP_RESIDENT_TENANT_ID";
+ public static final String ISSUED_TIME = "ISSUED_TIME";
+ public static final String ISSUER_ORGANIZATION_ID = "ISSUER_ORGANIZATION_ID";
+ public static final String ACCESSING_ORGANIZATION_ID = "ACCESSING_ORGANIZATION_ID";
+ public static final String EXISTING_TOKEN_USED = "EXISTING_TOKEN_USED";
+ public static final String SERVICE_PROVIDER = "SERVICE_PROVIDER";
}
}
-
diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuerTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuerTest.java
index 4214fbfe3b6..db9ca35f749 100644
--- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuerTest.java
+++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/token/AccessTokenIssuerTest.java
@@ -1,770 +1,300 @@
/*
- * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
*
- * WSO2 Inc. 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
+ * 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
+ * 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.
+ * 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.oauth2.token;
-import org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.oltu.oauth2.common.error.OAuthError;
-import org.apache.oltu.oauth2.common.message.types.GrantType;
import org.mockito.Mock;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
+import org.mockito.MockedStatic;
+import org.mockito.testng.MockitoTestNGListener;
import org.testng.Assert;
+import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
+import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
+import org.wso2.carbon.base.CarbonBaseConstants;
+import org.wso2.carbon.context.PrivilegedCarbonContext;
+import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser;
+import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException;
+import org.wso2.carbon.identity.application.common.model.LocalAndOutboundAuthenticationConfig;
+import org.wso2.carbon.identity.application.common.model.ServiceProvider;
+import org.wso2.carbon.identity.application.mgt.ApplicationManagementService;
import org.wso2.carbon.identity.base.IdentityException;
+import org.wso2.carbon.identity.central.log.mgt.utils.LoggerUtils;
+import org.wso2.carbon.identity.common.testng.WithCarbonHome;
+import org.wso2.carbon.identity.core.util.IdentityConfigParser;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
+import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.oauth.cache.AppInfoCache;
-import org.wso2.carbon.identity.oauth.common.OAuth2ErrorCodes;
+import org.wso2.carbon.identity.oauth.cache.OAuthCache;
import org.wso2.carbon.identity.oauth.common.OAuthConstants;
-import org.wso2.carbon.identity.oauth.common.exception.InvalidOAuthClientException;
import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration;
import org.wso2.carbon.identity.oauth.dao.OAuthAppDO;
-import org.wso2.carbon.identity.oauth2.IDTokenValidationFailureException;
-import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
-import org.wso2.carbon.identity.oauth2.ResponseHeader;
+import org.wso2.carbon.identity.oauth.event.OAuthEventInterceptor;
+import org.wso2.carbon.identity.oauth.internal.OAuthComponentServiceHolder;
+import org.wso2.carbon.identity.oauth.rar.core.AuthorizationDetailsSchemaValidator;
import org.wso2.carbon.identity.oauth2.bean.OAuthClientAuthnContext;
import org.wso2.carbon.identity.oauth2.dto.OAuth2AccessTokenReqDTO;
import org.wso2.carbon.identity.oauth2.dto.OAuth2AccessTokenRespDTO;
-import org.wso2.carbon.identity.oauth2.test.utils.CommonTestUtils;
+import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder;
+import org.wso2.carbon.identity.oauth2.rar.AuthorizationDetailsService;
+import org.wso2.carbon.identity.oauth2.rar.core.AuthorizationDetailsProcessorFactory;
import org.wso2.carbon.identity.oauth2.token.handlers.grant.AuthorizationGrantHandler;
-import org.wso2.carbon.identity.oauth2.token.handlers.grant.PasswordGrantHandler;
+import org.wso2.carbon.identity.oauth2.util.AuthzUtil;
+import org.wso2.carbon.identity.oauth2.util.OAuth2TokenUtil;
import org.wso2.carbon.identity.oauth2.util.OAuth2Util;
-import org.wso2.carbon.identity.oauth2.validators.JDBCPermissionBasedInternalScopeValidator;
-import org.wso2.carbon.identity.openidconnect.IDTokenBuilder;
-import org.wso2.carbon.utils.CarbonUtils;
-import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
+import org.wso2.carbon.identity.openidconnect.OIDCConstants;
+import org.wso2.carbon.identity.organization.management.service.OrganizationManager;
+import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
+import org.wso2.carbon.user.core.UserRealm;
+import org.wso2.carbon.user.core.UserStoreException;
+import org.wso2.carbon.user.core.common.AbstractUserStoreManager;
import java.lang.reflect.Field;
-import java.util.Arrays;
+import java.nio.file.Paths;
import java.util.HashMap;
-import java.util.Hashtable;
import java.util.Map;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.mock;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.openMocks;
import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OauthAppStates.APP_STATE_ACTIVE;
/**
- * Unit test cases for {@link AccessTokenIssuer}
+ * Unit test for {@link AccessTokenIssuer}.
*/
-
+@Listeners(MockitoTestNGListener.class)
+@WithCarbonHome
public class AccessTokenIssuerTest {
- public static final String SOME_CLIENT_ID = "some-client-id";
+ private static final String ENABLE_POST_TOKEN_ISSUE_EVENT = "PostTokenIssueEvent.Enable";
+ private final int testAppResidentTenantId = 1;
+ private final String testAccessingOrganizationId = "dExLASaD1Flb_fx7ZecfAA3n1HRka";
+ private final String testTenantDomain = "carbon.super";
+ private final String testClientId = "dExLASaD1Flb_fx7ZecfAA3n1HRka";
+ private final String testOrganizationId = "exLASaD1Flb_fx7ZecfAA3n1HRkaf";
+ private final String testTokenId = "dExLASaD1Flb_fx7ZecfAA3n1HRka12345";
+ private final String testApplicationName = "TestApplication";
+ private AutoCloseable mocks;
@Mock
- private OAuthServerConfiguration oAuthServerConfiguration;
-
+ private IdentityConfigParser identityConfigParserMock;
@Mock
- private OAuthAppDO mockOAuthAppDO;
-
+ private OAuthComponentServiceHolder oAuthComponentServiceHolderMock;
@Mock
- private PasswordGrantHandler passwordGrantHandler;
-
+ private OAuthServerConfiguration mockedOAuthServerConfig;
@Mock
- private OAuth2AccessTokenRespDTO mockOAuth2AccessTokenRespDTO;
+ private OAuthAppDO appDO;
- @Mock
- private JDBCPermissionBasedInternalScopeValidator scopeValidator;
-
- private static final String DUMMY_GRANT_TYPE = "dummy_grant_type";
- private static final String ID_TOKEN = "dummyIDToken";
- private static final String[] SCOPES_WITHOUT_OPENID = new String[]{"scope1", "scope2"};
- private static final String[] SCOPES_WITH_OPENID = new String[]{"scope1", OAuthConstants.Scope.OPENID};
-
-// @BeforeMethod
-// public void setUp() throws Exception {
-//
-// mockStatic(CarbonUtils.class);
-//
-// mockStatic(OAuthServerConfiguration.class);
-// when(OAuthServerConfiguration.getInstance()).thenReturn(oAuthServerConfiguration);
-// when(oAuthServerConfiguration.getTimeStampSkewInSeconds()).thenReturn(3600L);
-//
-// mockStatic(OAuth2Util.class);
-// when(OAuth2Util.getAppInformationByClientId(anyString())).thenReturn(mockOAuthAppDO);
-// when(mockOAuthAppDO.getState()).thenReturn(APP_STATE_ACTIVE);
-// when(OAuth2Util.getTenantDomainOfOauthApp(any(OAuthAppDO.class)))
-// .thenReturn(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
-// }
-//
-// @AfterMethod
-// public void tearDown() throws Exception {
-// // Reset the singleton
-// Field field = AccessTokenIssuer.class.getDeclaredField("instance");
-// field.setAccessible(true);
-// field.set(null, null);
-// }
-//
-// @DataProvider(name = "appConfigProvider")
-// public Object[][] provideAppConfigData() {
-//
-// return new Object[][]{
-// {null},
-// {mock(AppInfoCache.class)}
-// };
-// }
-//
-// @Test(dataProvider = "appConfigProvider")
-// public void testGetInstance(Object appInfoCache) throws Exception {
-//
-// mockStatic(AppInfoCache.class);
-// when(AppInfoCache.getInstance()).thenReturn((AppInfoCache) appInfoCache);
-// CommonTestUtils.testSingleton(AccessTokenIssuer.getInstance(), AccessTokenIssuer.getInstance());
-// }
-//
-// @DataProvider(name = "AccessTokenIssue")
-// public Object[][] accessTokenIssue() {
-// // isOfTypeApplicationUser,
-// // isAuthorizedClient,
-// // isValidGrant,
-// // isAuthorizedAccessDelegation,
-// // isValidScope,
-// // isAuthenticatedClient,
-// // isTokenIssuingSuccess
-// return new Object[][]{
-// {true, true, true, true, true, true},
-// {false, true, true, true, true, false},
-// {true, false, true, true, true, false},
-// {true, true, false, true, true, false},
-// {true, true, true, false, true, false},
-// {true, true, true, true, false, false},
-// };
-// }
-//
-// @Test(dataProvider = "AccessTokenIssue")
-// public void testIssue(boolean isAuthorizedClient,
-// boolean isValidGrant,
-// boolean isAuthorizedAccessDelegation,
-// boolean isValidScope,
-// boolean isAuthenticatedClient,
-// boolean isTokenIssueSuccess) throws IdentityException {
-//
-// mockPasswordGrantHandler(isAuthorizedClient, isValidGrant, isAuthorizedAccessDelegation, isValidScope);
-//
-// OAuth2AccessTokenReqDTO reqDTO = new OAuth2AccessTokenReqDTO();
-// reqDTO.setGrantType(OAuthConstants.GrantTypes.PASSWORD);
-// reqDTO.setClientId(SOME_CLIENT_ID);
-//
-// OAuthClientAuthnContext oAuthClientAuthnContext = new OAuthClientAuthnContext();
-// oAuthClientAuthnContext.setAuthenticated(isAuthenticatedClient);
-// reqDTO.setoAuthClientAuthnContext(oAuthClientAuthnContext);
-//
-// AccessTokenIssuer tokenIssuer = AccessTokenIssuer.getInstance();
-// OAuth2AccessTokenRespDTO tokenRespDTO = tokenIssuer.issue(reqDTO);
-//
-// if (isTokenIssueSuccess) {
-// Assert.assertFalse(tokenRespDTO.isError());
-// }
-// }
-//
-// /**
-// * Multiple Client Authentication mechanisms used to authenticate the request.
-// *
-// * @throws Exception
-// */
-// @Test
-// public void testIssueFailedMultipleClientAuthentication() throws Exception {
-//
-// OAuth2AccessTokenReqDTO reqDTO = new OAuth2AccessTokenReqDTO();
-// reqDTO.setGrantType(DUMMY_GRANT_TYPE);
-// OAuthClientAuthnContext oAuthClientAuthnContext = new OAuthClientAuthnContext();
-// oAuthClientAuthnContext.addAuthenticator("ClientAuthenticator1");
-// oAuthClientAuthnContext.addAuthenticator("ClientAuthenticator2");
-// reqDTO.setoAuthClientAuthnContext(oAuthClientAuthnContext);
-// OAuth2AccessTokenRespDTO tokenRespDTO = AccessTokenIssuer.getInstance().issue(reqDTO);
-// assertNotNull(tokenRespDTO);
-// assertTrue(tokenRespDTO.isError());
-// assertEquals(tokenRespDTO.getErrorCode(), OAuthError.TokenResponse.INVALID_REQUEST, "Error Code has been " +
-// "changed. Previously it was: " + OAuthError.TokenResponse.INVALID_REQUEST);
-// }
-//
-// @DataProvider(name = "tenantDataProvider")
-// public Object[][] getTenantDomainData() {
-//
-// return new Object[][]{
-// {"non_super_tenant.com"},
-// {null}
-// };
-// }
-//
-// /**
-// * Tests whether cross tenant token requests fail in tenant qualified URL mode.
-// *
-// * @throws Exception
-// */
-// @Test (dataProvider = "tenantDataProvider" , expectedExceptions = InvalidOAuthClientException.class)
-// public void testCrossTenantTokenRequestError(String tenantInContext) throws Exception {
-//
-// OAuth2AccessTokenReqDTO reqDTO = new OAuth2AccessTokenReqDTO();
-// reqDTO.setGrantType("password");
-//
-// OAuthClientAuthnContext oAuthClientAuthnContext = new OAuthClientAuthnContext();
-// oAuthClientAuthnContext.setAuthenticated(true);
-// reqDTO.setoAuthClientAuthnContext(oAuthClientAuthnContext);
-//
-// mockStatic(IdentityTenantUtil.class);
-// when(IdentityTenantUtil.isTenantQualifiedUrlsEnabled()).thenReturn(true);
-// when(IdentityTenantUtil.getTenantDomainFromContext()).thenReturn(tenantInContext);
-// when(OAuth2Util.class, "validateRequestTenantDomain", anyString()).thenCallRealMethod();
-//
-// mockPasswordGrantHandler(true, true, true, true);
-//
-// AccessTokenIssuer.getInstance().issue(reqDTO);
-// }
-//
-// /**
-// * No authorization grant handler found for the given grant type.
-// *
-// * @throws Exception
-// */
-// @Test
-// public void testIssueNoAuthorizationGrantHandler() throws Exception {
-//
-// when(oAuthServerConfiguration.getSupportedGrantTypes())
-// .thenReturn(new HashMap());
-//
-// OAuth2AccessTokenReqDTO reqDTO = new OAuth2AccessTokenReqDTO();
-// reqDTO.setGrantType(DUMMY_GRANT_TYPE);
-// OAuthClientAuthnContext oAuthClientAuthnContext = new OAuthClientAuthnContext();
-// oAuthClientAuthnContext.setAuthenticated(true);
-// reqDTO.setoAuthClientAuthnContext(oAuthClientAuthnContext);
-//
-// OAuth2AccessTokenRespDTO tokenRespDTO = AccessTokenIssuer.getInstance().issue(reqDTO);
-// assertNotNull(tokenRespDTO);
-// assertTrue(tokenRespDTO.isError());
-// assertEquals(tokenRespDTO.getErrorCode(), OAuthError.TokenResponse.UNSUPPORTED_GRANT_TYPE);
-// }
-//
-// /**
-// * No client authenticators to handle authentication but the grant type is restricted to confidential clients.
-// *
-// * @throws Exception
-// */
-// @Test
-// public void testIssueWithNoClientAuthentication() throws Exception {
-//
-// AuthorizationGrantHandler dummyGrantHandler = mock(AuthorizationGrantHandler.class);
-// when(dummyGrantHandler.isConfidentialClient()).thenReturn(true);
-//
-// HashMap authorizationGrantHandlers = new HashMap<>();
-// authorizationGrantHandlers.put(DUMMY_GRANT_TYPE, dummyGrantHandler);
-//
-// mockOAuth2ServerConfiguration(authorizationGrantHandlers);
-//
-// OAuth2AccessTokenReqDTO reqDTO = new OAuth2AccessTokenReqDTO();
-// reqDTO.setGrantType(DUMMY_GRANT_TYPE);
-//
-// OAuth2AccessTokenRespDTO tokenRespDTO = AccessTokenIssuer.getInstance().issue(reqDTO);
-// assertNotNull(tokenRespDTO);
-// assertTrue(tokenRespDTO.isError());
-// assertEquals(tokenRespDTO.getErrorCode(),
-// OAuth2ErrorCodes.INVALID_CLIENT);
-// }
-//
-// @DataProvider(name = "unauthorizedClientErrorConditionProvider")
-// public Object[][] getUnauthorizedClientErrorConditions() {
-//
-// return new Object[][]{
-// // whether to throw an exception or not for a valid grant, Exception message
-// {true, "Exception when authorizing client."},
-// {false, "The authenticated client is not authorized to use this authorization grant type"}
-// };
-// }
-//
-// @Test(dataProvider = "unauthorizedClientErrorConditionProvider")
-// public void testIssueErrorUnauthorizedClient(boolean throwException,
-// String exceptionMsg) throws Exception {
-//
-// AuthorizationGrantHandler dummyGrantHandler = mock(AuthorizationGrantHandler.class);
-// when(dummyGrantHandler.isConfidentialClient()).thenReturn(false);
-// // Not a confidential client
-// when(dummyGrantHandler.isOfTypeApplicationUser()).thenReturn(true);
-//
-// if (throwException) {
-// when(dummyGrantHandler.isAuthorizedClient(any(OAuthTokenReqMessageContext.class)))
-// .thenThrow(new IdentityOAuth2Exception(exceptionMsg));
-// } else {
-// // Unauthorized client
-// when(dummyGrantHandler.isAuthorizedClient(any(OAuthTokenReqMessageContext.class))).thenReturn(false);
-// }
-//
-// HashMap authorizationGrantHandlers = new HashMap<>();
-// authorizationGrantHandlers.put(DUMMY_GRANT_TYPE, dummyGrantHandler);
-//
-// mockOAuth2ServerConfiguration(authorizationGrantHandlers);
-//
-// OAuth2AccessTokenReqDTO reqDTO = new OAuth2AccessTokenReqDTO();
-// reqDTO.setGrantType(DUMMY_GRANT_TYPE);
-//
-// OAuthClientAuthnContext oAuthClientAuthnContext = new OAuthClientAuthnContext();
-// oAuthClientAuthnContext.setClientId(SOME_CLIENT_ID);
-// reqDTO.setoAuthClientAuthnContext(oAuthClientAuthnContext);
-//
-// OAuth2AccessTokenRespDTO tokenRespDTO = AccessTokenIssuer.getInstance().issue(reqDTO);
-// assertNotNull(tokenRespDTO);
-// assertTrue(tokenRespDTO.isError());
-// assertEquals(tokenRespDTO.getErrorCode(), OAuthError.TokenResponse.UNAUTHORIZED_CLIENT);
-// assertEquals(tokenRespDTO.getErrorMsg(), exceptionMsg);
-// }
-//
-// @DataProvider(name = "invalidGrantErrorDataProvider")
-// public Object[][] getInvalidGrantErrorData() {
-//
-// return new Object[][]{
-// // whether to throw an exception or not for a valid grant, Exception message
-// {true, "Exception when processing oauth2 grant."},
-// {false, "Provided Authorization Grant is invalid"}
-// };
-// }
-//
-// @Test(dataProvider = "invalidGrantErrorDataProvider")
-// public void testIssueValidateGrantError(boolean throwException,
-// String exceptionMsg) throws Exception {
-//
-// AuthorizationGrantHandler dummyGrantHandler = mock(AuthorizationGrantHandler.class);
-// when(dummyGrantHandler.isConfidentialClient()).thenReturn(false);
-// // Not a confidential client
-// when(dummyGrantHandler.isOfTypeApplicationUser()).thenReturn(true);
-// when(dummyGrantHandler.isAuthorizedClient(any(OAuthTokenReqMessageContext.class))).thenReturn(true);
-//
-// if (throwException) {
-// // validate grant will throw an exception
-// when(dummyGrantHandler.validateGrant(any(OAuthTokenReqMessageContext.class)))
-// .thenThrow(new IdentityOAuth2Exception(exceptionMsg));
-// } else {
-// // validate grant will return false
-// when(dummyGrantHandler.validateGrant(any(OAuthTokenReqMessageContext.class))).thenReturn(false);
-// }
-//
-// HashMap authorizationGrantHandlers = new HashMap<>();
-// authorizationGrantHandlers.put(DUMMY_GRANT_TYPE, dummyGrantHandler);
-//
-// mockOAuth2ServerConfiguration(authorizationGrantHandlers);
-//
-// OAuth2AccessTokenReqDTO reqDTO = new OAuth2AccessTokenReqDTO();
-// reqDTO.setGrantType(DUMMY_GRANT_TYPE);
-// OAuthClientAuthnContext oAuthClientAuthnContext = new OAuthClientAuthnContext();
-// oAuthClientAuthnContext.setClientId(SOME_CLIENT_ID);
-//
-// reqDTO.setoAuthClientAuthnContext(oAuthClientAuthnContext);
-// OAuth2AccessTokenRespDTO tokenRespDTO = AccessTokenIssuer.getInstance().issue(reqDTO);
-// assertNotNull(tokenRespDTO);
-// assertTrue(tokenRespDTO.isError());
-// assertEquals(tokenRespDTO.getErrorCode(), OAuthError.TokenResponse.INVALID_GRANT);
-// assertEquals(tokenRespDTO.getErrorMsg(), exceptionMsg);
-// }
-//
-// /**
-// * Exception thrown when issuing access token by the Grant Handler
-// *
-// * @throws Exception
-// */
-// @Test
-// public void testIssueErrorWhenIssue2() throws Exception {
-//
-// AuthorizationGrantHandler dummyGrantHandler = getMockGrantHandlerForSuccess(true);
-// when(dummyGrantHandler.issue(any(OAuthTokenReqMessageContext.class))).then(new Answer