diff --git a/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.api.server.claim.management.common/pom.xml b/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.api.server.claim.management.common/pom.xml index 25e8e7cb74..7d6eec20e8 100644 --- a/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.api.server.claim.management.common/pom.xml +++ b/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.api.server.claim.management.common/pom.xml @@ -45,6 +45,11 @@ org.wso2.carbon.identity.claim.metadata.mgt provided + + org.wso2.carbon.identity.organization.management.core + org.wso2.carbon.identity.organization.management.service + provided + org.springframework spring-web diff --git a/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.api.server.claim.management.common/src/main/java/org/wso2/carbon/identity/api/server/claim/management/common/ClaimManagementDataHolder.java b/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.api.server.claim.management.common/src/main/java/org/wso2/carbon/identity/api/server/claim/management/common/ClaimManagementDataHolder.java index 34db4413eb..5e06e0657e 100644 --- a/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.api.server.claim.management.common/src/main/java/org/wso2/carbon/identity/api/server/claim/management/common/ClaimManagementDataHolder.java +++ b/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.api.server.claim.management.common/src/main/java/org/wso2/carbon/identity/api/server/claim/management/common/ClaimManagementDataHolder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2019, WSO2 LLC. (http://www.wso2.org). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.wso2.carbon.identity.api.server.claim.management.common; import org.wso2.carbon.identity.claim.metadata.mgt.ClaimMetadataManagementService; +import org.wso2.carbon.identity.organization.management.service.OrganizationManager; /** * Service holder class for identity governance. @@ -24,6 +25,7 @@ public class ClaimManagementDataHolder { private static ClaimMetadataManagementService claimMetadataManagementService; + private static OrganizationManager organizationManager; public static ClaimMetadataManagementService getClaimMetadataManagementService() { @@ -35,4 +37,24 @@ public static void setClaimMetadataManagementService( ClaimManagementDataHolder.claimMetadataManagementService = claimMetadataManagementService; } + + /** + * Get organizationManager OSGi service. + * + * @return organization Manager. + */ + public static OrganizationManager getOrganizationManager() { + + return organizationManager; + } + + /** + * Set organizationManager OSGi service. + * + * @param organizationManager Organization Manager. + */ + public static void setOrganizationManager(OrganizationManager organizationManager) { + + ClaimManagementDataHolder.organizationManager = organizationManager; + } } diff --git a/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.api.server.claim.management.common/src/main/java/org/wso2/carbon/identity/api/server/claim/management/common/Constant.java b/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.api.server.claim.management.common/src/main/java/org/wso2/carbon/identity/api/server/claim/management/common/Constant.java index a9863bd7af..fcedf85575 100644 --- a/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.api.server.claim.management.common/src/main/java/org/wso2/carbon/identity/api/server/claim/management/common/Constant.java +++ b/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.api.server.claim.management.common/src/main/java/org/wso2/carbon/identity/api/server/claim/management/common/Constant.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2019, WSO2 LLC. (http://www.wso2.org). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -201,7 +201,12 @@ public enum ErrorMessage { ERROR_CODE_USERSTORE_NOT_SPECIFIED_IN_MAPPINGS("CMT-60005", "Userstore not specified", "Mapped userstore cannot be empty"), ERROR_CODE_EMPTY_ATTRIBUTE_MAPPINGS("CMT-60006", "Attribute mapping not specified", - "Attribute mapping cannot be empty"); + "Attribute mapping cannot be empty"), + ERROR_CODE_UNAUTHORIZED_ORG_FOR_CLAIM_MANAGEMENT("CMT-60007", "Claim modification is not " + + "allowed for this organization.", "Unable to execute the requested organization claim " + + "management task."), + ERROR_CODE_ERROR_RESOLVING_ORGANIZATION("CMT-60008", "Error resolving organization", + "Unable to resolve organization."); private final String code; private final String message; diff --git a/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.api.server.claim.management.common/src/main/java/org/wso2/carbon/identity/api/server/claim/management/common/factory/OrganizationManagementOSGIServiceFactory.java b/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.api.server.claim.management.common/src/main/java/org/wso2/carbon/identity/api/server/claim/management/common/factory/OrganizationManagementOSGIServiceFactory.java new file mode 100644 index 0000000000..cec4ed1e4f --- /dev/null +++ b/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.api.server.claim.management.common/src/main/java/org/wso2/carbon/identity/api/server/claim/management/common/factory/OrganizationManagementOSGIServiceFactory.java @@ -0,0 +1,54 @@ +/* + * 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.server.claim.management.common.factory; + +import org.springframework.beans.factory.config.AbstractFactoryBean; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.identity.organization.management.service.OrganizationManager; + +/** + * Factory Beans serves as a factory for creating other beans within the IOC container. This factory bean is used to + * instantiate the OrganizationManagementService type of object inside the container. + */ +public class OrganizationManagementOSGIServiceFactory extends AbstractFactoryBean { + + private OrganizationManager organizationManager; + + @Override + public Class getObjectType() { + + return Object.class; + } + + @Override + protected OrganizationManager createInstance() throws Exception { + + if (this.organizationManager == null) { + OrganizationManager orgMgtService = (OrganizationManager) PrivilegedCarbonContext. + getThreadLocalCarbonContext().getOSGiService(OrganizationManager.class, null); + if (orgMgtService == null) { + throw new Exception("Unable to retrieve Organization Management service."); + } + this.organizationManager = orgMgtService; + } + return this.organizationManager; + } +} + + diff --git a/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.rest.api.server.claim.management.v1/pom.xml b/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.rest.api.server.claim.management.v1/pom.xml index 3ae82b772c..fedaa1ced4 100644 --- a/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.rest.api.server.claim.management.v1/pom.xml +++ b/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.rest.api.server.claim.management.v1/pom.xml @@ -140,5 +140,10 @@ org.wso2.carbon.identity.api.server.claim.management.common provided + + org.wso2.carbon.identity.organization.management.core + org.wso2.carbon.identity.organization.management.service + provided + diff --git a/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.rest.api.server.claim.management.v1/src/main/java/org/wso2/carbon/identity/rest/api/server/claim/management/v1/core/ServerClaimManagementService.java b/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.rest.api.server.claim.management.v1/src/main/java/org/wso2/carbon/identity/rest/api/server/claim/management/v1/core/ServerClaimManagementService.java index 51369de3a1..9f01e8ee86 100644 --- a/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.rest.api.server.claim.management.v1/src/main/java/org/wso2/carbon/identity/rest/api/server/claim/management/v1/core/ServerClaimManagementService.java +++ b/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.rest.api.server.claim.management.v1/src/main/java/org/wso2/carbon/identity/rest/api/server/claim/management/v1/core/ServerClaimManagementService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2019, WSO2 LLC. (http://www.wso2.org). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.cxf.jaxrs.ext.multipart.Attachment; import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.identity.api.server.claim.management.common.Constant; import org.wso2.carbon.identity.api.server.common.ContextLoader; import org.wso2.carbon.identity.api.server.common.FileContent; @@ -43,6 +44,7 @@ import org.wso2.carbon.identity.claim.metadata.mgt.model.LocalClaim; import org.wso2.carbon.identity.claim.metadata.mgt.util.ClaimConstants; import org.wso2.carbon.identity.core.util.IdentityUtil; +import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException; import org.wso2.carbon.identity.rest.api.server.claim.management.v1.dto.AttributeMappingDTO; import org.wso2.carbon.identity.rest.api.server.claim.management.v1.dto.ClaimDialectReqDTO; import org.wso2.carbon.identity.rest.api.server.claim.management.v1.dto.ClaimDialectResDTO; @@ -85,6 +87,7 @@ import javax.xml.bind.Unmarshaller; import static org.wso2.carbon.identity.api.server.claim.management.common.ClaimManagementDataHolder.getClaimMetadataManagementService; +import static org.wso2.carbon.identity.api.server.claim.management.common.ClaimManagementDataHolder.getOrganizationManager; import static org.wso2.carbon.identity.api.server.claim.management.common.Constant.CMT_PATH_COMPONENT; import static org.wso2.carbon.identity.api.server.claim.management.common.Constant.ErrorMessage.ERROR_CODE_ATTRIBUTE_FILTERING_NOT_IMPLEMENTED; import static org.wso2.carbon.identity.api.server.claim.management.common.Constant.ErrorMessage.ERROR_CODE_CLAIMS_NOT_FOUND_FOR_DIALECT; @@ -115,6 +118,7 @@ import static org.wso2.carbon.identity.api.server.claim.management.common.Constant.ErrorMessage.ERROR_CODE_LOCAL_CLAIM_NOT_FOUND; import static org.wso2.carbon.identity.api.server.claim.management.common.Constant.ErrorMessage.ERROR_CODE_PAGINATION_NOT_IMPLEMENTED; import static org.wso2.carbon.identity.api.server.claim.management.common.Constant.ErrorMessage.ERROR_CODE_SORTING_NOT_IMPLEMENTED; +import static org.wso2.carbon.identity.api.server.claim.management.common.Constant.ErrorMessage.ERROR_CODE_UNAUTHORIZED_ORG_FOR_CLAIM_MANAGEMENT; import static org.wso2.carbon.identity.api.server.claim.management.common.Constant.ErrorMessage.ERROR_CODE_USERSTORE_NOT_SPECIFIED_IN_MAPPINGS; import static org.wso2.carbon.identity.api.server.claim.management.common.Constant.LOCAL_DIALECT; import static org.wso2.carbon.identity.api.server.claim.management.common.Constant.LOCAL_DIALECT_PATH; @@ -162,6 +166,7 @@ public class ServerClaimManagementService { public String addClaimDialect(ClaimDialectReqDTO claimDialectReqDTO) { try { + allowClaimManagementAccessForRootOrganizations(); getClaimMetadataManagementService().addClaimDialect( createClaimDialect(claimDialectReqDTO), ContextLoader.getTenantDomainFromContext()); @@ -182,6 +187,7 @@ public String addClaimDialect(ClaimDialectReqDTO claimDialectReqDTO) { public String addClaimDialect(String dialectURI) { try { + allowClaimManagementAccessForRootOrganizations(); getClaimMetadataManagementService().addClaimDialect( createClaimDialect(dialectURI), ContextLoader.getTenantDomainFromContext()); @@ -201,6 +207,7 @@ public void deleteClaimDialect(String dialectId) { String claimDialectURI; try { + allowClaimManagementAccessForRootOrganizations(); claimDialectURI = base64DecodeId(dialectId); } catch (Exception ignored) { // Ignoring the delete operation and return 204 response code, since the resource does not exist. @@ -281,6 +288,7 @@ public List getClaimDialects(Integer limit, Integer offset, public String updateClaimDialect(String dialectId, ClaimDialectReqDTO claimDialectReqDTO) { try { + allowClaimManagementAccessForRootOrganizations(); // If the old and new dialect uri is the same we don't need to do a db update. if (!StringUtils.equals(base64DecodeId(dialectId), claimDialectReqDTO.getDialectURI())) { getClaimMetadataManagementService().renameClaimDialect( @@ -320,6 +328,7 @@ public String addLocalClaim(LocalClaimReqDTO localClaimReqDTO) { } try { + allowClaimManagementAccessForRootOrganizations(); validateAttributeMappings(localClaimReqDTO.getAttributeMapping()); getClaimMetadataManagementService().addLocalClaim(createLocalClaim(localClaimReqDTO), ContextLoader.getTenantDomainFromContext()); @@ -343,6 +352,7 @@ public void deleteLocalClaim(String claimId) { String claimURI; try { + allowClaimManagementAccessForRootOrganizations(); claimURI = base64DecodeId(claimId); } catch (Exception ignored) { // Ignoring the delete operation and return 204 response code, since the resource does not exist. @@ -425,6 +435,7 @@ public List getLocalClaims(Boolean excludeIdentityClaims, Stri public void updateLocalClaim(String claimId, LocalClaimReqDTO localClaimReqDTO) { try { + allowClaimManagementAccessForRootOrganizations(); if (!StringUtils.equals(base64DecodeId(claimId), localClaimReqDTO.getClaimURI())) { throw handleClaimManagementClientError(ERROR_CODE_LOCAL_CLAIM_CONFLICT, CONFLICT, base64DecodeId(claimId)); @@ -699,6 +710,7 @@ private FileContent parseClaimDialectToYaml(ClaimDialectConfiguration dialectCon public String addExternalClaim(String dialectId, ExternalClaimReqDTO externalClaimReqDTO) { try { + allowClaimManagementAccessForRootOrganizations(); if (!isDialectExists(dialectId)) { throw handleClaimManagementClientError(ERROR_CODE_INVALID_DIALECT_ID, NOT_FOUND, dialectId); } @@ -725,6 +737,7 @@ public void deleteExternalClaim(String dialectId, String claimId) { String externalClaimURI; String externalClaimDialectURI; try { + allowClaimManagementAccessForRootOrganizations(); externalClaimURI = base64DecodeId(claimId); externalClaimDialectURI = base64DecodeId(dialectId); } catch (Exception ignored) { @@ -820,6 +833,7 @@ public List getExternalClaims(String dialectId, Integer lim public void updateExternalClaim(String dialectId, String claimId, ExternalClaimReqDTO externalClaimReqDTO) { try { + allowClaimManagementAccessForRootOrganizations(); if (!StringUtils.equals(base64DecodeId(claimId), externalClaimReqDTO.getClaimURI())) { throw handleClaimManagementClientError(ERROR_CODE_EXTERNAL_CLAIM_CONFLICT, CONFLICT, base64DecodeId(claimId), dialectId); @@ -1444,4 +1458,21 @@ private void validateAttributeMappings(List attributeMappin } } } + + private void allowClaimManagementAccessForRootOrganizations() throws ClaimMetadataClientException { + + String organizationId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getOrganizationId(); + if (StringUtils.isNotBlank(organizationId)) { + try { + String rootOrganizationId = getOrganizationManager().getPrimaryOrganizationId(organizationId); + if (!rootOrganizationId.equals(organizationId)) { + throw handleClaimManagementClientError(ERROR_CODE_UNAUTHORIZED_ORG_FOR_CLAIM_MANAGEMENT, FORBIDDEN, + organizationId); + } + } catch (OrganizationManagementException e) { + throw new ClaimMetadataClientException(Constant.ErrorMessage.ERROR_CODE_ERROR_RESOLVING_ORGANIZATION. + getCode(), Constant.ErrorMessage.ERROR_CODE_ERROR_RESOLVING_ORGANIZATION.getDescription()); + } + } + } } diff --git a/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.rest.api.server.claim.management.v1/src/main/resources/META-INF/cxf/claim-management-server-v1-cxf.xml b/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.rest.api.server.claim.management.v1/src/main/resources/META-INF/cxf/claim-management-server-v1-cxf.xml index eb6581cfbc..a3f3cfcc8d 100644 --- a/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.rest.api.server.claim.management.v1/src/main/resources/META-INF/cxf/claim-management-server-v1-cxf.xml +++ b/components/org.wso2.carbon.identity.api.server.claim.management/org.wso2.carbon.identity.rest.api.server.claim.management.v1/src/main/resources/META-INF/cxf/claim-management-server-v1-cxf.xml @@ -22,6 +22,12 @@ class="org.wso2.carbon.identity.api.server.claim.management.common.ClaimManagementDataHolder"> + + + + diff --git a/pom.xml b/pom.xml index 18bbfeb1c1..bff6852fc2 100644 --- a/pom.xml +++ b/pom.xml @@ -753,13 +753,13 @@ 1.0.3 - 1.0.56 + 1.0.64 [1.0.0, 2.0.0) - 1.3.70 + 1.3.73