Skip to content

Commit

Permalink
add shared role managing event handler
Browse files Browse the repository at this point in the history
  • Loading branch information
AnuradhaSK committed Oct 8, 2023
1 parent d7ce01d commit 58aacad
Show file tree
Hide file tree
Showing 5 changed files with 285 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@
<groupId>org.wso2.carbon.identity.governance</groupId>
<artifactId>org.wso2.carbon.identity.governance</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.organization.management</groupId>
<artifactId>org.wso2.carbon.identity.organization.management.application</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.event</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.role.v2.mgt.core</artifactId>
</dependency>

<!--Test Dependencies-->
<dependency>
Expand Down Expand Up @@ -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}",
</Import-Package>
</instructions>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
@@ -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<String, Object> 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<String, Object> 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<SharedApplication> 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<String, Object> 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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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() {

Expand Down Expand Up @@ -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;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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);
Expand Down Expand Up @@ -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.");
}
}
8 changes: 6 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,11 @@
<artifactId>org.wso2.carbon.identity.governance</artifactId>
<version>${org.wso2.carbon.identity.governance.version}</version>
</dependency>

<dependency>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.role.v2.mgt.core</artifactId>
<version>${carbon.identity.framework.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>annotations</artifactId>
Expand Down Expand Up @@ -494,7 +498,7 @@
<carbon.multitenancy.package.import.version.range>[4.7.0,5.0.0)
</carbon.multitenancy.package.import.version.range>

<carbon.identity.framework.version>5.25.264</carbon.identity.framework.version>
<carbon.identity.framework.version>5.25.356</carbon.identity.framework.version>
<carbon.identity.package.import.version.range>[5.20.0, 7.0.0)
</carbon.identity.package.import.version.range>

Expand Down

0 comments on commit 58aacad

Please sign in to comment.