Skip to content

[TASK] Enable Organization-level Custom Roles #11599

@hs-control-center-bot

Description

@hs-control-center-bot

Summary

Enable creation of custom roles at the Organization entity level in the user role management system.

Goal

Remove the explicit blocking validation that currently prevents users from creating custom roles with entity_type: Organization. Users with sufficient privileges (tenant_admin, org_admin) should be able to create organization-wide custom roles. The existing authorization validation already ensures that users can only create roles at or below their own entity level.

Technical Approach

Files to Modify

File 1: crates/router/src/core/user_role/role.rs

Remove the blocking check in the V1 create_role function (lines 96-99):

// REMOVE this block:
if matches!(role_entity_type, EntityType::Organization) {
    return Err(report!(UserErrors::InvalidRoleOperation))
        .attach_printable("User trying to create org level custom role");
}

Remove the blocking check in the V2 create_role_v2 function (lines 195-198):

// REMOVE this block:
if matches!(role_entity_type, EntityType::Organization) {
    return Err(report!(report!(UserErrors::InvalidRoleOperation))
        .attach_printable("User trying to create org level custom role");
}

Authorization

The existing validation at lines 110-115 (V1) and 210-213 (V2) already provides proper authorization:

if user_entity_type < max_from_scope_and_entity {
    return Err(report!(UserErrors::InvalidRoleOperation))
        .attach_printable(format!("..."));
}

This ensures:

  • tenant_admin can create org-level roles
  • org_admin can create org-level roles
  • merchant_admin cannot create org-level roles (blocked by validation)

API Changes

Endpoint: POST /v2/user/role (V2 create custom role)

Request body now accepts entity_type: "organization":

{
  "role_name": "org_custom_role",
  "role_scope": "organization",
  "entity_type": "organization",
  "parent_groups": [
    {
      "name": "Users",
      "scopes": ["read", "write"]
    }
  ]
}

Database

No schema changes required. The existing RoleNew struct already supports Organization entity type:

pub struct RoleNew {
    pub role_id: String,
    pub role_name: String,
    pub entity_type: EntityType,  // Already supports Organization
    pub scope: RoleScope,
    pub org_id: String,
    pub merchant_id: Option<String>,  // None for org-level
    pub profile_id: Option<String>,   // None for org-level
    // ...
}

Edge Cases

  1. Permission Escalation: Merchant admin attempting to create org-level role is blocked by existing validation
  2. Invalid Scope/Entity Combination: Setting entity_type="organization" with role_scope="merchant" is blocked by existing validation
  3. Duplicate Names: Handled by existing validate_role_name function

Testing

  1. Success Case: Tenant admin creates org-level custom role
  2. Success Case: Org admin creates org-level custom role
  3. Failure Case: Merchant admin attempt is rejected with InvalidRoleOperation
  4. Failure Case: entity_type=org with scope=merchant is rejected
  5. Failure Case: Duplicate role name is rejected with UR_35

Subtasks

  • Remove blocking check from V1 create_role function (lines 96-99)
  • Remove blocking check from V2 create_role_v2 function (lines 195-198)
  • Run existing tests to ensure no regressions
  • Add test case for tenant_admin creating org-level role (success)
  • Add test case for org_admin creating org-level role (success)
  • Add test case for merchant_admin attempting org-level role (failure)
  • Verify authorization validation still works correctly

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions