From 9cd9f88e4f42ebf8f0aa4cb11726d6749ecf014e Mon Sep 17 00:00:00 2001 From: Thamindu Aluthwala Date: Sun, 15 Oct 2023 11:30:10 +0530 Subject: [PATCH] Restrict API resource creation for organizations --- .../pom.xml | 15 +++++ .../resource/mgt/APIResourceManagerImpl.java | 25 +++++++- .../APIResourceManagementConstants.java | 2 + ...APIResourceManagementServiceComponent.java | 43 ++++++++++++++ ...ourceManagementServiceComponentHolder.java | 59 +++++++++++++++++++ .../resource/mgt/APIResourceManagerTest.java | 3 +- ...uthorizedAPIManagementServiceImplTest.java | 3 +- pom.xml | 2 +- 8 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/internal/APIResourceManagementServiceComponentHolder.java diff --git a/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/pom.xml b/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/pom.xml index b204d428112d..6647cc0f84b0 100644 --- a/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/pom.xml +++ b/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/pom.xml @@ -39,6 +39,14 @@ org.apache.felix org.apache.felix.scr.ds-annotations + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.core + + + org.wso2.carbon.identity.organization.management.core + org.wso2.carbon.identity.organization.management.service + org.jacoco @@ -121,6 +129,13 @@ org.wso2.carbon.user.api; version="${carbon.user.api.imp.pkg.version.range}", org.wso2.carbon.user.core.util; version="${carbon.kernel.package.import.version.range}", org.wso2.carbon.utils; version="${carbon.kernel.package.import.version.range}", + org.wso2.carbon.user.core.tenant;version="${carbon.kernel.package.import.version.range}", + org.wso2.carbon.identity.organization.management.service; + version="${org.wso2.carbon.identity.organization.management.core.version.range}", + org.wso2.carbon.identity.organization.management.service.exception; + version="${org.wso2.carbon.identity.organization.management.core.version.range}", + org.wso2.carbon.user.core.service; + version="${carbon.kernel.package.import.version.range}", diff --git a/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/APIResourceManagerImpl.java b/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/APIResourceManagerImpl.java index fb13f8796f2e..359f16f7a8e6 100644 --- a/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/APIResourceManagerImpl.java +++ b/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/APIResourceManagerImpl.java @@ -22,6 +22,7 @@ import org.wso2.carbon.identity.api.resource.mgt.constant.APIResourceManagementConstants; import org.wso2.carbon.identity.api.resource.mgt.dao.impl.APIResourceManagementDAOImpl; import org.wso2.carbon.identity.api.resource.mgt.dao.impl.CacheBackedAPIResourceMgtDAO; +import org.wso2.carbon.identity.api.resource.mgt.internal.APIResourceManagementServiceComponentHolder; import org.wso2.carbon.identity.api.resource.mgt.model.APIResourceSearchResult; import org.wso2.carbon.identity.api.resource.mgt.util.APIResourceManagementUtil; import org.wso2.carbon.identity.application.common.model.APIResource; @@ -32,6 +33,9 @@ import org.wso2.carbon.identity.core.model.Node; import org.wso2.carbon.identity.core.model.OperationNode; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; +import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException; +import org.wso2.carbon.user.api.Tenant; +import org.wso2.carbon.user.api.UserStoreException; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -82,7 +86,26 @@ public APIResource getAPIResourceById(String apiResourceId, String tenantDomain) public APIResource addAPIResource(APIResource apiResource, String tenantDomain) throws APIResourceMgtException { - return CACHE_BACKED_DAO.addAPIResource(apiResource, IdentityTenantUtil.getTenantId(tenantDomain)); + try { + // Check whether the tenant is a root organization. If not, throw a client error. + Tenant tenant = APIResourceManagementServiceComponentHolder.getInstance() + .getRealmService().getTenantManager().getTenant(IdentityTenantUtil.getTenantId(tenantDomain)); + if (StringUtils.isNotBlank(tenant.getAssociatedOrganizationUUID())) { + String organizationId = APIResourceManagementServiceComponentHolder.getInstance() + .getOrganizationManager().resolveOrganizationId(tenantDomain); + if (StringUtils.isNotBlank(organizationId)) { + if (!APIResourceManagementServiceComponentHolder.getInstance().getOrganizationManager() + .isPrimaryOrganization(organizationId)) { + throw APIResourceManagementUtil.handleClientException( + APIResourceManagementConstants.ErrorMessages.ERROR_CODE_CREATION_RESTRICTED); + } + } + } + return CACHE_BACKED_DAO.addAPIResource(apiResource, IdentityTenantUtil.getTenantId(tenantDomain)); + } catch (OrganizationManagementException | UserStoreException e) { + throw APIResourceManagementUtil.handleServerException( + APIResourceManagementConstants.ErrorMessages.ERROR_CODE_ERROR_WHILE_ADDING_API_RESOURCE, e); + } } @Override diff --git a/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/constant/APIResourceManagementConstants.java b/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/constant/APIResourceManagementConstants.java index 25b2f84bcc8a..2ce94151b4fe 100644 --- a/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/constant/APIResourceManagementConstants.java +++ b/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/constant/APIResourceManagementConstants.java @@ -74,6 +74,8 @@ public enum ErrorMessages { "Scope already exists for the tenant: %s."), ERROR_CODE_INVALID_FILTER_VALUE("60005", "Unable to retrieve API resources.", "Invalid filter value used for filtering."), + ERROR_CODE_CREATION_RESTRICTED("60006", "API resource creation restricted for organizations.", + "API resources cannot be created in organizations."), // Server errors. ERROR_CODE_ERROR_WHILE_RETRIEVING_API_RESOURCES("65001", "Error while retrieving API resources.", diff --git a/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/internal/APIResourceManagementServiceComponent.java b/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/internal/APIResourceManagementServiceComponent.java index 39128850b270..e547212023d9 100644 --- a/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/internal/APIResourceManagementServiceComponent.java +++ b/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/internal/APIResourceManagementServiceComponent.java @@ -25,8 +25,13 @@ import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; import org.wso2.carbon.identity.api.resource.mgt.APIResourceManager; import org.wso2.carbon.identity.api.resource.mgt.APIResourceManagerImpl; +import org.wso2.carbon.identity.organization.management.service.OrganizationManager; +import org.wso2.carbon.user.core.service.RealmService; /** * Service component for the API resource management. @@ -62,4 +67,42 @@ protected void deactivate(ComponentContext context) { LOG.error("Error while deactivating API resource management component.", e); } } + + @Reference( + name = "organization.service", + service = OrganizationManager.class, + cardinality = ReferenceCardinality.MANDATORY, + policy = ReferencePolicy.DYNAMIC, + unbind = "unsetOrganizationManager" + ) + protected void setOrganizationManager(OrganizationManager organizationManager) { + + APIResourceManagementServiceComponentHolder.getInstance().setOrganizationManager(organizationManager); + LOG.debug("Set the organization management service."); + } + + protected void unsetOrganizationManager(OrganizationManager organizationManager) { + + APIResourceManagementServiceComponentHolder.getInstance().setOrganizationManager(null); + LOG.debug("Unset organization management service."); + } + + @Reference( + name = "realm.service", + service = RealmService.class, + cardinality = ReferenceCardinality.MANDATORY, + policy = ReferencePolicy.DYNAMIC, + unbind = "unsetRealmService" + ) + protected void setRealmService(RealmService realmService) { + + APIResourceManagementServiceComponentHolder.getInstance().setRealmService(realmService); + LOG.debug("Set the Realm Service"); + } + + protected void unsetRealmService(RealmService realmService) { + + APIResourceManagementServiceComponentHolder.getInstance().setRealmService(null); + LOG.debug("Unset the Realm Service"); + } } diff --git a/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/internal/APIResourceManagementServiceComponentHolder.java b/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/internal/APIResourceManagementServiceComponentHolder.java new file mode 100644 index 000000000000..eb710cf593bc --- /dev/null +++ b/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/main/java/org/wso2/carbon/identity/api/resource/mgt/internal/APIResourceManagementServiceComponentHolder.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.identity.api.resource.mgt.internal; + +import org.wso2.carbon.identity.organization.management.service.OrganizationManager; +import org.wso2.carbon.user.core.service.RealmService; + +/** + * API Resource Management Service Component Holder class. + */ +public class APIResourceManagementServiceComponentHolder { + + private static final APIResourceManagementServiceComponentHolder instance = new + APIResourceManagementServiceComponentHolder(); + + private OrganizationManager organizationManager; + private RealmService realmService; + + public static APIResourceManagementServiceComponentHolder getInstance() { + + return instance; + } + + public OrganizationManager getOrganizationManager() { + + return organizationManager; + } + + public void setOrganizationManager(OrganizationManager organizationManager) { + + this.organizationManager = organizationManager; + } + + public RealmService getRealmService() { + + return realmService; + } + + public void setRealmService(RealmService realmService) { + + this.realmService = realmService; + } +} diff --git a/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/test/java/org/wso2/carbon/identity/api/resource/mgt/APIResourceManagerTest.java b/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/test/java/org/wso2/carbon/identity/api/resource/mgt/APIResourceManagerTest.java index d20476f7db05..ab7cbf12d728 100644 --- a/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/test/java/org/wso2/carbon/identity/api/resource/mgt/APIResourceManagerTest.java +++ b/components/api-resource-mgt/org.wso2.carbon.identity.api.resource.mgt/src/test/java/org/wso2/carbon/identity/api/resource/mgt/APIResourceManagerTest.java @@ -25,6 +25,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.identity.api.resource.mgt.internal.APIResourceManagementServiceComponentHolder; import org.wso2.carbon.identity.api.resource.mgt.model.APIResourceSearchResult; import org.wso2.carbon.identity.application.common.model.APIResource; import org.wso2.carbon.identity.application.common.model.Scope; @@ -41,7 +42,7 @@ @WithAxisConfiguration @WithCarbonHome @WithRegistry -@WithRealmService +@WithRealmService(injectToSingletons = {APIResourceManagementServiceComponentHolder.class}, initUserStoreManager = true) @WithH2Database(files = {"dbscripts/h2.sql"}) public class APIResourceManagerTest extends PowerMockTestCase { diff --git a/components/application-mgt/org.wso2.carbon.identity.application.mgt/src/test/java/org/wso2/carbon/identity/application/mgt/AuthorizedAPIManagementServiceImplTest.java b/components/application-mgt/org.wso2.carbon.identity.application.mgt/src/test/java/org/wso2/carbon/identity/application/mgt/AuthorizedAPIManagementServiceImplTest.java index 5efca35dc9ef..e31c5bae5c3e 100644 --- a/components/application-mgt/org.wso2.carbon.identity.application.mgt/src/test/java/org/wso2/carbon/identity/application/mgt/AuthorizedAPIManagementServiceImplTest.java +++ b/components/application-mgt/org.wso2.carbon.identity.application.mgt/src/test/java/org/wso2/carbon/identity/application/mgt/AuthorizedAPIManagementServiceImplTest.java @@ -32,6 +32,7 @@ import org.wso2.carbon.identity.api.resource.mgt.APIResourceManager; import org.wso2.carbon.identity.api.resource.mgt.APIResourceManagerImpl; import org.wso2.carbon.identity.api.resource.mgt.APIResourceMgtException; +import org.wso2.carbon.identity.api.resource.mgt.internal.APIResourceManagementServiceComponentHolder; import org.wso2.carbon.identity.application.common.model.APIResource; import org.wso2.carbon.identity.application.common.model.AuthorizedAPI; import org.wso2.carbon.identity.application.common.model.AuthorizedScopes; @@ -75,7 +76,7 @@ @WithAxisConfiguration @WithCarbonHome @WithRegistry -@WithRealmService +@WithRealmService(injectToSingletons = {APIResourceManagementServiceComponentHolder.class}, initUserStoreManager = true) @WithH2Database(files = {"dbscripts/identity.sql"}) public class AuthorizedAPIManagementServiceImplTest extends PowerMockTestCase { diff --git a/pom.xml b/pom.xml index 3c273c3e198c..946ea0da3f58 100644 --- a/pom.xml +++ b/pom.xml @@ -1820,7 +1820,7 @@ ${project.version} [5.14.0, 6.0.0) - 1.0.0 + 1.0.65 [1.0.0, 2.0.0)