From 58aacad51ba171b021d23689955633531ce32349 Mon Sep 17 00:00:00 2001 From: AnuradhaSK Date: Sun, 8 Oct 2023 23:55:12 +0530 Subject: [PATCH] add shared role managing event handler --- .../pom.xml | 14 ++ .../handler/SharedRoleMgtHandler.java | 180 ++++++++++++++++++ ...ganizationManagementHandlerDataHolder.java | 46 ++++- ...tionManagementHandlerServiceComponent.java | 44 ++++- pom.xml | 8 +- 5 files changed, 285 insertions(+), 7 deletions(-) create mode 100644 components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java 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 09b8f947b..e58a15306 100644 --- a/components/org.wso2.carbon.identity.organization.management.handler/pom.xml +++ b/components/org.wso2.carbon.identity.organization.management.handler/pom.xml @@ -56,6 +56,18 @@ org.wso2.carbon.identity.governance org.wso2.carbon.identity.governance + + org.wso2.carbon.identity.organization.management + org.wso2.carbon.identity.organization.management.application + + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.event + + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.role.v2.mgt.core + @@ -115,6 +127,8 @@ org.wso2.carbon.identity.event.services; version="${carbon.identity.package.import.version.range}", 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}", 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 new file mode 100644 index 000000000..e356491ee --- /dev/null +++ b/components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.identity.organization.management.handler; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.identity.event.IdentityEventConstants; +import org.wso2.carbon.identity.event.IdentityEventException; +import org.wso2.carbon.identity.event.event.Event; +import org.wso2.carbon.identity.event.handler.AbstractEventHandler; +import org.wso2.carbon.identity.organization.management.application.OrgApplicationManager; +import org.wso2.carbon.identity.organization.management.application.constant.OrgApplicationMgtConstants; +import org.wso2.carbon.identity.organization.management.application.model.SharedApplication; +import org.wso2.carbon.identity.organization.management.ext.Constants; +import org.wso2.carbon.identity.organization.management.handler.internal.OrganizationManagementHandlerDataHolder; +import org.wso2.carbon.identity.organization.management.service.OrganizationManager; +import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException; +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; +import org.wso2.carbon.identity.role.v2.mgt.core.RoleManagementService; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * Event handler to manage shared roles in sub-organizations. + */ +public class SharedRoleMgtHandler extends AbstractEventHandler { + + private static final Log LOG = LogFactory.getLog(SharedRoleMgtHandler.class); + + @Override + public void handleEvent(Event event) throws IdentityEventException { + + String eventName = event.getEventName(); + Map eventProperties = event.getEventProperties(); + 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. + */ + createSubOrgRolesOnAppSharing(eventProperties); + break; + case OrgApplicationMgtConstants.EVENT_POST_DELETE_SHARED_APPLICATION: + // TODO: no need to handle here if application audienced roles get + // deleted if the application is deleted. + break; + case OrgApplicationMgtConstants.EVENT_POST_DELETE_ALL_SHARED_APPLICATIONS: + // TODO: no need to handle here if application audienced roles get + // deleted if the application is deleted. + break; + case IdentityEventConstants.Event.POST_ADD_ROLE_V2_EVENT: + createSubOrgRolesOnNewRoleCreation(eventProperties); + break; + case IdentityEventConstants.Event.POST_DELETE_ROLE_V2_EVENT: + // If the deleted role is a primary org's role, delete the shared roles. +// String roleId = (String) eventProperties.get(IdentityEventConstants.EventProperty.ROLE_ID); +// String roleTenantDomain = +// (String) eventProperties.get(IdentityEventConstants.EventProperty.TENANT_DOMAIN); + + break; + case Constants.EVENT_POST_ADD_ORGANIZATION: + /* + If the org is a sub organization and if primary org has roles with organization audience, + create them in the sub org as well. + */ + break; + // TODO: role name update event. + } + } + + private void createSubOrgRolesOnNewRoleCreation(Map eventProperties) { + + try { + String roleName = (String) eventProperties.get(IdentityEventConstants.EventProperty.ROLE_NAME); + String roleTenantDomain = (String) eventProperties.get(IdentityEventConstants.EventProperty.TENANT_DOMAIN); + String roleAudienceType = (String) eventProperties.get(IdentityEventConstants.EventProperty.AUDIENCE); + String roleAudienceId = (String) eventProperties.get(IdentityEventConstants.EventProperty.AUDIENCE_ID); + String roleOrgId = getOrganizationManager().resolveOrganizationId(roleTenantDomain); + boolean isPrimaryOrganization = getOrganizationManager().isPrimaryOrganization(roleOrgId); + if (!isPrimaryOrganization) { + return; + } + switch (roleAudienceType) { + case RoleConstants.APPLICATION: + // If the audienced application is a shared application, create the role in the shared apps. + 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(roleName, Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), RoleConstants.APPLICATION, sharedApplicationId, + shareAppTenantDomain); + // Add relationship between main role and shared role. + // TODO + String mainRoleUUID = "TODO"; + getRoleManagementServiceV2().addMainRoleToSharedRoleRelationship(mainRoleUUID, + sharedRoleInfo.getId(), roleTenantDomain, shareAppTenantDomain); + } + break; + case RoleConstants.ORGANIZATION: + // If the audienced organization is a shared organization, create the role in the shared orgs. + break; + } + } catch (OrganizationManagementException e) { + LOG.debug(e.getMessage()); + } catch (IdentityRoleManagementException e) { + // TODO : handle exception + throw new RuntimeException(e); + } + } + + private void createSubOrgRolesOnAppSharing(Map eventProperties) { + + String parentOrganizationId = + (String) eventProperties.get(OrgApplicationMgtConstants.EVENT_PROP_PARENT_ORGANIZATION_ID); + String parentApplicationId = + (String) eventProperties.get(OrgApplicationMgtConstants.EVENT_PROP_PARENT_APPLICATION_ID); + String sharedOrganizationId = + (String) eventProperties.get(OrgApplicationMgtConstants.EVENT_PROP_SHARED_ORGANIZATION_ID); + String sharedApplicationId = + (String) eventProperties.get(OrgApplicationMgtConstants.EVENT_PROP_SHARED_APPLICATION_ID); + boolean hasAppAudiencedRoles = true; + // TODO: check application is using the application audience roles. + if (hasAppAudiencedRoles) { + // Create the role if not exists, and add the relationship. + try { + String mainApplicationTenantDomain = getOrganizationManager().resolveTenantDomain(parentOrganizationId); + String sharedApplicationTenantDomain = + getOrganizationManager().resolveTenantDomain(sharedOrganizationId); + RoleManagementService roleManagementServiceV2 = getRoleManagementServiceV2(); + roleManagementServiceV2.shareRoles(parentApplicationId, mainApplicationTenantDomain, + sharedApplicationId, + sharedApplicationTenantDomain); + } catch (OrganizationManagementException | IdentityRoleManagementException e) { + // TODO: handle exception + throw new RuntimeException(e); + } + } + } + + private static RoleManagementService getRoleManagementServiceV2() { + + return OrganizationManagementHandlerDataHolder.getInstance().getRoleManagementServiceV2(); + } + + private static OrganizationManager getOrganizationManager() { + + return OrganizationManagementHandlerDataHolder.getInstance().getOrganizationManager(); + } + + private static OrgApplicationManager getOrgApplicationManager() { + + return OrganizationManagementHandlerDataHolder.getInstance().getOrgApplicationManager(); + } +} diff --git a/components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/internal/OrganizationManagementHandlerDataHolder.java b/components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/internal/OrganizationManagementHandlerDataHolder.java index dddbba7b9..1f7cd7f1c 100644 --- a/components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/internal/OrganizationManagementHandlerDataHolder.java +++ b/components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/internal/OrganizationManagementHandlerDataHolder.java @@ -20,7 +20,9 @@ import org.wso2.carbon.identity.event.services.IdentityEventService; import org.wso2.carbon.identity.governance.IdentityGovernanceService; +import org.wso2.carbon.identity.organization.management.application.OrgApplicationManager; import org.wso2.carbon.identity.organization.management.service.OrganizationManager; +import org.wso2.carbon.identity.role.v2.mgt.core.RoleManagementService; /** * Organization management handler data holder. @@ -31,10 +33,10 @@ public class OrganizationManagementHandlerDataHolder { new OrganizationManagementHandlerDataHolder(); private IdentityEventService identityEventService; - private IdentityGovernanceService identityGovernanceService; - private OrganizationManager organizationManager; + private RoleManagementService roleManagementServiceV2; + private OrgApplicationManager orgApplicationManager; public static OrganizationManagementHandlerDataHolder getInstance() { @@ -100,5 +102,45 @@ public void setOrganizationManager(OrganizationManager organizationManager) { this.organizationManager = organizationManager; } + + /** + * Set {@link RoleManagementService}. + * + * @param roleManagementServiceV2 Instance of {@link RoleManagementService}. + */ + public void setRoleManagementServiceV2(RoleManagementService roleManagementServiceV2) { + + this.roleManagementServiceV2 = roleManagementServiceV2; + } + + /** + * Get {@link RoleManagementService}. + * + * @return role management service instance {@link RoleManagementService}. + */ + public RoleManagementService getRoleManagementServiceV2() { + + return roleManagementServiceV2; + } + + /** + * Get {@link OrgApplicationManager}. + * + * @return Org application manager instance {@link OrgApplicationManager}. + */ + public OrgApplicationManager getOrgApplicationManager() { + + return orgApplicationManager; + } + + /** + * Set {@link OrgApplicationManager}. + * + * @param orgApplicationManager Instance of {@link OrgApplicationManager}. + */ + public void setOrgApplicationManager(OrgApplicationManager orgApplicationManager) { + + this.orgApplicationManager = orgApplicationManager; + } } diff --git a/components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/internal/OrganizationManagementHandlerServiceComponent.java b/components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/internal/OrganizationManagementHandlerServiceComponent.java index d2e77840c..fe5f5669e 100644 --- a/components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/internal/OrganizationManagementHandlerServiceComponent.java +++ b/components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/internal/OrganizationManagementHandlerServiceComponent.java @@ -30,8 +30,11 @@ import org.wso2.carbon.identity.event.handler.AbstractEventHandler; import org.wso2.carbon.identity.event.services.IdentityEventService; import org.wso2.carbon.identity.governance.IdentityGovernanceService; +import org.wso2.carbon.identity.organization.management.application.OrgApplicationManager; import org.wso2.carbon.identity.organization.management.handler.GovernanceConfigUpdateHandler; +import org.wso2.carbon.identity.organization.management.handler.SharedRoleMgtHandler; import org.wso2.carbon.identity.organization.management.service.OrganizationManager; +import org.wso2.carbon.identity.role.v2.mgt.core.RoleManagementService; /** * Organization management handler service component. @@ -54,8 +57,8 @@ protected void activate(ComponentContext componentContext) { try { BundleContext bundleContext = componentContext.getBundleContext(); - bundleContext.registerService(AbstractEventHandler.class, new GovernanceConfigUpdateHandler(), - null); + bundleContext.registerService(AbstractEventHandler.class, new GovernanceConfigUpdateHandler(), null); + bundleContext.registerService(AbstractEventHandler.class, new SharedRoleMgtHandler(), null); LOG.debug("Organization management handler component activated successfully."); } catch (Throwable e) { LOG.error("Error while activating organization management handler module.", e); @@ -110,5 +113,40 @@ protected void unsetOrganizationManager(OrganizationManager organizationManager) OrganizationManagementHandlerDataHolder.getInstance().setOrganizationManager(null); } -} + @Reference( + name = "org.wso2.carbon.identity.role.v2.mgt.core.RoleManagementService", + service = org.wso2.carbon.identity.role.v2.mgt.core.RoleManagementService.class, + cardinality = ReferenceCardinality.MANDATORY, + policy = ReferencePolicy.DYNAMIC, + unbind = "unsetRoleManagementServiceV2") + protected void setRoleManagementServiceV2(RoleManagementService roleManagementService) { + + OrganizationManagementHandlerDataHolder.getInstance().setRoleManagementServiceV2(roleManagementService); + LOG.debug("RoleManagementServiceV2 set in OrganizationManagementHandlerService bundle."); + } + + protected void unsetRoleManagementServiceV2(RoleManagementService roleManagementService) { + + OrganizationManagementHandlerDataHolder.getInstance().setRoleManagementServiceV2(null); + LOG.debug("RoleManagementServiceV2 unset in OrganizationManagementHandlerService bundle."); + } + + @Reference( + name = "org.wso2.carbon.identity.organization.management.application.OrgApplicationManager", + service = org.wso2.carbon.identity.organization.management.application.OrgApplicationManager.class, + cardinality = ReferenceCardinality.MANDATORY, + policy = ReferencePolicy.DYNAMIC, + unbind = "unsetOrgApplicationManagementService") + protected void setOrgApplicationManagementService(OrgApplicationManager orgApplicationManagementService) { + + OrganizationManagementHandlerDataHolder.getInstance().setOrgApplicationManager(orgApplicationManagementService); + LOG.debug("OrgApplication management service unset in OrganizationManagementHandlerService bundle."); + } + + protected void unsetOrgApplicationManagementService(OrgApplicationManager orgApplicationManagementService) { + + OrganizationManagementHandlerDataHolder.getInstance().setOrgApplicationManager(null); + LOG.debug("OrgApplication management service unset in OrganizationManagementHandlerService bundle."); + } +} diff --git a/pom.xml b/pom.xml index cae192891..8e95d932b 100644 --- a/pom.xml +++ b/pom.xml @@ -235,7 +235,11 @@ org.wso2.carbon.identity.governance ${org.wso2.carbon.identity.governance.version} - + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.role.v2.mgt.core + ${carbon.identity.framework.version} + com.google.code.findbugs annotations @@ -494,7 +498,7 @@ [4.7.0,5.0.0) - 5.25.264 + 5.25.356 [5.20.0, 7.0.0)