diff --git a/components/org.wso2.carbon.identity.organization.management.handler/pom.xml b/components/org.wso2.carbon.identity.organization.management.handler/pom.xml index 8b24b80f0..635c34038 100644 --- a/components/org.wso2.carbon.identity.organization.management.handler/pom.xml +++ b/components/org.wso2.carbon.identity.organization.management.handler/pom.xml @@ -128,7 +128,12 @@ org.wso2.carbon.identity.recovery.*; version="${identity.governance.imp.pkg.version.range}", org.wso2.carbon.identity.governance; version="${identity.governance.imp.pkg.version.range}", org.wso2.carbon.identity.role.v2.mgt.core.*; version="${carbon.identity.package.import.version.range}", - org.wso2.carbon.identity.organization.management.application.*; version="${org.wso2.identity.organization.mgt.imp.pkg.version.range}", + org.wso2.carbon.identity.organization.management.application.*; + version="${org.wso2.identity.organization.mgt.imp.pkg.version.range}", + org.wso2.carbon.identity.application.mgt.*; + version="${carbon.identity.package.import.version.range}", + org.wso2.carbon.identity.application.common.*; + version="${carbon.identity.package.import.version.range}", diff --git a/components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java b/components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java index 49a4627d3..4478d80c0 100644 --- a/components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java +++ b/components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java @@ -35,7 +35,7 @@ import org.wso2.carbon.identity.organization.management.service.model.BasicOrganization; import org.wso2.carbon.identity.organization.management.service.model.Organization; import org.wso2.carbon.identity.organization.management.service.model.ParentOrganizationDO; -import org.wso2.carbon.identity.organization.management.service.util.Utils; +import org.wso2.carbon.identity.organization.management.service.util.OrganizationManagementUtil; import org.wso2.carbon.identity.role.v2.mgt.core.IdentityRoleManagementException; import org.wso2.carbon.identity.role.v2.mgt.core.RoleBasicInfo; import org.wso2.carbon.identity.role.v2.mgt.core.RoleConstants; @@ -44,6 +44,9 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; /** * Event handler to manage shared roles in sub-organizations. @@ -51,6 +54,7 @@ public class SharedRoleMgtHandler extends AbstractEventHandler { private static final Log LOG = LogFactory.getLog(SharedRoleMgtHandler.class); + private final ExecutorService executorService = Executors.newFixedThreadPool(5); @Override public void handleEvent(Event event) throws IdentityEventException { @@ -60,28 +64,33 @@ public void handleEvent(Event event) throws IdentityEventException { switch (eventName) { case OrgApplicationMgtConstants.EVENT_POST_SHARE_APPLICATION: /* - If the main application use application audienced roles, create the role for sub org space, - and add the relationship. + If the main application use application audienced roles, create the role for shared app's org space, + and add the relationship. If the main application use organization audienced roles, create the role in + shared app's org space, and add the relationship if already not exists. */ - createSubOrgRolesOnAppSharing(eventProperties); + createOrganizationRolesOnAppSharing(eventProperties); break; case IdentityEventConstants.Event.POST_ADD_ROLE_V2_EVENT: - createSubOrgRolesOnNewRoleCreation(eventProperties); + createOrganizationRolesOnNewRoleCreation(eventProperties); break; case Constants.EVENT_POST_ADD_ORGANIZATION: /* - If the org is a sub organization and if primary org has roles with organization audience, + If the created org's primary business org has roles with organization audience, create them in the sub org as well. */ - createSubOrgRolesOnNewOrgCreation(eventProperties); + // TODO: This might not required with new approach of handling org audience roles + createOrganizationRolesOnNewOrgCreation(eventProperties); break; default: - LOG.debug("Unsupported event: " + eventName); + if (LOG.isDebugEnabled()) { + LOG.debug("Unsupported event: " + eventName); + } break; } } - private void createSubOrgRolesOnNewOrgCreation(Map eventProperties) throws IdentityEventException { + private void createOrganizationRolesOnNewOrgCreation(Map eventProperties) + throws IdentityEventException { try { Organization organization = (Organization) eventProperties.get(Constants.EVENT_PROP_ORGANIZATION); @@ -115,7 +124,8 @@ private void createSubOrgRolesOnNewOrgCreation(Map eventProperti } } - private void createSubOrgRolesOnNewRoleCreation(Map eventProperties) throws IdentityEventException { + private void createOrganizationRolesOnNewRoleCreation(Map eventProperties) + throws IdentityEventException { try { String mainRoleUUID = (String) eventProperties.get(IdentityEventConstants.EventProperty.ROLE_ID); @@ -124,30 +134,53 @@ private void createSubOrgRolesOnNewRoleCreation(Map eventPropert String roleAudienceType = (String) eventProperties.get(IdentityEventConstants.EventProperty.AUDIENCE); String roleAudienceId = (String) eventProperties.get(IdentityEventConstants.EventProperty.AUDIENCE_ID); String roleOrgId = getOrganizationManager().resolveOrganizationId(roleTenantDomain); - if (Utils.isOrganization(roleTenantDomain)) { + if (OrganizationManagementUtil.isOrganization(roleTenantDomain)) { return; } switch (roleAudienceType) { case RoleConstants.APPLICATION: - // If the audienced application is a shared application, create the role in the shared apps. + /* + If the audienced application is a shared application, create the role in + the shared apps' org space. + */ List sharedApplications = getOrgApplicationManager().getSharedApplications(roleOrgId, roleAudienceId); - for (SharedApplication sharedApplication : sharedApplications) { - String sharedApplicationId = sharedApplication.getSharedApplicationId(); - String sharedOrganizationId = sharedApplication.getOrganizationId(); - String shareAppTenantDomain = - getOrganizationManager().resolveTenantDomain(sharedOrganizationId); - RoleBasicInfo sharedRoleInfo = - getRoleManagementServiceV2().addRole(mainRoleName, Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), RoleConstants.APPLICATION, sharedApplicationId, - shareAppTenantDomain); - // Add relationship between main role and shared role. - getRoleManagementServiceV2().addMainRoleToSharedRoleRelationship(mainRoleUUID, - sharedRoleInfo.getId(), roleTenantDomain, shareAppTenantDomain); + int noOfSharedApps = sharedApplications.size(); + CompletableFuture[] creations = new CompletableFuture[noOfSharedApps]; + for (int i = 0; i < noOfSharedApps; i++) { + final int taskId = i; + CompletableFuture sharedRoleCreation = CompletableFuture.runAsync(() -> { + try { + String sharedApplicationId = sharedApplications.get(taskId).getSharedApplicationId(); + String sharedOrganizationId = sharedApplications.get(taskId).getOrganizationId(); + String shareAppTenantDomain = + getOrganizationManager().resolveTenantDomain(sharedOrganizationId); + RoleBasicInfo sharedRoleInfo = + getRoleManagementServiceV2().addRole(mainRoleName, Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), RoleConstants.APPLICATION, sharedApplicationId, + shareAppTenantDomain); + // Add relationship between main role and shared role. + getRoleManagementServiceV2().addMainRoleToSharedRoleRelationship(mainRoleUUID, + sharedRoleInfo.getId(), roleTenantDomain, shareAppTenantDomain); + } catch (IdentityRoleManagementException | OrganizationManagementException e) { + LOG.error("Error occurred while creating shared role in organization with id: " + + sharedApplications.get(taskId).getOrganizationId(), e); + } + }, executorService); + creations[taskId] = sharedRoleCreation; } + CompletableFuture allOfCreations = CompletableFuture.allOf(creations); + allOfCreations.join(); break; case RoleConstants.ORGANIZATION: + /* + TODO: Need to create organization roles in suborgs only if the role is + attahced to at least on shared role + on new org role creation, this role can't be associated to an app. + therefore this logic can be removed + + */ // If the audienced organization is a shared organization, create the role in the shared orgs. List childOrganizations = getOrganizationManager().getChildOrganizations(roleOrgId, true); @@ -175,7 +208,8 @@ private void createSubOrgRolesOnNewRoleCreation(Map eventPropert } } - private void createSubOrgRolesOnAppSharing(Map eventProperties) throws IdentityEventException { + private void createOrganizationRolesOnAppSharing(Map eventProperties) + throws IdentityEventException { String parentOrganizationId = (String) eventProperties.get(OrgApplicationMgtConstants.EVENT_PROP_PARENT_ORGANIZATION_ID); @@ -193,6 +227,7 @@ private void createSubOrgRolesOnAppSharing(Map eventProperties) boolean hasAppAudiencedRoles = RoleConstants.APPLICATION.equalsIgnoreCase(allowedAudienceForRoleAssociation); if (!hasAppAudiencedRoles) { + // TODO: handle organization audience role creation if they doesn't exist in sub org. return; } // Create the role if not exists, and add the relationship. diff --git a/pom.xml b/pom.xml index 153dc4269..9893d555c 100644 --- a/pom.xml +++ b/pom.xml @@ -495,7 +495,7 @@ [1.0.0,2.0.0) - 1.0.69 + 1.0.70 [1.0.0,2.0.0)