Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Permission Validation for Hybrid User Role Deletion #6303

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ public static class RoleTableColumns {
public static final String UM_GROUP_ID = "UM_GROUP_ID";
public static final String GROUP_NAME = "GROUP_NAME";
public static final String ID = "ID";
public static final String UM_PERMITTED_ORG_ID = "UM_PERMITTED_ORG_ID";

public static final String NEW_ROLE_NAME = "NEW_ROLE_NAME";
public static final String USER_NOT_FOUND_ERROR_MESSAGE = "A user doesn't exist with name: %s " +
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023-2024, WSO2 LLC. (http://www.wso2.com).
* Copyright (c) 2023-2025, 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
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023-2024, WSO2 LLC. (http://www.wso2.com).
* Copyright (c) 2023-2025, 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
Expand Down Expand Up @@ -31,10 +31,12 @@
import org.wso2.carbon.identity.core.model.FilterTreeBuilder;
import org.wso2.carbon.identity.core.model.Node;
import org.wso2.carbon.identity.core.model.OperationNode;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.organization.management.service.OrganizationManager;
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
import org.wso2.carbon.identity.organization.management.service.util.OrganizationManagementUtil;
import org.wso2.carbon.identity.organization.management.service.util.Utils;
import org.wso2.carbon.identity.role.v2.mgt.core.dao.RoleDAO;
import org.wso2.carbon.identity.role.v2.mgt.core.dao.RoleMgtDAOFactory;
import org.wso2.carbon.identity.role.v2.mgt.core.exception.IdentityRoleManagementClientException;
Expand Down Expand Up @@ -423,6 +425,8 @@ public List<UserBasicInfo> getUserListOfRole(String roleId, String tenantDomain)
public RoleBasicInfo updateUserListOfRole(String roleId, List<String> newUserIDList, List<String> deletedUserIDList,
String tenantDomain) throws IdentityRoleManagementException {

deletedUserIDList = getEligibleUserIDsForUserRemovalFromRole(roleId, deletedUserIDList, tenantDomain);

List<RoleManagementListener> roleManagementListenerList = RoleManagementServiceComponentHolder.getInstance()
.getRoleManagementListenerList();
for (RoleManagementListener roleManagementListener : roleManagementListenerList) {
Expand Down Expand Up @@ -1245,4 +1249,72 @@ private List<String> getUserNamesByIDs(List<String> userIDs, String tenantDomain

return userIDResolver.getNamesByIDs(userIDs, tenantDomain);
}

/**
* Get user IDs by usernames.
*
* @param userNames List of usernames.
* @param tenantDomain Tenant Domain.
* @return List of user IDs.
* @throws IdentityRoleManagementException IdentityRoleManagementException.
*/
private List<String> getUserIDsByNames(List<String> userNames, String tenantDomain)
throws IdentityRoleManagementException {

return userIDResolver.getIDsByNames(userNames, tenantDomain);
}
sadilchamishka marked this conversation as resolved.
Show resolved Hide resolved

/**
* Retrieves the updated list of user IDs intended for deletion based on the specified permissions for the
* given role and permitted organization in the tenant domain.
*
* @param roleId The role ID associated with the users.
* @param deletedUserIDList The list of user IDs intended for deletion.
* @param tenantDomain The tenant domain.
* @param permittedOrgId The ID of the organization permitted for the operation.
* @return A modified list of user IDs that are permitted to be deleted.
* @throws IdentityRoleManagementException If an error occurs while updating the user ID list.
*/
private List<String> getUpdatedUserIDListToBeDeletedBasedOnPermission(String roleId, List<String> deletedUserIDList,
String tenantDomain, String permittedOrgId)
throws IdentityRoleManagementException {

List<String> deletedUserNamesList = getUserNamesByIDs(deletedUserIDList, tenantDomain);

List<String> modifiedDeletedUserNamesList =
roleDAO.getEligibleUsernamesForUserRemovalFromRole(roleId, deletedUserNamesList, tenantDomain,
permittedOrgId);

return getUserIDsByNames(modifiedDeletedUserNamesList, tenantDomain);
}

/**
* Retrieves the list of user IDs eligible for removal from the specified role in the given tenant domain,
* based on the permissions of the requesting organization.
*
* @param roleId The role ID from which the users are to be removed.
* @param deletedUserIDList The list of user IDs intended for removal.
* @param tenantDomain The tenant domain where the operation is being performed.
* @return A list of user IDs eligible for removal from the specified role.
* @throws IdentityRoleManagementException If an error occurs while validating permissions or retrieving the
* organization ID.
*/
private List<String> getEligibleUserIDsForUserRemovalFromRole(String roleId, List<String> deletedUserIDList,
String tenantDomain)
throws IdentityRoleManagementException {

int tenantId = IdentityTenantUtil.getTenantId(tenantDomain);
try {
if (OrganizationManagementUtil.isOrganization(tenantId)) {
return getUpdatedUserIDListToBeDeletedBasedOnPermission(roleId, deletedUserIDList, tenantDomain,
Utils.getOrganizationId());
}
} catch (OrganizationManagementException e) {
String errorMessage = "Error while retrieving the organization id for the given tenantDomain: "
+ tenantDomain;
throw new IdentityRoleManagementServerException(UNEXPECTED_SERVER_ERROR.getCode(), errorMessage, e);
}

return deletedUserIDList;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023-2024, WSO2 LLC. (http://www.wso2.com).
* Copyright (c) 2023-2025, 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
Expand Down Expand Up @@ -510,4 +510,23 @@ default boolean isSharedRole(String roleId, String tenantDomain) throws Identity

return false;
}

/**
* Retrieve the list of usernames eligible to be removed from the specified role within the given tenant domain,
* based on the permissions of the requesting organization.
*
* @param roleId The role ID from which the users are to be removed.
* @param deletedUserNamesList The list of usernames intended for removal.
* @param tenantDomain The tenant domain where the operation is being performed.
* @param requestingOrgId The ID of the requesting organization performing the operation.
* @return A list of usernames that the requesting organization is permitted to remove from the given role.
* @throws IdentityRoleManagementException If an error occurs while validating the permissions or retrieving
* eligible usernames.
*/
default List<String> getEligibleUsernamesForUserRemovalFromRole(String roleId, List<String> deletedUserNamesList,
String tenantDomain, String requestingOrgId)
throws IdentityRoleManagementException {

throw new NotImplementedException("getEligibleUsernamesForUserRemovalFromRole method is not implemented.");
}
}
Loading
Loading