diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/pom.xml b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/pom.xml
new file mode 100644
index 000000000..48215ca4a
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/pom.xml
@@ -0,0 +1,151 @@
+
+
+
+
+ org.wso2.carbon.identity.organization.management
+ identity-organization-management
+ 1.4.61-SNAPSHOT
+ ../../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.identity.organization.resource.sharing.policy.management
+ WSO2 - Organization Resource Sharing Policy Management Service
+ bundle
+
+
+ 11
+ 11
+ UTF-8
+
+
+
+
+ org.wso2.carbon
+ org.wso2.carbon.utils
+
+
+ org.wso2.carbon.identity.organization.management.core
+ org.wso2.carbon.identity.organization.management.service
+
+
+ org.wso2.carbon.utils
+ org.wso2.carbon.database.utils
+
+
+ org.wso2.carbon
+ org.wso2.carbon.user.core
+
+
+
+ org.testng
+ testng
+ test
+
+
+ org.mockito
+ mockito-core
+ test
+
+
+ com.h2database
+ h2
+ test
+
+
+ org.wso2.carbon.multitenancy
+ org.wso2.carbon.tenant.mgt
+ test
+
+
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+ ${project.artifactId}
+ ${project.artifactId}
+ Organization Resource Sharing Policy Service Bundle
+
+ org.wso2.carbon.identity.organization.resource.sharing.policy.management.internal
+ org.wso2.carbon.identity.organization.resource.sharing.policy.management.dao
+
+
+ org.wso2.carbon.identity.organization.resource.sharing.policy.management,
+ org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant,
+ org.wso2.carbon.identity.organization.resource.sharing.policy.management.exception,
+ org.wso2.carbon.identity.organization.resource.sharing.policy.management.model,
+ org.wso2.carbon.identity.organization.resource.sharing.policy.management.util;
+ version="${identity.organization.management.exp.pkg.version}",
+
+
+ javax.sql,
+ org.apache.commons.logging; version="${org.apache.commons.logging.imp.pkg.version.range}",
+ org.apache.commons.collections; version="${org.apache.commons.collections.imp.pkg.version.range}",
+ org.apache.commons.lang;version="${org.apache.commons.lang.imp.pkg.version.range}",
+ org.osgi.framework; version="${osgi.framework.imp.pkg.version.range}",
+ org.osgi.service.component; version="${osgi.service.component.imp.pkg.version.range}",
+ org.wso2.carbon.context;version="${carbon.kernel.package.import.version.range}",
+ org.wso2.carbon.database.utils.jdbc;version="${org.wso2.carbon.database.utils.version.range}",
+ org.wso2.carbon.database.utils.jdbc.exceptions;version="${org.wso2.carbon.database.utils.version.range}",
+ org.wso2.carbon.identity.organization.management.service;version="${org.wso2.identity.organization.mgt.imp.pkg.version.range}",
+ org.wso2.carbon.identity.organization.management.service.util;version="${org.wso2.identity.organization.mgt.imp.pkg.version.range}",
+ org.wso2.carbon;version="${carbon.kernel.package.import.version.range}",
+ org.wso2.carbon.user.core.util;version="${carbon.kernel.package.import.version.range}",
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco.version}
+
+
+ org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/*.class
+ org/wso2/carbon/identity/organization/resource/sharing/policy/management/exception/*.class
+ org/wso2/carbon/identity/organization/resource/sharing/policy/management/internal/*.class
+ org/wso2/carbon/identity/organization/resource/sharing/policy/management/model/*.class
+ org/wso2/carbon/identity/organization/resource/sharing/policy/management/ResourceSharingPolicyHandlerService.class
+
+
+
+
+
+ prepare-agent
+
+
+
+
+ report
+ test
+
+ report
+
+
+
+
+
+
+
+
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/ResourceSharingPolicyHandlerService.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/ResourceSharingPolicyHandlerService.java
new file mode 100644
index 000000000..075ac35b6
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/ResourceSharingPolicyHandlerService.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management;
+
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceType;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.SharedAttributeType;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.exception.ResourceSharingPolicyMgtException;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.model.ResourceSharingPolicy;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.model.SharedResourceAttribute;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * Service interface for managing resource sharing policies across organizations.
+ *
+ * This interface provides methods for adding, retrieving, and deleting resource sharing policies.
+ * It also allows managing shared resource attributes, offering capabilities to add, retrieve, and delete
+ * these attributes.
+ *
+ */
+public interface ResourceSharingPolicyHandlerService {
+
+ /**
+ * Creates a new resource sharing policy record and returns its unique identifier.
+ *
+ * @param resourceSharingPolicy The {@link ResourceSharingPolicy} containing details such as resource type,
+ * initiating organization, policy holding organization, and sharing policy.
+ * Must not be {@code null}.
+ * @return The unique identifier of the newly created resource sharing policy.
+ * @throws ResourceSharingPolicyMgtException If an error occurs during the creation of the resource sharing policy.
+ */
+ int addResourceSharingPolicy(ResourceSharingPolicy resourceSharingPolicy)
+ throws ResourceSharingPolicyMgtException;
+
+ /**
+ * Retrieves a resource sharing policy by its unique identifier, if present.
+ *
+ * @param resourceSharingPolicyId The unique identifier of the resource sharing policy to be retrieved.
+ * Must be a valid ID greater than zero.
+ * @return An {@link Optional} containing the {@link ResourceSharingPolicy} if found,
+ * or an empty {@link Optional} if no matching resource sharing policy exists.
+ * @throws ResourceSharingPolicyMgtException If an error occurs while retrieving the resource sharing policy.
+ */
+ Optional getResourceSharingPolicyById(int resourceSharingPolicyId)
+ throws ResourceSharingPolicyMgtException;
+
+ /**
+ * Retrieves a list of resource sharing policies associated with the given policy holding organization IDs.
+ *
+ * @param policyHoldingOrganizationIds A list of organization IDs whose policies need to be retrieved.
+ * Must not be {@code null} or empty.
+ * @return A list of {@link ResourceSharingPolicy} objects for the specified organization IDs.
+ * @throws ResourceSharingPolicyMgtException If an error occurs while retrieving the resource sharing policies.
+ */
+ List getResourceSharingPolicies(List policyHoldingOrganizationIds)
+ throws ResourceSharingPolicyMgtException;
+
+ /**
+ * Retrieves a map of resource sharing policies grouped by resource type for the given organization IDs.
+ *
+ * @param policyHoldingOrganizationIds A list of organization IDs whose policies need to be retrieved.
+ * Must not be {@code null} or empty.
+ * @return A map where each key is a {@link ResourceType} and the corresponding value is a list of
+ * {@link ResourceSharingPolicy}.
+ * @throws ResourceSharingPolicyMgtException If an error occurs while retrieving the resource sharing policies.
+ */
+ Map> getResourceSharingPoliciesGroupedByResourceType(
+ List policyHoldingOrganizationIds) throws ResourceSharingPolicyMgtException;
+
+ /**
+ * Retrieves a map of resource sharing policies grouped by policy holding organization ID for the given IDs.
+ *
+ * @param policyHoldingOrganizationIds A list of organization IDs whose policies need to be retrieved.
+ * Must not be {@code null} or empty.
+ * @return A map where each key is an organization ID, and the value is a list of {@link ResourceSharingPolicy}.
+ * @throws ResourceSharingPolicyMgtException If an error occurs while retrieving the resource sharing policies.
+ */
+ Map> getResourceSharingPoliciesGroupedByPolicyHoldingOrgId(
+ List policyHoldingOrganizationIds) throws ResourceSharingPolicyMgtException;
+
+ /**
+ * Deletes a resource sharing policy by its unique identifier if the specified organization has permission.
+ *
+ * @param resourceSharingPolicyId The unique identifier of the resource sharing policy to be deleted.
+ * @param sharingPolicyInitiatedOrgId The ID of the organization initiating the share request.
+ * The deletion will only be successful if the initiating organization
+ * has permission to delete sharing policies.
+ * Must not be {@code null}.
+ * @throws ResourceSharingPolicyMgtException If an error occurs while deleting the resource sharing policy.
+ */
+ void deleteResourceSharingPolicyRecordById(int resourceSharingPolicyId, String sharingPolicyInitiatedOrgId)
+ throws ResourceSharingPolicyMgtException;
+
+ /**
+ * Deletes a resource sharing policy based on its resource type and resource ID if permitted.
+ *
+ * @param resourceType The {@link ResourceType} of the resource.
+ * @param resourceId The unique identifier of the resource whose sharing policy is to be deleted.
+ * @param sharingPolicyInitiatedOrgId The ID of the organization initiating the share request.
+ * The deletion will only be successful if the initiating organization
+ * has permission to delete sharing policies.
+ * @throws ResourceSharingPolicyMgtException If an error occurs while deleting the resource sharing policy.
+ */
+ void deleteResourceSharingPolicyByResourceTypeAndId(ResourceType resourceType, String resourceId,
+ String sharingPolicyInitiatedOrgId)
+ throws ResourceSharingPolicyMgtException;
+
+ /**
+ * Adds shared resource attributes to an existing resource sharing policy.
+ *
+ * @param sharedResourceAttributes A list of {@link SharedResourceAttribute} objects to be added.
+ * Must not be {@code null} or empty.
+ * @return {@code true} if the shared resource attributes were added successfully.
+ * @throws ResourceSharingPolicyMgtException If an error occurs while adding the shared resource attributes.
+ */
+ boolean addSharedResourceAttributes(List sharedResourceAttributes)
+ throws ResourceSharingPolicyMgtException;
+
+ /**
+ * Retrieves shared resource attributes for a given resource sharing policy.
+ *
+ * @param resourceSharingPolicyId The unique identifier of the resource sharing policy.
+ * @return A list of {@link SharedResourceAttribute} associated with the given policy.
+ * @throws ResourceSharingPolicyMgtException If an error occurs while retrieving the shared resource attributes.
+ */
+ List getSharedResourceAttributesBySharingPolicyId(int resourceSharingPolicyId)
+ throws ResourceSharingPolicyMgtException;
+
+ /**
+ * Retrieves shared resource attributes based on attribute type.
+ *
+ * @param attributeType The {@link SharedAttributeType} of the resource attribute to be retrieved.
+ * @return A list of {@link SharedResourceAttribute} objects for the specified type.
+ * @throws ResourceSharingPolicyMgtException If an error occurs while retrieving the shared resource attributes.
+ */
+ List getSharedResourceAttributesByType(SharedAttributeType attributeType)
+ throws ResourceSharingPolicyMgtException;
+
+ /**
+ * Retrieves shared resource attributes based on attribute ID.
+ *
+ * @param attributeId The unique identifier of the resource attribute to be retrieved.
+ * @return A list of {@link SharedResourceAttribute} objects for the specified attribute ID.
+ * @throws ResourceSharingPolicyMgtException If an error occurs while retrieving the shared resource attributes.
+ */
+ List getSharedResourceAttributesById(String attributeId)
+ throws ResourceSharingPolicyMgtException;
+
+ /**
+ * Retrieves shared resource attributes based on attribute type and ID.
+ *
+ * @param attributeType The {@link SharedAttributeType} of the resource attribute to be retrieved.
+ * @param attributeId The unique identifier of the attribute to be retrieved.
+ * @return A list of {@link SharedResourceAttribute} objects for the specified type and ID.
+ * @throws ResourceSharingPolicyMgtException If an error occurs while retrieving the shared resource attributes.
+ */
+ List getSharedResourceAttributesByTypeAndId(SharedAttributeType attributeType,
+ String attributeId)
+ throws ResourceSharingPolicyMgtException;
+
+ /**
+ * Deletes shared resource attributes for a given resource sharing policy and attribute type if the specified
+ * organization has permission.
+ *
+ * @param resourceSharingPolicyId The unique identifier of the resource sharing policy.
+ * @param sharedAttributeType The {@link SharedAttributeType} to be deleted.
+ * @param sharingPolicyInitiatedOrgId The ID of the organization initiating the share request.
+ * The deletion will only be successful if the initiating organization
+ * has permission to delete shared attributes.
+ * @throws ResourceSharingPolicyMgtException If an error occurs while deleting the shared resource attributes.
+ */
+ void deleteSharedResourceAttributesByResourceSharingPolicyId(int resourceSharingPolicyId,
+ SharedAttributeType sharedAttributeType,
+ String sharingPolicyInitiatedOrgId)
+ throws ResourceSharingPolicyMgtException;
+
+ /**
+ * Deletes a shared resource attribute based on its attribute type and unique identifier if the specified
+ * organization has permission.
+ *
+ * @param attributeType The {@link SharedAttributeType} of the attribute to be deleted.
+ * @param attributeId The unique identifier of the attribute to be deleted.
+ * @param sharingPolicyInitiatedOrgId The ID of the organization initiating the share request.
+ * The deletion will only be successful if the initiating organization
+ * has permission to delete shared attributes.
+ * @throws ResourceSharingPolicyMgtException If an error occurs while deleting the shared resource attribute.
+ */
+ void deleteSharedResourceAttributeByAttributeTypeAndId(SharedAttributeType attributeType, String attributeId,
+ String sharingPolicyInitiatedOrgId)
+ throws ResourceSharingPolicyMgtException;
+
+ /**
+ * Adds a resource sharing policy along with its associated shared resource attributes in a single transaction.
+ *
+ * @param resourceSharingPolicy The {@link ResourceSharingPolicy} containing details such as resource type,
+ * initiating organization, policy holding organization, and sharing policy.
+ * Must not be {@code null}.
+ * @param sharedResourceAttributes A list of {@link SharedResourceAttribute} objects associated with the resource
+ * sharing policy. Must not be {@code null} or empty.
+ * @return {@code true} if both the resource sharing policy and the shared resource attributes were added
+ * successfully.
+ * @throws ResourceSharingPolicyMgtException If an error occurs while adding the resource sharing policy or the
+ * shared resource attributes.
+ */
+ boolean addResourceSharingPolicyWithAttributes(ResourceSharingPolicy resourceSharingPolicy,
+ List sharedResourceAttributes)
+ throws ResourceSharingPolicyMgtException;
+
+ /**
+ * Retrieves a map of resource sharing policies along with their associated shared resource attributes
+ * for the given list of policy holding organization IDs.
+ *
+ * @param policyHoldingOrganizationIds A list of organization IDs whose resource sharing policies along with
+ * shared resource attributes need to be retrieved.
+ * Must not be {@code null} or empty.
+ * @return A nested map where:
+ * - The first key is the organization ID.
+ * - The second key is the {@link ResourceSharingPolicy}.
+ * - The value is a list of {@link SharedResourceAttribute} associated with the policy.
+ * If no matching policies or attributes are found, an empty map will be returned.
+ * @throws ResourceSharingPolicyMgtException If an error occurs while retrieving the resource sharing
+ * policies or shared attributes.
+ */
+ Map>>
+ getResourceSharingPoliciesWithSharedAttributes(List policyHoldingOrganizationIds)
+ throws ResourceSharingPolicyMgtException;
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/ResourceSharingPolicyHandlerServiceImpl.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/ResourceSharingPolicyHandlerServiceImpl.java
new file mode 100644
index 000000000..801798cd5
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/ResourceSharingPolicyHandlerServiceImpl.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceType;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.SharedAttributeType;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.dao.ResourceSharingPolicyHandlerDAO;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.dao.ResourceSharingPolicyHandlerDAOImpl;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.exception.ResourceSharingPolicyMgtClientException;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.exception.ResourceSharingPolicyMgtException;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.model.ResourceSharingPolicy;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.model.SharedResourceAttribute;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingConstants.ErrorMessage.ERROR_CODE_INAPPLICABLE_RESOURCE_TYPE_TO_POLICY;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingConstants.ErrorMessage.ERROR_CODE_INVALID_ID;
+
+/**
+ * Implementation of the core service for managing resource sharing policies.
+ */
+public class ResourceSharingPolicyHandlerServiceImpl implements ResourceSharingPolicyHandlerService {
+
+ private static final Log LOG = LogFactory.getLog(ResourceSharingPolicyHandlerServiceImpl.class);
+ private static final ResourceSharingPolicyHandlerDAO RESOURCE_SHARING_POLICY_HANDLER_DAO =
+ new ResourceSharingPolicyHandlerDAOImpl();
+
+ @Override
+ public int addResourceSharingPolicy(ResourceSharingPolicy resourceSharingPolicy)
+ throws ResourceSharingPolicyMgtException {
+
+ List applicableResources = resourceSharingPolicy.getSharingPolicy().getApplicableResources();
+ if (!applicableResources.contains(resourceSharingPolicy.getResourceType())) {
+ throw new ResourceSharingPolicyMgtClientException(ERROR_CODE_INAPPLICABLE_RESOURCE_TYPE_TO_POLICY.getCode(),
+ ERROR_CODE_INAPPLICABLE_RESOURCE_TYPE_TO_POLICY.getMessage(),
+ ERROR_CODE_INAPPLICABLE_RESOURCE_TYPE_TO_POLICY.getDescription());
+ }
+
+ return RESOURCE_SHARING_POLICY_HANDLER_DAO.addResourceSharingPolicy(resourceSharingPolicy);
+ }
+
+ @Override
+ public Optional getResourceSharingPolicyById(int resourceSharingPolicyId)
+ throws ResourceSharingPolicyMgtException {
+
+ return RESOURCE_SHARING_POLICY_HANDLER_DAO.getResourceSharingPolicyById(resourceSharingPolicyId);
+ }
+
+ @Override
+ public List getResourceSharingPolicies(List policyHoldingOrganizationIds)
+ throws ResourceSharingPolicyMgtException {
+
+ validateIdFormat(policyHoldingOrganizationIds);
+
+ return RESOURCE_SHARING_POLICY_HANDLER_DAO.getResourceSharingPolicies(policyHoldingOrganizationIds);
+ }
+
+ @Override
+ public Map> getResourceSharingPoliciesGroupedByResourceType(
+ List policyHoldingOrganizationIds) throws ResourceSharingPolicyMgtException {
+
+ validateIdFormat(policyHoldingOrganizationIds);
+
+ return RESOURCE_SHARING_POLICY_HANDLER_DAO.getResourceSharingPoliciesGroupedByResourceType(
+ policyHoldingOrganizationIds);
+ }
+
+ @Override
+ public Map> getResourceSharingPoliciesGroupedByPolicyHoldingOrgId(
+ List policyHoldingOrganizationIds) throws ResourceSharingPolicyMgtException {
+
+ validateIdFormat(policyHoldingOrganizationIds);
+
+ return RESOURCE_SHARING_POLICY_HANDLER_DAO.getResourceSharingPoliciesGroupedByPolicyHoldingOrgId(
+ policyHoldingOrganizationIds);
+ }
+
+ @Override
+ public void deleteResourceSharingPolicyRecordById(int resourceSharingPolicyId,
+ String sharingPolicyInitiatedOrgId)
+ throws ResourceSharingPolicyMgtException {
+
+ validateIdFormat(sharingPolicyInitiatedOrgId);
+
+ RESOURCE_SHARING_POLICY_HANDLER_DAO.deleteResourceSharingPolicyRecordById(resourceSharingPolicyId,
+ sharingPolicyInitiatedOrgId);
+ }
+
+ @Override
+ public void deleteResourceSharingPolicyByResourceTypeAndId(ResourceType resourceType, String resourceId,
+ String sharingPolicyInitiatedOrgId)
+ throws ResourceSharingPolicyMgtException {
+
+ validateIdFormat(Arrays.asList(resourceId, sharingPolicyInitiatedOrgId));
+
+ RESOURCE_SHARING_POLICY_HANDLER_DAO.deleteResourceSharingPolicyByResourceTypeAndId(resourceType,
+ resourceId, sharingPolicyInitiatedOrgId);
+ }
+
+ @Override
+ public boolean addSharedResourceAttributes(List sharedResourceAttributes)
+ throws ResourceSharingPolicyMgtException {
+
+ List addableSharedResourceAttributes = new ArrayList<>();
+ List invalidPolicyIds = new ArrayList<>();
+
+ for (SharedResourceAttribute sharedResourceAttribute : sharedResourceAttributes) {
+ Optional resourceSharingPolicy =
+ getResourceSharingPolicyById(sharedResourceAttribute.getResourceSharingPolicyId());
+ if (resourceSharingPolicy.isPresent()) {
+ if (isValidAttributeForTheResource(resourceSharingPolicy.get(), sharedResourceAttribute)) {
+ addableSharedResourceAttributes.add(sharedResourceAttribute);
+ }
+ } else {
+ invalidPolicyIds.add(sharedResourceAttribute.getResourceSharingPolicyId());
+ }
+ }
+
+ if (!invalidPolicyIds.isEmpty()) {
+ String warnMessage = "Some attributes were skipped due to invalid ResourceSharingPolicy IDs: " +
+ invalidPolicyIds.stream().map(String::valueOf).collect(Collectors.joining(", ", "{", "}"));
+ LOG.warn(warnMessage);
+ }
+
+ return RESOURCE_SHARING_POLICY_HANDLER_DAO.addSharedResourceAttributes(addableSharedResourceAttributes);
+ }
+
+ @Override
+ public List getSharedResourceAttributesBySharingPolicyId(int resourceSharingPolicyId)
+ throws ResourceSharingPolicyMgtException {
+
+ return RESOURCE_SHARING_POLICY_HANDLER_DAO.getSharedResourceAttributesBySharingPolicyId(
+ resourceSharingPolicyId);
+ }
+
+ @Override
+ public List getSharedResourceAttributesByType(SharedAttributeType attributeType)
+ throws ResourceSharingPolicyMgtException {
+
+ return RESOURCE_SHARING_POLICY_HANDLER_DAO.getSharedResourceAttributesByType(attributeType);
+ }
+
+ @Override
+ public List getSharedResourceAttributesById(String attributeId)
+ throws ResourceSharingPolicyMgtException {
+
+ validateIdFormat(attributeId);
+
+ return RESOURCE_SHARING_POLICY_HANDLER_DAO.getSharedResourceAttributesById(attributeId);
+ }
+
+ @Override
+ public List getSharedResourceAttributesByTypeAndId(SharedAttributeType attributeType,
+ String attributeId)
+ throws ResourceSharingPolicyMgtException {
+
+ validateIdFormat(attributeId);
+
+ return RESOURCE_SHARING_POLICY_HANDLER_DAO.getSharedResourceAttributesByTypeAndId(attributeType, attributeId);
+ }
+
+ @Override
+ public void deleteSharedResourceAttributesByResourceSharingPolicyId(int resourceSharingPolicyId,
+ SharedAttributeType sharedAttributeType,
+ String sharingPolicyInitiatedOrgId)
+ throws ResourceSharingPolicyMgtException {
+
+ validateIdFormat(sharingPolicyInitiatedOrgId);
+
+ RESOURCE_SHARING_POLICY_HANDLER_DAO.deleteSharedResourceAttributesByResourceSharingPolicyId(
+ resourceSharingPolicyId, sharedAttributeType, sharingPolicyInitiatedOrgId);
+ }
+
+ @Override
+ public void deleteSharedResourceAttributeByAttributeTypeAndId(SharedAttributeType attributeType,
+ String attributeId,
+ String sharingPolicyInitiatedOrgId)
+ throws ResourceSharingPolicyMgtException {
+
+ validateIdFormat(sharingPolicyInitiatedOrgId);
+
+ RESOURCE_SHARING_POLICY_HANDLER_DAO.deleteSharedResourceAttributeByAttributeTypeAndId(attributeType,
+ attributeId, sharingPolicyInitiatedOrgId);
+ }
+
+ @Override
+ public boolean addResourceSharingPolicyWithAttributes(ResourceSharingPolicy resourceSharingPolicy,
+ List sharedResourceAttributes)
+ throws ResourceSharingPolicyMgtException {
+
+ List addableSharedResourceAttributes = new ArrayList<>();
+
+ for (SharedResourceAttribute sharedResourceAttribute : sharedResourceAttributes) {
+ if (isValidAttributeForTheResource(resourceSharingPolicy, sharedResourceAttribute)) {
+ addableSharedResourceAttributes.add(sharedResourceAttribute);
+ }
+ }
+
+ return RESOURCE_SHARING_POLICY_HANDLER_DAO.addResourceSharingPolicyWithAttributes(resourceSharingPolicy,
+ addableSharedResourceAttributes);
+ }
+
+ @Override
+ public Map>>
+ getResourceSharingPoliciesWithSharedAttributes(List policyHoldingOrganizationIds)
+ throws ResourceSharingPolicyMgtException {
+
+ validateIdFormat(policyHoldingOrganizationIds);
+
+ return RESOURCE_SHARING_POLICY_HANDLER_DAO.getResourceSharingPoliciesWithSharedAttributes(
+ policyHoldingOrganizationIds);
+ }
+
+ private boolean isValidAttributeForTheResource(ResourceSharingPolicy resourceSharingPolicy,
+ SharedResourceAttribute sharedResourceAttribute) {
+
+ return resourceSharingPolicy.getResourceType()
+ .isApplicableAttributeType(sharedResourceAttribute.getSharedAttributeType());
+ }
+
+ private void validateIdFormat(String id) throws ResourceSharingPolicyMgtClientException {
+
+ if (isInvalidId(id)) {
+ throw new ResourceSharingPolicyMgtClientException(ERROR_CODE_INVALID_ID.getCode(),
+ ERROR_CODE_INVALID_ID.getMessage(), ERROR_CODE_INVALID_ID.getDescription());
+ }
+ }
+
+ private void validateIdFormat(List ids) throws ResourceSharingPolicyMgtClientException {
+
+ for (String id : ids) {
+ validateIdFormat(id);
+ }
+ }
+
+ private boolean isInvalidId(String id) {
+
+ return id == null || id.isEmpty();
+ }
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/OrganizationScope.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/OrganizationScope.java
new file mode 100644
index 000000000..4035ec023
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/OrganizationScope.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management.constant;
+
+/**
+ * Enum representing the organization scope for which a given policy is shared with.
+ */
+public enum OrganizationScope {
+ EXISTING_ORGS_ONLY,
+ EXISTING_ORGS_AND_FUTURE_ORGS_ONLY,
+ FUTURE_ORGS_ONLY,
+ NO_ORG,
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/PolicyEnum.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/PolicyEnum.java
new file mode 100644
index 000000000..2ee9bccbf
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/PolicyEnum.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management.constant;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Enum representing user sharing policies with additional fields for code, name, value, organization scope, applicable
+ * resources, and details.
+ */
+public enum PolicyEnum {
+
+ ALL_EXISTING_ORGS_ONLY(
+ "GENERAL-001",
+ "AllExistingOrgsOnly",
+ "ALL_EXISTING_ORGS_ONLY",
+ OrganizationScope.EXISTING_ORGS_ONLY,
+ Collections.singletonList(ResourceType.USER),
+ "This policy applies when the resource needs to be shared with all existing organizations at " +
+ "the current time. Newly created organizations after the policy is applied will not be included " +
+ "under this policy."),
+ ALL_EXISTING_AND_FUTURE_ORGS(
+ "GENERAL-002",
+ "AllExistingAndFutureOrgs",
+ "ALL_EXISTING_AND_FUTURE_ORGS",
+ OrganizationScope.EXISTING_ORGS_AND_FUTURE_ORGS_ONLY,
+ Collections.singletonList(ResourceType.USER),
+ "This policy allows sharing the resource with all current and any future organizations. It " +
+ "ensures that any new organizations created after the policy is set are automatically included."),
+ IMMEDIATE_EXISTING_ORGS_ONLY(
+ "GENERAL-003",
+ "ImmediateExistingOrgsOnly",
+ "IMMEDIATE_EXISTING_ORGS_ONLY",
+ OrganizationScope.EXISTING_ORGS_ONLY,
+ Collections.singletonList(ResourceType.USER),
+ "This policy is used to share the resource exclusively with all immediate existing child " +
+ "organizations. Newly created immediate child organizations after the policy is applied are " +
+ "not included."),
+ IMMEDIATE_EXISTING_AND_FUTURE_ORGS(
+ "GENERAL-004",
+ "ImmediateExistingAndFutureOrgs",
+ "IMMEDIATE_EXISTING_AND_FUTURE_ORGS",
+ OrganizationScope.EXISTING_ORGS_AND_FUTURE_ORGS_ONLY,
+ Collections.singletonList(ResourceType.USER),
+ "This policy is used to share the resource exclusively with all immediate existing child " +
+ "organizations. Newly created immediate child organizations after the policy is applied are " +
+ "not included."),
+ SELECTED_ORG_ONLY(
+ "SELECTIVE-001",
+ "SelectedOrgOnly",
+ "SELECTED_ORG_ONLY",
+ OrganizationScope.EXISTING_ORGS_ONLY,
+ Collections.singletonList(ResourceType.USER),
+ "This policy applies when the resource is to be shared with a single, specific organization " +
+ "only. Newly created child organizations under this selected organization will not be included."),
+ SELECTED_ORG_WITH_ALL_EXISTING_CHILDREN_ONLY(
+ "SELECTIVE-002",
+ "SelectedOrgWithAllExistingChildrenOnly",
+ "SELECTED_ORG_WITH_ALL_EXISTING_CHILDREN_ONLY",
+ OrganizationScope.EXISTING_ORGS_ONLY,
+ Collections.singletonList(ResourceType.USER),
+ "This policy ensures the resource is shared with a selected organization and all of its " +
+ "existing child organizations. New child organizations created under this selected organization " +
+ "after the policy is applied will not be included."),
+ SELECTED_ORG_WITH_ALL_EXISTING_AND_FUTURE_CHILDREN(
+ "SELECTIVE-003",
+ "SelectedOrgWithAllExistingAndFutureChildren",
+ "SELECTED_ORG_WITH_ALL_EXISTING_AND_FUTURE_CHILDREN",
+ OrganizationScope.EXISTING_ORGS_AND_FUTURE_ORGS_ONLY,
+ Collections.singletonList(ResourceType.USER),
+ "This policy ensures the resource is shared with a selected organization and all of its child " +
+ "organizations, including those created in the future."),
+ SELECTED_ORG_WITH_EXISTING_IMMEDIATE_CHILDREN_ONLY(
+ "SELECTIVE-004",
+ "SelectedOrgWithExistingImmediateChildrenOnly",
+ "SELECTED_ORG_WITH_EXISTING_IMMEDIATE_CHILDREN_ONLY",
+ OrganizationScope.EXISTING_ORGS_ONLY,
+ Collections.singletonList(ResourceType.USER),
+ "This policy shares the resource with a selected organization and all of its existing " +
+ "immediate child organizations. Newly created immediate children will not be included after " +
+ "the policy is applied."),
+ SELECTED_ORG_WITH_EXISTING_IMMEDIATE_AND_FUTURE_CHILDREN(
+ "SELECTIVE-005",
+ "SelectedOrgWithExistingImmediateAndFutureChildren",
+ "SELECTED_ORG_WITH_EXISTING_IMMEDIATE_AND_FUTURE_CHILDREN",
+ OrganizationScope.EXISTING_ORGS_AND_FUTURE_ORGS_ONLY,
+ Collections.singletonList(ResourceType.USER),
+ "This policy allows sharing the resource with a selected organization and all of its " +
+ "immediate child organizations, including those created in the future."),
+ NO_SHARING(
+ "NONE-000",
+ "NoSharing",
+ "NO_SHARING",
+ OrganizationScope.NO_ORG,
+ Collections.emptyList(),
+ "This policy specifies that no sharing will occur. The resource remains restricted to its " +
+ "current context and is not shared with any organization."
+ );
+
+ private final String policyCode;
+ private final String policyName;
+ private final String value;
+ private final OrganizationScope organizationScope;
+ private final List applicableResources;
+ private final String description;
+
+ /**
+ * Constructor to initialize the user sharing policy enum.
+ *
+ * @param policyCode Unique code representing the sharing policy.
+ * @param policyName Name of the sharing policy.
+ * @param value The value of the sharing policy.
+ * @param applicableResources Type of resources to which the policy applies.
+ * @param description Short description of the sharing policy.
+ */
+ PolicyEnum(String policyCode, String policyName, String value, OrganizationScope organizationScope,
+ List applicableResources, String description) {
+
+ this.policyCode = policyCode;
+ this.policyName = policyName;
+ this.value = value;
+ this.organizationScope = organizationScope;
+ this.applicableResources = applicableResources;
+ this.description = description;
+ }
+
+ /**
+ * Get the unique code of the sharing policy.
+ *
+ * @return Unique code of the sharing policy.
+ */
+ public String getPolicyCode() {
+
+ return policyCode;
+ }
+
+ /**
+ * Get the name of the sharing policy.
+ *
+ * @return Name of the sharing policy.
+ */
+ public String getPolicyName() {
+
+ return policyName;
+ }
+
+ /**
+ * Get the value of the sharing policy.
+ *
+ * @return Value of the sharing policy.
+ */
+ public String getValue() {
+
+ return value;
+ }
+
+ /**
+ * Get the organization scope of the sharing policy.
+ *
+ * @return {@link OrganizationScope} of the sharing policy.
+ */
+ public OrganizationScope getOrganizationScope() {
+
+ return organizationScope;
+ }
+
+ /**
+ * Get the applicable resource type for the sharing policy.
+ *
+ * @return Types of the applicable resources.
+ */
+ public List getApplicableResources() {
+
+ return applicableResources;
+ }
+
+ /**
+ * Get the short description of the sharing policy.
+ *
+ * @return Description of the sharing policy.
+ */
+ public String getDescription() {
+
+ return description;
+ }
+
+ /**
+ * Get the PolicyEnum based on the given policy code.
+ *
+ * @param policyCode Code of the sharing policy.
+ * @return Corresponding PolicyEnum, wrapped in Optional.
+ */
+ public static Optional getByPolicyCode(String policyCode) {
+
+ for (PolicyEnum policy : PolicyEnum.values()) {
+ if (policy.policyCode.equals(policyCode)) {
+ return Optional.of(policy);
+ }
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Get the PolicyEnum based on the given policy value.
+ *
+ * @param value Code of the sharing policy.
+ * @return Corresponding PolicyEnum, wrapped in Optional.
+ */
+ public static Optional getByValue(String value) {
+
+ for (PolicyEnum policy : PolicyEnum.values()) {
+ if (policy.value.equals(value)) {
+ return Optional.of(policy);
+ }
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Validate and get the PolicyEnum based on the given requested policy.
+ *
+ * @param requestedPolicy Requested policy as an Object (should be an instance of String).
+ * @return Corresponding PolicyEnum.
+ * @throws IllegalArgumentException if the requested policy is invalid or not found.
+ */
+ public static PolicyEnum validateAndGetPolicyEnum(String requestedPolicy) {
+
+ for (PolicyEnum policy : PolicyEnum.values()) {
+ if (policy.value.equalsIgnoreCase(requestedPolicy) ||
+ policy.policyCode.equalsIgnoreCase(requestedPolicy) ||
+ policy.policyName.equalsIgnoreCase(requestedPolicy)) {
+ return policy;
+ }
+ }
+ // Handle the case where no matching policy is found
+ throw new IllegalArgumentException("Invalid policy: " + requestedPolicy);
+ }
+
+ /**
+ * Get the PolicyEnum by matching value.
+ *
+ * @param value Policy value to match.
+ * @return Corresponding PolicyEnum.
+ * @throws IllegalArgumentException if the policy value is not found.
+ */
+ public static PolicyEnum getPolicyByValue(String value) {
+
+ for (PolicyEnum policy : PolicyEnum.values()) {
+ if (policy.value.equalsIgnoreCase(value)) {
+ return policy;
+ }
+ }
+ throw new IllegalArgumentException("Invalid policy value: " + value);
+ }
+
+ /**
+ * Get the PolicyEnum by matching policy code.
+ *
+ * @param policyCode Policy code to match.
+ * @return Corresponding PolicyEnum.
+ * @throws IllegalArgumentException if the policy code is not found.
+ */
+ public static PolicyEnum getPolicyByPolicyCode(String policyCode) {
+
+ for (PolicyEnum policy : PolicyEnum.values()) {
+ if (policy.policyCode.equalsIgnoreCase(policyCode)) {
+ return policy;
+ }
+ }
+ throw new IllegalArgumentException("Invalid policy code: " + policyCode);
+ }
+
+ /**
+ * Get the PolicyEnum by matching policy name.
+ *
+ * @param policyName Policy name to match.
+ * @return Corresponding PolicyEnum.
+ * @throws IllegalArgumentException if the policy name is not found.
+ */
+ public static PolicyEnum getPolicyByPolicyName(String policyName) {
+
+ for (PolicyEnum policy : PolicyEnum.values()) {
+ if (policy.policyName.equalsIgnoreCase(policyName)) {
+ return policy;
+ }
+ }
+ throw new IllegalArgumentException("Invalid policy name: " + policyName);
+ }
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/ResourceSharingConstants.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/ResourceSharingConstants.java
new file mode 100644
index 000000000..3f716b9b5
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/ResourceSharingConstants.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management.constant;
+
+/**
+ * Constants for organization user sharing.
+ */
+public class ResourceSharingConstants {
+
+ public static final String SHARING_ERROR_PREFIX = "RSPM-";
+
+ /**
+ * Error messages for organization user sharing management related errors.
+ */
+ public enum ErrorMessage {
+
+ // Client Errors.
+ ERROR_CODE_MISSING_MANDATORY_FIELDS("60001",
+ "All fields are mandatory and must be provided.",
+ "One or more mandatory field is empty."),
+ ERROR_CODE_INAPPLICABLE_RESOURCE_TYPE_TO_POLICY("60002",
+ "The specified resource type is not supported by the selected sharing policy.",
+ "The resource sharing policy does not allow sharing for the provided resource type."),
+ ERROR_CODE_INVALID_ID("60003",
+ "ID is invalid.",
+ "ID cannot be null or empty."),
+
+ // Server Errors.
+ ERROR_CODE_RESOURCE_SHARING_POLICY_CREATION_FAILED("65001",
+ "Failed to create resource sharing policy.",
+ "An error occurred while creating the resource sharing policy in the database."),
+ ERROR_CODE_RESOURCE_SHARING_POLICY_DELETION_FAILED("65002",
+ "Failed to delete resource sharing policy.",
+ "An error occurred while deleting the resource sharing policy from the database."),
+ ERROR_CODE_RESOURCE_SHARED_RESOURCE_ATTRIBUTE_CREATION_FAILED("65003",
+ "Failed to add shared resource attributes for policy ID: %d. Failed attributes: %s",
+ "An error occurred while creating the shared resource attributes in the database."),
+ ERROR_CODE_RESOURCE_SHARED_RESOURCE_ATTRIBUTE_DELETION_FAILED("65004",
+ "Failed to delete shared resource attributes for policy ID: %d. Failed attributes: %s",
+ "An error occurred while deleting the shared resource attributes in the database."),
+ ERROR_CODE_RESOURCE_SHARING_POLICY_AND_SHARED_RESOURCE_ATTRIBUTE_CREATION_FAILED("65005",
+ "Failed to create resource sharing policy and shared resource attributes.",
+ "An error occurred while creating the resource sharing policy and shared resource " +
+ "attributes in the database."),
+ ERROR_CODE_RETRIEVING_SHARED_RESOURCE_ATTRIBUTES_FAILED("65006",
+ "Failed to retrieve shared resource attributes.",
+ "An error occurred while retrieving the shared resource attributes from the database."),
+ ERROR_CODE_CREATION_OF_SHARED_RESOURCE_ATTRIBUTE_BUILDER_FAILED("65007",
+ "Failed to create shared resource attributes builder.",
+ "An error occurred while creating the shared resource attributes builder from the database."),
+ ERROR_CODE_RETRIEVING_RESOURCE_SHARING_POLICY_FAILED("65008",
+ "Failed to retrieve resource sharing policies.",
+ "An error occurred while retrieving the resource sharing policies from the database."),
+ ERROR_CODE_RETRIEVING_SHARED_RESOURCE_ATTRIBUTES_BY_RESOURCE_ID_AND_TYPE_FAILED("65009",
+ "Failed to retrieve shared resource attributes by resource ID and type.",
+ "An error occurred while retrieving shared resource attributes from the database by " +
+ "resource ID and type."),
+ ERROR_CODE_RESOURCE_SHARING_POLICY_DELETION_BY_RESOURCE_TYPE_AND_ID_FAILED("65010",
+ "Failed to delete resource sharing policy by type and ID.",
+ "An error occurred while deleting the resource sharing policy by resource type and ID " +
+ "from the database."),
+ ERROR_CODE_SHARED_RESOURCE_ATTRIBUTE_DELETION_BY_ATTRIBUTE_TYPE_AND_ID_FAILED("65011",
+ "Failed to delete shared resource attribute by type and ID.",
+ "An error occurred while deleting the shared resource attribute by attribute type and ID " +
+ "from the database.");
+
+ private final String code;
+ private final String message;
+ private final String description;
+
+ ErrorMessage(String code, String message, String description) {
+
+ this.code = code;
+ this.message = message;
+ this.description = description;
+ }
+
+ public String getCode() {
+
+ return SHARING_ERROR_PREFIX + code;
+ }
+
+ public String getMessage() {
+
+ return message;
+ }
+
+ public String getDescription() {
+
+ return description;
+ }
+
+ @Override
+ public String toString() {
+
+ return String.format("ErrorMessage{code='%s', message='%s', description='%s'}",
+ getCode(), getMessage(), getDescription());
+ }
+ }
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/ResourceSharingSQLConstants.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/ResourceSharingSQLConstants.java
new file mode 100644
index 000000000..08846f66c
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/ResourceSharingSQLConstants.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management.constant;
+
+/**
+ * SQL constants for resource sharing policy management.
+ */
+public class ResourceSharingSQLConstants {
+
+ // SQL for creating a resource sharing policy.
+ public static final String CREATE_RESOURCE_SHARING_POLICY =
+ "INSERT INTO UM_RESOURCE_SHARING_POLICY (UM_RESOURCE_ID, UM_RESOURCE_TYPE, " +
+ "UM_INITIATING_ORG_ID, UM_POLICY_HOLDING_ORG_ID, UM_SHARING_POLICY) VALUES (" +
+ ":" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_RESOURCE_ID + ";, " +
+ ":" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_RESOURCE_TYPE + ";, " +
+ ":" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_INITIATING_ORG_ID + ";, " +
+ ":" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_POLICY_HOLDING_ORG_ID + ";, " +
+ ":" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_SHARING_POLICY + ";)";
+
+ // SQL for retrieving resource sharing policy by resource sharing policy ID.
+ public static final String GET_RESOURCE_SHARING_POLICY_BY_ID =
+ "SELECT UM_ID, UM_RESOURCE_ID, UM_RESOURCE_TYPE, UM_INITIATING_ORG_ID, " +
+ "UM_POLICY_HOLDING_ORG_ID, UM_SHARING_POLICY " +
+ "FROM UM_RESOURCE_SHARING_POLICY WHERE UM_ID = " +
+ ":" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_UM_ID + ";";
+
+ // SQL HEAD constant for retrieving resource sharing policies by organization IDs.
+ public static final String GET_RESOURCE_SHARING_POLICIES_BY_ORG_IDS_HEAD =
+ "SELECT UM_ID, UM_RESOURCE_ID, UM_RESOURCE_TYPE, UM_INITIATING_ORG_ID, UM_POLICY_HOLDING_ORG_ID," +
+ " UM_SHARING_POLICY FROM UM_RESOURCE_SHARING_POLICY WHERE UM_POLICY_HOLDING_ORG_ID IN ";
+
+ public static final String GET_RESOURCE_SHARING_POLICIES_WITH_SHARED_ATTRIBUTES_BY_POLICY_HOLDING_ORGS_HEAD =
+ "SELECT rsp.UM_POLICY_HOLDING_ORG_ID, " +
+ "rsp.UM_ID AS " +
+ SQLPlaceholders.JOIN_COLUMN_UM_ID_OF_UM_RESOURCE_SHARING_POLICY_TABLE + ", " +
+ "rsp.UM_RESOURCE_ID, rsp.UM_RESOURCE_TYPE, rsp.UM_INITIATING_ORG_ID, " +
+ "rsp.UM_POLICY_HOLDING_ORG_ID, rsp.UM_SHARING_POLICY, " +
+ "attr.UM_ID AS " +
+ SQLPlaceholders.JOIN_COLUMN_UM_ID_OF_UM_SHARED_RESOURCE_ATTRIBUTES_TABLE + ", " +
+ "attr.UM_RESOURCE_SHARING_POLICY_ID, attr.UM_SHARED_ATTRIBUTE_TYPE, attr.UM_SHARED_ATTRIBUTE_ID " +
+ "FROM " +
+ "UM_RESOURCE_SHARING_POLICY rsp LEFT JOIN UM_SHARED_RESOURCE_ATTRIBUTES attr " +
+ "ON rsp.UM_ID = attr.UM_RESOURCE_SHARING_POLICY_ID " +
+ "WHERE rsp.UM_POLICY_HOLDING_ORG_ID IN (%s)";
+
+ // SQL for deleting resource sharing policy.
+ public static final String DELETE_RESOURCE_SHARING_POLICY =
+ "DELETE FROM UM_RESOURCE_SHARING_POLICY WHERE " +
+ "UM_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_UM_ID + "; AND " +
+ "UM_INITIATING_ORG_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_INITIATING_ORG_ID + ";";
+
+ // SQL for deleting resource sharing policy by resource type and ID.
+ public static final String DELETE_RESOURCE_SHARING_POLICY_BY_RESOURCE_TYPE_AND_ID =
+ "DELETE FROM UM_RESOURCE_SHARING_POLICY WHERE " +
+ "UM_RESOURCE_TYPE = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_RESOURCE_TYPE + "; AND " +
+ "UM_RESOURCE_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_RESOURCE_ID + "; AND " +
+ "UM_INITIATING_ORG_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_INITIATING_ORG_ID + ";";
+
+ // SQL constant for inserting a shared resource attribute.
+ public static final String CREATE_SHARED_RESOURCE_ATTRIBUTE =
+ "INSERT INTO UM_SHARED_RESOURCE_ATTRIBUTES " +
+ "(UM_RESOURCE_SHARING_POLICY_ID, UM_SHARED_ATTRIBUTE_ID, UM_SHARED_ATTRIBUTE_TYPE) VALUES (" +
+ ":" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_RESOURCE_SHARING_POLICY_ID + ";, " +
+ ":" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_ID + ";, " +
+ ":" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_TYPE + ";)";
+
+ // SQL for retrieving shared resource attributes.
+ public static final String GET_SHARED_RESOURCE_ATTRIBUTES =
+ "SELECT UM_ID, UM_RESOURCE_SHARING_POLICY_ID, UM_SHARED_ATTRIBUTE_TYPE, UM_SHARED_ATTRIBUTE_ID " +
+ "FROM UM_SHARED_RESOURCE_ATTRIBUTES WHERE UM_RESOURCE_SHARING_POLICY_ID = " +
+ ":" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_RESOURCE_SHARING_POLICY_ID + ";";
+
+ // SQL for retrieving shared resource attributes by attribute type.
+ public static final String GET_SHARED_RESOURCE_ATTRIBUTES_BY_ATTRIBUTE_TYPE =
+ "SELECT UM_ID, UM_RESOURCE_SHARING_POLICY_ID, UM_SHARED_ATTRIBUTE_TYPE, UM_SHARED_ATTRIBUTE_ID " +
+ "FROM UM_SHARED_RESOURCE_ATTRIBUTES WHERE " +
+ "UM_SHARED_ATTRIBUTE_TYPE = " +
+ ":" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_TYPE + ";";
+
+ // SQL for retrieving shared resource attributes by attribute ID.
+ public static final String GET_SHARED_RESOURCE_ATTRIBUTES_BY_ATTRIBUTE_ID =
+ "SELECT UM_ID, UM_RESOURCE_SHARING_POLICY_ID, UM_SHARED_ATTRIBUTE_TYPE, UM_SHARED_ATTRIBUTE_ID " +
+ "FROM UM_SHARED_RESOURCE_ATTRIBUTES WHERE " +
+ "UM_SHARED_ATTRIBUTE_ID = " +
+ ":" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_ID + ";";
+
+ // SQL for retrieving shared resource attributes by attribute type and ID.
+ public static final String GET_SHARED_RESOURCE_ATTRIBUTES_BY_ATTRIBUTE_TYPE_AND_ID =
+ "SELECT UM_ID, UM_RESOURCE_SHARING_POLICY_ID, UM_SHARED_ATTRIBUTE_TYPE, UM_SHARED_ATTRIBUTE_ID " +
+ "FROM UM_SHARED_RESOURCE_ATTRIBUTES WHERE " +
+ "UM_SHARED_ATTRIBUTE_TYPE = " +
+ ":" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_TYPE + "; AND " +
+ "UM_SHARED_ATTRIBUTE_ID = " +
+ ":" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_ID + ";";
+
+ // SQL for deleting shared resource attributes.
+ public static final String DELETE_SHARED_RESOURCE_ATTRIBUTE =
+ "DELETE FROM UM_SHARED_RESOURCE_ATTRIBUTES WHERE " +
+ "UM_RESOURCE_SHARING_POLICY_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_RESOURCE_SHARING_POLICY_ID + "; AND " +
+ "UM_SHARED_ATTRIBUTE_TYPE = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_TYPE + "; AND " +
+ "UM_RESOURCE_SHARING_POLICY_ID IN (SELECT UM_ID FROM UM_RESOURCE_SHARING_POLICY WHERE " +
+ "UM_INITIATING_ORG_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_INITIATING_ORG_ID + ";)";
+
+ // SQL for deleting shared resource attribute by attribute type and ID.
+ public static final String DELETE_SHARED_RESOURCE_ATTRIBUTE_BY_ATTRIBUTE_TYPE_AND_ID =
+ "DELETE FROM UM_SHARED_RESOURCE_ATTRIBUTES WHERE " +
+ "UM_SHARED_ATTRIBUTE_TYPE = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_TYPE + "; AND " +
+ "UM_SHARED_ATTRIBUTE_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_ID + "; AND " +
+ "UM_RESOURCE_SHARING_POLICY_ID IN (SELECT UM_ID FROM UM_RESOURCE_SHARING_POLICY WHERE " +
+ "UM_INITIATING_ORG_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_INITIATING_ORG_ID + ";)";
+
+ private ResourceSharingSQLConstants() {
+
+ }
+
+ /**
+ * SQL Placeholders.
+ */
+ public static final class SQLPlaceholders {
+
+ public static final String DB_SCHEMA_COLUMN_NAME_UM_ID = "UM_ID";
+ public static final String DB_SCHEMA_COLUMN_NAME_RESOURCE_ID = "UM_RESOURCE_ID";
+ public static final String DB_SCHEMA_COLUMN_NAME_RESOURCE_TYPE = "UM_RESOURCE_TYPE";
+ public static final String DB_SCHEMA_COLUMN_NAME_INITIATING_ORG_ID = "UM_INITIATING_ORG_ID";
+ public static final String DB_SCHEMA_COLUMN_NAME_POLICY_HOLDING_ORG_ID = "UM_POLICY_HOLDING_ORG_ID";
+ public static final String DB_SCHEMA_COLUMN_NAME_SHARING_POLICY = "UM_SHARING_POLICY";
+ public static final String DB_SCHEMA_COLUMN_NAME_RESOURCE_SHARING_POLICY_ID = "UM_RESOURCE_SHARING_POLICY_ID";
+ public static final String DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_ID = "UM_SHARED_ATTRIBUTE_ID";
+ public static final String DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_TYPE = "UM_SHARED_ATTRIBUTE_TYPE";
+
+ public static final String JOIN_COLUMN_UM_ID_OF_UM_RESOURCE_SHARING_POLICY_TABLE = "POLICY_ID";
+ public static final String JOIN_COLUMN_UM_ID_OF_UM_SHARED_RESOURCE_ATTRIBUTES_TABLE = "ATTRIBUTE_ID";
+
+ private SQLPlaceholders() {
+
+ }
+ }
+
+}
+
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/ResourceType.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/ResourceType.java
new file mode 100644
index 000000000..a9b0a550d
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/ResourceType.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management.constant;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Enum representing the type of resource being shared.
+ */
+public enum ResourceType {
+ USER(Collections.singletonList(SharedAttributeType.ROLE));
+
+ private final List applicableAttributes;
+
+ ResourceType(List applicableAttributes) {
+
+ this.applicableAttributes = applicableAttributes;
+ }
+
+ /**
+ * Checks if the given SharedAttributeType is applicable for this ResourceType.
+ *
+ * @param attributeType The shared attribute type to be checked.
+ * @return True if the attribute type is applicable, false otherwise.
+ */
+ public boolean isApplicableAttributeType(SharedAttributeType attributeType) {
+
+ return applicableAttributes.contains(attributeType);
+ }
+
+ /**
+ * Returns the list of applicable shared attribute types for this resource type.
+ *
+ * @return List of applicable shared attribute types.
+ */
+ public List getApplicableAttributes() {
+
+ return applicableAttributes;
+ }
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/SharedAttributeType.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/SharedAttributeType.java
new file mode 100644
index 000000000..41a58e35d
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constant/SharedAttributeType.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management.constant;
+
+/**
+ * Enum representing the type of shared attribute.
+ */
+public enum SharedAttributeType {
+ ROLE
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/dao/ResourceSharingPolicyHandlerDAO.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/dao/ResourceSharingPolicyHandlerDAO.java
new file mode 100644
index 000000000..9cb862073
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/dao/ResourceSharingPolicyHandlerDAO.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management.dao;
+
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceType;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.SharedAttributeType;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.exception.ResourceSharingPolicyMgtServerException;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.model.ResourceSharingPolicy;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.model.SharedResourceAttribute;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * DAO interface for handling resource sharing policies across organizations.
+ *
+ * This interface provides methods for adding, retrieving, and deleting resource sharing policies.
+ * It also allows managing shared resource attributes, offering capabilities to add, retrieve, and delete
+ * these attributes.
+ *
+ */
+public interface ResourceSharingPolicyHandlerDAO {
+
+ /**
+ * Adds a new resource sharing policy to the database and returns its unique identifier.
+ *
+ * @param resourceSharingPolicy The {@link ResourceSharingPolicy} containing details such as resource type,
+ * initiating organization, policy holding organization, and sharing policy.
+ * Must not be {@code null}.
+ * @return The unique identifier of the newly created resource sharing policy.
+ * @throws ResourceSharingPolicyMgtServerException If an error occurs while adding the resource sharing policy.
+ */
+ int addResourceSharingPolicy(ResourceSharingPolicy resourceSharingPolicy)
+ throws ResourceSharingPolicyMgtServerException;
+
+ /**
+ * Retrieves a resource sharing policy by its unique identifier, if present.
+ *
+ * @param resourceSharingPolicyId The unique identifier of the resource sharing policy to be retrieved.
+ * Must be a valid ID greater than zero.
+ * @return An {@link Optional} containing the {@link ResourceSharingPolicy} if found,
+ * or an empty {@link Optional} if no matching resource sharing policy exists.
+ * @throws ResourceSharingPolicyMgtServerException If an error occurs while retrieving the resource sharing policy.
+ */
+ Optional getResourceSharingPolicyById(int resourceSharingPolicyId)
+ throws ResourceSharingPolicyMgtServerException;
+
+
+ /**
+ * Retrieves a list of resource sharing policies associated with the given policy holding organization IDs.
+ *
+ * @param policyHoldingOrganizationIds A list of organization IDs whose policies need to be retrieved.
+ * Must not be {@code null} or empty.
+ * @return A list of {@link ResourceSharingPolicy} objects for the specified organization IDs.
+ * @throws ResourceSharingPolicyMgtServerException If an error occurs while retrieving the resource sharing
+ * policies.
+ */
+ List getResourceSharingPolicies(List policyHoldingOrganizationIds)
+ throws ResourceSharingPolicyMgtServerException;
+
+ /**
+ * Retrieves a map of resource sharing policies grouped by resource type for the given policy holding
+ * organization IDs.
+ *
+ * @param policyHoldingOrganizationIds A list of organization IDs whose policies need to be retrieved.
+ * Must not be {@code null} or empty.
+ * @return A map where each key is a {@link ResourceType} and the corresponding value is a list of
+ * {@link ResourceSharingPolicy}.
+ * @throws ResourceSharingPolicyMgtServerException If an error occurs while retrieving the resource sharing
+ * policies.
+ */
+ Map> getResourceSharingPoliciesGroupedByResourceType(
+ List policyHoldingOrganizationIds) throws ResourceSharingPolicyMgtServerException;
+
+ /**
+ * Retrieves a map of resource sharing policies grouped by policy holding organization ID for the given policy
+ * holding organization IDs.
+ *
+ * @param policyHoldingOrganizationIds A list of organization IDs whose policies need to be retrieved.
+ * Must not be {@code null} or empty.
+ * @return A map where each key is an organization ID, and the value is a list of {@link ResourceSharingPolicy}.
+ * @throws ResourceSharingPolicyMgtServerException If an error occurs while retrieving the resource sharing
+ * policies.
+ */
+ Map> getResourceSharingPoliciesGroupedByPolicyHoldingOrgId(
+ List policyHoldingOrganizationIds) throws ResourceSharingPolicyMgtServerException;
+
+ /**
+ * Deletes a resource sharing policy by its unique identifier if the specified organization has permission.
+ *
+ * @param resourceSharingPolicyId The unique identifier of the resource sharing policy to be deleted.
+ * @param sharingPolicyInitiatedOrgId The ID of the organization initiating the share request.
+ * The deletion will only be successful if the initiating organization
+ * has permission to delete sharing policies.
+ * Must not be {@code null}.
+ * @throws ResourceSharingPolicyMgtServerException If an error occurs while deleting the resource sharing policy.
+ */
+ void deleteResourceSharingPolicyRecordById(int resourceSharingPolicyId, String sharingPolicyInitiatedOrgId)
+ throws ResourceSharingPolicyMgtServerException;
+
+ /**
+ * Deletes a resource sharing policy based on its resource type and resource ID if permitted.
+ *
+ * @param resourceType The {@link ResourceType} of the resource.
+ * @param resourceId The unique identifier of the resource whose sharing policy is to be deleted.
+ * @param sharingPolicyInitiatedOrgId The ID of the organization initiating the share request.
+ * The deletion will only be successful if the initiating organization
+ * has permission to delete sharing policies.
+ * @throws ResourceSharingPolicyMgtServerException If an error occurs while deleting the resource sharing policy.
+ */
+ void deleteResourceSharingPolicyByResourceTypeAndId(ResourceType resourceType, String resourceId,
+ String sharingPolicyInitiatedOrgId)
+ throws ResourceSharingPolicyMgtServerException;
+
+ /**
+ * Adds shared resource attributes to an existing resource sharing policy.
+ *
+ * @param sharedResourceAttributes A list of {@link SharedResourceAttribute} objects to be added.
+ * Must not be {@code null} or empty.
+ * @return {@code true} if the shared resource attributes were added successfully.
+ * @throws ResourceSharingPolicyMgtServerException If an error occurs while adding the shared resource attributes.
+ */
+ boolean addSharedResourceAttributes(List sharedResourceAttributes)
+ throws ResourceSharingPolicyMgtServerException;
+
+ /**
+ * Retrieves shared resource attributes for a given resource sharing policy.
+ *
+ * @param resourceSharingPolicyId The unique identifier of the resource sharing policy.
+ * @return A list of {@link SharedResourceAttribute} associated with the given policy.
+ * @throws ResourceSharingPolicyMgtServerException If an error occurs while retrieving the shared resource
+ * attributes.
+ */
+ List getSharedResourceAttributesBySharingPolicyId(int resourceSharingPolicyId)
+ throws ResourceSharingPolicyMgtServerException;
+
+ /**
+ * Retrieves shared resource attributes based on attribute type.
+ *
+ * @param attributeType The {@link SharedAttributeType} of the resource attribute to be retrieved.
+ * @return A list of {@link SharedResourceAttribute} objects for the specified type.
+ * @throws ResourceSharingPolicyMgtServerException If an error occurs while retrieving the shared resource
+ * attributes.
+ */
+ List getSharedResourceAttributesByType(SharedAttributeType attributeType)
+ throws ResourceSharingPolicyMgtServerException;
+
+ /**
+ * Retrieves shared resource attributes based on attribute ID.
+ *
+ * @param attributeId The unique identifier of the resource attribute to be retrieved.
+ * @return A list of {@link SharedResourceAttribute} objects for the specified attribute ID.
+ * @throws ResourceSharingPolicyMgtServerException If an error occurs while retrieving the shared resource
+ * attributes.
+ */
+ List getSharedResourceAttributesById(String attributeId)
+ throws ResourceSharingPolicyMgtServerException;
+
+ /**
+ * Retrieves shared resource attributes based on attribute type and ID.
+ *
+ * @param attributeType The {@link SharedAttributeType} of the resource attribute to be retrieved.
+ * @param attributeId The unique identifier of the attribute to be retrieved.
+ * @return A list of {@link SharedResourceAttribute} objects for the specified type and ID.
+ * @throws ResourceSharingPolicyMgtServerException If an error occurs while retrieving the shared resource
+ * attributes.
+ */
+ List getSharedResourceAttributesByTypeAndId(SharedAttributeType attributeType,
+ String attributeId)
+ throws ResourceSharingPolicyMgtServerException;
+
+ /**
+ * Deletes shared resource attributes for a given resource sharing policy and attribute type if the specified
+ * organization has permission.
+ *
+ * @param resourceSharingPolicyId The unique identifier of the resource sharing policy.
+ * @param sharedAttributeType The {@link SharedAttributeType} to be deleted.
+ * @param sharingPolicyInitiatedOrgId The ID of the organization initiating the share request.
+ * The deletion will only be successful if the initiating organization
+ * has permission to delete shared attributes.
+ * @throws ResourceSharingPolicyMgtServerException If an error occurs while deleting the shared resource attributes.
+ */
+ void deleteSharedResourceAttributesByResourceSharingPolicyId(int resourceSharingPolicyId,
+ SharedAttributeType sharedAttributeType,
+ String sharingPolicyInitiatedOrgId)
+ throws ResourceSharingPolicyMgtServerException;
+
+ /**
+ * Deletes a shared resource attribute based on its attribute type and unique identifier if the specified
+ * organization has permission.
+ *
+ * @param attributeType The {@link SharedAttributeType} of the attribute to be deleted.
+ * @param attributeId The unique identifier of the attribute to be deleted.
+ * @param sharingPolicyInitiatedOrgId The ID of the organization initiating the share request.
+ * The deletion will only be successful if the initiating organization
+ * has permission to delete shared attributes.
+ * @throws ResourceSharingPolicyMgtServerException If an error occurs while deleting the shared resource attribute.
+ */
+ void deleteSharedResourceAttributeByAttributeTypeAndId(SharedAttributeType attributeType, String attributeId,
+ String sharingPolicyInitiatedOrgId)
+ throws ResourceSharingPolicyMgtServerException;
+
+ /**
+ * Adds a resource sharing policy along with its associated shared resource attributes in a single transaction.
+ *
+ * @param resourceSharingPolicy The {@link ResourceSharingPolicy} containing details such as resource type,
+ * initiating organization, policy holding organization, and sharing policy.
+ * Must not be {@code null}.
+ * @param sharedResourceAttributes A list of {@link SharedResourceAttribute} objects associated with the resource
+ * sharing policy. Must not be {@code null} or empty.
+ * @return {@code true} if both the resource sharing policy and the shared resource attributes were added
+ * successfully.
+ * @throws ResourceSharingPolicyMgtServerException If an error occurs while adding the resource sharing policy or
+ * the shared resource attributes.
+ */
+ boolean addResourceSharingPolicyWithAttributes(ResourceSharingPolicy resourceSharingPolicy,
+ List sharedResourceAttributes)
+ throws ResourceSharingPolicyMgtServerException;
+
+ /**
+ * Retrieves a map of resource sharing policies along with their associated shared resource attributes
+ * for the given list of policy holding organization IDs.
+ *
+ * @param policyHoldingOrganizationIds A list of organization IDs whose resource sharing policies along with
+ * shared resource attributes need to be retrieved.
+ * Must not be {@code null} or empty.
+ * @return A nested map where:
+ * - The first key is the organization ID.
+ * - The second key is the {@link ResourceSharingPolicy}.
+ * - The value is a list of {@link SharedResourceAttribute} associated with the policy.
+ * If no matching policies or attributes are found, an empty map will be returned.
+ * @throws ResourceSharingPolicyMgtServerException If an error occurs while retrieving the resource sharing
+ * policies or shared attributes.
+ */
+ Map>>
+ getResourceSharingPoliciesWithSharedAttributes(List policyHoldingOrganizationIds)
+ throws ResourceSharingPolicyMgtServerException;
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/dao/ResourceSharingPolicyHandlerDAOImpl.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/dao/ResourceSharingPolicyHandlerDAOImpl.java
new file mode 100644
index 000000000..6b452ba6a
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/dao/ResourceSharingPolicyHandlerDAOImpl.java
@@ -0,0 +1,443 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management.dao;
+
+import org.wso2.carbon.database.utils.jdbc.NamedJdbcTemplate;
+import org.wso2.carbon.database.utils.jdbc.NamedPreparedStatement;
+import org.wso2.carbon.database.utils.jdbc.exceptions.DataAccessException;
+import org.wso2.carbon.database.utils.jdbc.exceptions.TransactionException;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.PolicyEnum;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceType;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.SharedAttributeType;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.exception.ResourceSharingPolicyMgtServerException;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.model.ResourceSharingPolicy;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.model.ResourceSharingPolicyWithAttributes;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.model.SharedResourceAttribute;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static org.wso2.carbon.identity.organization.management.service.util.Utils.getNewTemplate;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingConstants.ErrorMessage.ERROR_CODE_RESOURCE_SHARED_RESOURCE_ATTRIBUTE_CREATION_FAILED;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingConstants.ErrorMessage.ERROR_CODE_RESOURCE_SHARED_RESOURCE_ATTRIBUTE_DELETION_FAILED;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingConstants.ErrorMessage.ERROR_CODE_RESOURCE_SHARING_POLICY_AND_SHARED_RESOURCE_ATTRIBUTE_CREATION_FAILED;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingConstants.ErrorMessage.ERROR_CODE_RESOURCE_SHARING_POLICY_CREATION_FAILED;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingConstants.ErrorMessage.ERROR_CODE_RESOURCE_SHARING_POLICY_DELETION_BY_RESOURCE_TYPE_AND_ID_FAILED;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingConstants.ErrorMessage.ERROR_CODE_RESOURCE_SHARING_POLICY_DELETION_FAILED;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingConstants.ErrorMessage.ERROR_CODE_RETRIEVING_RESOURCE_SHARING_POLICY_FAILED;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingConstants.ErrorMessage.ERROR_CODE_RETRIEVING_SHARED_RESOURCE_ATTRIBUTES_BY_RESOURCE_ID_AND_TYPE_FAILED;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingConstants.ErrorMessage.ERROR_CODE_RETRIEVING_SHARED_RESOURCE_ATTRIBUTES_FAILED;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingConstants.ErrorMessage.ERROR_CODE_SHARED_RESOURCE_ATTRIBUTE_DELETION_BY_ATTRIBUTE_TYPE_AND_ID_FAILED;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.CREATE_RESOURCE_SHARING_POLICY;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.CREATE_SHARED_RESOURCE_ATTRIBUTE;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.DELETE_RESOURCE_SHARING_POLICY;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.DELETE_RESOURCE_SHARING_POLICY_BY_RESOURCE_TYPE_AND_ID;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.DELETE_SHARED_RESOURCE_ATTRIBUTE;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.DELETE_SHARED_RESOURCE_ATTRIBUTE_BY_ATTRIBUTE_TYPE_AND_ID;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.GET_RESOURCE_SHARING_POLICIES_BY_ORG_IDS_HEAD;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.GET_RESOURCE_SHARING_POLICIES_WITH_SHARED_ATTRIBUTES_BY_POLICY_HOLDING_ORGS_HEAD;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.GET_RESOURCE_SHARING_POLICY_BY_ID;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.GET_SHARED_RESOURCE_ATTRIBUTES;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.GET_SHARED_RESOURCE_ATTRIBUTES_BY_ATTRIBUTE_ID;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.GET_SHARED_RESOURCE_ATTRIBUTES_BY_ATTRIBUTE_TYPE;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.GET_SHARED_RESOURCE_ATTRIBUTES_BY_ATTRIBUTE_TYPE_AND_ID;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_INITIATING_ORG_ID;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_POLICY_HOLDING_ORG_ID;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_RESOURCE_ID;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_RESOURCE_SHARING_POLICY_ID;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_RESOURCE_TYPE;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_ID;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_TYPE;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_SHARING_POLICY;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_UM_ID;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingSQLConstants.SQLPlaceholders.JOIN_COLUMN_UM_ID_OF_UM_SHARED_RESOURCE_ATTRIBUTES_TABLE;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.util.ResourceSharingUtils.handleServerException;
+
+/**
+ * DAO implementation for handling resource sharing policies.
+ */
+public class ResourceSharingPolicyHandlerDAOImpl implements ResourceSharingPolicyHandlerDAO {
+
+ @Override
+ public int addResourceSharingPolicy(ResourceSharingPolicy resourceSharingPolicy)
+ throws ResourceSharingPolicyMgtServerException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ return namedJdbcTemplate.executeInsert(CREATE_RESOURCE_SHARING_POLICY, namedPreparedStatement -> {
+ setResourceSharingPolicyParameters(namedPreparedStatement, resourceSharingPolicy);
+ }, null, true, DB_SCHEMA_COLUMN_NAME_UM_ID);
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_RESOURCE_SHARING_POLICY_CREATION_FAILED, e,
+ resourceSharingPolicy.getResourceType(), resourceSharingPolicy.getResourceId());
+ }
+ }
+
+ @Override
+ public Optional getResourceSharingPolicyById(int resourceSharingPolicyId)
+ throws ResourceSharingPolicyMgtServerException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+
+ try {
+ return Optional.ofNullable(namedJdbcTemplate.fetchSingleRecord(
+ GET_RESOURCE_SHARING_POLICY_BY_ID,
+ (resultSet, rowNum) -> retrieveResourceSharingPolicyRecordFromDB(resultSet),
+ namedPreparedStatement ->
+ namedPreparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_UM_ID, resourceSharingPolicyId)));
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_RETRIEVING_RESOURCE_SHARING_POLICY_FAILED);
+ }
+ }
+
+ @Override
+ public List getResourceSharingPolicies(List policyHoldingOrganizationIds)
+ throws ResourceSharingPolicyMgtServerException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+
+ // Dynamically build placeholders for the query
+ String placeholders = policyHoldingOrganizationIds.stream()
+ .map(id -> "?")
+ .collect(Collectors.joining(","));
+ String query = GET_RESOURCE_SHARING_POLICIES_BY_ORG_IDS_HEAD + "(" + placeholders + ");";
+
+ try {
+ return namedJdbcTemplate.executeQuery(query,
+ (resultSet, rowNumber) -> retrieveResourceSharingPolicyRecordFromDB(resultSet),
+ preparedStatement -> {
+ for (int i = 0; i < policyHoldingOrganizationIds.size(); i++) {
+ preparedStatement.setString(i + 1, policyHoldingOrganizationIds.get(i));
+ }
+ });
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_RETRIEVING_RESOURCE_SHARING_POLICY_FAILED);
+ }
+ }
+
+ @Override
+ public Map> getResourceSharingPoliciesGroupedByResourceType(
+ List policyHoldingOrganizationIds) throws ResourceSharingPolicyMgtServerException {
+
+ List resourceSharingPolicies = getResourceSharingPolicies(policyHoldingOrganizationIds);
+ return resourceSharingPolicies.stream().collect(Collectors.groupingBy(ResourceSharingPolicy::getResourceType));
+ }
+
+ @Override
+ public Map> getResourceSharingPoliciesGroupedByPolicyHoldingOrgId(
+ List policyHoldingOrganizationIds) throws ResourceSharingPolicyMgtServerException {
+
+ List resourceSharingPolicies = getResourceSharingPolicies(policyHoldingOrganizationIds);
+ return resourceSharingPolicies.stream()
+ .collect(Collectors.groupingBy(ResourceSharingPolicy::getPolicyHoldingOrgId));
+ }
+
+ @Override
+ public void deleteResourceSharingPolicyRecordById(int resourceSharingPolicyId,
+ String sharingPolicyInitiatedOrgId)
+ throws ResourceSharingPolicyMgtServerException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ namedJdbcTemplate.executeUpdate(DELETE_RESOURCE_SHARING_POLICY,
+ namedPreparedStatement -> {
+ namedPreparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_UM_ID, resourceSharingPolicyId);
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_INITIATING_ORG_ID,
+ sharingPolicyInitiatedOrgId);
+ });
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_RESOURCE_SHARING_POLICY_DELETION_FAILED);
+ }
+ }
+
+ @Override
+ public void deleteResourceSharingPolicyByResourceTypeAndId(ResourceType resourceType, String resourceId,
+ String sharingPolicyInitiatedOrgId)
+ throws ResourceSharingPolicyMgtServerException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ namedJdbcTemplate.executeUpdate(DELETE_RESOURCE_SHARING_POLICY_BY_RESOURCE_TYPE_AND_ID,
+ namedPreparedStatement -> {
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_RESOURCE_TYPE,
+ resourceType.name());
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_RESOURCE_ID,
+ resourceId);
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_INITIATING_ORG_ID,
+ sharingPolicyInitiatedOrgId);
+ });
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_RESOURCE_SHARING_POLICY_DELETION_BY_RESOURCE_TYPE_AND_ID_FAILED);
+ }
+ }
+
+ @Override
+ public boolean addSharedResourceAttributes(List sharedResourceAttributes)
+ throws ResourceSharingPolicyMgtServerException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+
+ try {
+ namedJdbcTemplate.withTransaction(template -> {
+ template.executeBatchInsert(CREATE_SHARED_RESOURCE_ATTRIBUTE, (namedPreparedStatement -> {
+ for (SharedResourceAttribute sharedResourceAttribute : sharedResourceAttributes) {
+ setSharedResourceAttributeParameters(namedPreparedStatement, sharedResourceAttribute);
+ }
+ }), null);
+ return true;
+ });
+ } catch (TransactionException e) {
+ throw handleServerException(ERROR_CODE_RESOURCE_SHARED_RESOURCE_ATTRIBUTE_CREATION_FAILED);
+ }
+ return true;
+ }
+
+ @Override
+ public List getSharedResourceAttributesBySharingPolicyId(int resourceSharingPolicyId)
+ throws ResourceSharingPolicyMgtServerException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ List sharedResourceAttributes = new ArrayList<>();
+
+ try {
+ namedJdbcTemplate.executeQuery(GET_SHARED_RESOURCE_ATTRIBUTES, (resultSet, rowNumber) -> {
+ sharedResourceAttributes.add(retrieveSharedResourceAttributeRecordFromDB(resultSet));
+ return null;
+ }, namedPreparedStatement -> namedPreparedStatement.setInt(
+ DB_SCHEMA_COLUMN_NAME_RESOURCE_SHARING_POLICY_ID,
+ resourceSharingPolicyId));
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_RETRIEVING_SHARED_RESOURCE_ATTRIBUTES_FAILED);
+ }
+ return sharedResourceAttributes;
+ }
+
+ @Override
+ public List getSharedResourceAttributesByType(SharedAttributeType attributeType)
+ throws ResourceSharingPolicyMgtServerException {
+
+ return getSharedResourceAttributes(GET_SHARED_RESOURCE_ATTRIBUTES_BY_ATTRIBUTE_TYPE, attributeType, null);
+ }
+
+ @Override
+ public List getSharedResourceAttributesById(String attributeId)
+ throws ResourceSharingPolicyMgtServerException {
+
+ return getSharedResourceAttributes(GET_SHARED_RESOURCE_ATTRIBUTES_BY_ATTRIBUTE_ID, null, attributeId);
+ }
+
+ @Override
+ public List getSharedResourceAttributesByTypeAndId(SharedAttributeType attributeType,
+ String attributeId)
+ throws ResourceSharingPolicyMgtServerException {
+
+ return getSharedResourceAttributes(GET_SHARED_RESOURCE_ATTRIBUTES_BY_ATTRIBUTE_TYPE_AND_ID, attributeType,
+ attributeId);
+ }
+
+ @Override
+ public void deleteSharedResourceAttributesByResourceSharingPolicyId(int resourceSharingPolicyId,
+ SharedAttributeType sharedAttributeType,
+ String sharingPolicyInitiatedOrgId)
+ throws ResourceSharingPolicyMgtServerException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ namedJdbcTemplate.executeUpdate(DELETE_SHARED_RESOURCE_ATTRIBUTE, namedPreparedStatement -> {
+ namedPreparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_RESOURCE_SHARING_POLICY_ID,
+ resourceSharingPolicyId);
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_TYPE,
+ sharedAttributeType.name());
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_INITIATING_ORG_ID,
+ sharingPolicyInitiatedOrgId);
+ });
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_RESOURCE_SHARED_RESOURCE_ATTRIBUTE_DELETION_FAILED);
+ }
+ }
+
+ @Override
+ public void deleteSharedResourceAttributeByAttributeTypeAndId(SharedAttributeType attributeType,
+ String attributeId,
+ String sharingPolicyInitiatedOrgId)
+ throws ResourceSharingPolicyMgtServerException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ namedJdbcTemplate.executeUpdate(DELETE_SHARED_RESOURCE_ATTRIBUTE_BY_ATTRIBUTE_TYPE_AND_ID,
+ namedPreparedStatement -> {
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_TYPE,
+ attributeType.name());
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_ID,
+ attributeId);
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_INITIATING_ORG_ID,
+ sharingPolicyInitiatedOrgId);
+ });
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_SHARED_RESOURCE_ATTRIBUTE_DELETION_BY_ATTRIBUTE_TYPE_AND_ID_FAILED);
+ }
+ }
+
+ @Override
+ public boolean addResourceSharingPolicyWithAttributes(ResourceSharingPolicy resourceSharingPolicy,
+ List sharedResourceAttributes)
+ throws ResourceSharingPolicyMgtServerException {
+
+ int resourceSharingPolicyId = addResourceSharingPolicy(resourceSharingPolicy);
+
+ sharedResourceAttributes.forEach(attribute -> attribute.setResourceSharingPolicyId(resourceSharingPolicyId));
+
+ try {
+ addSharedResourceAttributes(sharedResourceAttributes);
+ } catch (ResourceSharingPolicyMgtServerException e) {
+ deleteResourceSharingPolicyRecordById(resourceSharingPolicyId, resourceSharingPolicy.getInitiatingOrgId());
+ throw handleServerException(
+ ERROR_CODE_RESOURCE_SHARING_POLICY_AND_SHARED_RESOURCE_ATTRIBUTE_CREATION_FAILED);
+ }
+
+ return true;
+ }
+
+ @Override
+ public Map>>
+ getResourceSharingPoliciesWithSharedAttributes(List policyHoldingOrganizationIds)
+ throws ResourceSharingPolicyMgtServerException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+
+ String placeholders = policyHoldingOrganizationIds.stream().map(id -> "?").collect(Collectors.joining(","));
+ String query = String.format(GET_RESOURCE_SHARING_POLICIES_WITH_SHARED_ATTRIBUTES_BY_POLICY_HOLDING_ORGS_HEAD,
+ placeholders);
+
+ try {
+ List result = namedJdbcTemplate.executeQuery(query,
+ (resultSet, rowNumber) -> {
+ ResourceSharingPolicy policy = retrieveResourceSharingPolicyRecordFromDB(resultSet);
+ SharedResourceAttribute attribute = null;
+ if (resultSet.getString(JOIN_COLUMN_UM_ID_OF_UM_SHARED_RESOURCE_ATTRIBUTES_TABLE) != null) {
+ attribute = retrieveSharedResourceAttributeRecordFromDB(resultSet);
+ }
+ return new ResourceSharingPolicyWithAttributes(
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_POLICY_HOLDING_ORG_ID), policy, attribute);
+ },
+ namedPreparedStatement -> {
+ for (int i = 0; i < policyHoldingOrganizationIds.size(); i++) {
+ namedPreparedStatement.setString(i + 1, policyHoldingOrganizationIds.get(i));
+ }
+ });
+
+ return result.stream()
+ .collect(Collectors.groupingBy(
+ ResourceSharingPolicyWithAttributes::getPolicyHoldingOrgId,
+ Collectors.groupingBy(
+ ResourceSharingPolicyWithAttributes::getPolicy,
+ Collectors.mapping(ResourceSharingPolicyWithAttributes::getAttribute,
+ Collectors.toList())
+ )
+ ));
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_RETRIEVING_RESOURCE_SHARING_POLICY_FAILED);
+ }
+ }
+
+ private List getSharedResourceAttributes(String query, SharedAttributeType attributeType,
+ String attributeId)
+ throws ResourceSharingPolicyMgtServerException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ List sharedResourceAttributes = new ArrayList<>();
+
+ try {
+ namedJdbcTemplate.executeQuery(query, (resultSet, rowNumber) -> {
+ sharedResourceAttributes.add(retrieveSharedResourceAttributeRecordFromDB(resultSet));
+ return null;
+ }, namedPreparedStatement -> {
+ if (attributeType != null) {
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_TYPE, attributeType.name());
+ }
+ if (attributeId != null) {
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_ID, attributeId);
+ }
+ });
+ } catch (DataAccessException e) {
+ throw handleServerException(
+ ERROR_CODE_RETRIEVING_SHARED_RESOURCE_ATTRIBUTES_BY_RESOURCE_ID_AND_TYPE_FAILED);
+ }
+ return sharedResourceAttributes;
+ }
+
+ private ResourceSharingPolicy retrieveResourceSharingPolicyRecordFromDB(ResultSet resultSet) throws SQLException {
+
+ ResourceSharingPolicy policy = new ResourceSharingPolicy();
+ policy.setResourceSharingPolicyId(
+ resultSet.getInt(DB_SCHEMA_COLUMN_NAME_UM_ID));
+ policy.setResourceType(ResourceType.valueOf(
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_RESOURCE_TYPE)));
+ policy.setResourceId(
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_RESOURCE_ID));
+ policy.setInitiatingOrgId(
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_INITIATING_ORG_ID));
+ policy.setPolicyHoldingOrgId(
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_POLICY_HOLDING_ORG_ID));
+ policy.setSharingPolicy(
+ PolicyEnum.getPolicyByPolicyCode(resultSet.getString(DB_SCHEMA_COLUMN_NAME_SHARING_POLICY)));
+ return policy;
+ }
+
+ private SharedResourceAttribute retrieveSharedResourceAttributeRecordFromDB(ResultSet resultSet)
+ throws SQLException {
+
+ SharedResourceAttribute attributes = new SharedResourceAttribute();
+ attributes.setResourceSharingPolicyId(
+ resultSet.getInt(DB_SCHEMA_COLUMN_NAME_RESOURCE_SHARING_POLICY_ID));
+ attributes.setSharedAttributeType(SharedAttributeType.valueOf(
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_TYPE)));
+ attributes.setSharedAttributeId(
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_ID));
+ attributes.setSharedResourceAttributeId(
+ resultSet.getInt(DB_SCHEMA_COLUMN_NAME_UM_ID));
+ return attributes;
+ }
+
+ private void setResourceSharingPolicyParameters(NamedPreparedStatement namedPreparedStatement,
+ ResourceSharingPolicy policy) throws SQLException {
+
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_RESOURCE_TYPE, policy.getResourceType().name());
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_RESOURCE_ID, policy.getResourceId());
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_INITIATING_ORG_ID, policy.getInitiatingOrgId());
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_POLICY_HOLDING_ORG_ID, policy.getPolicyHoldingOrgId());
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_SHARING_POLICY,
+ policy.getSharingPolicy().getPolicyCode());
+ }
+
+ private void setSharedResourceAttributeParameters(NamedPreparedStatement namedPreparedStatement,
+ SharedResourceAttribute attribute) throws SQLException {
+
+ namedPreparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_RESOURCE_SHARING_POLICY_ID,
+ attribute.getResourceSharingPolicyId());
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_TYPE,
+ attribute.getSharedAttributeType().name());
+ namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_SHARED_ATTRIBUTE_ID, attribute.getSharedAttributeId());
+ }
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/exception/ResourceSharingPolicyMgtClientException.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/exception/ResourceSharingPolicyMgtClientException.java
new file mode 100644
index 000000000..6002fe649
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/exception/ResourceSharingPolicyMgtClientException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management.exception;
+
+/**
+ * Exception class for resource sharing policy management for client exceptions.
+ */
+public class ResourceSharingPolicyMgtClientException extends ResourceSharingPolicyMgtException {
+
+ public ResourceSharingPolicyMgtClientException(String errorCode, String message, String description) {
+
+ super(errorCode, message, description);
+ }
+
+ public ResourceSharingPolicyMgtClientException(String errorCode, String message, String description,
+ Throwable cause) {
+
+ super(errorCode, message, description, cause);
+ }
+
+ public ResourceSharingPolicyMgtClientException(String errorCode, String message, String description,
+ Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+
+ super(errorCode, message, description, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/exception/ResourceSharingPolicyMgtException.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/exception/ResourceSharingPolicyMgtException.java
new file mode 100644
index 000000000..09e4bf0e3
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/exception/ResourceSharingPolicyMgtException.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management.exception;
+
+/**
+ * Exception class for resource sharing policy management.
+ */
+public class ResourceSharingPolicyMgtException extends Exception {
+
+ private final String errorCode;
+ private final String description;
+
+ public ResourceSharingPolicyMgtException(String errorCode, String message, String description) {
+
+ super(message);
+ this.errorCode = errorCode;
+ this.description = description;
+ }
+
+ public ResourceSharingPolicyMgtException(String errorCode, String message, String description, Throwable cause) {
+
+ super(message, cause);
+ this.errorCode = errorCode;
+ this.description = description;
+ }
+
+ public ResourceSharingPolicyMgtException(String errorCode, String message, String description, Throwable cause,
+ boolean enableSuppression, boolean writableStackTrace) {
+
+ super(message, cause, enableSuppression, writableStackTrace);
+ this.errorCode = errorCode;
+ this.description = description;
+ }
+
+ public String getErrorCode() {
+
+ return errorCode;
+ }
+
+ public String getDescription() {
+
+ return description;
+ }
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/exception/ResourceSharingPolicyMgtServerException.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/exception/ResourceSharingPolicyMgtServerException.java
new file mode 100644
index 000000000..367595167
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/exception/ResourceSharingPolicyMgtServerException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management.exception;
+
+/**
+ * Exception class for resource sharing policy management for server exceptions.
+ */
+public class ResourceSharingPolicyMgtServerException extends ResourceSharingPolicyMgtException {
+
+ public ResourceSharingPolicyMgtServerException(String errorCode, String message, String description) {
+
+ super(errorCode, message, description);
+ }
+
+ public ResourceSharingPolicyMgtServerException(String errorCode, String message, String description,
+ Throwable cause) {
+
+ super(errorCode, message, description, cause);
+ }
+
+ public ResourceSharingPolicyMgtServerException(String errorCode, String message, String description,
+ Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+
+ super(errorCode, message, description, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/internal/ResourceSharingPolicyHandlerServiceComponent.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/internal/ResourceSharingPolicyHandlerServiceComponent.java
new file mode 100644
index 000000000..cb3f9c575
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/internal/ResourceSharingPolicyHandlerServiceComponent.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management.internal;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.ResourceSharingPolicyHandlerService;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.ResourceSharingPolicyHandlerServiceImpl;
+
+/**
+ * OSGi service component for Resource Sharing Policy Handler bundle.
+ */
+@Component(
+ name = "identity.organization.resource.sharing.policy.management.component",
+ immediate = true
+)
+public class ResourceSharingPolicyHandlerServiceComponent {
+
+ private static final Log LOG = LogFactory.getLog(ResourceSharingPolicyHandlerServiceComponent.class);
+
+ /**
+ * Register the Resource Sharing Policy Mgt service in the OSGI context.
+ *
+ * @param componentContext OSGi service component context.
+ */
+ @Activate
+ protected void activate(ComponentContext componentContext) {
+
+ BundleContext bundleContext = componentContext.getBundleContext();
+ ResourceSharingPolicyHandlerService resourceSharingPolicyHandlerService =
+ new ResourceSharingPolicyHandlerServiceImpl();
+ bundleContext.registerService(ResourceSharingPolicyHandlerService.class.getName(),
+ resourceSharingPolicyHandlerService, null);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("ResourceSharingPolicyHandlerServiceComponent activated successfully.");
+ }
+ }
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/model/ResourceSharingPolicy.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/model/ResourceSharingPolicy.java
new file mode 100644
index 000000000..1d504436c
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/model/ResourceSharingPolicy.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management.model;
+
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.PolicyEnum;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceType;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.exception.ResourceSharingPolicyMgtException;
+
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingConstants.ErrorMessage.ERROR_CODE_MISSING_MANDATORY_FIELDS;
+
+/**
+ * Model representing the Resource Sharing Policy.
+ */
+public class ResourceSharingPolicy {
+
+ private int resourceSharingPolicyId;
+ private ResourceType resourceType;
+ private String resourceId;
+ private String initiatingOrgId;
+ private String policyHoldingOrgId;
+ private PolicyEnum sharingPolicy;
+
+ public int getResourceSharingPolicyId() {
+
+ return resourceSharingPolicyId;
+ }
+
+ public void setResourceSharingPolicyId(int resourceSharingPolicyId) {
+
+ this.resourceSharingPolicyId = resourceSharingPolicyId;
+ }
+
+ public String getResourceId() {
+
+ return resourceId;
+ }
+
+ public void setResourceType(ResourceType resourceType) {
+
+ this.resourceType = resourceType;
+ }
+
+ public String getInitiatingOrgId() {
+
+ return initiatingOrgId;
+ }
+
+ public void setResourceId(String resourceId) {
+
+ this.resourceId = resourceId;
+ }
+
+ public ResourceType getResourceType() {
+
+ return resourceType;
+ }
+
+ public void setInitiatingOrgId(String initiatingOrgId) {
+
+ this.initiatingOrgId = initiatingOrgId;
+ }
+
+ public String getPolicyHoldingOrgId() {
+
+ return policyHoldingOrgId;
+ }
+
+ public void setPolicyHoldingOrgId(String policyHoldingOrgId) {
+
+ this.policyHoldingOrgId = policyHoldingOrgId;
+ }
+
+ public PolicyEnum getSharingPolicy() {
+
+ return sharingPolicy;
+ }
+
+ public void setSharingPolicy(PolicyEnum sharingPolicy) {
+
+ this.sharingPolicy = sharingPolicy;
+ }
+
+ @Override
+ public String toString() {
+
+ return "{" +
+ "\"resourceSharingPolicyId\": " + resourceSharingPolicyId + ", " +
+ "\"resourceType\": \"" + resourceType + "\", " +
+ "\"resourceId\": \"" + resourceId + "\", " +
+ "\"initiatingOrgId\": \"" + initiatingOrgId + "\", " +
+ "\"policyHoldingOrgId\": \"" + policyHoldingOrgId + "\", " +
+ "\"sharingPolicy\": \"" + sharingPolicy + "\"" +
+ "}";
+ }
+
+ public static Builder builder() {
+
+ return new Builder();
+ }
+
+ /**
+ * Builder for constructing {@link ResourceSharingPolicy} instances.
+ */
+ public static class Builder {
+
+ private ResourceType resourceType;
+ private String resourceId;
+ private String initiatingOrgId;
+ private String policyHoldingOrgId;
+ private PolicyEnum sharingPolicy;
+
+ public Builder withResourceType(ResourceType resourceType) {
+
+ this.resourceType = resourceType;
+ return this;
+ }
+
+ public Builder withResourceId(String resourceId) {
+
+ this.resourceId = resourceId;
+ return this;
+ }
+
+ public Builder withInitiatingOrgId(String initiatingOrgId) {
+
+ this.initiatingOrgId = initiatingOrgId;
+ return this;
+ }
+
+ public Builder withPolicyHoldingOrgId(String policyHoldingOrgId) {
+
+ this.policyHoldingOrgId = policyHoldingOrgId;
+ return this;
+ }
+
+ public Builder withSharingPolicy(PolicyEnum sharingPolicy) {
+
+ this.sharingPolicy = sharingPolicy;
+ return this;
+ }
+
+ public ResourceSharingPolicy build() throws ResourceSharingPolicyMgtException {
+
+ if (resourceType == null || resourceId == null || initiatingOrgId == null || policyHoldingOrgId == null ||
+ sharingPolicy == null) {
+
+ throw new ResourceSharingPolicyMgtException(ERROR_CODE_MISSING_MANDATORY_FIELDS.getCode(),
+ ERROR_CODE_MISSING_MANDATORY_FIELDS.getMessage(),
+ ERROR_CODE_MISSING_MANDATORY_FIELDS.getDescription());
+ }
+ ResourceSharingPolicy policy = new ResourceSharingPolicy();
+ policy.setResourceType(this.resourceType);
+ policy.setResourceId(this.resourceId);
+ policy.setInitiatingOrgId(this.initiatingOrgId);
+ policy.setPolicyHoldingOrgId(this.policyHoldingOrgId);
+ policy.setSharingPolicy(this.sharingPolicy);
+ return policy;
+ }
+ }
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/model/ResourceSharingPolicyWithAttributes.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/model/ResourceSharingPolicyWithAttributes.java
new file mode 100644
index 000000000..e75f1e723
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/model/ResourceSharingPolicyWithAttributes.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management.model;
+
+/**
+ * Model representing the Shared Resource Attribute with respective policies and policy holding orgs.
+ */
+public class ResourceSharingPolicyWithAttributes {
+
+ private final String policyHoldingOrgId;
+ private final ResourceSharingPolicy policy;
+ private final SharedResourceAttribute attribute;
+
+ public ResourceSharingPolicyWithAttributes(String policyHoldingOrgId, ResourceSharingPolicy policy,
+ SharedResourceAttribute attribute) {
+
+ this.policyHoldingOrgId = policyHoldingOrgId;
+ this.policy = policy;
+ this.attribute = attribute;
+ }
+
+ public String getPolicyHoldingOrgId() {
+
+ return policyHoldingOrgId;
+ }
+
+ public ResourceSharingPolicy getPolicy() {
+
+ return policy;
+ }
+
+ public SharedResourceAttribute getAttribute() {
+
+ return attribute;
+ }
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/model/SharedResourceAttribute.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/model/SharedResourceAttribute.java
new file mode 100644
index 000000000..649cea4af
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/model/SharedResourceAttribute.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management.model;
+
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.SharedAttributeType;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.exception.ResourceSharingPolicyMgtException;
+
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingConstants.ErrorMessage.ERROR_CODE_MISSING_MANDATORY_FIELDS;
+
+/**
+ * Model representing the Shared Resource Attribute.
+ */
+public class SharedResourceAttribute {
+
+ private int sharedResourceAttributeId;
+ private int resourceSharingPolicyId;
+ private SharedAttributeType sharedAttributeType;
+ private String sharedAttributeId;
+
+ public int getSharedResourceAttributeId() {
+
+ return sharedResourceAttributeId;
+ }
+
+ public void setSharedResourceAttributeId(int sharedResourceAttributeId) {
+
+ this.sharedResourceAttributeId = sharedResourceAttributeId;
+ }
+
+ public int getResourceSharingPolicyId() {
+
+ return resourceSharingPolicyId;
+ }
+
+ public void setResourceSharingPolicyId(int resourceSharingPolicyId) {
+
+ this.resourceSharingPolicyId = resourceSharingPolicyId;
+ }
+
+ public SharedAttributeType getSharedAttributeType() {
+
+ return sharedAttributeType;
+ }
+
+ public void setSharedAttributeType(
+ SharedAttributeType sharedAttributeType) {
+
+ this.sharedAttributeType = sharedAttributeType;
+ }
+
+ public String getSharedAttributeId() {
+
+ return sharedAttributeId;
+ }
+
+ public void setSharedAttributeId(String sharedAttributeId) {
+
+ this.sharedAttributeId = sharedAttributeId;
+ }
+
+ @Override
+ public String toString() {
+
+ return "{" +
+ "\"sharedResourceAttributeId\": " + sharedResourceAttributeId + ", " +
+ "\"resourceSharingPolicyId\": " + resourceSharingPolicyId + ", " +
+ "\"sharedAttributeType\": \"" + sharedAttributeType + "\", " +
+ "\"sharedAttributeId\": \"" + sharedAttributeId + "\"" +
+ "}";
+ }
+
+ public static Builder builder() {
+
+ return new Builder();
+ }
+
+ /**
+ * Builder for constructing {@link SharedResourceAttribute} instances.
+ */
+ public static class Builder {
+
+ private int resourceSharingPolicyId;
+ private SharedAttributeType sharedAttributeType;
+ private String sharedAttributeId;
+
+ public Builder withResourceSharingPolicyId(int resourceSharingPolicyId) {
+
+ this.resourceSharingPolicyId = resourceSharingPolicyId;
+ return this;
+ }
+
+ public Builder withSharedAttributeType(SharedAttributeType sharedAttributeType) {
+
+ this.sharedAttributeType = sharedAttributeType;
+ return this;
+ }
+
+ public Builder withSharedAttributeId(String sharedAttributeId) {
+
+ this.sharedAttributeId = sharedAttributeId;
+ return this;
+ }
+
+ public SharedResourceAttribute build() throws ResourceSharingPolicyMgtException {
+
+ if (sharedAttributeType == null || sharedAttributeId == null) {
+ throw new ResourceSharingPolicyMgtException(ERROR_CODE_MISSING_MANDATORY_FIELDS.getCode(),
+ ERROR_CODE_MISSING_MANDATORY_FIELDS.getMessage(),
+ ERROR_CODE_MISSING_MANDATORY_FIELDS.getDescription());
+ }
+ SharedResourceAttribute attributes = new SharedResourceAttribute();
+ attributes.setResourceSharingPolicyId(this.resourceSharingPolicyId);
+ attributes.setSharedAttributeType(this.sharedAttributeType);
+ attributes.setSharedAttributeId(this.sharedAttributeId);
+ return attributes;
+ }
+ }
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/util/ResourceSharingUtils.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/util/ResourceSharingUtils.java
new file mode 100644
index 000000000..ce08cb7fd
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/main/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/util/ResourceSharingUtils.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2024, 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.wso2.com/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.organization.resource.sharing.policy.management.util;
+
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceSharingConstants.ErrorMessage;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceType;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.exception.ResourceSharingPolicyMgtServerException;
+
+/**
+ * Utility class for resource sharing util management.
+ */
+public class ResourceSharingUtils {
+
+ /**
+ * Handle server exception by generating a relevant description message.
+ *
+ * @param error The ErrorMessage enum containing error details.
+ * @param e The Throwable cause of the exception.
+ * @param resourceType The type of the resource (as an enum).
+ * @param resourceId The UUID of the resource.
+ * @return A ResourceSharingPolicyMgtServerException.
+ */
+ public static ResourceSharingPolicyMgtServerException handleServerException(ErrorMessage error, Throwable e,
+ ResourceType resourceType,
+ String resourceId) {
+
+ String description = String.format("%s (Resource Type: %s, Resource ID: %s)",
+ error.getDescription(), resourceType.name(), resourceId);
+
+ return new ResourceSharingPolicyMgtServerException(error.getCode(), error.getMessage(), description, e);
+ }
+
+ /**
+ * Handle server exception for failed shared resource attributes.
+ *
+ * @param error The ErrorMessage enum containing error details.
+ * @return A ResourceSharingPolicyMgtServerException.
+ */
+ public static ResourceSharingPolicyMgtServerException handleServerException(ErrorMessage error) {
+
+ return new ResourceSharingPolicyMgtServerException(error.getCode(), error.getMessage(), error.getDescription());
+ }
+
+ private ResourceSharingUtils() {}
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/ResourceSharingPolicyHandlerServiceImplTest.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/ResourceSharingPolicyHandlerServiceImplTest.java
new file mode 100644
index 000000000..fa25e3142
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/ResourceSharingPolicyHandlerServiceImplTest.java
@@ -0,0 +1,889 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management;
+
+import org.mockito.MockedStatic;
+import org.testng.Assert;
+import org.testng.TestException;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.wso2.carbon.database.utils.jdbc.NamedJdbcTemplate;
+import org.wso2.carbon.database.utils.jdbc.exceptions.DataAccessException;
+import org.wso2.carbon.database.utils.jdbc.exceptions.TransactionException;
+import org.wso2.carbon.identity.organization.management.service.util.Utils;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.PolicyEnum;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceType;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.SharedAttributeType;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.exception.ResourceSharingPolicyMgtClientException;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.exception.ResourceSharingPolicyMgtException;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.exception.ResourceSharingPolicyMgtServerException;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.model.ResourceSharingPolicy;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.model.SharedResourceAttribute;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.util.TestUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.openMocks;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceType.USER;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constants.TestResourceSharingConstants.MOCKED_DATA_ACCESS_EXCEPTION;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constants.TestResourceSharingConstants.MOCKED_TRANSACTION_EXCEPTION;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constants.TestResourceSharingConstants.RESOURCE_TYPE_RESOURCE_1;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constants.TestResourceSharingConstants.SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constants.TestResourceSharingConstants.UM_ID_ORGANIZATION_INVALID;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constants.TestResourceSharingConstants.UM_ID_ORGANIZATION_INVALID_FORMAT;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constants.TestResourceSharingConstants.UM_ID_ORGANIZATION_ORG_ALL;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constants.TestResourceSharingConstants.UM_ID_ORGANIZATION_ORG_ALL_CHILD1;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constants.TestResourceSharingConstants.UM_ID_ORGANIZATION_ORG_IMMEDIATE;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constants.TestResourceSharingConstants.UM_ID_ORGANIZATION_ORG_IMMEDIATE_CHILD1;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constants.TestResourceSharingConstants.UM_ID_ORGANIZATION_SUPER;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constants.TestResourceSharingConstants.UM_ID_RESOURCE_1;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constants.TestResourceSharingConstants.UM_ID_RESOURCE_2;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constants.TestResourceSharingConstants.UM_ID_RESOURCE_3;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constants.TestResourceSharingConstants.UM_ID_RESOURCE_4;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constants.TestResourceSharingConstants.UM_ID_RESOURCE_ATTRIBUTE_1;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.constants.TestResourceSharingConstants.UM_ID_RESOURCE_ATTRIBUTE_2;
+import static org.wso2.carbon.identity.organization.resource.sharing.policy.management.util.TestUtils.closeH2Base;
+
+public class ResourceSharingPolicyHandlerServiceImplTest {
+
+ private ResourceSharingPolicyHandlerServiceImpl resourceSharingPolicyHandlerService;
+
+ @BeforeClass
+ public void setUp() throws Exception {
+
+ resourceSharingPolicyHandlerService = new ResourceSharingPolicyHandlerServiceImpl();
+ openMocks(this);
+ TestUtils.initiateH2Base();
+ TestUtils.mockDataSource();
+ }
+
+ @AfterClass
+ public void tearDown() throws Exception {
+
+ closeH2Base();
+ }
+
+ // Tests: CREATE Resource Sharing Policy Records.
+ @DataProvider(name = "resourceSharingPolicyProvider")
+ public Object[][] resourceSharingPolicyProvider() throws ResourceSharingPolicyMgtException {
+
+ return new Object[][]{
+ {new ResourceSharingPolicy.Builder()
+ .withResourceType(RESOURCE_TYPE_RESOURCE_1)
+ .withResourceId(UM_ID_RESOURCE_1)
+ .withInitiatingOrgId(UM_ID_ORGANIZATION_SUPER)
+ .withPolicyHoldingOrgId(UM_ID_ORGANIZATION_SUPER)
+ .withSharingPolicy(PolicyEnum.ALL_EXISTING_AND_FUTURE_ORGS).build()},
+ {new ResourceSharingPolicy.Builder()
+ .withResourceType(RESOURCE_TYPE_RESOURCE_1)
+ .withResourceId(UM_ID_RESOURCE_3)
+ .withInitiatingOrgId(UM_ID_ORGANIZATION_SUPER)
+ .withPolicyHoldingOrgId(UM_ID_ORGANIZATION_SUPER)
+ .withSharingPolicy(PolicyEnum.IMMEDIATE_EXISTING_AND_FUTURE_ORGS).build()},
+ {new ResourceSharingPolicy.Builder()
+ .withResourceType(RESOURCE_TYPE_RESOURCE_1)
+ .withResourceId(UM_ID_RESOURCE_2)
+ .withInitiatingOrgId(UM_ID_ORGANIZATION_SUPER)
+ .withPolicyHoldingOrgId(UM_ID_ORGANIZATION_ORG_ALL)
+ .withSharingPolicy(PolicyEnum.SELECTED_ORG_WITH_ALL_EXISTING_AND_FUTURE_CHILDREN).build()},
+ {new ResourceSharingPolicy.Builder()
+ .withResourceType(RESOURCE_TYPE_RESOURCE_1)
+ .withResourceId(UM_ID_RESOURCE_4)
+ .withInitiatingOrgId(UM_ID_ORGANIZATION_SUPER)
+ .withPolicyHoldingOrgId(UM_ID_ORGANIZATION_ORG_IMMEDIATE)
+ .withSharingPolicy(PolicyEnum.SELECTED_ORG_WITH_EXISTING_IMMEDIATE_AND_FUTURE_CHILDREN).build()}
+ };
+
+ }
+
+ @Test(dataProvider = "resourceSharingPolicyProvider", priority = 1)
+ public void testAddResourceSharingPolicySuccess(ResourceSharingPolicy testData) throws Exception {
+
+ ResourceSharingPolicy resourceSharingPolicy = new ResourceSharingPolicy.Builder()
+ .withResourceId(testData.getResourceId())
+ .withResourceType(testData.getResourceType())
+ .withInitiatingOrgId(testData.getInitiatingOrgId())
+ .withPolicyHoldingOrgId(testData.getPolicyHoldingOrgId())
+ .withSharingPolicy(testData.getSharingPolicy())
+ .build();
+
+ int addedPolicyId = resourceSharingPolicyHandlerService.addResourceSharingPolicy(resourceSharingPolicy);
+
+ Assert.assertTrue(addedPolicyId > 0,
+ "Expected a positive non-zero integer as the result for a clean record insertion to the database.");
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtServerException.class, priority = 2)
+ public void testAddResourceSharingPolicyFailure() throws Exception {
+
+ ResourceSharingPolicy resourceSharingPolicy = new ResourceSharingPolicy.Builder()
+ .withResourceId(UM_ID_RESOURCE_1)
+ .withResourceType(RESOURCE_TYPE_RESOURCE_1)
+ .withInitiatingOrgId(UM_ID_ORGANIZATION_INVALID)
+ .withPolicyHoldingOrgId(UM_ID_ORGANIZATION_ORG_ALL)
+ .withSharingPolicy(PolicyEnum.SELECTED_ORG_WITH_ALL_EXISTING_AND_FUTURE_CHILDREN)
+ .build();
+
+ resourceSharingPolicyHandlerService.addResourceSharingPolicy(resourceSharingPolicy);
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtClientException.class, priority = 3)
+ public void testAddResourceSharingPolicyFailureForNotApplicableResource() throws Exception {
+
+ ResourceSharingPolicy resourceSharingPolicy = new ResourceSharingPolicy.Builder()
+ .withResourceId(UM_ID_RESOURCE_1)
+ .withResourceType(RESOURCE_TYPE_RESOURCE_1)
+ .withInitiatingOrgId(UM_ID_ORGANIZATION_INVALID)
+ .withPolicyHoldingOrgId(UM_ID_ORGANIZATION_ORG_ALL)
+ .withSharingPolicy(PolicyEnum.NO_SHARING)
+ .build();
+
+ resourceSharingPolicyHandlerService.addResourceSharingPolicy(resourceSharingPolicy);
+ }
+
+ // Tests: GET Resource Sharing Policy Records.
+ @Test(priority = 4)
+ public void testGetResourceSharingPolicyByIdSuccess() throws ResourceSharingPolicyMgtException {
+
+ ResourceSharingPolicy resourceSharingPolicy = new ResourceSharingPolicy.Builder()
+ .withResourceId(UM_ID_RESOURCE_1)
+ .withResourceType(RESOURCE_TYPE_RESOURCE_1)
+ .withInitiatingOrgId(UM_ID_ORGANIZATION_SUPER)
+ .withPolicyHoldingOrgId(UM_ID_ORGANIZATION_ORG_ALL)
+ .withSharingPolicy(PolicyEnum.SELECTED_ORG_ONLY)
+ .build();
+
+ int recordId = resourceSharingPolicyHandlerService.addResourceSharingPolicy(resourceSharingPolicy);
+ Optional optionalResource =
+ resourceSharingPolicyHandlerService.getResourceSharingPolicyById(recordId);
+
+ Assert.assertTrue(optionalResource.isPresent(), "ResourceSharingPolicy should be present.");
+ ResourceSharingPolicy resource = optionalResource.get();
+ Assert.assertNotNull(resource, "ResourceSharingPolicy object should not be null.");
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtServerException.class, priority = 5)
+ public void testGetResourceSharingPolicyByIdFailure() throws ResourceSharingPolicyMgtException {
+
+ NamedJdbcTemplate mockJdbcTemplate = mock(NamedJdbcTemplate.class);
+
+ try (MockedStatic mockedStatic = mockStatic(Utils.class)) {
+ mockedStatic.when(Utils::getNewTemplate).thenReturn(mockJdbcTemplate);
+ doThrow(new DataAccessException(MOCKED_DATA_ACCESS_EXCEPTION)).when(mockJdbcTemplate)
+ .fetchSingleRecord(anyString(), any(), any());
+
+ resourceSharingPolicyHandlerService.getResourceSharingPolicyById(1);
+
+ mockedStatic.verify(Utils::getNewTemplate, times(1));
+ } catch (DataAccessException e) {
+ throw new TestException(e);
+ }
+ }
+
+ @DataProvider(name = "organizationIdsProvider")
+ public Object[][] organizationIdsProvider() {
+
+ return new Object[][]{
+ {Arrays.asList(UM_ID_ORGANIZATION_SUPER, UM_ID_ORGANIZATION_ORG_ALL)},
+ {Arrays.asList(UM_ID_ORGANIZATION_ORG_IMMEDIATE, UM_ID_ORGANIZATION_ORG_IMMEDIATE_CHILD1)},
+ {Arrays.asList(UM_ID_ORGANIZATION_ORG_ALL, UM_ID_ORGANIZATION_ORG_ALL_CHILD1)}
+ };
+ }
+
+ @Test(dataProvider = "organizationIdsProvider", priority = 6)
+ public void testGetResourceSharingPoliciesSuccess(List organizationIds) throws Exception {
+
+ addAndAssertResourceSharingPolicy(Arrays.asList(organizationIds.get(0), organizationIds.get(1)));
+
+ List actualPolicies =
+ resourceSharingPolicyHandlerService.getResourceSharingPolicies(organizationIds);
+
+ for (ResourceSharingPolicy policy : actualPolicies) {
+ Assert.assertTrue(organizationIds.contains(policy.getPolicyHoldingOrgId()));
+ }
+ }
+
+ @Test(dataProvider = "organizationIdsProvider", priority = 7)
+ public void testGetResourceSharingPoliciesGroupedByResourceTypeSuccess(List organizationIds)
+ throws Exception {
+
+ addAndAssertResourceSharingPolicy(Arrays.asList(organizationIds.get(0), organizationIds.get(1)));
+
+ Map> actualPoliciesGroupedByType =
+ resourceSharingPolicyHandlerService.getResourceSharingPoliciesGroupedByResourceType(organizationIds);
+
+ Assert.assertTrue(actualPoliciesGroupedByType.containsKey(RESOURCE_TYPE_RESOURCE_1));
+ Assert.assertTrue(actualPoliciesGroupedByType.containsKey(RESOURCE_TYPE_RESOURCE_1));
+
+ for (Map.Entry> entry : actualPoliciesGroupedByType.entrySet()) {
+ ResourceType resourceType = entry.getKey();
+ List policies = entry.getValue();
+
+ switch (resourceType) {
+ case USER:
+ for (ResourceSharingPolicy policy : policies) {
+ Assert.assertEquals(policy.getResourceType(), USER);
+ Assert.assertTrue(organizationIds.contains(policy.getPolicyHoldingOrgId()));
+ }
+ break;
+
+ default:
+ Assert.fail("Unexpected resource type found: " + resourceType);
+ break;
+ }
+ }
+ }
+
+ @Test(dataProvider = "organizationIdsProvider", priority = 8)
+ public void testGetResourceSharingPoliciesGroupedByPolicyHoldingOrgIdSuccess(List organizationIds)
+ throws Exception {
+
+ addAndAssertResourceSharingPolicy(Arrays.asList(organizationIds.get(0), organizationIds.get(1)));
+
+ Map> actualPoliciesGroupedByOrgId =
+ resourceSharingPolicyHandlerService.getResourceSharingPoliciesGroupedByPolicyHoldingOrgId(
+ organizationIds);
+
+ for (String policyHoldingOrgId : actualPoliciesGroupedByOrgId.keySet()) {
+ Assert.assertTrue(organizationIds.contains(policyHoldingOrgId));
+ }
+
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtClientException.class, priority = 9)
+ public void testGetResourceSharingPoliciesFailureForNullOrgIdInList() throws Exception {
+
+ List actualPolicies =
+ resourceSharingPolicyHandlerService.getResourceSharingPolicies(Collections.singletonList(null));
+
+ Assert.assertTrue(actualPolicies.isEmpty());
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtClientException.class, priority = 9)
+ public void testGetResourceSharingPoliciesFailureForEmptyOrgIdInList() throws Exception {
+
+ List actualPolicies =
+ resourceSharingPolicyHandlerService.getResourceSharingPolicies(Collections.singletonList(""));
+
+ Assert.assertTrue(actualPolicies.isEmpty());
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtServerException.class, priority = 10)
+ public void testGetResourceSharingPoliciesFailureForInvalidOrgId() throws Exception {
+
+ NamedJdbcTemplate mockJdbcTemplate = mock(NamedJdbcTemplate.class);
+
+ try (MockedStatic mockedStatic = mockStatic(Utils.class)) {
+ mockedStatic.when(Utils::getNewTemplate).thenReturn(mockJdbcTemplate);
+ doThrow(new DataAccessException(MOCKED_DATA_ACCESS_EXCEPTION)).when(mockJdbcTemplate)
+ .executeQuery(anyString(), any(), any());
+
+ resourceSharingPolicyHandlerService.getResourceSharingPolicies(
+ Collections.singletonList(UM_ID_ORGANIZATION_INVALID_FORMAT));
+
+ mockedStatic.verify(Utils::getNewTemplate, times(1));
+ } catch (DataAccessException e) {
+ throw new TestException(e);
+ }
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtClientException.class, priority = 11)
+ public void testGetResourceSharingPoliciesFailureForNullOrgs() throws Exception {
+
+ List policyHoldingOrgIds = new ArrayList<>();
+ policyHoldingOrgIds.add(UM_ID_RESOURCE_1);
+ policyHoldingOrgIds.add(null);
+
+ List actualPolicies =
+ resourceSharingPolicyHandlerService.getResourceSharingPolicies(policyHoldingOrgIds);
+
+ Assert.assertTrue(actualPolicies.isEmpty());
+ }
+
+ // Tests: DELETE Resource Sharing Policy Records.
+ @Test(dataProvider = "organizationIdsProvider", priority = 12)
+ public void testDeleteResourceSharingPolicyRecordByIdSuccess(List organizationIds) throws Exception {
+
+ List addedResourceSharingPolyIds =
+ addAndAssertResourceSharingPolicy(Arrays.asList(organizationIds.get(0), organizationIds.get(1)));
+
+ for (int addedResourceSharingPolyId : addedResourceSharingPolyIds) {
+ resourceSharingPolicyHandlerService.deleteResourceSharingPolicyRecordById(
+ addedResourceSharingPolyId, UM_ID_ORGANIZATION_SUPER);
+ Optional resourceSharingPolicyById =
+ resourceSharingPolicyHandlerService.getResourceSharingPolicyById(addedResourceSharingPolyId);
+ Assert.assertFalse(resourceSharingPolicyById.isPresent());
+ }
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtServerException.class, priority = 13)
+ public void testDeleteResourceSharingPolicyRecordByIdFailure()
+ throws ResourceSharingPolicyMgtException {
+
+ NamedJdbcTemplate mockJdbcTemplate = mock(NamedJdbcTemplate.class);
+
+ try (MockedStatic mockedStatic = mockStatic(Utils.class)) {
+ mockedStatic.when(Utils::getNewTemplate).thenReturn(mockJdbcTemplate);
+ doThrow(new DataAccessException(MOCKED_DATA_ACCESS_EXCEPTION)).when(mockJdbcTemplate)
+ .executeUpdate(anyString(), any());
+
+ resourceSharingPolicyHandlerService.deleteResourceSharingPolicyRecordById(1, UM_ID_ORGANIZATION_SUPER);
+
+ mockedStatic.verify(Utils::getNewTemplate, times(1));
+ } catch (DataAccessException e) {
+ throw new TestException(e);
+ }
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtClientException.class, priority = 21)
+ public void testDeleteResourceSharingPolicyRecordByIdAndEmptySharingInitiatedOrgIdFailure()
+ throws ResourceSharingPolicyMgtException {
+
+ resourceSharingPolicyHandlerService.deleteResourceSharingPolicyRecordById(1, "");
+ }
+
+ @DataProvider(name = "organizationsAndResourceTypesAndIdsProvider")
+ public Object[][] organizationsAndResourceTypesAndIdsProvider() {
+
+ return new Object[][]{
+ {Arrays.asList(UM_ID_ORGANIZATION_SUPER, UM_ID_ORGANIZATION_ORG_ALL),
+ RESOURCE_TYPE_RESOURCE_1, UM_ID_RESOURCE_1},
+ {Arrays.asList(UM_ID_ORGANIZATION_ORG_IMMEDIATE, UM_ID_ORGANIZATION_ORG_IMMEDIATE_CHILD1),
+ RESOURCE_TYPE_RESOURCE_1, UM_ID_RESOURCE_2},
+ {Arrays.asList(UM_ID_ORGANIZATION_ORG_ALL, UM_ID_ORGANIZATION_ORG_ALL_CHILD1),
+ RESOURCE_TYPE_RESOURCE_1, UM_ID_RESOURCE_3},
+ {Arrays.asList(UM_ID_ORGANIZATION_SUPER, UM_ID_ORGANIZATION_SUPER),
+ RESOURCE_TYPE_RESOURCE_1, UM_ID_RESOURCE_4},
+ };
+ }
+
+ @Test(priority = 14)
+ public void testDeleteResourceSharingPolicyByResourceTypeAndIdSuccess() throws Exception {
+
+ ResourceSharingPolicy resourceSharingPolicy = new ResourceSharingPolicy.Builder()
+ .withResourceId(UM_ID_RESOURCE_1)
+ .withResourceType(RESOURCE_TYPE_RESOURCE_1)
+ .withInitiatingOrgId(UM_ID_ORGANIZATION_SUPER)
+ .withPolicyHoldingOrgId(UM_ID_ORGANIZATION_SUPER)
+ .withSharingPolicy(PolicyEnum.SELECTED_ORG_WITH_EXISTING_IMMEDIATE_AND_FUTURE_CHILDREN)
+ .build();
+
+ int addedPolicyId = resourceSharingPolicyHandlerService.addResourceSharingPolicy(resourceSharingPolicy);
+
+ // Deleting the added policy
+ resourceSharingPolicyHandlerService.deleteResourceSharingPolicyByResourceTypeAndId(
+ RESOURCE_TYPE_RESOURCE_1, UM_ID_RESOURCE_1, UM_ID_ORGANIZATION_SUPER);
+
+ // Verifying that the policy is deleted
+ Optional deletedPolicy =
+ resourceSharingPolicyHandlerService.getResourceSharingPolicyById(addedPolicyId);
+ Assert.assertFalse(deletedPolicy.isPresent());
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtServerException.class, priority = 15)
+ public void testDeleteResourceSharingPolicyByResourceTypeAndIdFailure() throws ResourceSharingPolicyMgtException {
+
+ NamedJdbcTemplate mockJdbcTemplate = mock(NamedJdbcTemplate.class);
+
+ try (MockedStatic mockedStatic = mockStatic(Utils.class)) {
+ mockedStatic.when(Utils::getNewTemplate).thenReturn(mockJdbcTemplate);
+ doThrow(new DataAccessException(MOCKED_DATA_ACCESS_EXCEPTION)).when(mockJdbcTemplate)
+ .executeUpdate(anyString(), any());
+
+ resourceSharingPolicyHandlerService.deleteResourceSharingPolicyByResourceTypeAndId(RESOURCE_TYPE_RESOURCE_1,
+ UM_ID_RESOURCE_1, UM_ID_ORGANIZATION_SUPER);
+
+ mockedStatic.verify(Utils::getNewTemplate, times(1));
+ } catch (DataAccessException e) {
+ throw new TestException(e);
+ }
+ }
+
+ // Tests: CREATE Shared Resource Attributes Records.
+ @Test(priority = 16)
+ public void testAddSharedResourceAttributesSuccess() throws Exception {
+
+ List sharedResourceAttributes = Arrays.asList(
+ new SharedResourceAttribute.Builder()
+ .withResourceSharingPolicyId(1)
+ .withSharedAttributeType(SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1)
+ .withSharedAttributeId(UM_ID_RESOURCE_ATTRIBUTE_1)
+ .build(),
+ new SharedResourceAttribute.Builder()
+ .withResourceSharingPolicyId(1)
+ .withSharedAttributeType(SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1)
+ .withSharedAttributeId(UM_ID_RESOURCE_ATTRIBUTE_2)
+ .build());
+
+ boolean isAdded = resourceSharingPolicyHandlerService.addSharedResourceAttributes(sharedResourceAttributes);
+ Assert.assertTrue(isAdded, "Added shared resource attributes.");
+
+ }
+
+ @Test(priority = 17)
+ public void testAddSharedResourceAttributesSuccessWithIgnoringInvalidAttributes() throws Exception {
+
+ List sharedResourceAttributes = Arrays.asList(
+ new SharedResourceAttribute.Builder()
+ .withResourceSharingPolicyId(Integer.MIN_VALUE)
+ .withSharedAttributeType(SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1)
+ .withSharedAttributeId(UM_ID_RESOURCE_ATTRIBUTE_1)
+ .build(),
+ new SharedResourceAttribute.Builder()
+ .withResourceSharingPolicyId(1)
+ .withSharedAttributeType(SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1)
+ .withSharedAttributeId(UM_ID_RESOURCE_ATTRIBUTE_2)
+ .build());
+
+ boolean isAdded = resourceSharingPolicyHandlerService.addSharedResourceAttributes(sharedResourceAttributes);
+ Assert.assertTrue(isAdded, "Skipped the invalid attributes and added the rest.");
+
+ }
+
+ @Test(priority = 18)
+ public void testAddSharedResourceAttributesSuccessWithInapplicableAttribute() throws Exception {
+
+ ResourceSharingPolicy resourceSharingPolicyMock = mock(ResourceSharingPolicy.class);
+ ResourceType resourceTypeMock = mock(ResourceType.class);
+
+ when(resourceSharingPolicyMock.getResourceType()).thenReturn(resourceTypeMock);
+ when(resourceTypeMock.isApplicableAttributeType(any(SharedAttributeType.class))).thenReturn(false);
+
+ // Valid attribute
+ SharedResourceAttribute validSharedResourceAttribute = new SharedResourceAttribute.Builder()
+ .withResourceSharingPolicyId(1)
+ .withSharedAttributeType(SharedAttributeType.ROLE)
+ .withSharedAttributeId(UM_ID_RESOURCE_ATTRIBUTE_1)
+ .build();
+
+ // Invalid attribute
+ SharedResourceAttribute invalidSharedResourceAttribute = new SharedResourceAttribute.Builder()
+ .withResourceSharingPolicyId(-1)
+ .withSharedAttributeType(SharedAttributeType.ROLE)
+ .withSharedAttributeId(UM_ID_RESOURCE_ATTRIBUTE_2)
+ .build();
+
+ ResourceSharingPolicyHandlerService resourceSharingPolicyHandlerServiceMock =
+ spy(new ResourceSharingPolicyHandlerServiceImpl());
+
+ doReturn(Optional.of(resourceSharingPolicyMock)).when(resourceSharingPolicyHandlerServiceMock)
+ .getResourceSharingPolicyById(validSharedResourceAttribute.getResourceSharingPolicyId());
+
+ doReturn(Optional.empty()).when(resourceSharingPolicyHandlerServiceMock)
+ .getResourceSharingPolicyById(invalidSharedResourceAttribute.getResourceSharingPolicyId());
+
+ List sharedResourceAttributes =
+ Arrays.asList(validSharedResourceAttribute, invalidSharedResourceAttribute);
+
+ boolean isAdded = resourceSharingPolicyHandlerServiceMock.addSharedResourceAttributes(sharedResourceAttributes);
+
+ Assert.assertTrue(isAdded, "Skipped the inapplicable attributes and added the rest.");
+ verify(resourceSharingPolicyHandlerServiceMock, times(1))
+ .getResourceSharingPolicyById(validSharedResourceAttribute.getResourceSharingPolicyId());
+ verify(resourceSharingPolicyHandlerServiceMock, times(1))
+ .getResourceSharingPolicyById(invalidSharedResourceAttribute.getResourceSharingPolicyId());
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtServerException.class, priority = 19)
+ public void testAddSharedResourceAttributesFailure() throws ResourceSharingPolicyMgtException {
+
+ NamedJdbcTemplate mockJdbcTemplate = mock(NamedJdbcTemplate.class);
+
+ try (MockedStatic mockedStatic = mockStatic(Utils.class)) {
+ mockedStatic.when(Utils::getNewTemplate).thenReturn(mockJdbcTemplate);
+ doThrow(new TransactionException(MOCKED_TRANSACTION_EXCEPTION)).when(mockJdbcTemplate)
+ .withTransaction(any());
+
+ resourceSharingPolicyHandlerService.addSharedResourceAttributes(
+ Collections.singletonList(new SharedResourceAttribute()));
+
+ mockedStatic.verify(Utils::getNewTemplate, times(1));
+ } catch (TransactionException e) {
+ throw new TestException(e);
+ }
+ }
+
+ // Tests: GET Shared Resource Attributes Records.
+ @Test(priority = 20)
+ public void testGetSharedResourceAttributesBySharingPolicyIdSuccess() throws Exception {
+
+ addAndAssertSharedResourceAttributes();
+ List sharedResourceAttributes =
+ resourceSharingPolicyHandlerService.getSharedResourceAttributesBySharingPolicyId(1);
+ Assert.assertNotNull(sharedResourceAttributes,
+ "Expected non-null list of shared resource attributes.");
+ Assert.assertFalse(sharedResourceAttributes.isEmpty(),
+ "Expected non-empty list of shared resource attributes.");
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtServerException.class, priority = 21)
+ public void testGetSharedResourceAttributesBySharingPolicyIdFailure() throws ResourceSharingPolicyMgtException {
+
+ NamedJdbcTemplate mockJdbcTemplate = mock(NamedJdbcTemplate.class);
+
+ try (MockedStatic mockedStatic = mockStatic(Utils.class)) {
+ mockedStatic.when(Utils::getNewTemplate).thenReturn(mockJdbcTemplate);
+ doThrow(new DataAccessException(MOCKED_DATA_ACCESS_EXCEPTION)).when(mockJdbcTemplate)
+ .executeQuery(anyString(), any(), any());
+
+ resourceSharingPolicyHandlerService.getSharedResourceAttributesBySharingPolicyId(1);
+
+ mockedStatic.verify(Utils::getNewTemplate, times(1));
+ } catch (DataAccessException e) {
+ throw new TestException(e);
+ }
+ }
+
+ @Test(priority = 22)
+ public void testGetSharedResourceAttributesByTypeSuccess() throws Exception {
+
+ List sharedResourceAttributes =
+ resourceSharingPolicyHandlerService.getSharedResourceAttributesByType(
+ SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1);
+ Assert.assertNotNull(sharedResourceAttributes,
+ "Expected non-null list of shared resource attributes by type.");
+ Assert.assertFalse(sharedResourceAttributes.isEmpty(),
+ "Expected non-empty list of shared resource attributes by type.");
+ }
+
+ @Test(priority = 24)
+ public void testGetSharedResourceAttributesByIdSuccess() throws Exception {
+
+ addAndAssertSharedResourceAttributes();
+ List sharedResourceAttributes =
+ resourceSharingPolicyHandlerService.getSharedResourceAttributesById(UM_ID_RESOURCE_ATTRIBUTE_1);
+ Assert.assertNotNull(sharedResourceAttributes,
+ "Expected non-null list of shared resource attributes by ID.");
+ Assert.assertFalse(sharedResourceAttributes.isEmpty(),
+ "Expected non-empty list of shared resource attributes by ID.");
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtClientException.class, priority = 25)
+ public void testGetSharedResourceAttributesByIdFailureForNull() throws Exception {
+
+ resourceSharingPolicyHandlerService.getSharedResourceAttributesById(null);
+ }
+
+ @Test(priority = 26)
+ public void testGetSharedResourceAttributesByTypeAndIdSuccess() throws Exception {
+
+ addAndAssertSharedResourceAttributes();
+ List sharedResourceAttributes =
+ resourceSharingPolicyHandlerService.getSharedResourceAttributesByTypeAndId(
+ SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1, UM_ID_RESOURCE_ATTRIBUTE_1);
+ Assert.assertNotNull(sharedResourceAttributes,
+ "Expected non-null list of shared resource attributes by type and ID.");
+ Assert.assertFalse(sharedResourceAttributes.isEmpty(),
+ "Expected non-empty list of shared resource attributes by type and ID.");
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtClientException.class, priority = 27)
+ public void testGetSharedResourceAttributesByTypeAndIdFailureForNull() throws Exception {
+
+ resourceSharingPolicyHandlerService.getSharedResourceAttributesByTypeAndId(null, null);
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtServerException.class, priority = 28)
+ public void testGetSharedResourceAttributesByTypeAndIdFailure()
+ throws ResourceSharingPolicyMgtException {
+
+ NamedJdbcTemplate mockJdbcTemplate = mock(NamedJdbcTemplate.class);
+
+ try (MockedStatic mockedStatic = mockStatic(Utils.class)) {
+ mockedStatic.when(Utils::getNewTemplate).thenReturn(mockJdbcTemplate);
+ doThrow(new DataAccessException(MOCKED_DATA_ACCESS_EXCEPTION)).when(mockJdbcTemplate)
+ .executeQuery(anyString(), any(), any());
+
+ resourceSharingPolicyHandlerService.getSharedResourceAttributesByTypeAndId(
+ SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1, UM_ID_RESOURCE_ATTRIBUTE_1);
+
+ mockedStatic.verify(Utils::getNewTemplate, times(1));
+ } catch (DataAccessException e) {
+ throw new TestException(e);
+ }
+ }
+
+ // Tests: DELETE Shared Resource Attributes Records.
+ @Test(priority = 29)
+ public void testDeleteSharedResourceAttributesByResourceSharingPolicyIdSuccess() throws Exception {
+
+ resourceSharingPolicyHandlerService.deleteSharedResourceAttributesByResourceSharingPolicyId
+ (1, SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1, UM_ID_ORGANIZATION_SUPER);
+ List sharedResourceAttributes =
+ resourceSharingPolicyHandlerService.getSharedResourceAttributesBySharingPolicyId(1);
+ Assert.assertEquals(sharedResourceAttributes.size(), 0);
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtServerException.class, priority = 30)
+ public void testDeleteSharedResourceAttributesByResourceSharingPolicyIdFailure()
+ throws ResourceSharingPolicyMgtException {
+
+ NamedJdbcTemplate mockJdbcTemplate = mock(NamedJdbcTemplate.class);
+
+ try (MockedStatic mockedStatic = mockStatic(Utils.class)) {
+ mockedStatic.when(Utils::getNewTemplate).thenReturn(mockJdbcTemplate);
+ doThrow(new DataAccessException(MOCKED_DATA_ACCESS_EXCEPTION)).when(mockJdbcTemplate)
+ .executeUpdate(anyString(), any());
+
+ resourceSharingPolicyHandlerService.deleteSharedResourceAttributesByResourceSharingPolicyId(1,
+ SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1, UM_ID_ORGANIZATION_SUPER);
+
+ mockedStatic.verify(Utils::getNewTemplate, times(1));
+ } catch (DataAccessException e) {
+ throw new TestException(e);
+ }
+ }
+
+ @Test(priority = 31)
+ public void testDeleteSharedResourceAttributeByAttributeTypeAndIdSuccess() throws Exception {
+
+ resourceSharingPolicyHandlerService.deleteSharedResourceAttributeByAttributeTypeAndId(
+ SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1, UM_ID_RESOURCE_ATTRIBUTE_1, UM_ID_ORGANIZATION_SUPER);
+ List sharedResourceAttributes =
+ resourceSharingPolicyHandlerService.getSharedResourceAttributesByTypeAndId(
+ SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1, UM_ID_RESOURCE_ATTRIBUTE_1);
+ Assert.assertEquals(sharedResourceAttributes.size(), 0);
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtServerException.class, priority = 32)
+ public void testDeleteSharedResourceAttributeByAttributeTypeAndIdFailure()
+ throws ResourceSharingPolicyMgtException {
+
+ NamedJdbcTemplate mockJdbcTemplate = mock(NamedJdbcTemplate.class);
+
+ try (MockedStatic mockedStatic = mockStatic(Utils.class)) {
+ mockedStatic.when(Utils::getNewTemplate).thenReturn(mockJdbcTemplate);
+ doThrow(new DataAccessException(MOCKED_DATA_ACCESS_EXCEPTION)).when(mockJdbcTemplate)
+ .executeUpdate(anyString(), any());
+
+ resourceSharingPolicyHandlerService.deleteSharedResourceAttributeByAttributeTypeAndId(
+ SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1, UM_ID_RESOURCE_1, UM_ID_ORGANIZATION_SUPER);
+
+ mockedStatic.verify(Utils::getNewTemplate, times(1));
+ } catch (DataAccessException e) {
+ throw new TestException(e);
+ }
+ }
+
+ @Test(priority = 33)
+ public void testAddResourceSharingPolicyWithAttributesSuccess() throws ResourceSharingPolicyMgtException {
+
+ ResourceSharingPolicy resourceSharingPolicy = new ResourceSharingPolicy.Builder()
+ .withResourceId(UM_ID_RESOURCE_1)
+ .withResourceType(RESOURCE_TYPE_RESOURCE_1)
+ .withInitiatingOrgId(UM_ID_ORGANIZATION_SUPER)
+ .withPolicyHoldingOrgId(UM_ID_ORGANIZATION_ORG_ALL)
+ .withSharingPolicy(PolicyEnum.SELECTED_ORG_WITH_ALL_EXISTING_AND_FUTURE_CHILDREN)
+ .build();
+
+ List sharedResourceAttributes = Arrays.asList(
+ new SharedResourceAttribute.Builder()
+ .withSharedAttributeType(SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1)
+ .withSharedAttributeId(UM_ID_RESOURCE_ATTRIBUTE_1)
+ .build(),
+ new SharedResourceAttribute.Builder()
+ .withSharedAttributeType(SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1)
+ .withSharedAttributeId(UM_ID_RESOURCE_ATTRIBUTE_2)
+ .build());
+
+ boolean result =
+ resourceSharingPolicyHandlerService.addResourceSharingPolicyWithAttributes(resourceSharingPolicy,
+ sharedResourceAttributes);
+
+ Assert.assertTrue(result, "Expected the method to successfully add valid attributes.");
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtServerException.class, priority = 34)
+ public void testAddResourceSharingPolicyWithAttributesFailure() throws ResourceSharingPolicyMgtException {
+
+ ResourceSharingPolicy resourceSharingPolicy = new ResourceSharingPolicy.Builder()
+ .withResourceId(UM_ID_RESOURCE_1)
+ .withResourceType(RESOURCE_TYPE_RESOURCE_1)
+ .withInitiatingOrgId(UM_ID_ORGANIZATION_SUPER)
+ .withPolicyHoldingOrgId(UM_ID_ORGANIZATION_ORG_ALL)
+ .withSharingPolicy(PolicyEnum.SELECTED_ORG_WITH_ALL_EXISTING_AND_FUTURE_CHILDREN)
+ .build();
+
+ NamedJdbcTemplate mockJdbcTemplate = mock(NamedJdbcTemplate.class);
+
+ try (MockedStatic mockedStatic = mockStatic(Utils.class)) {
+ mockedStatic.when(Utils::getNewTemplate).thenReturn(mockJdbcTemplate);
+ doThrow(new TransactionException(MOCKED_TRANSACTION_EXCEPTION)).when(mockJdbcTemplate)
+ .withTransaction(any());
+
+ resourceSharingPolicyHandlerService.addResourceSharingPolicyWithAttributes(resourceSharingPolicy,
+ Collections.singletonList(new SharedResourceAttribute()));
+
+ mockedStatic.verify(Utils::getNewTemplate, times(1));
+ } catch (TransactionException e) {
+ throw new TestException(e);
+ }
+ }
+
+ @Test(priority = 35)
+ public void testGetResourceSharingPoliciesWithSharedAttributesSuccess() throws Exception {
+ // Prepare mock data
+ List policyHoldingOrganizationIds = Arrays.asList(
+ UM_ID_ORGANIZATION_SUPER, UM_ID_ORGANIZATION_ORG_ALL);
+
+ SharedResourceAttribute attribute1 = new SharedResourceAttribute.Builder()
+ .withResourceSharingPolicyId(1)
+ .withSharedAttributeType(SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1)
+ .withSharedAttributeId(UM_ID_RESOURCE_ATTRIBUTE_1)
+ .build();
+
+ SharedResourceAttribute attribute2 = new SharedResourceAttribute.Builder()
+ .withResourceSharingPolicyId(2)
+ .withSharedAttributeType(SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1)
+ .withSharedAttributeId(UM_ID_RESOURCE_ATTRIBUTE_2)
+ .build();
+
+ List sharedAttributes = Arrays.asList(attribute1, attribute2);
+ boolean attributesAdded = resourceSharingPolicyHandlerService.addSharedResourceAttributes(sharedAttributes);
+ Assert.assertTrue(attributesAdded, "Shared resource attributes were not added successfully.");
+
+ Map>> result =
+ resourceSharingPolicyHandlerService.getResourceSharingPoliciesWithSharedAttributes(
+ policyHoldingOrganizationIds);
+
+ Assert.assertNotNull(result);
+ Assert.assertEquals(result.size(), policyHoldingOrganizationIds.size(),
+ "Grouped result size does not match the number of policy holding organizations.");
+
+ for (String policyHoldingOrgId : policyHoldingOrganizationIds) {
+ Assert.assertTrue(result.containsKey(policyHoldingOrgId),
+ "Grouped result does not contain expected organization ID: " + policyHoldingOrgId);
+
+ Map> policyMap = result.get(policyHoldingOrgId);
+
+ for (Map.Entry> entry : policyMap.entrySet()) {
+ ResourceSharingPolicy policy = entry.getKey();
+ List attributes = entry.getValue();
+
+ Assert.assertNotNull(policy, "Resource sharing policy should not be null.");
+ Assert.assertNotNull(attributes, "Shared resource attributes list should not be null.");
+ }
+ }
+ }
+
+ @Test(priority = 36)
+ public void testGetResourceSharingPoliciesWithSharedAttributesEmptyResult() throws Exception {
+
+ List policyHoldingOrganizationIds = Collections.singletonList(UM_ID_ORGANIZATION_INVALID);
+
+ Map>> result =
+ resourceSharingPolicyHandlerService.getResourceSharingPoliciesWithSharedAttributes(
+ policyHoldingOrganizationIds);
+
+ Assert.assertEquals(result.size(), 0);
+ }
+
+ @Test(expectedExceptions = ResourceSharingPolicyMgtServerException.class, priority = 37)
+ public void testGetResourceSharingPoliciesWithSharedAttributesFailure() throws ResourceSharingPolicyMgtException {
+
+ NamedJdbcTemplate mockJdbcTemplate = mock(NamedJdbcTemplate.class);
+
+ try (MockedStatic mockedStatic = mockStatic(Utils.class)) {
+ mockedStatic.when(Utils::getNewTemplate).thenReturn(mockJdbcTemplate);
+ doThrow(new DataAccessException(MOCKED_DATA_ACCESS_EXCEPTION)).when(mockJdbcTemplate)
+ .executeQuery(anyString(), any(), any());
+
+ resourceSharingPolicyHandlerService.getResourceSharingPoliciesWithSharedAttributes(
+ Arrays.asList(UM_ID_ORGANIZATION_SUPER, UM_ID_ORGANIZATION_ORG_ALL));
+
+ mockedStatic.verify(Utils::getNewTemplate, times(1));
+ } catch (DataAccessException e) {
+ throw new TestException(e);
+ }
+ }
+
+ // Helpers: Private helper methods for tests.
+ private List addAndAssertResourceSharingPolicy(List policyHoldingOrgIds)
+ throws ResourceSharingPolicyMgtException {
+
+ ResourceSharingPolicy policy1 = new ResourceSharingPolicy.Builder()
+ .withResourceId(UM_ID_RESOURCE_1)
+ .withResourceType(RESOURCE_TYPE_RESOURCE_1)
+ .withInitiatingOrgId(UM_ID_ORGANIZATION_SUPER)
+ .withPolicyHoldingOrgId(policyHoldingOrgIds.get(0))
+ .withSharingPolicy(PolicyEnum.ALL_EXISTING_AND_FUTURE_ORGS)
+ .build();
+
+ ResourceSharingPolicy policy2 = new ResourceSharingPolicy.Builder()
+ .withResourceId(UM_ID_RESOURCE_2)
+ .withResourceType(RESOURCE_TYPE_RESOURCE_1)
+ .withInitiatingOrgId(UM_ID_ORGANIZATION_SUPER)
+ .withPolicyHoldingOrgId(policyHoldingOrgIds.get(1))
+ .withSharingPolicy(PolicyEnum.SELECTED_ORG_WITH_ALL_EXISTING_AND_FUTURE_CHILDREN)
+ .build();
+
+ List policyIds = new ArrayList<>();
+ List resourceSharingPolicies = Arrays.asList(policy1, policy2);
+
+ for (ResourceSharingPolicy resourceSharingPolicy : resourceSharingPolicies) {
+ int resourceSharingPolicyRecord =
+ resourceSharingPolicyHandlerService.addResourceSharingPolicy(resourceSharingPolicy);
+ Assert.assertTrue(resourceSharingPolicyRecord > 0,
+ "Expected a positive non-zero integer as the result for a clean record insertion " +
+ "to the database.");
+ policyIds.add(resourceSharingPolicyRecord);
+ }
+ return policyIds;
+ }
+
+ private void addAndAssertSharedResourceAttributes()
+ throws ResourceSharingPolicyMgtException {
+
+ List sharedResourceAttributes = new ArrayList<>();
+ List resourceSharingPolicyIds =
+ addAndAssertResourceSharingPolicy(Arrays.asList(UM_ID_ORGANIZATION_SUPER, UM_ID_ORGANIZATION_ORG_ALL));
+
+ for (int resourceSharingPolicyId : resourceSharingPolicyIds) {
+ SharedResourceAttribute sharedResourceAttribute = new SharedResourceAttribute.Builder()
+ .withResourceSharingPolicyId(resourceSharingPolicyId)
+ .withSharedAttributeType(SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1)
+ .withSharedAttributeId(UM_ID_RESOURCE_ATTRIBUTE_1)
+ .build();
+
+ sharedResourceAttributes.add(sharedResourceAttribute);
+ }
+
+ boolean isAdded = resourceSharingPolicyHandlerService.addSharedResourceAttributes(sharedResourceAttributes);
+ Assert.assertTrue(isAdded, "Added shared resource attributes.");
+
+ }
+
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constants/TestResourceSharingConstants.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constants/TestResourceSharingConstants.java
new file mode 100644
index 000000000..28130a31a
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/constants/TestResourceSharingConstants.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management.constants;
+
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.ResourceType;
+import org.wso2.carbon.identity.organization.resource.sharing.policy.management.constant.SharedAttributeType;
+
+/**
+ * Constants related to the test cases of Resource Sharing policy Management component.
+ */
+public class TestResourceSharingConstants {
+
+ //Organizations.
+ public static final String UM_ID_ORGANIZATION_SUPER = "10084a8d-113f-4211-a0d5-efe36b082211";
+ public static final String UM_ID_ORGANIZATION_ORG_ALL = "c524c30a-cbd4-4169-ac9d-1ee3edf1bf16";
+ public static final String UM_ID_ORGANIZATION_ORG_ALL_CHILD1 = "cd5a1dcb-fff2-4c14-a073-c07b3caf1757";
+ public static final String UM_ID_ORGANIZATION_ORG_IMMEDIATE = "7cb4ab7e-9a25-44bd-a9e0-cf4e07d804dc";
+ public static final String UM_ID_ORGANIZATION_ORG_IMMEDIATE_CHILD1 = "440ad5b6-6a41-4da7-aadd-272995d0e5db";
+
+ //Invalid Organizations.
+ public static final String UM_ID_ORGANIZATION_INVALID = "abcdefgh-0123-ijkl-4563-mnopqrstuvwx";
+ public static final String UM_ID_ORGANIZATION_INVALID_FORMAT = "12'3";
+
+ //Resources.
+ public static final String UM_ID_RESOURCE_1 = "448e57e7-ff6b-4c31-a1eb-2a0e2d635b2a";
+ public static final String UM_ID_RESOURCE_2 = "558e57e7-ff6b-4c31-a1eb-2a0e2d635b2a";
+ public static final String UM_ID_RESOURCE_3 = "668e57e7-ff6b-4c31-a1eb-2a0e2d635b2b";
+ public static final String UM_ID_RESOURCE_4 = "778e57e7-ff6b-4c31-a1eb-2a0e2d635b2c";
+
+ //Resources Types.
+ public static final ResourceType RESOURCE_TYPE_RESOURCE_1 = ResourceType.USER;
+
+ //Resource Attributes.
+ public static final String UM_ID_RESOURCE_ATTRIBUTE_1 = "daea2340-4686-4929-b0c3-aad28237b065";
+ public static final String UM_ID_RESOURCE_ATTRIBUTE_2 = "daea2341-4686-4929-b0c3-aad28237b065";
+
+ //Resource Attributes Types.
+ public static final SharedAttributeType SHARED_ATTRIBUTE_TYPE_RESOURCE_ATTRIBUTE_1 = SharedAttributeType.ROLE;
+
+ //Mocks
+ public static final String MOCKED_DATA_ACCESS_EXCEPTION = "Mocked DataAccessException";
+ public static final String MOCKED_TRANSACTION_EXCEPTION = "Mocked TransactionException";
+
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/util/TestUtils.java b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/util/TestUtils.java
new file mode 100644
index 000000000..3eb83c4ca
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/java/org/wso2/carbon/identity/organization/resource/sharing/policy/management/util/TestUtils.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2024, 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.organization.resource.sharing.policy.management.util;
+
+import org.apache.commons.dbcp.BasicDataSource;
+import org.apache.commons.lang.StringUtils;
+import org.wso2.carbon.base.CarbonBaseConstants;
+import org.wso2.carbon.context.CarbonContext;
+import org.wso2.carbon.context.internal.CarbonContextDataHolder;
+import org.wso2.carbon.identity.organization.management.service.util.Utils;
+import org.wso2.carbon.user.api.UserRealm;
+import org.wso2.carbon.user.core.util.DatabaseUtil;
+
+import java.lang.reflect.Field;
+import java.nio.file.Paths;
+import java.sql.Connection;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.sql.DataSource;
+
+import static org.mockito.Mockito.mock;
+
+/**
+ * Util methods needed for testing of Resource Sharing policy Management component.
+ */
+public class TestUtils {
+
+ public static final String DB_NAME = "testResourceSharingPolicyMgt_db";
+ public static final String H2_SCRIPT_NAME = "h2.sql";
+ public static Map dataSourceMap = new HashMap<>();
+
+ public static String getFilePath(String fileName) {
+
+ if (StringUtils.isNotBlank(fileName)) {
+ return Paths.get(System.getProperty("user.dir"), "src", "test", "resources", "dbscripts",
+ fileName).toString();
+ }
+ throw new IllegalArgumentException("DB Script file name cannot be empty.");
+ }
+
+ public static void initiateH2Base() throws Exception {
+
+ BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName("org.h2.Driver");
+ dataSource.setUsername("username");
+ dataSource.setPassword("password");
+ dataSource.setUrl("jdbc:h2:mem:test" + DB_NAME);
+ dataSource.setTestOnBorrow(true);
+ dataSource.setValidationQuery("select 1");
+ try (Connection connection = dataSource.getConnection()) {
+ connection.createStatement().executeUpdate(getExecuteUpdateQuery());
+ }
+ dataSourceMap.put(DB_NAME, dataSource);
+ }
+
+ public static void closeH2Base() throws Exception {
+
+ BasicDataSource dataSource = dataSourceMap.remove(DB_NAME);
+ if (dataSource != null) {
+ dataSource.close();
+ }
+ }
+
+ public static void mockDataSource() throws Exception {
+
+ String carbonHome = Paths.get(System.getProperty("user.dir"), "target", "test-classes").toString();
+ System.setProperty(CarbonBaseConstants.CARBON_HOME, carbonHome);
+ System.setProperty(CarbonBaseConstants.CARBON_CONFIG_DIR_PATH, Paths.get(carbonHome,
+ "repository/conf").toString());
+
+ DataSource dataSource = dataSourceMap.get(DB_NAME);
+
+ setStatic(DatabaseUtil.class.getDeclaredField("dataSource"), dataSource);
+
+ Field carbonContextHolderField =
+ CarbonContext.getThreadLocalCarbonContext().getClass().getDeclaredField("carbonContextHolder");
+ carbonContextHolderField.setAccessible(true);
+ CarbonContextDataHolder carbonContextHolder
+ = (CarbonContextDataHolder) carbonContextHolderField.get(CarbonContext.getThreadLocalCarbonContext());
+ carbonContextHolder.setUserRealm(mock(UserRealm.class));
+ setStatic(Utils.class.getDeclaredField("dataSource"), dataSource);
+ }
+
+ private static void setStatic(Field field, Object newValue) throws Exception {
+
+ field.setAccessible(true);
+ field.set(null, newValue);
+ }
+
+ private static String getExecuteUpdateQuery() {
+
+ return "RUNSCRIPT FROM '" + getFilePath(H2_SCRIPT_NAME) + "'";
+ }
+}
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/resources/dbscripts/h2.sql b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/resources/dbscripts/h2.sql
new file mode 100644
index 000000000..733a588a6
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/resources/dbscripts/h2.sql
@@ -0,0 +1,74 @@
+-- UM_ORG definition
+CREATE TABLE UM_ORG
+(
+ UM_ID CHARACTER VARYING(36) NOT NULL,
+ UM_ORG_NAME CHARACTER VARYING(255) NOT NULL,
+ UM_ORG_DESCRIPTION CHARACTER VARYING(1024),
+ UM_CREATED_TIME TIMESTAMP NOT NULL,
+ UM_LAST_MODIFIED TIMESTAMP NOT NULL,
+ UM_STATUS CHARACTER VARYING(255) DEFAULT 'ACTIVE' NOT NULL,
+ UM_PARENT_ID CHARACTER VARYING(36),
+ UM_ORG_TYPE CHARACTER VARYING(100) NOT NULL,
+ PRIMARY KEY (UM_ID),
+ FOREIGN KEY (UM_PARENT_ID) REFERENCES PUBLIC.UM_ORG (UM_ID) ON DELETE CASCADE ON UPDATE RESTRICT
+);
+CREATE INDEX IDX_UM_ORG_PARENT_ID ON PUBLIC.UM_ORG (UM_PARENT_ID);
+CREATE UNIQUE INDEX IDX_UNIQUE_UM_ORG_ID ON PUBLIC.UM_ORG (UM_ID);
+
+-- Table to store polices of sharing resources
+CREATE TABLE UM_RESOURCE_SHARING_POLICY
+(
+ UM_ID INTEGER NOT NULL AUTO_INCREMENT,
+ UM_RESOURCE_TYPE VARCHAR(255) NOT NULL,
+ UM_RESOURCE_ID VARCHAR(36) NOT NULL,
+ UM_INITIATING_ORG_ID VARCHAR(36) NOT NULL,
+ UM_POLICY_HOLDING_ORG_ID VARCHAR(36) NOT NULL,
+ UM_SHARING_POLICY VARCHAR(255) NOT NULL,
+ PRIMARY KEY (UM_ID),
+ FOREIGN KEY (UM_INITIATING_ORG_ID) REFERENCES UM_ORG (UM_ID) ON DELETE CASCADE ON UPDATE CASCADE,
+ FOREIGN KEY (UM_POLICY_HOLDING_ORG_ID) REFERENCES UM_ORG (UM_ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+-- Table to store attributes related to shared resources
+CREATE TABLE UM_SHARED_RESOURCE_ATTRIBUTES
+(
+ UM_ID INTEGER NOT NULL AUTO_INCREMENT,
+ UM_RESOURCE_SHARING_POLICY_ID INTEGER NOT NULL,
+ UM_SHARED_ATTRIBUTE_TYPE VARCHAR(255) NOT NULL,
+ UM_SHARED_ATTRIBUTE_ID VARCHAR(36) NOT NULL,
+ PRIMARY KEY (UM_ID),
+ FOREIGN KEY (UM_RESOURCE_SHARING_POLICY_ID) REFERENCES UM_RESOURCE_SHARING_POLICY (UM_ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+INSERT INTO UM_ORG (UM_ID, UM_ORG_NAME, UM_ORG_DESCRIPTION, UM_CREATED_TIME, UM_LAST_MODIFIED, UM_STATUS, UM_PARENT_ID,
+ UM_ORG_TYPE)
+VALUES ('10084a8d-113f-4211-a0d5-efe36b082211', 'Super', 'This is the super organization.',
+ '2024-10-24 16:40:48.641555', '2024-10-24 16:40:48.641555', 'ACTIVE', NULL, 'TENANT'),
+ ('c524c30a-cbd4-4169-ac9d-1ee3edf1bf16', 'org-all', NULL, '2024-11-19 07:19:01.16727',
+ '2024-11-19 07:19:01.16727', 'ACTIVE', '10084a8d-113f-4211-a0d5-efe36b082211', 'TENANT'),
+ ('cd5a1dcb-fff2-4c14-a073-c07b3caf1757', 'org-all-child1', NULL, '2024-11-19 07:19:17.677139',
+ '2024-11-19 07:19:17.677139', 'ACTIVE', 'c524c30a-cbd4-4169-ac9d-1ee3edf1bf16', 'TENANT'),
+ ('46edfee9-b9f7-4480-ab45-353a571eafb4', 'org-all-grandchild1', NULL, '2024-11-19 07:19:49.208315',
+ '2024-11-19 07:19:49.208315', 'ACTIVE', 'cd5a1dcb-fff2-4c14-a073-c07b3caf1757', 'TENANT'),
+ ('7cb4ab7e-9a25-44bd-a9e0-cf4e07d804dc', 'org-immediate', NULL, '2024-11-19 07:20:04.418474',
+ '2024-11-19 07:20:04.418474', 'ACTIVE', '10084a8d-113f-4211-a0d5-efe36b082211', 'TENANT'),
+ ('440ad5b6-6a41-4da7-aadd-272995d0e5db', 'org-immediate-child1', NULL, '2024-11-19 07:20:19.34002',
+ '2024-11-19 07:20:19.34002', 'ACTIVE', '7cb4ab7e-9a25-44bd-a9e0-cf4e07d804dc', 'TENANT'),
+ ('ea1a347c-0b2b-421a-a21a-50fb489bc41f', 'org-immediate-grandchild1', NULL, '2024-11-19 07:20:30.359943',
+ '2024-11-19 07:20:30.359943', 'ACTIVE', '440ad5b6-6a41-4da7-aadd-272995d0e5db', 'TENANT');
+
+INSERT INTO UM_RESOURCE_SHARING_POLICY (UM_RESOURCE_TYPE, UM_RESOURCE_ID, UM_INITIATING_ORG_ID, UM_POLICY_HOLDING_ORG_ID, UM_SHARING_POLICY)
+VALUES
+ ('USER', 'a07a3509-f646-498c-890e-cedb08cd1586', '10084a8d-113f-4211-a0d5-efe36b082211', 'c524c30a-cbd4-4169-ac9d-1ee3edf1bf16', 'SELECTIVE-003'),
+ ('USER', '678afe66-36ed-4c0a-8789-b6f83c4f40dc', '10084a8d-113f-4211-a0d5-efe36b082211', 'c524c30a-cbd4-4169-ac9d-1ee3edf1bf16', 'SELECTIVE-003'),
+ ('USER', '150b7b05-21bb-4b20-a7be-9e7a299969bb', '10084a8d-113f-4211-a0d5-efe36b082211', '7cb4ab7e-9a25-44bd-a9e0-cf4e07d804dc', 'SELECTIVE-005'),
+ ('USER', '94154a9a-e177-404c-8504-d58a71db1f84', '10084a8d-113f-4211-a0d5-efe36b082211', 'c524c30a-cbd4-4169-ac9d-1ee3edf1bf16', 'SELECTIVE-003'),
+ ('USER', '94154a9a-e177-404c-8504-d58a71db1f84', '10084a8d-113f-4211-a0d5-efe36b082211', 'c524c30a-cbd4-4169-ac9d-1ee3edf1bf16', 'SELECTIVE-005');
+
+INSERT INTO UM_SHARED_RESOURCE_ATTRIBUTES (UM_RESOURCE_SHARING_POLICY_ID, UM_SHARED_ATTRIBUTE_TYPE, UM_SHARED_ATTRIBUTE_ID)
+VALUES
+ (1, 'ROLE', 'daea2340-4686-4929-b0c3-aad28237b065'),
+ (2, 'ROLE', 'fcee2861-3687-4f66-b656-94591faf44ab'),
+ (3, 'ROLE', 'daea2340-4686-4929-b0c3-aad28237b065'),
+ (4, 'ROLE', 'fcee2861-3687-4f66-b656-94591faf44ab'),
+ (5, 'ROLE', 'f0dd8c17-e085-4816-bed1-eee84052e3ab');
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/resources/repository.conf/carbon.xml b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/resources/repository.conf/carbon.xml
new file mode 100644
index 000000000..260bcd7f3
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/resources/repository.conf/carbon.xml
@@ -0,0 +1,686 @@
+
+
+
+
+
+
+
+ WSO2 Identity Server
+
+
+ IS
+
+
+ 5.3.0
+
+
+ localhost
+
+
+ localhost
+
+
+ local:/${carbon.context}/services/
+
+
+
+
+
+
+ IdentityServer
+
+
+
+
+
+
+ org.wso2.carbon
+
+
+ /
+
+
+
+
+
+
+
+
+ 15
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+ 9999
+
+ 11111
+
+
+
+
+
+ 10389
+
+ 8000
+
+
+
+
+
+ 10500
+
+
+
+
+
+
+
+
+ org.wso2.carbon.tomcat.jndi.CarbonJavaURLContextFactory
+
+
+
+
+
+
+
+
+ java
+
+
+
+
+
+
+
+
+
+ false
+
+
+ false
+
+
+ 600
+
+
+
+ false
+
+
+
+
+
+
+
+ 30
+
+
+
+
+
+
+
+
+ 15
+
+
+
+
+
+ ${carbon.home}/repository/deployment/server/
+
+
+ 15
+
+
+ ${carbon.home}/repository/conf/axis2/axis2.xml
+
+
+ 30000
+
+
+ ${carbon.home}/repository/deployment/client/
+
+ ${carbon.home}/repository/conf/axis2/axis2_client.xml
+
+ true
+
+
+
+
+
+
+
+
+
+ admin
+ Default Administrator Role
+
+
+ user
+ Default User Role
+
+
+
+
+
+
+
+
+
+
+
+ ${carbon.home}/repository/resources/security/wso2carbon.jks
+
+ JKS
+
+ wso2carbon
+
+ wso2carbon
+
+ wso2carbon
+
+
+
+
+
+ ${carbon.home}/repository/resources/security/client-truststore.jks
+
+ JKS
+
+ wso2carbon
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UserManager
+
+
+ false
+
+ org.wso2.carbon.identity.provider.AttributeCallbackHandler
+
+
+ org.wso2.carbon.identity.sts.store.DBTokenStore
+
+
+ true
+ allow
+
+
+
+
+
+
+ claim_mgt_menu
+ identity_mgt_emailtemplate_menu
+ identity_security_questions_menu
+
+
+
+ ${carbon.home}/tmp/work
+
+
+
+
+
+ true
+
+
+ 10
+
+
+ 30
+
+
+
+
+
+ 100
+
+
+
+ keystore
+ certificate
+ *
+
+ org.wso2.carbon.ui.transports.fileupload.AnyFileUploadExecutor
+
+
+
+
+ jarZip
+
+ org.wso2.carbon.ui.transports.fileupload.JarZipUploadExecutor
+
+
+
+ dbs
+
+ org.wso2.carbon.ui.transports.fileupload.DBSFileUploadExecutor
+
+
+
+ tools
+
+ org.wso2.carbon.ui.transports.fileupload.ToolsFileUploadExecutor
+
+
+
+ toolsAny
+
+ org.wso2.carbon.ui.transports.fileupload.ToolsAnyFileUploadExecutor
+
+
+
+
+
+
+
+
+
+ - info
+ org.wso2.carbon.core.transports.util.InfoProcessor
+
+
+ - wsdl
+ org.wso2.carbon.core.transports.util.Wsdl11Processor
+
+
+ - wsdl2
+ org.wso2.carbon.core.transports.util.Wsdl20Processor
+
+
+ - xsd
+ org.wso2.carbon.core.transports.util.XsdProcessor
+
+
+
+
+
+ false
+ false
+ true
+ svn
+ http://svnrepo.example.com/repos/
+ username
+ password
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${require.carbon.servlet}
+
+
+
+
+ true
+
+
+
+
+
+
+ default repository
+ http://product-dist.wso2.com/p2/carbon/releases/wilkes/
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+ true
+
+
diff --git a/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/resources/testing.xml b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/resources/testing.xml
new file mode 100644
index 000000000..c6ed86ce1
--- /dev/null
+++ b/components/org.wso2.carbon.identity.organization.resource.sharing.policy.management/src/test/resources/testing.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 8d339b34e..d794fdee9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,6 +1,6 @@
- 4.9.17
+ 4.10.25
[4.7.0, 5.0.0)
4.6.0
@@ -573,7 +586,7 @@
[1.0.1, 2.0.0)
[4.7.0, 5.0.0)
- 2.1.7
+ 2.2.2
[2.0.0,3.0.0)
1.4.47
@@ -593,7 +606,8 @@
5.2.0
6.9.10
2.22.0
- 1.4.199
+ 2.2.224
+ 4.11.30
4.1.2