diff --git a/components/org.wso2.carbon.identity.api.server.dcr/pom.xml b/components/org.wso2.carbon.identity.api.server.dcr/pom.xml index ba493c29c27..a37ddcb1aa6 100644 --- a/components/org.wso2.carbon.identity.api.server.dcr/pom.xml +++ b/components/org.wso2.carbon.identity.api.server.dcr/pom.xml @@ -23,12 +23,12 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth - 7.0.205 + 7.0.212-SNAPSHOT ../../pom.xml org.wso2.carbon.identity.api.server.dcr - 7.0.205 + 7.0.212-SNAPSHOT WSO2 Carbon - User DCR Rest API WSO2 Carbon - User DCR Rest API diff --git a/components/org.wso2.carbon.identity.api.server.oauth.scope/pom.xml b/components/org.wso2.carbon.identity.api.server.oauth.scope/pom.xml index 31a943dfac1..03da88e0e60 100644 --- a/components/org.wso2.carbon.identity.api.server.oauth.scope/pom.xml +++ b/components/org.wso2.carbon.identity.api.server.oauth.scope/pom.xml @@ -23,12 +23,12 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth - 7.0.205 + 7.0.212-SNAPSHOT ../.. org.wso2.carbon.identity.api.server.oauth.scope - 7.0.205 + 7.0.212-SNAPSHOT WSO2 Carbon - Identity OAuth 2.0 Scope Rest APIs Rest APIs for OAuth 2.0 Scope Handling diff --git a/components/org.wso2.carbon.identity.client.attestation.filter/pom.xml b/components/org.wso2.carbon.identity.client.attestation.filter/pom.xml index 784c57e4c36..d776a4baf97 100644 --- a/components/org.wso2.carbon.identity.client.attestation.filter/pom.xml +++ b/components/org.wso2.carbon.identity.client.attestation.filter/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth - 7.0.205 + 7.0.212-SNAPSHOT ../../pom.xml diff --git a/components/org.wso2.carbon.identity.discovery/pom.xml b/components/org.wso2.carbon.identity.discovery/pom.xml index f611fbc6388..bf85003d527 100644 --- a/components/org.wso2.carbon.identity.discovery/pom.xml +++ b/components/org.wso2.carbon.identity.discovery/pom.xml @@ -21,7 +21,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth.ciba/pom.xml b/components/org.wso2.carbon.identity.oauth.ciba/pom.xml index 4c2019ada84..a52aa6e50bb 100644 --- a/components/org.wso2.carbon.identity.oauth.ciba/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.ciba/pom.xml @@ -20,7 +20,7 @@ identity-inbound-auth-oauth org.wso2.carbon.identity.inbound.auth.oauth2 - 7.0.205 + 7.0.212-SNAPSHOT ../../pom.xml diff --git a/components/org.wso2.carbon.identity.oauth.client.authn.filter/pom.xml b/components/org.wso2.carbon.identity.oauth.client.authn.filter/pom.xml index 608cc0cc51e..ea3a9f956ed 100644 --- a/components/org.wso2.carbon.identity.oauth.client.authn.filter/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.client.authn.filter/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth.common/pom.xml b/components/org.wso2.carbon.identity.oauth.common/pom.xml index a05506b05e8..571ff2f1fa3 100644 --- a/components/org.wso2.carbon.identity.oauth.common/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.common/pom.xml @@ -23,7 +23,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth.dcr.endpoint/pom.xml b/components/org.wso2.carbon.identity.oauth.dcr.endpoint/pom.xml index 7ddc16763b5..5705fc241cc 100644 --- a/components/org.wso2.carbon.identity.oauth.dcr.endpoint/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.dcr.endpoint/pom.xml @@ -6,7 +6,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth.dcr/pom.xml b/components/org.wso2.carbon.identity.oauth.dcr/pom.xml index 86a9144f55f..f0df6f50244 100644 --- a/components/org.wso2.carbon.identity.oauth.dcr/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.dcr/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 @@ -126,7 +126,10 @@ org.wso2.carbon.identity.framework org.wso2.carbon.identity.configuration.mgt.core - + + org.wso2.carbon.identity.organization.management.core + org.wso2.carbon.identity.organization.management.service + @@ -165,6 +168,8 @@ org.wso2.carbon.identity.application.common.model;version="${carbon.identity.framework.imp.pkg.version.range}", org.wso2.carbon.identity.application.mgt.*;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.organization.management.service; version="${carbon.identity.organization.management.core.version.range}", + org.wso2.carbon.identity.organization.management.service.exception; version="${carbon.identity.organization.management.core.version.range}", javax.servlet.http; version="${imp.pkg.version.javax.servlet}", org.wso2.carbon.user.api; version="${carbon.user.api.imp.pkg.version.range}", org.wso2.carbon.identity.oauth.*;version="${identity.inbound.auth.oauth.imp.pkg.version.range}", diff --git a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/DCRMConstants.java b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/DCRMConstants.java index 83b32bb5e0d..8eabb696ce1 100644 --- a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/DCRMConstants.java +++ b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/DCRMConstants.java @@ -60,7 +60,8 @@ public enum ErrorMessages { SIGNATURE_VALIDATION_FAILED("Signature validation failed for the software statement"), MANDATORY_SOFTWARE_STATEMENT("Mandatory software statement is missing"), FAILED_TO_READ_SSA("Error occurred while reading the software statement"), - ADDITIONAL_ATTRIBUTE_ERROR("Error occurred while handling additional attributes"); + ADDITIONAL_ATTRIBUTE_ERROR("Error occurred while handling additional attributes"), + FAILED_TO_RESOLVE_TENANT_DOMAIN("Error while resolving tenant domain from the organization id: %s"); private final String message; private final String errorCode; diff --git a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/internal/DCRDataHolder.java b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/internal/DCRDataHolder.java index eaaf88e4f68..25bf98dbe34 100644 --- a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/internal/DCRDataHolder.java +++ b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/internal/DCRDataHolder.java @@ -23,6 +23,7 @@ import org.wso2.carbon.identity.oauth.dcr.handler.RegistrationHandler; import org.wso2.carbon.identity.oauth.dcr.handler.UnRegistrationHandler; import org.wso2.carbon.identity.oauth2.token.bindings.TokenBinder; +import org.wso2.carbon.identity.organization.management.service.OrganizationManager; import java.util.ArrayList; import java.util.List; @@ -33,7 +34,6 @@ * This was deprecated as part of deprecating the legacy identity/register DCR endpoint. * The recommendation is to use /identity/oauth2/dcr/v1.1 instead. */ -@Deprecated public class DCRDataHolder { private static DCRDataHolder thisInstance = new DCRDataHolder(); @@ -42,6 +42,7 @@ public class DCRDataHolder { private List unRegistrationHandlerList = new ArrayList<>(); private List tokenBinders = new ArrayList<>(); private ConfigurationManager configurationManager; + private OrganizationManager organizationManager; private DCRDataHolder() { @@ -111,4 +112,14 @@ public void setConfigurationManager(ConfigurationManager configurationManager) { this.configurationManager = configurationManager; } + + public OrganizationManager getOrganizationManager() { + + return organizationManager; + } + + public void setOrganizationManager(OrganizationManager organizationManager) { + + this.organizationManager = organizationManager; + } } diff --git a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/internal/DCRServiceComponent.java b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/internal/DCRServiceComponent.java index fedd5a94b7f..6a0b63318a1 100644 --- a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/internal/DCRServiceComponent.java +++ b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/internal/DCRServiceComponent.java @@ -42,6 +42,7 @@ import org.wso2.carbon.identity.oauth.dcr.processor.DCRProcessor; import org.wso2.carbon.identity.oauth.dcr.service.DCRMService; import org.wso2.carbon.identity.oauth2.token.bindings.TokenBinder; +import org.wso2.carbon.identity.organization.management.service.OrganizationManager; /** * OAuth DCRM service component. @@ -52,7 +53,6 @@ name = "identity.oauth.dcr", immediate = true ) -@Deprecated public class DCRServiceComponent { private static final Log log = LogFactory.getLog(DCRServiceComponent.class); @@ -254,4 +254,23 @@ protected void unregisterConfigurationManager(ConfigurationManager configuration log.debug("Unregistering the ConfigurationManager in DCR Service Component."); DCRDataHolder.getInstance().setConfigurationManager(null); } + + @Reference( + name = "organization.service", + service = OrganizationManager.class, + cardinality = ReferenceCardinality.MANDATORY, + policy = ReferencePolicy.DYNAMIC, + unbind = "unsetOrganizationManager" + ) + protected void setOrganizationManager(OrganizationManager organizationManager) { + + DCRDataHolder.getInstance().setOrganizationManager(organizationManager); + log.debug("Set the organization management service."); + } + + protected void unsetOrganizationManager(OrganizationManager organizationManager) { + + DCRDataHolder.getInstance().setOrganizationManager(null); + log.debug("Unset organization management service."); + } } diff --git a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/service/DCRMService.java b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/service/DCRMService.java index 8e2c9c147f7..e0b95d33387 100644 --- a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/service/DCRMService.java +++ b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/service/DCRMService.java @@ -64,6 +64,7 @@ import org.wso2.carbon.identity.oauth2.OAuth2Constants; import org.wso2.carbon.identity.oauth2.util.JWTSignatureValidationUtils; import org.wso2.carbon.identity.oauth2.util.OAuth2Util; +import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException; import org.wso2.carbon.user.api.UserStoreException; import java.lang.reflect.InvocationTargetException; @@ -105,12 +106,12 @@ public class DCRMService { */ public Application getApplication(String clientId) throws DCRMException { - validateRequestTenantDomain(clientId); + String tenantDomain = getTenantDomain(); + validateRequestTenantDomain(clientId, tenantDomain); OAuthConsumerAppDTO consumerAppDTO = getApplicationById( - clientId, DCRMUtils.isApplicationRolePermissionRequired()); + clientId, DCRMUtils.isApplicationRolePermissionRequired(), tenantDomain); // Get the jwksURI from the service provider. String applicationName = consumerAppDTO.getApplicationName(); - String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); ServiceProvider serviceProvider = getServiceProvider(applicationName, tenantDomain); String jwksURI = serviceProvider.getJwksUri(); if (StringUtils.isNotEmpty(jwksURI)) { @@ -156,7 +157,7 @@ public Application getApplicationByName(String clientName) throws DCRMException DCRMConstants.ErrorMessages.BAD_REQUEST_INSUFFICIENT_DATA, null); } - String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String tenantDomain = getTenantDomain(); if (!isServiceProviderExist(clientName, tenantDomain)) { throw DCRMUtils.generateClientException( DCRMConstants.ErrorMessages.NOT_FOUND_APPLICATION_WITH_NAME, clientName); @@ -203,10 +204,10 @@ public Application registerApplication(ApplicationRegistrationRequest registrati */ public void deleteApplication(String clientId) throws DCRMException { - validateRequestTenantDomain(clientId); - OAuthConsumerAppDTO appDTO = getApplicationById(clientId); + String tenantDomain = getTenantDomain(); + validateRequestTenantDomain(clientId, tenantDomain); + OAuthConsumerAppDTO appDTO = getApplicationById(clientId, tenantDomain); String applicationOwner = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); - String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); String spName; try { spName = DCRDataHolder.getInstance().getApplicationManagementService() @@ -241,9 +242,9 @@ public void deleteApplication(String clientId) throws DCRMException { */ public Application updateApplication(ApplicationUpdateRequest updateRequest, String clientId) throws DCRMException { - validateRequestTenantDomain(clientId); - OAuthConsumerAppDTO appDTO = getApplicationById(clientId); - String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String tenantDomain = getTenantDomain(); + validateRequestTenantDomain(clientId, tenantDomain); + OAuthConsumerAppDTO appDTO = getApplicationById(clientId, tenantDomain); String applicationOwner = StringUtils.isNotBlank(updateRequest.getExtApplicationOwner()) ? updateRequest.getExtApplicationOwner() : PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); @@ -426,7 +427,7 @@ public Application updateApplication(ApplicationUpdateRequest updateRequest, Str throw DCRMUtils.generateServerException( DCRMConstants.ErrorMessages.FAILED_TO_UPDATE_APPLICATION, clientId, e); } - OAuthConsumerAppDTO oAuthConsumerAppDTO = getApplicationById(clientId); + OAuthConsumerAppDTO oAuthConsumerAppDTO = getApplicationById(clientId, tenantDomain); // Setting the jwksURI to be sent in the response. oAuthConsumerAppDTO.setJwksURI(updateRequest.getJwksURI()); Application application = buildResponse(oAuthConsumerAppDTO, tenantDomain); @@ -489,12 +490,13 @@ private String getDisplayNameProperty(ServiceProvider serviceProvider) { return displayNameProperty.map(ServiceProviderProperty::getValue).orElse(null); } - private OAuthConsumerAppDTO getApplicationById(String clientId) throws DCRMException { + private OAuthConsumerAppDTO getApplicationById(String clientId, String tenantDomain) throws DCRMException { - return getApplicationById(clientId, true); + return getApplicationById(clientId, true, tenantDomain); } - private OAuthConsumerAppDTO getApplicationById(String clientId, boolean isApplicationRolePermissionRequired) + private OAuthConsumerAppDTO getApplicationById(String clientId, boolean isApplicationRolePermissionRequired, + String tenantDomain) throws DCRMException { if (StringUtils.isEmpty(clientId)) { @@ -504,7 +506,7 @@ private OAuthConsumerAppDTO getApplicationById(String clientId, boolean isApplic } try { - OAuthConsumerAppDTO dto = oAuthAdminService.getOAuthApplicationData(clientId); + OAuthConsumerAppDTO dto = oAuthAdminService.getOAuthApplicationData(clientId, tenantDomain); if (dto == null || StringUtils.isEmpty(dto.getApplicationName())) { throw DCRMUtils.generateClientException( DCRMConstants.ErrorMessages.NOT_FOUND_APPLICATION_WITH_ID, clientId); @@ -529,8 +531,7 @@ private Application createOAuthApplication(ApplicationRegistrationRequest regist String applicationOwner = StringUtils.isNotBlank(registrationRequest.getExtApplicationOwner()) ? registrationRequest.getExtApplicationOwner() : PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); - - String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String tenantDomain = getTenantDomain(); /* * ApplicationOwner will be null and a server error is thrown when creating an app, if the api authentication/ @@ -566,7 +567,7 @@ private Application createOAuthApplication(ApplicationRegistrationRequest regist } if (StringUtils.isNotEmpty(registrationRequest.getConsumerKey()) && isClientIdExist( - registrationRequest.getConsumerKey())) { + registrationRequest.getConsumerKey(), tenantDomain)) { throw DCRMUtils.generateClientException(DCRMConstants.ErrorMessages.CONFLICT_EXISTING_CLIENT_ID, registrationRequest.getConsumerKey()); } @@ -941,10 +942,10 @@ private boolean isServiceProviderExist(String serviceProviderName, String tenant * @return true if application exists with the client id. * @throws DCRMException in case of failure. */ - private boolean isClientIdExist(String clientId) throws DCRMException { + private boolean isClientIdExist(String clientId, String tenantDomain) throws DCRMException { try { - OAuthConsumerAppDTO dto = oAuthAdminService.getOAuthApplicationData(clientId); + OAuthConsumerAppDTO dto = oAuthAdminService.getOAuthApplicationData(clientId, tenantDomain); return dto != null && StringUtils.isNotBlank(dto.getApplicationName()); } catch (IdentityOAuthAdminException e) { if (e.getCause() instanceof InvalidOAuthClientException) { @@ -1144,7 +1145,7 @@ private String escapeQueryParamsIfPresent(String redirectURI) { private boolean isUserAuthorized(String clientId) throws DCRMServerException { try { - String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String tenantDomain = getTenantDomain(); String spName = DCRDataHolder.getInstance().getApplicationManagementService() .getServiceProviderNameByClientId(clientId, DCRMConstants.OAUTH2, tenantDomain); String threadLocalUserName = CarbonContext.getThreadLocalCarbonContext().getUsername(); @@ -1176,10 +1177,10 @@ private static boolean clientIdMatchesRegex(String clientId, String clientIdVali * @param clientId Consumer key of application. * @throws DCRMException DCRMException */ - private void validateRequestTenantDomain(String clientId) throws DCRMException { + private void validateRequestTenantDomain(String clientId, String tenantDomain) throws DCRMException { try { - String tenantDomainOfApp = OAuth2Util.getTenantDomainOfOauthApp(clientId); + String tenantDomainOfApp = OAuth2Util.getTenantDomainOfOauthApp(clientId, tenantDomain); OAuth2Util.validateRequestTenantDomain(tenantDomainOfApp); } catch (InvalidOAuthClientException e) { throw new DCRMClientException(DCRMConstants.ErrorMessages.TENANT_DOMAIN_MISMATCH.getErrorCode(), @@ -1275,4 +1276,21 @@ private void addSPProperties(Map spProperties, ServiceProvider s } serviceProvider.setSpProperties(serviceProviderProperties); } + + private static String getTenantDomain() throws DCRMServerException { + + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String applicationResidentOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext() + .getApplicationResidentOrganizationId(); + if (StringUtils.isNotEmpty(applicationResidentOrgId)) { + try { + tenantDomain = DCRDataHolder.getInstance().getOrganizationManager() + .resolveTenantDomain(applicationResidentOrgId); + } catch (OrganizationManagementException e) { + throw DCRMUtils.generateServerException( + DCRMConstants.ErrorMessages.FAILED_TO_RESOLVE_TENANT_DOMAIN, applicationResidentOrgId, e); + } + } + return tenantDomain; + } } diff --git a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/util/DCRMUtils.java b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/util/DCRMUtils.java index 7e2df76179e..beb611f1de1 100644 --- a/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/util/DCRMUtils.java +++ b/components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/util/DCRMUtils.java @@ -37,7 +37,6 @@ * This was deprecated as part of deprecating the legacy identity/register DCR endpoint. * The recommendation is to use /identity/oauth2/dcr/v1.1 instead. */ -@Deprecated public class DCRMUtils { private static final Log log = LogFactory.getLog(DCRMUtils.class); diff --git a/components/org.wso2.carbon.identity.oauth.dcr/src/test/java/org/wso2/carbon/identity/oauth/dcr/service/DCRMServiceTest.java b/components/org.wso2.carbon.identity.oauth.dcr/src/test/java/org/wso2/carbon/identity/oauth/dcr/service/DCRMServiceTest.java index 87c456aaf23..1678df7280b 100644 --- a/components/org.wso2.carbon.identity.oauth.dcr/src/test/java/org/wso2/carbon/identity/oauth/dcr/service/DCRMServiceTest.java +++ b/components/org.wso2.carbon.identity.oauth.dcr/src/test/java/org/wso2/carbon/identity/oauth/dcr/service/DCRMServiceTest.java @@ -199,12 +199,12 @@ public void getApplicationEmptyClientIdTest() throws DCRMException { public void getApplicationNullDTOTest(String dtoStatus) throws Exception { if (dtoStatus == null) { - when(mockOAuthAdminService.getOAuthApplicationData(dummyConsumerKey)).thenReturn(null); + when(mockOAuthAdminService.getOAuthApplicationData(dummyConsumerKey, dummyTenantDomain)).thenReturn(null); lenient().when(mockOAuthAdminService.getAllOAuthApplicationData()).thenReturn(new OAuthConsumerAppDTO[0]); } else { OAuthConsumerAppDTO dto = new OAuthConsumerAppDTO(); dto.setApplicationName(""); - when(mockOAuthAdminService.getOAuthApplicationData(dummyConsumerKey)).thenReturn(dto); + when(mockOAuthAdminService.getOAuthApplicationData(dummyConsumerKey, dummyTenantDomain)).thenReturn(dto); lenient().when(mockOAuthAdminService.getAllOAuthApplicationData()) .thenReturn(new OAuthConsumerAppDTO[]{dto}); } @@ -222,7 +222,7 @@ public void getApplicationNullDTOTest(String dtoStatus) throws Exception { public void getApplicationDTOTestWithIOAException() throws Exception { doThrow(new IdentityOAuthAdminException("")).when(mockOAuthAdminService) - .getOAuthApplicationData(dummyConsumerKey); + .getOAuthApplicationData(dummyConsumerKey, dummyTenantDomain); lenient().when(mockOAuthAdminService.getAllOAuthApplicationData()).thenReturn(new OAuthConsumerAppDTO[0]); setInternalState(dcrmService, "oAuthAdminService", mockOAuthAdminService); @@ -239,7 +239,7 @@ public void getApplicationDTOTestWithIOAException() throws Exception { public void getApplicationDTOTestWithIOCException() throws Exception { doThrow(new IdentityOAuthAdminException("", new InvalidOAuthClientException(""))).when(mockOAuthAdminService) - .getOAuthApplicationData(dummyConsumerKey); + .getOAuthApplicationData(dummyConsumerKey, dummyTenantDomain); lenient().when(mockOAuthAdminService.getAllOAuthApplicationData()).thenReturn(new OAuthConsumerAppDTO[0]); setInternalState(dcrmService, "oAuthAdminService", mockOAuthAdminService); @@ -256,7 +256,7 @@ public void getApplicationDTOTestWithIOCException() throws Exception { public void getApplicationDTOTestUserUnauthorized() throws Exception { setInternalState(dcrmService, "oAuthAdminService", mockOAuthAdminService); - when(mockOAuthAdminService.getOAuthApplicationData(dummyConsumerKey)).thenReturn(dto); + when(mockOAuthAdminService.getOAuthApplicationData(dummyConsumerKey, dummyTenantDomain)).thenReturn(dto); when(dto.getApplicationName()).thenReturn(dummyClientName); try { @@ -276,7 +276,7 @@ public void isUserAuthorizedTestWithIAMException() throws IdentityOAuthAdminExce UserStoreException, NoSuchFieldException, IllegalAccessException { setInternalState(dcrmService, "oAuthAdminService", mockOAuthAdminService); - when(mockOAuthAdminService.getOAuthApplicationData(dummyConsumerKey)).thenReturn(dto); + when(mockOAuthAdminService.getOAuthApplicationData(dummyConsumerKey, dummyTenantDomain)).thenReturn(dto); when(dto.getApplicationName()).thenReturn(dummyClientName); try { @@ -304,7 +304,7 @@ public void getApplicationDTOTest(String roleAudience) throws Exception { dto.setCallbackUrl(dummyCallbackUrl); dto.setUsername(dummyUserName.concat("@").concat(dummyTenantDomain)); - when(mockOAuthAdminService.getOAuthApplicationData(dummyConsumerKey)).thenReturn(dto); + when(mockOAuthAdminService.getOAuthApplicationData(dummyConsumerKey, dummyTenantDomain)).thenReturn(dto); setInternalState(dcrmService, "oAuthAdminService", mockOAuthAdminService); PrivilegedCarbonContext.getThreadLocalCarbonContext().setUserRealm(mockedUserRealm); when(mockedUserRealm.getUserStoreManager()).thenReturn(mockedUserStoreManager); @@ -328,7 +328,8 @@ public void getApplicationDTOTest(String roleAudience) throws Exception { public void validateRequestTenantDomainTestWitInvalidOAuthClientException() throws IdentityOAuth2Exception, InvalidOAuthClientException { - when(OAuth2Util.getTenantDomainOfOauthApp(dummyConsumerKey)).thenThrow(new InvalidOAuthClientException("")); + when(OAuth2Util.getTenantDomainOfOauthApp(dummyConsumerKey, dummyTenantDomain)). + thenThrow(new InvalidOAuthClientException("")); try { dcrmService.getApplication(dummyConsumerKey); } catch (DCRMException ex) { @@ -343,7 +344,8 @@ public void validateRequestTenantDomainTestWitInvalidOAuthClientException() public void validateRequestTenantDomainTestWitIdentityOAuth2Exception() throws IdentityOAuth2Exception, InvalidOAuthClientException { - when(OAuth2Util.getTenantDomainOfOauthApp(dummyConsumerKey)).thenThrow(new IdentityOAuth2Exception("")); + when(OAuth2Util.getTenantDomainOfOauthApp(dummyConsumerKey, dummyTenantDomain)). + thenThrow(new IdentityOAuth2Exception("")); try { dcrmService.getApplication(dummyConsumerKey); } catch (DCRMException ex) { @@ -535,7 +537,7 @@ public void registerApplicationTestWithExistClientId() throws Exception { applicationRegistrationRequest.setGrantTypes(dummyGrantTypes); applicationRegistrationRequest.setConsumerKey(dummyConsumerKey); setInternalState(dcrmService, "oAuthAdminService", mockOAuthAdminService); - when(mockOAuthAdminService.getOAuthApplicationData(dummyConsumerKey)) + when(mockOAuthAdminService.getOAuthApplicationData(dummyConsumerKey, dummyTenantDomain)) .thenReturn(dto); when(dto.getApplicationName()).thenReturn(dummyClientName); @@ -915,7 +917,8 @@ public void isClientIdExistTestWithIdentityOAuthAdminException() throws Exceptio setInternalState(dcrmService, "oAuthAdminService", mockOAuthAdminService); IdentityOAuthAdminException identityOAuthAdminException = mock(IdentityOAuthAdminException.class); - doThrow(identityOAuthAdminException).when(mockOAuthAdminService).getOAuthApplicationData(dummyConsumerKey); + doThrow(identityOAuthAdminException).when(mockOAuthAdminService).getOAuthApplicationData(dummyConsumerKey, + dummyTenantDomain); try { dcrmService.registerApplication(applicationRegistrationRequest); } catch (IdentityException ex) { @@ -974,7 +977,7 @@ private OAuthConsumerAppDTO registerApplicationTestWithFailedToUpdateSP() throws lenient().when(mockOAuthAdminService .getOAuthApplicationDataByAppName(dummyClientName)).thenReturn(oAuthConsumerApp); lenient().when(mockOAuthAdminService - .getOAuthApplicationData("dummyConsumerKey")).thenReturn(oAuthConsumerApp); + .getOAuthApplicationData("dummyConsumerKey", dummyTenantDomain)).thenReturn(oAuthConsumerApp); lenient().when(mockOAuthAdminService.getAllOAuthApplicationData()) .thenReturn(new OAuthConsumerAppDTO[]{oAuthConsumerApp}); lenient().when(mockOAuthAdminService.registerAndRetrieveOAuthApplicationData(any(OAuthConsumerAppDTO.class))). @@ -1107,7 +1110,7 @@ private OAuthConsumerAppDTO updateApplication() dto.setCallbackUrl(dummyCallbackUrl); dto.setUsername(dummyUserName.concat("@").concat(dummyTenantDomain)); - when(mockOAuthAdminService.getOAuthApplicationData(dummyConsumerKey)).thenReturn(dto); + when(mockOAuthAdminService.getOAuthApplicationData(dummyConsumerKey, dummyTenantDomain)).thenReturn(dto); setInternalState(dcrmService, "oAuthAdminService", mockOAuthAdminService); ServiceProvider serviceProvider = new ServiceProvider(); diff --git a/components/org.wso2.carbon.identity.oauth.endpoint/pom.xml b/components/org.wso2.carbon.identity.oauth.endpoint/pom.xml index b61961f2a7b..358c9b9d893 100644 --- a/components/org.wso2.carbon.identity.oauth.endpoint/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.endpoint/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth.extension/pom.xml b/components/org.wso2.carbon.identity.oauth.extension/pom.xml index b68510e65c3..d0ce9449dc7 100644 --- a/components/org.wso2.carbon.identity.oauth.extension/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.extension/pom.xml @@ -19,7 +19,7 @@ identity-inbound-auth-oauth org.wso2.carbon.identity.inbound.auth.oauth2 - 7.0.205 + 7.0.212-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth.par/pom.xml b/components/org.wso2.carbon.identity.oauth.par/pom.xml index f26dc8490c0..4e9cdb24c85 100644 --- a/components/org.wso2.carbon.identity.oauth.par/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.par/pom.xml @@ -23,7 +23,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth.scope.endpoint/pom.xml b/components/org.wso2.carbon.identity.oauth.scope.endpoint/pom.xml index 77e1995fed1..6ba0536c37e 100644 --- a/components/org.wso2.carbon.identity.oauth.scope.endpoint/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.scope.endpoint/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth.stub/pom.xml b/components/org.wso2.carbon.identity.oauth.stub/pom.xml index cd93e96fc9b..387ccc515ad 100644 --- a/components/org.wso2.carbon.identity.oauth.stub/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.stub/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth.ui/pom.xml b/components/org.wso2.carbon.identity.oauth.ui/pom.xml index 2501251adfc..df84ec27693 100644 --- a/components/org.wso2.carbon.identity.oauth.ui/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.ui/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth/pom.xml b/components/org.wso2.carbon.identity.oauth/pom.xml index 45b5c3cf9ee..e7db7e18cd2 100644 --- a/components/org.wso2.carbon.identity.oauth/pom.xml +++ b/components/org.wso2.carbon.identity.oauth/pom.xml @@ -23,7 +23,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthAdminService.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthAdminService.java index a21135cb428..369ab4f6fd8 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthAdminService.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthAdminService.java @@ -88,6 +88,24 @@ public OAuthConsumerAppDTO getOAuthApplicationData(String consumerKey) throws Id } } + /** + * Get OAuth application data by the consumer key and tenant domain. + * + * @param consumerKey Consumer Key. + * @param tenantDomain Tenant Domain. + * @return OAuthConsumerAppDTO with application information. + * @throws IdentityOAuthAdminException Error when reading application information from persistence store. + */ + public OAuthConsumerAppDTO getOAuthApplicationData(String consumerKey, String tenantDomain) + throws IdentityOAuthAdminException { + + try { + return oAuthAdminServiceImpl.getOAuthApplicationData(consumerKey, tenantDomain); + } catch (IdentityOAuthAdminException ex) { + throw handleError(ex); + } + } + /** * Get OAuth application data by the application name. * diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthAdminServiceImpl.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthAdminServiceImpl.java index 2e3c6414c72..739ee3aa55e 100755 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthAdminServiceImpl.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthAdminServiceImpl.java @@ -800,7 +800,7 @@ void updateConsumerApplication(OAuthConsumerAppDTO consumerAppDTO, boolean enabl throw handleClientError(INVALID_REQUEST, errorMessage); } - String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String tenantDomain = getAppTenantDomain(); OAuthAppDAO dao = new OAuthAppDAO(); OAuthAppDO oAuthAppDO; @@ -2391,7 +2391,7 @@ AuthenticatedUser getAppOwner(OAuthConsumerAppDTO application, try { // Since the app owner sent in OAuthConsumerAppDTO is a valid one we set the appOwner to be // the one sent in the OAuthConsumerAppDTO. - String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String tenantDomain = getAppTenantDomain(); Optional maybeAppOwner = OAuthUtil.getUser(tenantDomain, tenantAwareAppOwnerInRequest); if (maybeAppOwner.isPresent()) { appOwner = new AuthenticatedUser(maybeAppOwner.get()); @@ -2925,4 +2925,21 @@ private boolean isAccessTokenClaimsSeparationEnabledForApp(String consumerKey, S return OAuth2Util.isAppVersionAllowed(serviceProvider.getApplicationVersion(), ApplicationConstants.ApplicationVersion.APP_VERSION_V2); } + + private static String getAppTenantDomain() throws IdentityOAuthAdminException { + + String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String applicationResidentOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext() + .getApplicationResidentOrganizationId(); + if (StringUtils.isNotEmpty(applicationResidentOrgId)) { + try { + tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager() + .resolveTenantDomain(applicationResidentOrgId); + } catch (OrganizationManagementException e) { + throw handleError("Error while resolving tenant domain from the organization id: " + + applicationResidentOrgId, e); + } + } + return tenantDomain; + } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthUtil.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthUtil.java index c1da1ab35f0..6cee8c9a1eb 100755 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthUtil.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/OAuthUtil.java @@ -31,9 +31,10 @@ 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.IdentityProvider; +import org.wso2.carbon.identity.application.common.model.InboundAuthenticationRequestConfig; import org.wso2.carbon.identity.application.common.model.ServiceProvider; import org.wso2.carbon.identity.application.common.model.User; -import org.wso2.carbon.identity.application.mgt.ApplicationConstants; +import org.wso2.carbon.identity.application.mgt.ApplicationConstants.StandardInboundProtocols; import org.wso2.carbon.identity.application.mgt.ApplicationManagementService; import org.wso2.carbon.identity.base.IdentityConstants; import org.wso2.carbon.identity.central.log.mgt.utils.LoggerUtils; @@ -67,8 +68,7 @@ import org.wso2.carbon.identity.role.v2.mgt.core.RoleConstants; import org.wso2.carbon.identity.role.v2.mgt.core.RoleManagementService; import org.wso2.carbon.identity.role.v2.mgt.core.exception.IdentityRoleManagementException; -import org.wso2.carbon.identity.role.v2.mgt.core.model.AssociatedApplication; -import org.wso2.carbon.identity.role.v2.mgt.core.model.Role; +import org.wso2.carbon.identity.role.v2.mgt.core.model.RoleBasicInfo; import org.wso2.carbon.idp.mgt.IdentityProviderManagementException; import org.wso2.carbon.user.api.Tenant; import org.wso2.carbon.user.api.UserRealm; @@ -88,7 +88,6 @@ import java.util.Optional; import java.util.Set; import java.util.UUID; -import java.util.stream.Collectors; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; @@ -718,7 +717,7 @@ private static AuthenticatedUser buildAuthenticatedUser(UserStoreManager userSto AuthenticatedUser authenticatedUser = new AuthenticatedUser(); authenticatedUser.setUserStoreDomain(userStoreDomain); authenticatedUser.setTenantDomain(tenantDomain); - authenticatedUser.setUserName(username); + authenticatedUser.setUserName(UserCoreUtil.removeDomainFromName(username)); boolean isOrganization; try { isOrganization = OrganizationManagementUtil.isOrganization(tenantDomain); @@ -781,51 +780,43 @@ private static AuthenticatedUser buildAuthenticatedUser(UserStoreManager userSto /** * Get clientIds of associated application of an application role. - * @param role Role object. + * + * @param role Role basic info object. * @param authenticatedUser Authenticated user. * @return Set of clientIds of associated applications. */ - private static Set getClientIdsOfAssociatedApplications(Role role, AuthenticatedUser authenticatedUser) + private static Optional getClientIdOfAssociatedApplication(RoleBasicInfo role, + AuthenticatedUser authenticatedUser) throws UserStoreException { ApplicationManagementService applicationManagementService = OAuthComponentServiceHolder.getInstance().getApplicationManagementService(); - List associatedApplications = role.getAssociatedApplications().stream() - .map(AssociatedApplication::getId).collect(Collectors.toList()); + String associatedApplication = role.getAudienceId(); try { if (authenticatedUser.getUserResidentOrganization() != null) { - List newAssociatedApplications = new ArrayList<>(); - for (String app : associatedApplications) { - newAssociatedApplications.add( - SharedAppResolveDAO.getMainApplication(app, authenticatedUser.getAccessingOrganization())); - } - associatedApplications = newAssociatedApplications; + associatedApplication = SharedAppResolveDAO.getMainApplication( + associatedApplication, authenticatedUser.getAccessingOrganization()); } } catch (IdentityOAuth2Exception e) { throw new UserStoreException("Error occurred while getting the main applications of the shared apps.", e); } - Set clientIds = new HashSet<>(); - associatedApplications.forEach(associatedApplication -> { - try { - ServiceProvider application = applicationManagementService - .getApplicationByResourceId(associatedApplication, authenticatedUser.getTenantDomain()); - if (application == null || application.getInboundAuthenticationConfig() == null) { - return; - } - Arrays.stream(application.getInboundAuthenticationConfig().getInboundAuthenticationRequestConfigs()) - .forEach(inboundAuthenticationRequestConfig -> { - if (ApplicationConstants.StandardInboundProtocols.OAUTH2.equals( - inboundAuthenticationRequestConfig.getInboundAuthType())) { - clientIds.add(inboundAuthenticationRequestConfig.getInboundAuthKey()); - } - }); - } catch (IdentityApplicationManagementException e) { - String errorMessage = "Error occurred while retrieving application of id : " + - associatedApplication; - LOG.error(errorMessage); + try { + ServiceProvider application = applicationManagementService + .getApplicationByResourceId(associatedApplication, authenticatedUser.getTenantDomain()); + if (application != null && application.getInboundAuthenticationConfig() != null) { + InboundAuthenticationRequestConfig[] inboundAuthenticationRequestConfigs = + application.getInboundAuthenticationConfig().getInboundAuthenticationRequestConfigs(); + return Arrays.stream(inboundAuthenticationRequestConfigs) + .filter(config -> StandardInboundProtocols.OAUTH2.equals(config.getInboundAuthType())) + .map(InboundAuthenticationRequestConfig::getInboundAuthKey) + .findFirst(); } - }); - return clientIds; + } catch (IdentityApplicationManagementException e) { + String errorMessage = "Error occurred while retrieving application of id : " + + associatedApplication; + LOG.error(errorMessage); + } + return Optional.empty(); } private static Set filterClientIdsWithOrganizationAudience(List clientIds, String tenantDomain) { @@ -855,14 +846,14 @@ private static Set filterClientIdsWithOrganizationAudience(List * @param tenantDomain Tenant domain. * @return Role. */ - private static Role getRole(String roleId, String tenantDomain) throws UserStoreException { + private static RoleBasicInfo getRoleBasicInfo(String roleId, String tenantDomain) throws UserStoreException { try { RoleManagementService roleV2ManagementService = OAuthComponentServiceHolder.getInstance().getRoleV2ManagementService(); - return roleV2ManagementService.getRole(roleId, tenantDomain); + return roleV2ManagementService.getRoleBasicInfoById(roleId, tenantDomain); } catch (IdentityRoleManagementException e) { - String errorMessage = "Error occurred while retrieving role of id : " + roleId; + String errorMessage = "Error occurred while retrieving basic role info of id : " + roleId; throw new UserStoreException(errorMessage, e); } } @@ -1017,18 +1008,19 @@ public static boolean revokeTokens(String username, UserStoreManager userStoreMa } // Get details about the role to identify the audience and associated applications. - Set clientIds = null; - Role role = null; + Set clientIds = new HashSet<>();; + RoleBasicInfo role = null; boolean getClientIdsFromUser = false; if (roleId != null) { - role = getRole(roleId, IdentityTenantUtil.getTenantDomain(userStoreManager.getTenantId())); + role = getRoleBasicInfo(roleId, tenantDomain); if (role != null && RoleConstants.APPLICATION.equals(role.getAudience())) { // Get clientIds of associated applications for the specific application role. if (LOG.isDebugEnabled()) { LOG.debug("Get clientIds of associated applications for the application role: " + role.getName()); } - clientIds = getClientIdsOfAssociatedApplications(role, authenticatedUser); + getClientIdOfAssociatedApplication(role, authenticatedUser) + .ifPresent(clientIds::add); } else { // Get all the distinct client Ids authorized by this user since this is an organization role. if (LOG.isDebugEnabled()) { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/dao/OAuthAppDAO.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/dao/OAuthAppDAO.java index 30a2b40d2d0..43656059ba3 100755 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/dao/OAuthAppDAO.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/dao/OAuthAppDAO.java @@ -157,6 +157,16 @@ public void addOAuthApplication(OAuthAppDO consumerAppDO) throws IdentityOAuthAd AuthenticatedUser appOwner = consumerAppDO.getAppOwner(); String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String appOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getApplicationResidentOrganizationId(); + if (StringUtils.isNotEmpty(appOrgId)) { + try { + tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager() + .resolveTenantDomain(appOrgId); + } catch (OrganizationManagementException e) { + throw handleError("Error occurred while resolving tenant domain for organization id: " + + appOrgId, e); + } + } int spTenantId = IdentityTenantUtil.getTenantId(tenantDomain); String userStoreDomain = appOwner.getUserStoreDomain(); if (!isDuplicateApplication(appOwner.getUserName(), spTenantId, userStoreDomain, consumerAppDO)) { @@ -687,6 +697,18 @@ public OAuthAppDO getAppInformationByAppName(String appName, int tenantID) OAuthAppDO oauthApp; try (Connection connection = IdentityDatabaseUtil.getDBConnection(false)) { + String appOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext() + .getApplicationResidentOrganizationId(); + if (StringUtils.isNotEmpty(appOrgId)) { + try { + String tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager() + .resolveTenantDomain(appOrgId); + tenantID = IdentityTenantUtil.getTenantId(tenantDomain); + } catch (OrganizationManagementException e) { + throw new IdentityOAuth2Exception("Error occurred while resolving tenant domain for " + + "organization id: " + appOrgId, e); + } + } String sqlQuery = SQLQueries.OAuthAppDAOSQLQueries.GET_APP_INFO_BY_APP_NAME_WITH_PKCE; try (PreparedStatement prepStmt = connection.prepareStatement(sqlQuery)) { @@ -878,6 +900,18 @@ private void setValuesToStatementWithPKCEAndOwnerUpdate(OAuthAppDO oauthAppDO, P prepStmt.setString(11, oauthAppDO.getAppOwner().getUserStoreDomain()); prepStmt.setString(12, persistenceProcessor.getProcessedClientId(oauthAppDO.getOauthConsumerKey())); prepStmt.setInt(13, IdentityTenantUtil.getLoginTenantId()); + String appOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext() + .getApplicationResidentOrganizationId(); + if (StringUtils.isNotEmpty(appOrgId)) { + try { + String tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager() + .resolveTenantDomain(appOrgId); + prepStmt.setInt(13, IdentityTenantUtil.getTenantId(tenantDomain)); + } catch (OrganizationManagementException e) { + throw new IdentityOAuth2Exception("Error occurred while resolving tenant domain for " + + "organization id: " + appOrgId, e); + } + } } private void setValuesToStatementWithPKCENoOwnerUpdate(OAuthAppDO oauthAppDO, PreparedStatement prepStmt) diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/listener/IdentityOauthEventHandler.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/listener/IdentityOauthEventHandler.java index f563449abd3..a9f31ca9f2a 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/listener/IdentityOauthEventHandler.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth/listener/IdentityOauthEventHandler.java @@ -490,23 +490,24 @@ private void terminateSession(List userIDList, String roleId, String ten throws IdentityEventException { try { - int tenantId = IdentityTenantUtil.getTenantId(tenantDomain); - UserStoreManager userStoreManager = getUserStoreManager(tenantId); - - String userName; if (CollectionUtils.isNotEmpty(userIDList)) { + int tenantId = IdentityTenantUtil.getTenantId(tenantDomain); + UserStoreManager userStoreManager = getUserStoreManager(tenantId); + for (String userId : userIDList) { try { - userName = FrameworkUtils.resolveUserNameFromUserId(userStoreManager, userId); + String userName = FrameworkUtils.resolveUserNameFromUserId(userStoreManager, userId); if (userName == null) { log.warn("User name is null for user id: " + userId + ". Hence skipping " + "token revocation and session termination processes."); continue; } + UserStoreManager userStoreManagerOfUser = getUserStoreManagerOfUser( + userStoreManager, userName); OAuth2ServiceComponentHolder.getInstance() .getRevocationProcessor() - .revokeTokens(userName, userStoreManager, roleId); - OAuthUtil.removeUserClaimsFromCache(userName, userStoreManager); + .revokeTokens(userName, userStoreManagerOfUser, roleId); + OAuthUtil.removeUserClaimsFromCache(userName, userStoreManagerOfUser); } catch (UserSessionException e) { String errorMsg = "Error occurred while revoking access token for user Id: " + userId; log.error(errorMsg, e); @@ -520,4 +521,22 @@ private void terminateSession(List userIDList, String roleId, String ten throw new IdentityEventException(errorMsg, e); } } + + /** + * Get the user store manager of the user. + * + * @param userStoreManager User store manager. + * @param userName Username of the user. + * @return User store manager of the user. + */ + private UserStoreManager getUserStoreManagerOfUser(UserStoreManager userStoreManager, String userName) { + + String userStoreDomainOfUser = IdentityUtil.extractDomainFromName(userName); + UserStoreManager secondaryUserStoreManager = userStoreManager.getSecondaryUserStoreManager( + userStoreDomainOfUser); + if (secondaryUserStoreManager == null) { + return userStoreManager; + } + return secondaryUserStoreManager; + } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/dao/OldTokensCleanDAO.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/dao/OldTokensCleanDAO.java index 719d932b758..3560806df09 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/dao/OldTokensCleanDAO.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/dao/OldTokensCleanDAO.java @@ -18,11 +18,13 @@ package org.wso2.carbon.identity.oauth2.dao; +import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration; import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder; import org.wso2.carbon.identity.oauth2.model.OldAccessTokenDO; +import org.wso2.carbon.identity.oauth2.token.bindings.TokenBinding; import java.sql.Connection; import java.sql.PreparedStatement; @@ -31,6 +33,8 @@ import java.sql.Timestamp; import java.util.List; +import static org.wso2.carbon.identity.oauth.common.OAuthConstants.TokenBindings.NONE; + /** * This is DAO class for cleaning old Tokens. When new tokens is generated ,refreshed or revoked old access token * will be moved to Audit table and deleted from the Access token table. Token cleaning process can be enable or @@ -98,8 +102,22 @@ public void cleanupTokenByTokenValue(String token, Connection connection) throws oldAccessTokenObject.setSubjectIdentifier(resultSet.getString(17)); oldAccessTokenObject.setAccessTokenHash(resultSet.getString(18)); oldAccessTokenObject.setRefreshTokenHash(resultSet.getString(19)); + String tokenBindingRef = resultSet.getString(20); + if (StringUtils.isNotBlank(tokenBindingRef)) { + TokenBinding tokenBinding = new TokenBinding(); + tokenBinding.setBindingReference(tokenBindingRef); + oldAccessTokenObject.setTokenBinding(tokenBinding); + } + + String isConsentedToken = resultSet.getString(21); + if (StringUtils.isNotEmpty(isConsentedToken)) { + oldAccessTokenObject.setIsConsentedToken(Boolean.parseBoolean(isConsentedToken)); + } + + oldAccessTokenObject.setAuthorizedOrganizationId(resultSet.getString(22)); + if (OAuth2ServiceComponentHolder.isIDPIdColumnEnabled()) { - oldAccessTokenObject.setIdpId(resultSet.getInt(20)); + oldAccessTokenObject.setIdpId(resultSet.getInt(23)); } } if (OAuthServerConfiguration.getInstance().useRetainOldAccessTokens()) { @@ -138,8 +156,16 @@ private void saveTokenInAuditTable(OldAccessTokenDO oldAccessTokenDAO, Connectio insertintoaudittable.setString(18, oldAccessTokenDAO.getAccessTokenHash()); insertintoaudittable.setString(19, oldAccessTokenDAO.getRefreshTokenHash()); insertintoaudittable.setTimestamp(20, new Timestamp(System.currentTimeMillis())); + if (oldAccessTokenDAO.getTokenBinding() != null && StringUtils + .isNotBlank(oldAccessTokenDAO.getTokenBinding().getBindingReference())) { + insertintoaudittable.setString(21, oldAccessTokenDAO.getTokenBinding().getBindingReference()); + } else { + insertintoaudittable.setString(21, NONE); + } + insertintoaudittable.setString(22, Boolean.toString(oldAccessTokenDAO.isConsentedToken())); + insertintoaudittable.setString(23, oldAccessTokenDAO.getAuthorizedOrganizationId()); if (OAuth2ServiceComponentHolder.isIDPIdColumnEnabled()) { - insertintoaudittable.setInt(21, oldAccessTokenDAO.getIdpId()); + insertintoaudittable.setInt(24, oldAccessTokenDAO.getIdpId()); } insertintoaudittable.execute(); if (log.isDebugEnabled()) { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/dao/SQLQueries.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/dao/SQLQueries.java index 8abccfe10fd..c03994c6947 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/dao/SQLQueries.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/dao/SQLQueries.java @@ -878,13 +878,15 @@ public class SQLQueries { public static final String RETRIEVE_OLD_TOKEN_BY_TOKEN_HASH = "SELECT TOKEN_ID, ACCESS_TOKEN, REFRESH_TOKEN, " + "CONSUMER_KEY_ID, AUTHZ_USER, TENANT_ID, USER_DOMAIN, USER_TYPE, GRANT_TYPE, TIME_CREATED, " + "REFRESH_TOKEN_TIME_CREATED, VALIDITY_PERIOD, REFRESH_TOKEN_VALIDITY_PERIOD, TOKEN_SCOPE_HASH, " + - "TOKEN_STATE, TOKEN_STATE_ID, SUBJECT_IDENTIFIER, ACCESS_TOKEN_HASH, REFRESH_TOKEN_HASH " + + "TOKEN_STATE, TOKEN_STATE_ID, SUBJECT_IDENTIFIER, ACCESS_TOKEN_HASH, REFRESH_TOKEN_HASH, " + + "TOKEN_BINDING_REF, CONSENTED_TOKEN, AUTHORIZED_ORGANIZATION " + "FROM IDN_OAUTH2_ACCESS_TOKEN WHERE ACCESS_TOKEN_HASH = ?"; public static final String RETRIEVE_OLD_TOKEN_BY_TOKEN_HASH_WITH_IDP_NAME = "SELECT TOKEN_ID, ACCESS_TOKEN, " + "REFRESH_TOKEN, CONSUMER_KEY_ID, AUTHZ_USER, TENANT_ID, USER_DOMAIN, USER_TYPE, GRANT_TYPE, TIME_CREATED," + " REFRESH_TOKEN_TIME_CREATED, VALIDITY_PERIOD, REFRESH_TOKEN_VALIDITY_PERIOD, TOKEN_SCOPE_HASH, " + - "TOKEN_STATE, TOKEN_STATE_ID, SUBJECT_IDENTIFIER, ACCESS_TOKEN_HASH, REFRESH_TOKEN_HASH, IDP_ID FROM " + + "TOKEN_STATE, TOKEN_STATE_ID, SUBJECT_IDENTIFIER, ACCESS_TOKEN_HASH, REFRESH_TOKEN_HASH, " + + "TOKEN_BINDING_REF, CONSENTED_TOKEN, AUTHORIZED_ORGANIZATION, IDP_ID FROM " + "IDN_OAUTH2_ACCESS_TOKEN WHERE ACCESS_TOKEN_HASH = ?"; public static final String INSERT_OAUTH2_ACCESS_TOKEN = "INSERT INTO IDN_OAUTH2_ACCESS_TOKEN (ACCESS_TOKEN, " + @@ -932,33 +934,39 @@ public class SQLQueries { "(TOKEN_ID, ACCESS_TOKEN, REFRESH_TOKEN, CONSUMER_KEY_ID, AUTHZ_USER, TENANT_ID, USER_DOMAIN, USER_TYPE, " + "GRANT_TYPE, TIME_CREATED, REFRESH_TOKEN_TIME_CREATED, VALIDITY_PERIOD, REFRESH_TOKEN_VALIDITY_PERIOD, " + "TOKEN_SCOPE_HASH, TOKEN_STATE, TOKEN_STATE_ID, SUBJECT_IDENTIFIER, ACCESS_TOKEN_HASH, " + - "REFRESH_TOKEN_HASH, INVALIDATED_TIME) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + "REFRESH_TOKEN_HASH, INVALIDATED_TIME, TOKEN_BINDING_REF, CONSENTED_TOKEN, AUTHORIZED_ORGANIZATION) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; public static final String STORE_OLD_TOKEN_IN_AUDIT_WITH_IDP_NAME = "INSERT INTO IDN_OAUTH2_ACCESS_TOKEN_AUDIT " + "(TOKEN_ID, ACCESS_TOKEN, REFRESH_TOKEN, CONSUMER_KEY_ID, AUTHZ_USER, TENANT_ID, USER_DOMAIN, USER_TYPE, " + "GRANT_TYPE, TIME_CREATED, REFRESH_TOKEN_TIME_CREATED, VALIDITY_PERIOD, REFRESH_TOKEN_VALIDITY_PERIOD, " + "TOKEN_SCOPE_HASH, TOKEN_STATE, TOKEN_STATE_ID, SUBJECT_IDENTIFIER, ACCESS_TOKEN_HASH, " + - "REFRESH_TOKEN_HASH, INVALIDATED_TIME, IDP_ID) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + "REFRESH_TOKEN_HASH, INVALIDATED_TIME, TOKEN_BINDING_REF, CONSENTED_TOKEN, AUTHORIZED_ORGANIZATION, " + + "IDP_ID) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; public static final String RETRIEVE_AND_STORE_IN_AUDIT = "INSERT INTO IDN_OAUTH2_ACCESS_TOKEN_AUDIT (TOKEN_ID, ACCESS_TOKEN, REFRESH_TOKEN, CONSUMER_KEY_ID, " + "AUTHZ_USER, TENANT_ID, USER_DOMAIN, USER_TYPE, GRANT_TYPE, TIME_CREATED, " + "REFRESH_TOKEN_TIME_CREATED, VALIDITY_PERIOD, REFRESH_TOKEN_VALIDITY_PERIOD, " + "TOKEN_SCOPE_HASH, TOKEN_STATE, TOKEN_STATE_ID, SUBJECT_IDENTIFIER, ACCESS_TOKEN_HASH, " + - "REFRESH_TOKEN_HASH, INVALIDATED_TIME) SELECT TOKEN_ID, ACCESS_TOKEN, REFRESH_TOKEN, " + + "REFRESH_TOKEN_HASH, INVALIDATED_TIME, TOKEN_BINDING_REF, CONSENTED_TOKEN, " + + "AUTHORIZED_ORGANIZATION) SELECT TOKEN_ID, ACCESS_TOKEN, REFRESH_TOKEN, " + "CONSUMER_KEY_ID, AUTHZ_USER, TENANT_ID, USER_DOMAIN, USER_TYPE, GRANT_TYPE, TIME_CREATED, " + "REFRESH_TOKEN_TIME_CREATED, VALIDITY_PERIOD, REFRESH_TOKEN_VALIDITY_PERIOD, TOKEN_SCOPE_HASH, " + - "TOKEN_STATE, TOKEN_STATE_ID, SUBJECT_IDENTIFIER, ACCESS_TOKEN_HASH, REFRESH_TOKEN_HASH, ? " + + "TOKEN_STATE, TOKEN_STATE_ID, SUBJECT_IDENTIFIER, ACCESS_TOKEN_HASH, REFRESH_TOKEN_HASH, ?, " + + "TOKEN_BINDING_REF, CONSENTED_TOKEN, AUTHORIZED_ORGANIZATION " + "FROM IDN_OAUTH2_ACCESS_TOKEN WHERE TOKEN_ID = ?"; public static final String RETRIEVE_AND_STORE_IN_AUDIT_WITH_IDP_NAME = "INSERT INTO IDN_OAUTH2_ACCESS_TOKEN_AUDIT" + " (TOKEN_ID, ACCESS_TOKEN, REFRESH_TOKEN, CONSUMER_KEY_ID, AUTHZ_USER, TENANT_ID, USER_DOMAIN, USER_TYPE," + " GRANT_TYPE, TIME_CREATED, REFRESH_TOKEN_TIME_CREATED, VALIDITY_PERIOD, REFRESH_TOKEN_VALIDITY_PERIOD, " + "TOKEN_SCOPE_HASH, TOKEN_STATE, TOKEN_STATE_ID, SUBJECT_IDENTIFIER, ACCESS_TOKEN_HASH, " + - "REFRESH_TOKEN_HASH, INVALIDATED_TIME, IDP_ID) SELECT TOKEN_ID, ACCESS_TOKEN, REFRESH_TOKEN, " + + "REFRESH_TOKEN_HASH, INVALIDATED_TIME, IDP_ID, TOKEN_BINDING_REF, CONSENTED_TOKEN, " + + "AUTHORIZED_ORGANIZATION) SELECT TOKEN_ID, ACCESS_TOKEN, REFRESH_TOKEN, " + "CONSUMER_KEY_ID, AUTHZ_USER, TENANT_ID, USER_DOMAIN, USER_TYPE, GRANT_TYPE, TIME_CREATED, " + "REFRESH_TOKEN_TIME_CREATED, VALIDITY_PERIOD, REFRESH_TOKEN_VALIDITY_PERIOD, TOKEN_SCOPE_HASH, " + - "TOKEN_STATE, TOKEN_STATE_ID, SUBJECT_IDENTIFIER, ACCESS_TOKEN_HASH, REFRESH_TOKEN_HASH, ?, IDP_ID " + + "TOKEN_STATE, TOKEN_STATE_ID, SUBJECT_IDENTIFIER, ACCESS_TOKEN_HASH, REFRESH_TOKEN_HASH, ?, IDP_ID, " + + "TOKEN_BINDING_REF, CONSENTED_TOKEN, AUTHORIZED_ORGANIZATION " + "FROM IDN_OAUTH2_ACCESS_TOKEN WHERE TOKEN_ID = ?"; public static final String DELETE_OLD_TOKEN_BY_ID = "DELETE FROM IDN_OAUTH2_ACCESS_TOKEN WHERE TOKEN_ID = ?"; diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java index 08982d55aa5..6503a0cd59c 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/OAuth2Util.java @@ -2441,7 +2441,8 @@ public static OauthTokenIssuer getOAuthTokenIssuerForOAuthApp(String clientId) OAuthAppDO appDO; try { - appDO = getAppInformationByClientId(clientId); + String tenantDomain = getTenantDomain(); + appDO = getAppInformationByClientId(clientId, tenantDomain); } catch (IdentityOAuth2Exception e) { throw new IdentityOAuth2Exception("Error while retrieving app information for clientId: " + clientId, e); } @@ -2619,6 +2620,32 @@ public static String getTenantDomainOfOauthApp(String clientId) return getTenantDomainOfOauthApp(oAuthAppDO); } + /** + * This is used to get the tenant domain of an application by clientId. Internally it uses the tenant present in + * the carbon context. + * + * @param clientId Consumer key of Application. + * @return Tenant Domain. + * @throws IdentityOAuth2Exception Error while retrieving the application. + * @throws InvalidOAuthClientException If an application not found for the given client ID. + */ + public static String getTenantDomainOfOauthApp(String clientId, String tenantDomain) + throws IdentityOAuth2Exception, InvalidOAuthClientException { + + String appOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getApplicationResidentOrganizationId(); + if (StringUtils.isNotEmpty(appOrgId)) { + try { + tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager() + .resolveTenantDomain(appOrgId); + } catch (OrganizationManagementException e) { + throw new IdentityOAuth2Exception("Error while resolving tenant domain for the organization ID: " + + appOrgId, e); + } + } + OAuthAppDO oAuthAppDO = getAppInformationByClientId(clientId, tenantDomain); + return getTenantDomainOfOauthApp(oAuthAppDO); + } + /** * Get all the OAuth applications for the client ID. * @@ -3864,9 +3891,9 @@ public static ServiceProvider getServiceProvider(String clientId, public static ServiceProvider getServiceProvider(String clientId) throws IdentityOAuth2Exception { ApplicationManagementService applicationMgtService = OAuth2ServiceComponentHolder.getApplicationMgtService(); - String tenantDomain = null; + String tenantDomain = IdentityTenantUtil.getTenantDomain(IdentityTenantUtil.getLoginTenantId()); try { - tenantDomain = getTenantDomainOfOauthApp(clientId); + tenantDomain = getTenantDomainOfOauthApp(clientId, tenantDomain); // Get the Service Provider. return applicationMgtService.getServiceProviderByClientId( clientId, IdentityApplicationConstants.OAuth2.NAME, tenantDomain); @@ -4338,7 +4365,8 @@ public static String getIdTokenIssuer(String tenantDomain) throws IdentityOAuth2 public static String getIdTokenIssuer(String tenantDomain, boolean isMtlsRequest) throws IdentityOAuth2Exception { - if (IdentityTenantUtil.isTenantQualifiedUrlsEnabled()) { + if (IdentityTenantUtil.isTenantQualifiedUrlsEnabled() && StringUtils.isEmpty(PrivilegedCarbonContext. + getThreadLocalCarbonContext().getApplicationResidentOrganizationId())) { try { return isMtlsRequest ? OAuthURL.getOAuth2MTLSTokenEPUrl() : ServiceURLBuilder.create().addPath(OAUTH2_TOKEN_EP_URL).build().getAbsolutePublicURL(); @@ -4979,7 +5007,18 @@ public static void validateRequestTenantDomain(String tenantDomainOfApp) throws if (IdentityTenantUtil.isTenantQualifiedUrlsEnabled()) { - String tenantDomainFromContext = IdentityTenantUtil.resolveTenantDomain(); + String tenantDomainFromContext = getTenantDomain(); + String appOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext(). + getApplicationResidentOrganizationId(); + if (StringUtils.isNotBlank(appOrgId)) { + try { + tenantDomainFromContext = OAuthComponentServiceHolder.getInstance().getOrganizationManager() + .resolveTenantDomain(appOrgId); + } catch (OrganizationManagementException e) { + throw new InvalidOAuthClientException("Error while resolving tenant domain from organization id: " + + appOrgId, e); + } + } if (!StringUtils.equals(tenantDomainFromContext, tenantDomainOfApp)) { // This means the tenant domain sent in the request and app's tenant domain do not match. if (log.isDebugEnabled()) { @@ -5326,7 +5365,7 @@ public static boolean isFapiConformantApp(String clientId) if (!Boolean.parseBoolean(IdentityUtil.getProperty(OAuthConstants.ENABLE_FAPI))) { return false; } - String tenantDomain = IdentityTenantUtil.resolveTenantDomain(); + String tenantDomain = getTenantDomain(); OAuthAppDO oAuthAppDO = OAuth2Util.getAppInformationByClientId(clientId, tenantDomain); return oAuthAppDO.isFapiConformanceEnabled(); } @@ -5662,4 +5701,21 @@ public static boolean isAppVersionAllowed(String appVersion, String allowedAppVe } return true; } + + private static String getTenantDomain() throws InvalidOAuthClientException { + + String tenantDomain = IdentityTenantUtil.resolveTenantDomain(); + String applicationResidentOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext() + .getApplicationResidentOrganizationId(); + if (StringUtils.isNotEmpty(applicationResidentOrgId)) { + try { + tenantDomain = OAuthComponentServiceHolder.getInstance().getOrganizationManager() + .resolveTenantDomain(applicationResidentOrgId); + } catch (OrganizationManagementException e) { + throw new InvalidOAuthClientException("Error while resolving tenant domain from the organization " + + "id: ", e); + } + } + return tenantDomain; + } } diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/OAuthUtilTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/OAuthUtilTest.java index 1d7b5da5ec5..f6e982060af 100644 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/OAuthUtilTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/OAuthUtilTest.java @@ -1,7 +1,7 @@ /* - * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2017-2025, WSO2 LLC. (http://www.wso2.com). * - * WSO2 Inc. licenses this file to you under the Apache License, + * 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 @@ -11,7 +11,7 @@ * 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 + * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ @@ -19,15 +19,50 @@ package org.wso2.carbon.identity.oauth; import org.apache.commons.lang.StringUtils; +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.DataProvider; import org.testng.annotations.Test; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.application.common.model.InboundAuthenticationConfig; +import org.wso2.carbon.identity.application.common.model.InboundAuthenticationRequestConfig; +import org.wso2.carbon.identity.application.common.model.ServiceProvider; import org.wso2.carbon.identity.application.common.model.User; +import org.wso2.carbon.identity.application.mgt.ApplicationConstants; +import org.wso2.carbon.identity.application.mgt.ApplicationManagementService; import org.wso2.carbon.identity.common.testng.WithCarbonHome; import org.wso2.carbon.identity.common.testng.WithRealmService; import org.wso2.carbon.identity.oauth.cache.CacheEntry; import org.wso2.carbon.identity.oauth.cache.OAuthCache; import org.wso2.carbon.identity.oauth.cache.OAuthCacheKey; - +import org.wso2.carbon.identity.oauth.internal.OAuthComponentServiceHolder; +import org.wso2.carbon.identity.oauth2.dao.AccessTokenDAO; +import org.wso2.carbon.identity.oauth2.dao.OAuthTokenPersistenceFactory; +import org.wso2.carbon.identity.oauth2.model.AccessTokenDO; +import org.wso2.carbon.identity.oauth2.util.OAuth2Util; +import org.wso2.carbon.identity.organization.management.service.util.OrganizationManagementUtil; +import org.wso2.carbon.identity.role.v2.mgt.core.RoleConstants; +import org.wso2.carbon.identity.role.v2.mgt.core.RoleManagementService; +import org.wso2.carbon.identity.role.v2.mgt.core.model.RoleBasicInfo; +import org.wso2.carbon.user.api.RealmConfiguration; +import org.wso2.carbon.user.core.UserStoreManager; +import org.wso2.carbon.utils.multitenancy.MultitenantConstants; + +import java.util.HashSet; +import java.util.Set; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.nullable; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; @@ -40,6 +75,37 @@ @WithCarbonHome @WithRealmService public class OAuthUtilTest { + + @Mock + RoleManagementService roleManagementService; + @Mock + ApplicationManagementService applicationManagementService; + + private AutoCloseable closeable; + private MockedStatic organizationManagementUtil; + private MockedStatic oAuthComponentServiceHolder; + private MockedStatic oAuth2Util; + private MockedStatic oAuthTokenPersistenceFactory; + + @BeforeMethod + public void setUp() throws Exception { + + organizationManagementUtil = mockStatic(OrganizationManagementUtil.class); + oAuthComponentServiceHolder = mockStatic(OAuthComponentServiceHolder.class); + oAuth2Util = mockStatic(OAuth2Util.class); + oAuthTokenPersistenceFactory = mockStatic(OAuthTokenPersistenceFactory.class); + closeable = MockitoAnnotations.openMocks(this); + } + + @AfterMethod + public void tearDown() throws Exception { + + organizationManagementUtil.close(); + oAuthComponentServiceHolder.close(); + oAuth2Util.close(); + oAuthTokenPersistenceFactory.close(); + closeable.close(); + } @DataProvider(name = "testGetAuthenticatedUser") public Object[][] fullQualifiedUserName() { @@ -160,6 +226,71 @@ public void testGetAuthenticatedUserException() throws Exception { OAuthUtil.getAuthenticatedUser(""); } + @Test + public void testRevokeTokensForApplicationAudienceRoles() throws Exception { + + String username = "testUser"; + String roleId = "testRoleId"; + String roleName = "testRole"; + String appId = "testAppId"; + String clientId = "testClientId"; + String accessToken = "testAccessToken"; + + UserStoreManager userStoreManager = mock(UserStoreManager.class); + when(userStoreManager.getTenantId()).thenReturn(-1234); + when(userStoreManager.getRealmConfiguration()).thenReturn(mock(RealmConfiguration.class)); + when(userStoreManager.getRealmConfiguration().getUserStoreProperty(anyString())).thenReturn("PRIMARY"); + + when(OrganizationManagementUtil.isOrganization(anyString())).thenReturn(false); + when(OAuth2Util.getTenantId(anyString())).thenReturn(-1234); + + OAuthComponentServiceHolder mockOAuthComponentServiceHolder = mock(OAuthComponentServiceHolder.class); + when(OAuthComponentServiceHolder.getInstance()).thenReturn(mockOAuthComponentServiceHolder); + + when(mockOAuthComponentServiceHolder.getRoleV2ManagementService()).thenReturn(roleManagementService); + RoleBasicInfo roleBasicInfo = new RoleBasicInfo(); + roleBasicInfo.setId(roleId); + roleBasicInfo.setAudience(RoleConstants.APPLICATION); + roleBasicInfo.setAudienceId(appId); + roleBasicInfo.setName(roleName); + when(roleManagementService.getRoleBasicInfoById(roleId, MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) + .thenReturn(roleBasicInfo); + + when(mockOAuthComponentServiceHolder.getApplicationManagementService()) + .thenReturn(applicationManagementService); + ServiceProvider serviceProvider = new ServiceProvider(); + InboundAuthenticationConfig inboundAuthenticationConfig = new InboundAuthenticationConfig(); + InboundAuthenticationRequestConfig[] inboundAuthenticationRequestConfigs = + new InboundAuthenticationRequestConfig[1]; + InboundAuthenticationRequestConfig inboundAuthenticationRequestConfig = + new InboundAuthenticationRequestConfig(); + inboundAuthenticationRequestConfig.setInboundAuthKey(clientId); + inboundAuthenticationRequestConfig.setInboundAuthType(ApplicationConstants.StandardInboundProtocols.OAUTH2); + inboundAuthenticationRequestConfigs[0] = inboundAuthenticationRequestConfig; + inboundAuthenticationConfig.setInboundAuthenticationRequestConfigs(inboundAuthenticationRequestConfigs); + serviceProvider.setInboundAuthenticationConfig(inboundAuthenticationConfig); + when(applicationManagementService.getApplicationByResourceId( + appId, MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)).thenReturn(serviceProvider); + + OAuthTokenPersistenceFactory mockOAuthTokenPersistenceFactory = mock(OAuthTokenPersistenceFactory.class); + when(OAuthTokenPersistenceFactory.getInstance()).thenReturn(mockOAuthTokenPersistenceFactory); + AccessTokenDAO mockAccessTokenDAO = mock(AccessTokenDAO.class); + when(mockOAuthTokenPersistenceFactory.getAccessTokenDAO()).thenReturn(mockAccessTokenDAO); + Set accessTokens = new HashSet<>(); + AccessTokenDO accessTokenDO = new AccessTokenDO(); + accessTokenDO.setAccessToken(accessToken); + accessTokenDO.setConsumerKey(clientId); + accessTokenDO.setScope(new String[]{"default"}); + accessTokenDO.setAuthzUser(new AuthenticatedUser()); + accessTokens.add(accessTokenDO); + when(mockAccessTokenDAO.getAccessTokens(anyString(), + any(AuthenticatedUser.class), nullable(String.class), anyBoolean())).thenReturn(accessTokens); + + boolean result = OAuthUtil.revokeTokens(username, userStoreManager, roleId); + verify(mockAccessTokenDAO, times(1)).revokeAccessTokens(any(), anyBoolean()); + assertTrue(result, "Token revocation failed."); + } + private OAuthCache getOAuthCache(OAuthCacheKey oAuthCacheKey) { diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/dao/OAuthAppDAOTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/dao/OAuthAppDAOTest.java index c85de96151a..43313c7c55e 100644 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/dao/OAuthAppDAOTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth/dao/OAuthAppDAOTest.java @@ -20,6 +20,7 @@ import org.apache.commons.lang.StringUtils; import org.mockito.Mock; import org.mockito.MockedStatic; +import org.mockito.Mockito; import org.testng.annotations.AfterClass; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeClass; @@ -41,6 +42,8 @@ import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; import org.wso2.carbon.identity.oauth2.model.AccessTokenDO; import org.wso2.carbon.identity.oauth2.test.utils.CommonTestUtils; +import org.wso2.carbon.identity.organization.management.service.OrganizationManager; +import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException; import org.wso2.carbon.user.api.Tenant; import org.wso2.carbon.user.api.UserRealm; import org.wso2.carbon.user.core.common.AbstractUserStoreManager; @@ -85,6 +88,7 @@ public class OAuthAppDAOTest extends TestOAuthDAOBase { private static final String USER_STORE_DOMAIN = "USER_STORE_DOMAIN_NAME"; private static final String TENANT_DOMAIN = "TENANT_DOMAIN"; private static final String TENANT_DOMAIN_2 = "TENANT_DOMAIN_2"; + private static final String TENANT_DOMAIN_2_ORG_ID = "1234-1234"; private static final String CONSUMER_KEY = "ca19a540f544777860e44e75f605d927"; private static final String CONSUMER_SECRET = "87n9a540f544777860e44e75f605d435"; private static final String APP_NAME = "myApp"; @@ -137,6 +141,9 @@ public class OAuthAppDAOTest extends TestOAuthDAOBase { @Mock OAuthComponentServiceHolder mockOAuthComponentServiceHolder; + @Mock + OrganizationManager mockOrganizationManager; + @BeforeClass public void setUp() throws Exception { initMocks(this); @@ -173,6 +180,34 @@ public void testAddOAuthApplication() throws Exception { } } + @Test + public void testAddOAuthApplicationWithAppResidentOrgId() throws Exception { + + try (MockedStatic oAuthServerConfiguration = mockStatic( + OAuthServerConfiguration.class); + MockedStatic identityTenantUtil = mockStatic(IdentityTenantUtil.class); + MockedStatic identityUtil = mockStatic(IdentityUtil.class); + MockedStatic identityDatabaseUtil = mockStatic(IdentityDatabaseUtil.class); + MockedStatic oAuthComponentServiceHolder = + mockStatic(OAuthComponentServiceHolder.class)) { + setupMocksForTest(oAuthServerConfiguration, identityTenantUtil, identityUtil); + // Set the application resident organization id + PrivilegedCarbonContext.getThreadLocalCarbonContext(). + setApplicationResidentOrganizationId(TENANT_DOMAIN_2_ORG_ID); + oAuthComponentServiceHolder.when(OAuthComponentServiceHolder::getInstance) + .thenReturn(mockOAuthComponentServiceHolder); + when(mockOAuthComponentServiceHolder.getOrganizationManager()).thenReturn(mockOrganizationManager); + when(mockOrganizationManager.resolveTenantDomain(TENANT_DOMAIN_2_ORG_ID)).thenReturn(TENANT_DOMAIN_2); + OAuthAppDO appDO = getDefaultOAuthAppDO(); + try (Connection connection = getConnection(DB_NAME)) { + mockIdentityUtilDataBaseConnection(connection, identityDatabaseUtil); + addOAuthApplication(appDO, TENANT_ID_2); + } + } finally { + resetPrivilegedCarbonContext(); + } + } + /** * Add an OAuth app. This method will be reused in other tests where an OAuth app is required to be present * before the actual test can take place. @@ -290,6 +325,35 @@ public void testAddOAuthApplicationWithExceptions() throws Exception { } } + @Test(expectedExceptions = IdentityOAuthAdminException.class) + public void testAddOAuthApplicationWithAppResidentOrgIdAndWithExceptions() throws Exception { + + try (MockedStatic oAuthServerConfiguration = mockStatic( + OAuthServerConfiguration.class); + MockedStatic identityTenantUtil = mockStatic(IdentityTenantUtil.class); + MockedStatic identityUtil = mockStatic(IdentityUtil.class); + MockedStatic identityDatabaseUtil = mockStatic(IdentityDatabaseUtil.class); + MockedStatic oAuthComponentServiceHolder = + mockStatic(OAuthComponentServiceHolder.class)) { + setupMocksForTest(oAuthServerConfiguration, identityTenantUtil, identityUtil); + PrivilegedCarbonContext.getThreadLocalCarbonContext(). + setApplicationResidentOrganizationId(TENANT_DOMAIN_2_ORG_ID); + oAuthComponentServiceHolder.when(OAuthComponentServiceHolder::getInstance) + .thenReturn(mockOAuthComponentServiceHolder); + when(mockOAuthComponentServiceHolder.getOrganizationManager()).thenReturn(mockOrganizationManager); + when(mockOrganizationManager.resolveTenantDomain(TENANT_DOMAIN_2_ORG_ID)). + thenThrow(new OrganizationManagementException("Error while resolving tenant domain.")); + OAuthAppDO appDO = getDefaultOAuthAppDO(); + try (Connection connection = getConnection(DB_NAME)) { + mockIdentityUtilDataBaseConnection(connection, identityDatabaseUtil); + new OAuthAppDAO().addOAuthApplication(appDO); + } + } finally { + resetPrivilegedCarbonContext(); + Mockito.reset(mockOrganizationManager); + } + } + @Test public void testAddOAuthConsumer() throws Exception { @@ -1004,6 +1068,41 @@ public void testGetAppInformationByAppName() throws Exception { } } + @Test + public void testGetAppInformationByAppNameWithAppResidentOrgId() throws Exception { + + try (MockedStatic oAuthServerConfiguration = mockStatic( + OAuthServerConfiguration.class); + MockedStatic identityTenantUtil = mockStatic(IdentityTenantUtil.class); + MockedStatic identityUtil = mockStatic(IdentityUtil.class); + MockedStatic identityDatabaseUtil = mockStatic(IdentityDatabaseUtil.class); + MockedStatic oAuthComponentServiceHolder = + mockStatic(OAuthComponentServiceHolder.class)) { + setupMocksForTest(oAuthServerConfiguration, identityTenantUtil, identityUtil); + try (Connection connection = getConnection(DB_NAME)) { + mockIdentityUtilDataBaseConnection(connection, identityDatabaseUtil); + // Set the application resident organization id + PrivilegedCarbonContext.getThreadLocalCarbonContext(). + setApplicationResidentOrganizationId(TENANT_DOMAIN_2_ORG_ID); + oAuthComponentServiceHolder.when(OAuthComponentServiceHolder::getInstance) + .thenReturn(mockOAuthComponentServiceHolder); + when(mockOAuthComponentServiceHolder.getOrganizationManager()).thenReturn(mockOrganizationManager); + when(mockOrganizationManager.resolveTenantDomain(TENANT_DOMAIN_2_ORG_ID)).thenReturn(TENANT_DOMAIN_2); + + OAuthAppDO oAuthAppDO = getDefaultOAuthAppDO(); + new OAuthAppDAO().addOAuthApplication(oAuthAppDO); + + OAuthAppDO actualAppDO = new OAuthAppDAO().getAppInformationByAppName(APP_NAME, TENANT_ID); + assertNotNull(actualAppDO); + assertEquals(actualAppDO.getApplicationName(), APP_NAME); + assertEquals(actualAppDO.getOauthConsumerKey(), CONSUMER_KEY); + assertEquals(actualAppDO.getOauthConsumerSecret(), CONSUMER_SECRET); + } + } finally { + resetPrivilegedCarbonContext(); + } + } + @Test(expectedExceptions = IdentityOAuth2Exception.class) public void testGetAppInformationByAppNameWithExceptions() throws Exception { @@ -1030,6 +1129,41 @@ public void testGetAppInformationByAppNameWithExceptions() throws Exception { } } + @Test(expectedExceptions = IdentityOAuth2Exception.class) + public void testGetAppInformationByAppNameWithAppResidentOrgIdAndWithException() throws Exception { + + try (MockedStatic oAuthServerConfiguration = mockStatic( + OAuthServerConfiguration.class); + MockedStatic identityTenantUtil = mockStatic(IdentityTenantUtil.class); + MockedStatic identityUtil = mockStatic(IdentityUtil.class); + MockedStatic identityDatabaseUtil = mockStatic(IdentityDatabaseUtil.class); + MockedStatic oAuthComponentServiceHolder = + mockStatic(OAuthComponentServiceHolder.class)) { + setupMocksForTest(oAuthServerConfiguration, identityTenantUtil, identityUtil); + // Set the application resident organization id + PrivilegedCarbonContext.getThreadLocalCarbonContext(). + setApplicationResidentOrganizationId(TENANT_DOMAIN_2_ORG_ID); + oAuthComponentServiceHolder.when(OAuthComponentServiceHolder::getInstance) + .thenReturn(mockOAuthComponentServiceHolder); + when(mockOAuthComponentServiceHolder.getOrganizationManager()).thenReturn(mockOrganizationManager); + when(mockOrganizationManager.resolveTenantDomain(TENANT_DOMAIN_2_ORG_ID)).thenReturn(TENANT_DOMAIN_2); + try (Connection connection = getConnection(DB_NAME)) { + + mockIdentityUtilDataBaseConnection(connection, identityDatabaseUtil); + OAuthAppDO oAuthAppDO = getDefaultOAuthAppDO(); + OAuthAppDAO appDAO = new OAuthAppDAO(); + appDAO.addOAuthApplication(oAuthAppDO); + + when(mockOrganizationManager.resolveTenantDomain(TENANT_DOMAIN_2_ORG_ID)).thenThrow( + new OrganizationManagementException("Error while resolving tenant domain.")); + appDAO.getAppInformationByAppName(APP_NAME, TENANT_ID); + } + } finally { + resetPrivilegedCarbonContext(); + Mockito.reset(mockOrganizationManager); + } + } + private OAuthAppDO getDefaultOAuthAppDO() { AuthenticatedUser authenticatedUser = new AuthenticatedUser(); authenticatedUser.setUserName(USER_NAME); diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManagerTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManagerTest.java index d2612c2abb5..79895798fb3 100644 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManagerTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/authz/AuthorizationHandlerManagerTest.java @@ -16,6 +16,7 @@ package org.wso2.carbon.identity.oauth2.authz; import org.apache.oltu.oauth2.common.error.OAuthError; +import org.mockito.MockedStatic; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; @@ -37,11 +38,13 @@ import org.wso2.carbon.identity.oauth2.dto.OAuth2AuthorizeReqDTO; import org.wso2.carbon.identity.oauth2.dto.OAuth2AuthorizeRespDTO; import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder; +import org.wso2.carbon.identity.oauth2.util.AuthzUtil; import org.wso2.carbon.identity.testutil.IdentityBaseTest; import org.wso2.carbon.user.api.UserStoreException; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.when; @WithCarbonHome @@ -56,6 +59,7 @@ public class AuthorizationHandlerManagerTest extends IdentityBaseTest { private AuthorizationHandlerManager authorizationHandlerManager; private OAuth2AuthorizeReqDTO authzReqDTO = new OAuth2AuthorizeReqDTO(); private ServiceProvider serviceProvider; + private MockedStatic mockedAuthzUtil; @BeforeClass public void setUp() throws Exception { @@ -70,12 +74,16 @@ public void setUp() throws Exception { when(applicationManagementService.getServiceProviderByClientId(anyString(), anyString(), anyString())) .thenReturn(serviceProvider); authorizationHandlerManager = AuthorizationHandlerManager.getInstance(); + mockedAuthzUtil = mockStatic(AuthzUtil.class); + mockedAuthzUtil.when(AuthzUtil::isLegacyAuthzRuntime).thenReturn(false); } @AfterClass public void tearDown() { CentralLogMgtServiceComponentHolder.getInstance().setIdentityEventService(null); + mockedAuthzUtil.close(); + } @BeforeMethod diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/authz/handlers/CodeResponseTypeHandlerTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/authz/handlers/CodeResponseTypeHandlerTest.java index 2765c5ad189..5f09858950d 100644 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/authz/handlers/CodeResponseTypeHandlerTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/authz/handlers/CodeResponseTypeHandlerTest.java @@ -18,6 +18,8 @@ package org.wso2.carbon.identity.oauth2.authz.handlers; +import org.mockito.MockedStatic; +import org.mockito.Mockito; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; @@ -41,8 +43,10 @@ import org.wso2.carbon.identity.oauth2.dto.OAuth2AuthorizeReqDTO; import org.wso2.carbon.identity.oauth2.dto.OAuth2AuthorizeRespDTO; import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder; +import org.wso2.carbon.identity.oauth2.util.AuthzUtil; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; /** * Test class covering CodeResponseTypeHandler @@ -62,6 +66,7 @@ public class CodeResponseTypeHandlerTest { OAuthAuthzReqMessageContext authAuthzReqMessageContext; OAuth2AuthorizeReqDTO authorizationReqDTO; + private MockedStatic mockedAuthzUtil; @BeforeClass public void init() throws IdentityOAuthAdminException { @@ -69,6 +74,9 @@ public void init() throws IdentityOAuthAdminException { IdentityEventService identityEventService = mock(IdentityEventService.class); CentralLogMgtServiceComponentHolder.getInstance().setIdentityEventService(identityEventService); new OAuthAppDAO().addOAuthApplication(getDefaultOAuthAppDO()); + Mockito.clearAllCaches(); + mockedAuthzUtil = mockStatic(AuthzUtil.class); + mockedAuthzUtil.when(AuthzUtil::isLegacyAuthzRuntime).thenReturn(false); } @AfterClass @@ -76,6 +84,7 @@ public void clear() throws IdentityOAuthAdminException { CentralLogMgtServiceComponentHolder.getInstance().setIdentityEventService(null); new OAuthAppDAO().removeConsumerApplication(TEST_CONSUMER_KEY); + mockedAuthzUtil.close(); } @BeforeMethod diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/authz/handlers/TokenResponseTypeHandlerTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/authz/handlers/TokenResponseTypeHandlerTest.java index 40cabbd9e50..6f4e3ee3bea 100644 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/authz/handlers/TokenResponseTypeHandlerTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/authz/handlers/TokenResponseTypeHandlerTest.java @@ -18,6 +18,7 @@ package org.wso2.carbon.identity.oauth2.authz.handlers; +import org.mockito.MockedStatic; import org.mockito.Mockito; import org.testng.Assert; import org.testng.annotations.BeforeTest; @@ -27,6 +28,7 @@ import org.wso2.carbon.identity.common.testng.WithCarbonHome; import org.wso2.carbon.identity.common.testng.WithH2Database; import org.wso2.carbon.identity.common.testng.WithRealmService; +import org.wso2.carbon.identity.oauth.cache.AppInfoCache; import org.wso2.carbon.identity.oauth.common.OAuthConstants; import org.wso2.carbon.identity.oauth.dao.OAuthAppDAO; import org.wso2.carbon.identity.oauth.dao.OAuthAppDO; @@ -38,14 +40,21 @@ import org.wso2.carbon.identity.oauth2.dto.OAuth2AuthorizeRespDTO; import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder; import org.wso2.carbon.identity.oauth2.model.AccessTokenDO; +import org.wso2.carbon.identity.oauth2.util.AuthzUtil; import org.wso2.carbon.identity.test.common.testng.utils.MockAuthenticatedUser; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; + /** * Unit test covering TokenResponseTypeHandler class */ @WithCarbonHome @WithRealmService(injectToSingletons = OAuthComponentServiceHolder.class) -@WithH2Database(files = { "dbScripts/identity.sql" }) +@WithH2Database(files = { "dbScripts/identity.sql", "dbScripts/insert_local_idp.sql" }) public class TokenResponseTypeHandlerTest { private static final String TEST_CLIENT_ID_1 = "SDSDSDS23131231"; @@ -57,6 +66,7 @@ public class TokenResponseTypeHandlerTest { public void setUp() throws Exception { OAuthEventInterceptor interceptor = Mockito.mock(OAuthEventInterceptor.class); OAuthComponentServiceHolder.getInstance().addOauthEventInterceptorProxy(interceptor); + Mockito.clearAllCaches(); } /** @@ -105,10 +115,19 @@ public void testIssue(boolean isIDPIdColumnEnabled, String clientId) throws Exce new OAuthAppDAO().addOAuthApplication(oAuthAppDO); - OAuth2AuthorizeRespDTO auth2AuthorizeReqDTO = tokenResponseTypeHandler. - issue(authAuthzReqMessageContext); - Assert.assertNotNull(auth2AuthorizeReqDTO.getAccessToken()); - Assert.assertTrue(auth2AuthorizeReqDTO.getValidityPeriod() > 1, - "Access Token should be valid, i.e. not expired."); + try (MockedStatic appInfoCache = mockStatic(AppInfoCache.class); + MockedStatic mockedAuthzUtil = mockStatic(AuthzUtil.class)) { + + mockedAuthzUtil.when(AuthzUtil::isLegacyAuthzRuntime).thenReturn(false); + AppInfoCache mockAppInfoCache = mock(AppInfoCache.class); + appInfoCache.when(AppInfoCache::getInstance).thenReturn(mockAppInfoCache); + doNothing().when(mockAppInfoCache).addToCache(anyString(), any(OAuthAppDO.class)); + + OAuth2AuthorizeRespDTO auth2AuthorizeReqDTO = tokenResponseTypeHandler. + issue(authAuthzReqMessageContext); + Assert.assertNotNull(auth2AuthorizeReqDTO.getAccessToken()); + Assert.assertTrue(auth2AuthorizeReqDTO.getValidityPeriod() > 1, + "Access Token should be valid, i.e. not expired."); + } } } diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandlerTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandlerTest.java index 7661ddf35fa..b23e74675a9 100644 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandlerTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/token/handlers/grant/AbstractAuthorizationGrantHandlerTest.java @@ -20,6 +20,7 @@ import org.mockito.Mock; import org.mockito.MockedStatic; +import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; @@ -59,6 +60,7 @@ import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext; import org.wso2.carbon.identity.oauth2.token.OauthTokenIssuer; import org.wso2.carbon.identity.oauth2.token.bindings.TokenBinding; +import org.wso2.carbon.identity.oauth2.util.AuthzUtil; import org.wso2.carbon.identity.oauth2.util.OAuth2Util; import org.wso2.carbon.identity.oauth2.validators.OAuth2ScopeHandler; @@ -104,6 +106,7 @@ public class AbstractAuthorizationGrantHandlerTest { "org.wso2.carbon.identity.oauth.callback.DefaultCallbackHandler"; private static final String PASSWORD_GRANT = "password"; private OAuthAppDO oAuthAppDO; + private MockedStatic mockedAuthzUtil; @BeforeMethod public void setUp() throws IdentityOAuth2Exception, IdentityOAuthAdminException, ActionExecutionException { @@ -144,12 +147,16 @@ public void setUpMocks() { IdentityEventService identityEventService = mock(IdentityEventService.class); CentralLogMgtServiceComponentHolder.getInstance().setIdentityEventService(identityEventService); + Mockito.clearAllCaches(); + mockedAuthzUtil = mockStatic(AuthzUtil.class); + mockedAuthzUtil.when(AuthzUtil::isLegacyAuthzRuntime).thenReturn(false); } @AfterClass public void tearDown() { CentralLogMgtServiceComponentHolder.getInstance().setIdentityEventService(null); + mockedAuthzUtil.close(); } @Test(dataProvider = "IssueWithRenewDataProvider", expectedExceptions = IdentityOAuth2Exception.class) diff --git a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/util/OAuth2UtilTest.java b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/util/OAuth2UtilTest.java index 16b1a61d69c..7f05221ccf6 100644 --- a/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/util/OAuth2UtilTest.java +++ b/components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/util/OAuth2UtilTest.java @@ -2232,12 +2232,13 @@ public void testGetOAuthTokenIssuerForOAuthApp(String tokenType) throws Exceptio appDO.setTokenType(tokenType); AppInfoCache mockAppInfoCache = mock(AppInfoCache.class); - when(mockAppInfoCache.getValueFromCache(clientId)).thenReturn(appDO); + when(mockAppInfoCache.getValueFromCache(clientId, clientTenantDomain)).thenReturn(appDO); appInfoCache.when(AppInfoCache::getInstance).thenReturn(mockAppInfoCache); OauthTokenIssuer oauthTokenIssuer = mock(OauthTokenIssuer.class); when(oauthServerConfigurationMock.getIdentityOauthTokenIssuer()).thenReturn(oauthTokenIssuer); + identityTenantUtil.when(IdentityTenantUtil::resolveTenantDomain).thenReturn(clientTenantDomain); assertEquals(OAuth2Util.getOAuthTokenIssuerForOAuthApp(clientId), oauthTokenIssuer); } } @@ -2247,11 +2248,12 @@ public void testGetOAuthTokenIssuerForOAuthAppWithException() { try (MockedStatic appInfoCache = mockStatic(AppInfoCache.class)) { AppInfoCache mockAppInfoCache = mock(AppInfoCache.class); - when(mockAppInfoCache.getValueFromCache(clientId)). + when(mockAppInfoCache.getValueFromCache(clientId, clientTenantDomain)). thenAnswer(i -> { throw new IdentityOAuth2Exception("IdentityOAuth2Exception"); }); appInfoCache.when(AppInfoCache::getInstance).thenReturn(mockAppInfoCache); + identityTenantUtil.when(IdentityTenantUtil::resolveTenantDomain).thenReturn(clientTenantDomain); try { OAuth2Util.getOAuthTokenIssuerForOAuthApp(clientId); @@ -2603,7 +2605,7 @@ private void setCache(MockedStatic appInfoCache) { appDO.setUser(user); AppInfoCache mockAppInfoCache = mock(AppInfoCache.class); - lenient().when(mockAppInfoCache.getValueFromCache(clientId)).thenReturn(appDO); + lenient().when(mockAppInfoCache.getValueFromCache(clientId, SUPER_TENANT_DOMAIN_NAME)).thenReturn(appDO); appInfoCache.when(AppInfoCache::getInstance).thenReturn(mockAppInfoCache); } @@ -2612,7 +2614,7 @@ public void testGetServiceProviderWithIdentityInvalidOAuthClientException() { try (MockedStatic appInfoCache = mockStatic(AppInfoCache.class)) { AppInfoCache mockAppInfoCache = mock(AppInfoCache.class); - when(mockAppInfoCache.getValueFromCache(clientId)). + when(mockAppInfoCache.getValueFromCache(clientId, SUPER_TENANT_DOMAIN_NAME)). thenAnswer(i -> { throw new InvalidOAuthClientException("InvalidOAuthClientException"); }); diff --git a/components/org.wso2.carbon.identity.oidc.dcr/pom.xml b/components/org.wso2.carbon.identity.oidc.dcr/pom.xml index 0fc55ea445d..51a862b37db 100644 --- a/components/org.wso2.carbon.identity.oidc.dcr/pom.xml +++ b/components/org.wso2.carbon.identity.oidc.dcr/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.oidc.session/pom.xml b/components/org.wso2.carbon.identity.oidc.session/pom.xml index 979a3027375..5f19b3641e6 100644 --- a/components/org.wso2.carbon.identity.oidc.session/pom.xml +++ b/components/org.wso2.carbon.identity.oidc.session/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/components/org.wso2.carbon.identity.webfinger/pom.xml b/components/org.wso2.carbon.identity.webfinger/pom.xml index c09786b5851..3e3426c3c51 100644 --- a/components/org.wso2.carbon.identity.webfinger/pom.xml +++ b/components/org.wso2.carbon.identity.webfinger/pom.xml @@ -21,7 +21,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/features/org.wso2.carbon.identity.oauth.common.feature/pom.xml b/features/org.wso2.carbon.identity.oauth.common.feature/pom.xml index 066e11d8fa0..06132a5de2d 100644 --- a/features/org.wso2.carbon.identity.oauth.common.feature/pom.xml +++ b/features/org.wso2.carbon.identity.oauth.common.feature/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/features/org.wso2.carbon.identity.oauth.dcr.server.feature/pom.xml b/features/org.wso2.carbon.identity.oauth.dcr.server.feature/pom.xml index 819521be3e5..f92a5df35b8 100644 --- a/features/org.wso2.carbon.identity.oauth.dcr.server.feature/pom.xml +++ b/features/org.wso2.carbon.identity.oauth.dcr.server.feature/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/features/org.wso2.carbon.identity.oauth.feature/pom.xml b/features/org.wso2.carbon.identity.oauth.feature/pom.xml index a182e57a339..c915000ed8c 100644 --- a/features/org.wso2.carbon.identity.oauth.feature/pom.xml +++ b/features/org.wso2.carbon.identity.oauth.feature/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/features/org.wso2.carbon.identity.oauth.server.feature/pom.xml b/features/org.wso2.carbon.identity.oauth.server.feature/pom.xml index f8f9c1320f0..e19261486b1 100644 --- a/features/org.wso2.carbon.identity.oauth.server.feature/pom.xml +++ b/features/org.wso2.carbon.identity.oauth.server.feature/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/features/org.wso2.carbon.identity.oauth.ui.feature/pom.xml b/features/org.wso2.carbon.identity.oauth.ui.feature/pom.xml index 5bc706abde9..299ec97c984 100644 --- a/features/org.wso2.carbon.identity.oauth.ui.feature/pom.xml +++ b/features/org.wso2.carbon.identity.oauth.ui.feature/pom.xml @@ -22,7 +22,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index b8d9ea5dce8..5e4ada5feca 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ 4.0.0 org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth - 7.0.205 + 7.0.212-SNAPSHOT pom WSO2 Carbon OAuth module http://wso2.org @@ -37,7 +37,7 @@ https://github.com/wso2-extensions/identity-inbound-auth-oauth.git scm:git:https://github.com/wso2-extensions/identity-inbound-auth-oauth.git scm:git:https://github.com/wso2-extensions/identity-inbound-auth-oauth.git - v7.0.205 + HEAD @@ -938,7 +938,7 @@ 1.2.4 - 4.10.22 + 4.10.26 4.10.22 [4.10.22, 5.0.0) [1.0.1, 2.0.0) diff --git a/service-stubs/org.wso2.carbon.claim.metadata.mgt.stub/pom.xml b/service-stubs/org.wso2.carbon.claim.metadata.mgt.stub/pom.xml index 46d809387f8..b895c35f129 100644 --- a/service-stubs/org.wso2.carbon.claim.metadata.mgt.stub/pom.xml +++ b/service-stubs/org.wso2.carbon.claim.metadata.mgt.stub/pom.xml @@ -21,7 +21,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth - 7.0.205 + 7.0.212-SNAPSHOT ../../pom.xml diff --git a/test-utils/org.wso2.carbon.identity.oauth.common.testng/pom.xml b/test-utils/org.wso2.carbon.identity.oauth.common.testng/pom.xml index 1688c691be5..b81791ddbab 100644 --- a/test-utils/org.wso2.carbon.identity.oauth.common.testng/pom.xml +++ b/test-utils/org.wso2.carbon.identity.oauth.common.testng/pom.xml @@ -23,7 +23,7 @@ org.wso2.carbon.identity.inbound.auth.oauth2 identity-inbound-auth-oauth ../../pom.xml - 7.0.205 + 7.0.212-SNAPSHOT 4.0.0