Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow sub-organizations to update local claim mappings. #771

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,12 @@ public enum ErrorMessage {
"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.");
"Unable to resolve organization."),
ERROR_CODE_UNAUTHORIZED_ORG_FOR_CLAIM_PROPERTY_UPDATE("CMT-60009", "Claim property update is not " +
"allowed for this organization.", "Unable to update the claim properties."),
ERROR_CODE_UNAUTHORIZED_ORG_FOR_ATTRIBUTE_MAPPING_UPDATE("CMT-60010",
"Unable to update attribute mappings.",
"Updating the mapped attribute for userstore: %s is not allowed for this organization");

private final String code;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) (2019-2023), WSO2 LLC. (http://www.wso2.org).
* Copyright (c) (2019-2025), 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.
Expand Down Expand Up @@ -79,6 +79,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.ws.rs.core.Response;
Expand Down Expand Up @@ -119,7 +121,9 @@
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_ATTRIBUTE_MAPPING_UPDATE;
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_UNAUTHORIZED_ORG_FOR_CLAIM_PROPERTY_UPDATE;
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;
Expand Down Expand Up @@ -165,6 +169,8 @@ public class ServerClaimManagementService {
ClaimConstants.ErrorMessage.ERROR_CODE_NO_DELETE_SYSTEM_CLAIM.getCode()
);

public static final String FALSE = "false";

/**
* Add a claim dialect.
*
Expand Down Expand Up @@ -357,7 +363,6 @@ public String addLocalClaim(LocalClaimReqDTO localClaimReqDTO) {
*/
public void deleteLocalClaim(String claimId) {


String claimURI;
try {
validateClaimModificationEligibility();
Expand Down Expand Up @@ -443,7 +448,14 @@ public List<LocalClaimResDTO> getLocalClaims(Boolean excludeIdentityClaims, Stri
public void updateLocalClaim(String claimId, LocalClaimReqDTO localClaimReqDTO) {

try {
validateClaimModificationEligibility();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this allow to update any property of the claim in sub org?

if (isSubOrganizationContext()) {
/*
* For sub organizations, only attribute mappings are allowed to be updated. Updating any other
* claim properties are restricted.
*/
validateAttributeMappingUpdate(claimId, createLocalClaim(localClaimReqDTO));
}

if (!StringUtils.equals(base64DecodeId(claimId), localClaimReqDTO.getClaimURI())) {
throw handleClaimManagementClientError(ERROR_CODE_LOCAL_CLAIM_CONFLICT, CONFLICT,
base64DecodeId(claimId));
Expand Down Expand Up @@ -1096,6 +1108,7 @@ public String importClaimDialectFromFile(InputStream fileInputStream, Attachment
throw handleClaimManagementException(e, Constant.ErrorMessage.ERROR_CODE_ERROR_IMPORTING_CLAIM_DIALECT);
}
}

private void importExternalClaims(String dialectID, List<ExternalClaimReqDTO> externalClaimReqDTOList) {

List<ClaimErrorDTO> errors = new ArrayList<>();
Expand Down Expand Up @@ -1499,4 +1512,57 @@ private void validateClaimModificationEligibility() throws ClaimMetadataClientEx
}

}

private boolean isSubOrganizationContext() throws ClaimMetadataClientException {

try {
String organizationId =
getOrganizationManager().resolveOrganizationId(ContextLoader.getTenantDomainFromContext());
return !getOrganizationManager().isPrimaryOrganization(organizationId);
} catch (OrganizationManagementException e) {
throw new ClaimMetadataClientException(Constant.ErrorMessage.ERROR_CODE_ERROR_RESOLVING_ORGANIZATION.
getCode(), Constant.ErrorMessage.ERROR_CODE_ERROR_RESOLVING_ORGANIZATION.getDescription());
}
}

private void validateAttributeMappingUpdate(String claimID, LocalClaim incomingLocalClaim)
throws ClaimMetadataException {

Optional<LocalClaim>
existingLocalClaim = getClaimMetadataManagementService().getLocalClaim(base64DecodeId(claimID),
ContextLoader.getTenantDomainFromContext());

if (!existingLocalClaim.isPresent()) {
throw handleClaimManagementClientError(ERROR_CODE_LOCAL_CLAIM_NOT_FOUND, BAD_REQUEST, claimID);
}

populateDefaultProperties(existingLocalClaim.get());
if (Objects.hash(existingLocalClaim.get().getClaimProperties().entrySet()) !=
Objects.hash(incomingLocalClaim.getClaimProperties().entrySet())) {
throw handleClaimManagementClientError(ERROR_CODE_UNAUTHORIZED_ORG_FOR_CLAIM_PROPERTY_UPDATE, FORBIDDEN);
}

for (AttributeMapping existingMapping : existingLocalClaim.get().getMappedAttributes()) {
if (IdentityUtil.getPrimaryDomainName().equals(existingMapping.getUserStoreDomain())) {
Optional<AttributeMapping> incomingAttributeMapping = incomingLocalClaim.getMappedAttributes().stream()
.filter(mapping -> IdentityUtil.getPrimaryDomainName().equals(mapping.getUserStoreDomain()))
.findFirst();
// Not allowing to update the primary userstore attribute mapping for sub-orgs.
if (incomingAttributeMapping.isPresent() && !StringUtils.equals(existingMapping.getAttributeName(),
incomingAttributeMapping.get().getAttributeName())) {
throw handleClaimManagementClientError(ERROR_CODE_UNAUTHORIZED_ORG_FOR_ATTRIBUTE_MAPPING_UPDATE,
FORBIDDEN, existingMapping.getUserStoreDomain());
}
}
}
}

private void populateDefaultProperties(LocalClaim localClaim) {

localClaim.getClaimProperties().putIfAbsent(PROP_DESCRIPTION, StringUtils.EMPTY);
localClaim.getClaimProperties().putIfAbsent(PROP_DISPLAY_ORDER, "0");
localClaim.getClaimProperties().putIfAbsent(PROP_READ_ONLY, FALSE);
localClaim.getClaimProperties().putIfAbsent(PROP_REQUIRED, FALSE);
localClaim.getClaimProperties().putIfAbsent(PROP_SUPPORTED_BY_DEFAULT, FALSE);
}
}
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@
<maven.buildnumber.plugin.version>1.4</maven.buildnumber.plugin.version>
<org.apache.felix.annotations.version>1.2.4</org.apache.felix.annotations.version>
<identity.governance.version>1.11.11</identity.governance.version>
<carbon.identity.framework.version>7.7.19</carbon.identity.framework.version>
<carbon.identity.framework.version>7.7.84</carbon.identity.framework.version>
<maven.findbugsplugin.version>3.0.5</maven.findbugsplugin.version>
<findsecbugs-plugin.version>1.12.0</findsecbugs-plugin.version>
<maven.checkstyleplugin.excludes>**/gen/**/*</maven.checkstyleplugin.excludes>
Expand Down