Skip to content

Commit

Permalink
Resolve role sharing conflicts in app sharing
Browse files Browse the repository at this point in the history
  • Loading branch information
ShanChathusanda93 committed Nov 22, 2024
1 parent 7c2af23 commit e6b551c
Show file tree
Hide file tree
Showing 6 changed files with 991 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.application.mgt</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.central.log.mgt</artifactId>
</dependency>
<!--Test Dependencies-->
<dependency>
<groupId>org.testng</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
import org.wso2.carbon.identity.application.common.model.ApplicationBasicInfo;
import org.wso2.carbon.identity.application.common.model.RoleV2;
import org.wso2.carbon.identity.application.mgt.ApplicationManagementService;
import org.wso2.carbon.identity.central.log.mgt.utils.LogConstants;
import org.wso2.carbon.identity.central.log.mgt.utils.LoggerUtils;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.event.IdentityEventConstants;
import org.wso2.carbon.identity.event.IdentityEventException;
import org.wso2.carbon.identity.event.event.Event;
Expand All @@ -42,9 +45,11 @@
import org.wso2.carbon.identity.role.v2.mgt.core.RoleManagementService;
import org.wso2.carbon.identity.role.v2.mgt.core.exception.IdentityRoleManagementException;
import org.wso2.carbon.identity.role.v2.mgt.core.model.RoleBasicInfo;
import org.wso2.carbon.utils.AuditLog;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
Expand Down Expand Up @@ -72,6 +77,9 @@ public void handleEvent(Event event) throws IdentityEventException {
case IdentityEventConstants.Event.POST_ADD_ROLE_V2_EVENT:
createSharedRolesOnNewRoleCreation(eventProperties);
break;
case OrgApplicationMgtConstants.EVENT_PRE_SHARE_APPLICATION:
checkSharingRoleConflicts(eventProperties);
break;
default:
if (LOG.isDebugEnabled()) {
LOG.debug("Unsupported event: " + eventName);
Expand Down Expand Up @@ -271,13 +279,30 @@ private void createSharedRolesOnNewRoleCreation(Map<String, Object> eventPropert
for (BasicOrganization organization : applicationSharedOrganizations) {
String shareAppTenantDomain =
getOrganizationManager().resolveTenantDomain(organization.getId());
RoleBasicInfo sharedRoleInfo = getRoleManagementServiceV2().addRole(mainRoleName,
Collections.emptyList(),
Collections.emptyList(),
Collections.emptyList(), RoleConstants.ORGANIZATION, organization.getId(),
shareAppTenantDomain);
getRoleManagementServiceV2().addMainRoleToSharedRoleRelationship(mainRoleUUID,
sharedRoleInfo.getId(), roleTenantDomain, shareAppTenantDomain);
if (!getRoleManagementServiceV2().isExistingRoleName(mainRoleName, RoleConstants.ORGANIZATION,
organization.getId(), shareAppTenantDomain)) {
RoleBasicInfo sharedRoleInfo = getRoleManagementServiceV2().addRole(mainRoleName,
Collections.emptyList(),
Collections.emptyList(),
Collections.emptyList(), RoleConstants.ORGANIZATION, organization.getId(),

Check warning on line 287 in components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java

View check run for this annotation

Codecov / codecov/patch

components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java#L283-L287

Added lines #L283 - L287 were not covered by tests
shareAppTenantDomain);
getRoleManagementServiceV2().addMainRoleToSharedRoleRelationship(mainRoleUUID,
sharedRoleInfo.getId(), roleTenantDomain, shareAppTenantDomain);
} else {

Check warning on line 291 in components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java

View check run for this annotation

Codecov / codecov/patch

components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java#L289-L291

Added lines #L289 - L291 were not covered by tests
if (LoggerUtils.isEnableV2AuditLogs()) {
String username = PrivilegedCarbonContext.getThreadLocalCarbonContext()
.getUsername();
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext()
.getTenantDomain();
AuditLog.AuditLogBuilder auditLogBuilder = new AuditLog.AuditLogBuilder(
IdentityUtil.getInitiatorId(username, tenantDomain),
LoggerUtils.Target.User.name(), mainRoleName, LoggerUtils.Target.Role.name(),

Check warning on line 299 in components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java

View check run for this annotation

Codecov / codecov/patch

components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java#L293-L299

Added lines #L293 - L299 were not covered by tests
LogConstants.UserManagement.ADD_ROLE_ACTION)
.data(buildAuditData(roleOrgId, null, organization.getId(), mainRoleName,

Check warning on line 301 in components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java

View check run for this annotation

Codecov / codecov/patch

components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java#L301

Added line #L301 was not covered by tests
mainRoleUUID, "Role conflict"));
LoggerUtils.triggerAuditLogEvent(auditLogBuilder, true);

Check warning on line 303 in components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java

View check run for this annotation

Codecov / codecov/patch

components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java#L303

Added line #L303 was not covered by tests
}
}
}
break;
default:
Expand All @@ -289,6 +314,60 @@ private void createSharedRolesOnNewRoleCreation(Map<String, Object> eventPropert
}
}

private void checkSharingRoleConflicts(Map<String, Object> eventProperties) throws IdentityEventException {

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);
try {
String sharedAppTenantDomain = getOrganizationManager().resolveTenantDomain(sharedOrganizationId);
String mainAppTenantDomain = getOrganizationManager().resolveTenantDomain(parentOrganizationId);
String allowedAudienceForRoleAssociationInMainApp = getApplicationMgtService().
getAllowedAudienceForRoleAssociation(parentApplicationId, mainAppTenantDomain);
if (RoleConstants.ORGANIZATION.equals(allowedAudienceForRoleAssociationInMainApp.toLowerCase())) {
List<RoleV2> associatedRolesOfApplication = getApplicationMgtService().
getAssociatedRolesOfApplication(parentApplicationId, mainAppTenantDomain);
for (RoleV2 roleV2 : associatedRolesOfApplication) {
boolean roleExistsInSharedOrg = getRoleManagementServiceV2().isExistingRoleName(roleV2.getName(),
RoleConstants.ORGANIZATION, sharedOrganizationId, sharedAppTenantDomain);
Map<String, String> mainRoleToSharedRoleMappingInSharedOrg =
getRoleManagementServiceV2().getMainRoleToSharedRoleMappingsBySubOrg(
Collections.singletonList(roleV2.getId()), sharedAppTenantDomain);
boolean roleRelationshipExistsInSharedOrg =
MapUtils.isNotEmpty(mainRoleToSharedRoleMappingInSharedOrg);
if (roleExistsInSharedOrg && !roleRelationshipExistsInSharedOrg) {
// If the role exists in the shared org, but the relationship does not exist then this role is
// created directly in the sub organization level. So this is a conflict to share the role
// with same name and organization audience to the sub organization.
if (LoggerUtils.isEnableV2AuditLogs()) {
String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().
getTenantDomain();
AuditLog.AuditLogBuilder auditLogBuilder = new AuditLog.AuditLogBuilder(
IdentityUtil.getInitiatorId(username, tenantDomain),
LoggerUtils.Target.User.name(), roleV2.getName(), LoggerUtils.Target.Role.name(),
LogConstants.ApplicationManagement.CREATE_APPLICATION_ACTION).
data(buildAuditData(parentOrganizationId, parentApplicationId,
sharedOrganizationId, roleV2.getName(), roleV2.getId(), "Role conflict"));
LoggerUtils.triggerAuditLogEvent(auditLogBuilder, true);
}
throw new IdentityEventException(String.format("Organization %s has a non shared role with " +
"name %s, ", sharedOrganizationId, roleV2.getName()));
}
}
}
} catch (OrganizationManagementException | IdentityRoleManagementException |

Check warning on line 364 in components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java

View check run for this annotation

Codecov / codecov/patch

components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java#L364

Added line #L364 was not covered by tests
IdentityApplicationManagementException e) {
throw new IdentityEventException(String.format("Error while sharing roles related to application %s.",

Check warning on line 366 in components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java

View check run for this annotation

Codecov / codecov/patch

components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/SharedRoleMgtHandler.java#L366

Added line #L366 was not covered by tests
sharedApplicationId), e);
}
}

private static RoleManagementService getRoleManagementServiceV2() {

return OrganizationManagementHandlerDataHolder.getInstance().getRoleManagementServiceV2();
Expand All @@ -308,4 +387,18 @@ private static ApplicationManagementService getApplicationMgtService() {

return OrganizationManagementHandlerDataHolder.getInstance().getApplicationManagementService();
}

private Map<String, ?> buildAuditData(String parentOrganizationId, String parentApplicationId,
String sharedOrganizationId, String roleName, String roleId,
String failureReason) {

Map<String, String> auditData = new HashMap<>();
auditData.put("parentOrganizationId", parentOrganizationId);
auditData.put("parentApplicationId", parentApplicationId);
auditData.put("sharedOrganizationId", sharedOrganizationId);
auditData.put("roleId", roleId);
auditData.put("roleName", roleName);
auditData.put("failureReason", failureReason);
return auditData;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -608,11 +608,13 @@ public boolean doPostGetAssociatedRolesOfApplication(List<RoleV2> associatedRole
throws IdentityApplicationManagementException {

try {
if (!OrganizationManagementUtil.isOrganization(tenantDomain)) {
String mainAppId = applicationManagementService.getMainAppId(applicationUUID);

Check warning on line 611 in components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/listener/SharedRoleMgtListener.java

View check run for this annotation

Codecov / codecov/patch

components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/listener/SharedRoleMgtListener.java#L611

Added line #L611 was not covered by tests
// If the main application id is null, then this is the main application. We can skip this operation based
// on that.
if (StringUtils.isEmpty(mainAppId)) {
return true;
}
// Resolve the associated roles of shared application from main application details.
String mainAppId = applicationManagementService.getMainAppId(applicationUUID);
int mainAppTenantId = applicationManagementService.getTenantIdByApp(mainAppId);
String mainAppTenantDomain = IdentityTenantUtil.getTenantDomain(mainAppTenantId);
List<RoleV2> resolvedAssociatedRolesFromMainApp =
Expand Down Expand Up @@ -641,7 +643,7 @@ public boolean doPostGetAssociatedRolesOfApplication(List<RoleV2> associatedRole
.collect(Collectors.toList());
associatedRolesOfApplication.clear();
associatedRolesOfApplication.addAll(associatedRolesOfSharedApplication);
} catch (OrganizationManagementException | IdentityRoleManagementException e) {
} catch (IdentityRoleManagementException e) {

Check warning on line 646 in components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/listener/SharedRoleMgtListener.java

View check run for this annotation

Codecov / codecov/patch

components/org.wso2.carbon.identity.organization.management.handler/src/main/java/org/wso2/carbon/identity/organization/management/handler/listener/SharedRoleMgtListener.java#L646

Added line #L646 was not covered by tests
throw new IdentityApplicationManagementException(String.format(
"Error while fetching the allowed audience for role association of application with: %s.",
applicationUUID), e);
Expand Down
Loading

0 comments on commit e6b551c

Please sign in to comment.