Skip to content

Commit

Permalink
Merge pull request #191 from RushanNanayakkara/ft_restrict_admin_role…
Browse files Browse the repository at this point in the history
…_modify

Add Administrator role for creator and restrict Administrator role modification and deletion
  • Loading branch information
AnuradhaSK authored Feb 20, 2023
2 parents e27a225 + 13b02d6 commit f2023d9
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

import static org.wso2.carbon.identity.organization.management.role.management.service.constant.RoleManagementConstants.CursorDirection.BACKWARD;
import static org.wso2.carbon.identity.organization.management.role.management.service.constant.RoleManagementConstants.CursorDirection.FORWARD;
import static org.wso2.carbon.identity.organization.management.role.management.service.constant.RoleManagementConstants.DISPLAY_NAME;
import static org.wso2.carbon.identity.organization.management.role.management.service.constant.RoleManagementConstants.GROUPS;
import static org.wso2.carbon.identity.organization.management.role.management.service.constant.RoleManagementConstants.ORG_ADMINISTRATOR_ROLE;
import static org.wso2.carbon.identity.organization.management.role.management.service.constant.RoleManagementConstants.ORG_CREATOR_ROLE;
import static org.wso2.carbon.identity.organization.management.role.management.service.constant.RoleManagementConstants.PERMISSIONS;
import static org.wso2.carbon.identity.organization.management.role.management.service.constant.RoleManagementConstants.USERS;
Expand Down Expand Up @@ -90,7 +92,8 @@ public class RoleManagerImpl implements RoleManager {
@Override
public Role createRole(String organizationId, Role role) throws OrganizationManagementException {

if (!StringUtils.equals(ORG_CREATOR_ROLE, role.getDisplayName())) {
if (!StringUtils.equals(ORG_CREATOR_ROLE, role.getDisplayName()) &&
!StringUtils.equals(ORG_ADMINISTRATOR_ROLE, role.getDisplayName())) {
validateOrganizationRoleAllowedToAccess(organizationId);
}
role.setId(generateUniqueID());
Expand Down Expand Up @@ -189,7 +192,7 @@ public Role patchRole(String organizationId, String roleId, List<PatchOperation>
validateOrganizationRoleAllowedToAccess(organizationId);
validateOrganizationId(organizationId);
validateRoleId(organizationId, roleId);
if (!isRoleModifiable(organizationId, roleId)) {
if (!isPatchOperationAllowed(organizationId, roleId, patchOperations)) {
throw handleClientException(ERROR_CODE_ROLE_IS_UNMODIFIABLE, roleId);
}
for (PatchOperation patchOperation : patchOperations) {
Expand Down Expand Up @@ -229,7 +232,7 @@ public Role putRole(String organizationId, String roleId, Role role) throws Orga
validateOrganizationRoleAllowedToAccess(organizationId);
validateOrganizationId(organizationId);
validateRoleId(organizationId, roleId);
if (!isRoleModifiable(organizationId, roleId)) {
if (!isPutOperationAllowed(organizationId, roleId, role)) {
throw handleClientException(ERROR_CODE_ROLE_IS_UNMODIFIABLE, roleId);
}
if (StringUtils.isBlank(role.getDisplayName())) {
Expand Down Expand Up @@ -257,7 +260,7 @@ public void deleteRole(String organizationId, String roleId) throws Organization
validateOrganizationRoleAllowedToAccess(organizationId);
validateOrganizationId(organizationId);
validateRoleId(organizationId, roleId);
if (!isRoleModifiable(organizationId, roleId)) {
if (!isDeleteOperationAllowed(organizationId, roleId)) {
throw handleClientException(ERROR_CODE_ROLE_IS_UNMODIFIABLE, roleId);
}
roleManagementDAO.deleteRole(organizationId, roleId);
Expand Down Expand Up @@ -363,20 +366,73 @@ private void validateUsers(List<String> userIdList, String organizationId) throw
}

/**
* Check whether the role is allowed for modification.
* Check whether the role is allowed to be deleted.
*
* @param organizationId Organization Id.
* @param roleId Role Id.
* @return Whether role can be modified.
* @return Whether role can be deleted.
* @throws OrganizationManagementServerException Error while retrieving role.
*/
private boolean isRoleModifiable(String organizationId, String roleId) throws OrganizationManagementException {
private boolean isDeleteOperationAllowed(String organizationId, String roleId)
throws OrganizationManagementException {

Role role = roleManagementDAO.getRoleById(organizationId, roleId);
if (role == null) {
throw handleClientException(ERROR_CODE_INVALID_ROLE, roleId);
}
// The org-creator role assigned during org creation, is not allowed to be deleted.
return !ORG_CREATOR_ROLE.equalsIgnoreCase(role.getDisplayName())
&& !ORG_ADMINISTRATOR_ROLE.equalsIgnoreCase(role.getDisplayName());
}

/**
* Check whether the incoming updates are allowed for the role.
*
* @param organizationId Organization Id.
* @param roleId Role Id.
* @param modifiedRole Incoming updated role.
* @return Whether put operation on the role is allowed with incoming values.
* @throws OrganizationManagementServerException Error while retrieving role.
*/
private boolean isPutOperationAllowed(String organizationId, String roleId, Role modifiedRole)
throws OrganizationManagementException {

Role role = roleManagementDAO.getRoleById(organizationId, roleId);
if (role == null) {
throw handleClientException(ERROR_CODE_INVALID_ROLE, roleId);
}
// The Administrator role permissions and display name are not allowed to be updated.
if (ORG_ADMINISTRATOR_ROLE.equalsIgnoreCase(role.getDisplayName())) {
return new HashSet<>(role.getPermissions()).equals(new HashSet<>(modifiedRole.getPermissions()))
&& ORG_ADMINISTRATOR_ROLE.equalsIgnoreCase(modifiedRole.getDisplayName());
}
// The org-creator role assigned during org creation, is not allowed to be updated.
return !ORG_CREATOR_ROLE.equalsIgnoreCase(role.getDisplayName());
}

/**
* Check whether the incoming patch operations are allowed for the role.
*
* @param organizationId Organization Id.
* @param roleId Role Id.
* @param patchOperations Incoming patch operations with updated values.
* @return Whether incoming patch operations are allowed on the role.
* @throws OrganizationManagementServerException Error while retrieving role.
*/
private boolean isPatchOperationAllowed(String organizationId, String roleId, List<PatchOperation> patchOperations)
throws OrganizationManagementException {

Role role = roleManagementDAO.getRoleById(organizationId, roleId);
if (role == null) {
throw handleClientException(ERROR_CODE_INVALID_ROLE, roleId);
}
// The org-creator role assigned during org creation, is not allowed for update / delete.
// The Administrator role permissions and display name are not allowed to be patched.
if (ORG_ADMINISTRATOR_ROLE.equalsIgnoreCase(role.getDisplayName())) {
return !patchOperations.stream().anyMatch(patchOperation ->
PERMISSIONS.equals(patchOperation.getPath()) ||
DISPLAY_NAME.equals(patchOperation.getPath()));
}
// The org-creator role assigned during org creation, is not allowed to be patched.
return !ORG_CREATOR_ROLE.equalsIgnoreCase(role.getDisplayName());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class RoleManagementConstants {
public static final String UNION_SEPARATOR = " UNION ALL ";

public static final String ORG_CREATOR_ROLE = "org-creator";
public static final String ORG_ADMINISTRATOR_ROLE = "Administrator";

/**
* Enum for cursor based pagination direction.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class Constants {
public static final String CLAIM_META_DATA_MGT_VIEW_PERMISSION =
"/permission/admin/manage/identity/claimmgt/metadata/view";
public static final String USER_MGT_CREATE_PERMISSION = "/permission/admin/manage/identity/usermgt/create";
public static final String ADMINISTRATOR_ROLE_PERMISSION = "/permission";

/*
Minimum permissions required for org creator to logged in to the console and view user, groups, roles, SP,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import java.util.ArrayList;
import java.util.Collections;

import static org.wso2.carbon.identity.organization.management.role.management.service.constant.RoleManagementConstants.ORG_ADMINISTRATOR_ROLE;
import static org.wso2.carbon.identity.organization.management.role.management.service.constant.RoleManagementConstants.ORG_CREATOR_ROLE;
import static org.wso2.carbon.identity.organization.management.tenant.association.Constants.MINIMUM_PERMISSIONS_REQUIRED_FOR_ORG_CREATOR_VIEW;

Expand Down Expand Up @@ -91,7 +92,9 @@ public void onTenantCreate(TenantInfoBean tenantInfo) {
return;
}
Role organizationCreatorRole = buildOrgCreatorRole(adminUUID);
Role administratorRole = buildAdministratorRole(adminUUID);
TenantAssociationDataHolder.getRoleManager().createRole(organizationID, organizationCreatorRole);
TenantAssociationDataHolder.getRoleManager().createRole(organizationID, administratorRole);
} catch (UserStoreException | OrganizationManagementException e) {
String error = "Error occurred while adding user-tenant association for the tenant id: " + tenantId;
LOG.error(error, e);
Expand Down Expand Up @@ -120,4 +123,18 @@ private Role buildOrgCreatorRole(String adminUUID) {
organizationCreatorRole.setPermissions(orgCreatorRolePermissions);
return organizationCreatorRole;
}

private Role buildAdministratorRole(String adminUUID) {

Role organizationAdministratorRole = new Role();
organizationAdministratorRole.setDisplayName(ORG_ADMINISTRATOR_ROLE);
User orgAdministrator = new User(adminUUID);
organizationAdministratorRole.setUsers(Collections.singletonList(orgAdministrator));
// Set permissions for org-administrator role.
ArrayList<String> orgAdministratorRolePermissions = new ArrayList<>();
// Setting all administrative permissions for the Administrator role
orgAdministratorRolePermissions.add(Constants.ADMINISTRATOR_ROLE_PERMISSION);
organizationAdministratorRole.setPermissions(orgAdministratorRolePermissions);
return organizationAdministratorRole;
}
}

0 comments on commit f2023d9

Please sign in to comment.