fix(doc): fix role/permission docs
This commit is contained in:
@@ -26,6 +26,41 @@ use tracing::instrument;
|
|||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[instrument(skip(state))]
|
#[instrument(skip(state))]
|
||||||
|
/// 查询权限列表(Permission Catalog)。
|
||||||
|
///
|
||||||
|
/// 返回全局权限目录(`permissions` 表)的分页结果,用于:
|
||||||
|
/// - 后台展示可分配权限;
|
||||||
|
/// - 角色绑定权限前的检索与校验;
|
||||||
|
/// - 按应用(`app_code`)/资源(`resource`)/动作(`action`)筛选。
|
||||||
|
///
|
||||||
|
/// 权限编码规范为 `${app_code}:${resource}:${action}`,例如 `cms:article:publish`。
|
||||||
|
///
|
||||||
|
/// ## Parameters
|
||||||
|
/// - `TenantId(tenant_id): TenantId`(`Uuid`):当前租户 ID(用于鉴权与跨租户隔离)。
|
||||||
|
/// - `State(state): State<AppState>`:应用状态,包含 `PermissionService`/`AuthorizationService`。
|
||||||
|
/// - `AuthContext { tenant_id: auth_tenant_id, user_id, .. }`:认证上下文。
|
||||||
|
/// - `Query(query): Query<ListPermissionsQuery>`:查询参数(分页/搜索/筛选/排序)。
|
||||||
|
/// - `page: Option<u32>`:页码(默认 1)。
|
||||||
|
/// - `page_size: Option<u32>`:每页条数(默认 20,范围 1..=200)。
|
||||||
|
/// - `search: Option<String>`:按 `code` 或 `description` 模糊搜索。
|
||||||
|
/// - `app_code/resource/action`:精确筛选(用于权限目录分组)。
|
||||||
|
///
|
||||||
|
/// ## Returns
|
||||||
|
/// - `Ok(AppResponse<Vec<Permission>>)`:成功返回 `200`,`data` 为权限列表。
|
||||||
|
///
|
||||||
|
/// ## Errors
|
||||||
|
/// - `Err(AppError::PermissionDenied("tenant:mismatch"))`:跨租户访问被拒绝。
|
||||||
|
/// - `Err(AppError::PermissionDenied("role:read"))`:调用方缺少 `role:read` 权限(用于控制“查看权限目录”的能力)。
|
||||||
|
/// - `Err(AppError::BadRequest(_))`:分页参数非法(如 `page_size>200` 或为 0)。
|
||||||
|
/// - `Err(AppError::DbError(_))`:数据库查询失败。
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
/// ```rust,ignore
|
||||||
|
/// // GET /permissions?page=1&page_size=20&app_code=cms&search=article
|
||||||
|
/// // Headers:
|
||||||
|
/// // Authorization: Bearer <access_token>
|
||||||
|
/// // X-Tenant-ID: <tenant_uuid> // 可选,但若提供必须与 token 中 tenant_id 一致
|
||||||
|
/// ```
|
||||||
pub async fn list_permissions_handler(
|
pub async fn list_permissions_handler(
|
||||||
TenantId(tenant_id): TenantId,
|
TenantId(tenant_id): TenantId,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
|
|||||||
@@ -32,24 +32,36 @@ use uuid::Uuid;
|
|||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[instrument(skip(state, payload))]
|
#[instrument(skip(state, payload))]
|
||||||
/// Create role in current tenant.
|
/// 在当前租户下创建自定义角色(Role)。
|
||||||
/// 在当前租户下创建角色。
|
|
||||||
///
|
///
|
||||||
/// 业务规则:
|
/// 本接口用于创建 **租户级自定义角色**(`roles.tenant_id = 当前租户`)。创建后可继续通过
|
||||||
/// - 角色归属到当前租户(由 `TenantId` 决定),禁止跨租户写入。
|
/// “角色-权限绑定”接口为角色授予权限,再通过“用户-角色绑定”接口把角色授予用户。
|
||||||
/// - 需要具备 `role:write` 权限,否则返回 403。
|
|
||||||
///
|
///
|
||||||
/// 输入:
|
/// ## Parameters
|
||||||
/// - Header `Authorization: Bearer <access_token>`(必填)
|
/// - `TenantId(tenant_id): TenantId`(内部包含 `Uuid`):当前请求的租户 ID(由中间件解析并注入)。
|
||||||
/// - Body `CreateRoleRequest`(必填)
|
/// - `State(state): State<AppState>`:应用状态,包含 `RoleService`/`AuthorizationService` 等依赖。
|
||||||
|
/// - `AuthContext { tenant_id: auth_tenant_id, user_id, .. }`:
|
||||||
|
/// 从 `Authorization: Bearer <access_token>` 解析得到的认证上下文,包含调用方用户 ID 与租户 ID。
|
||||||
|
/// - `Json(payload): Json<CreateRoleRequest>`:创建角色的请求体(角色名与描述)。
|
||||||
///
|
///
|
||||||
/// 输出:
|
/// ## Returns
|
||||||
/// - `201`:返回新建角色信息(含 `id`)
|
/// - `Ok(AppResponse<RoleResponse>)`:创建成功返回 `201`,`data` 为新建角色(含 `id/name/description`)。
|
||||||
///
|
///
|
||||||
/// 异常:
|
/// ## Errors
|
||||||
/// - `401`:未认证
|
/// - `Err(AppError::PermissionDenied("tenant:mismatch"))`:Token 中租户与当前租户不一致(跨租户访问被拒绝)。
|
||||||
/// - `403`:租户不匹配或无权限
|
/// - `Err(AppError::PermissionDenied("role:write"))`:调用方缺少 `role:write` 权限。
|
||||||
/// - `400`:请求参数错误
|
/// - `Err(AppError::AlreadyExists(_))`:角色名冲突(同租户下同名角色已存在)。
|
||||||
|
/// - `Err(AppError::DbError(_))`:数据库写入失败(连接异常、约束失败等)。
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
/// ```rust,ignore
|
||||||
|
/// // POST /roles
|
||||||
|
/// // Headers:
|
||||||
|
/// // Authorization: Bearer <access_token>
|
||||||
|
/// // X-Tenant-ID: <tenant_uuid> // 可选,但若提供必须与 token 中 tenant_id 一致
|
||||||
|
/// // Body:
|
||||||
|
/// // { "name": "ContentAdmin", "description": "CMS content admins" }
|
||||||
|
/// ```
|
||||||
pub async fn create_role_handler(
|
pub async fn create_role_handler(
|
||||||
TenantId(tenant_id): TenantId,
|
TenantId(tenant_id): TenantId,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
@@ -97,22 +109,23 @@ pub async fn create_role_handler(
|
|||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[instrument(skip(state))]
|
#[instrument(skip(state))]
|
||||||
/// List roles in current tenant.
|
/// 查询当前租户下的角色列表(Role)。
|
||||||
/// 查询当前租户下的角色列表。
|
|
||||||
///
|
///
|
||||||
/// 业务规则:
|
/// 返回当前租户的所有角色(包含系统角色与自定义角色)。系统角色通常 `is_system=true`,
|
||||||
/// - 仅返回当前租户角色;若 `X-Tenant-ID` 与 Token 不一致则返回 403。
|
/// 用于内置管理员/平台管理员等能力;自定义角色用于业务场景的权限组合。
|
||||||
/// - 需要具备 `role:read` 权限。
|
|
||||||
///
|
///
|
||||||
/// 输入:
|
/// ## Parameters
|
||||||
/// - Header `Authorization: Bearer <access_token>`(必填)
|
/// - `TenantId(tenant_id): TenantId`(`Uuid`):当前请求的租户 ID。
|
||||||
|
/// - `State(state): State<AppState)`:应用状态。
|
||||||
|
/// - `AuthContext { tenant_id: auth_tenant_id, user_id, .. }`:认证上下文。
|
||||||
///
|
///
|
||||||
/// 输出:
|
/// ## Returns
|
||||||
/// - `200`:角色列表
|
/// - `Ok(AppResponse<Vec<RoleResponse>>)`:成功返回 `200`,`data` 为角色数组。
|
||||||
///
|
///
|
||||||
/// 异常:
|
/// ## Errors
|
||||||
/// - `401`:未认证
|
/// - `Err(AppError::PermissionDenied("tenant:mismatch"))`:跨租户访问被拒绝。
|
||||||
/// - `403`:租户不匹配或无权限
|
/// - `Err(AppError::PermissionDenied("role:read"))`:调用方缺少 `role:read` 权限。
|
||||||
|
/// - `Err(AppError::DbError(_))`:数据库查询失败。
|
||||||
pub async fn list_roles_handler(
|
pub async fn list_roles_handler(
|
||||||
TenantId(tenant_id): TenantId,
|
TenantId(tenant_id): TenantId,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
@@ -162,6 +175,24 @@ pub async fn list_roles_handler(
|
|||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[instrument(skip(state))]
|
#[instrument(skip(state))]
|
||||||
|
/// 查询角色详情(Role)。
|
||||||
|
///
|
||||||
|
/// 仅允许读取当前租户内的角色,避免跨租户信息泄露。
|
||||||
|
///
|
||||||
|
/// ## Parameters
|
||||||
|
/// - `TenantId(tenant_id): TenantId`(`Uuid`):当前租户 ID。
|
||||||
|
/// - `State(state): State<AppState>`:应用状态。
|
||||||
|
/// - `AuthContext { tenant_id: auth_tenant_id, user_id, .. }`:认证上下文。
|
||||||
|
/// - `Path(role_id): Path<Uuid>`:目标角色 ID。
|
||||||
|
///
|
||||||
|
/// ## Returns
|
||||||
|
/// - `Ok(AppResponse<RoleResponse>)`:成功返回 `200`,`data` 为角色信息。
|
||||||
|
///
|
||||||
|
/// ## Errors
|
||||||
|
/// - `Err(AppError::PermissionDenied("tenant:mismatch"))`:跨租户访问被拒绝。
|
||||||
|
/// - `Err(AppError::PermissionDenied("role:read"))`:调用方缺少 `role:read` 权限。
|
||||||
|
/// - `Err(AppError::NotFound(_))`:角色不存在或不属于当前租户。
|
||||||
|
/// - `Err(AppError::DbError(_))`:数据库查询失败。
|
||||||
pub async fn get_role_handler(
|
pub async fn get_role_handler(
|
||||||
TenantId(tenant_id): TenantId,
|
TenantId(tenant_id): TenantId,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
@@ -209,6 +240,28 @@ pub async fn get_role_handler(
|
|||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[instrument(skip(state, payload))]
|
#[instrument(skip(state, payload))]
|
||||||
|
/// 更新角色基础信息(Role)。
|
||||||
|
///
|
||||||
|
/// 仅允许修改 **自定义角色**。当目标角色为系统角色(`is_system=true`)时返回 403,
|
||||||
|
/// 以防止线上误操作导致全局权限体系漂移。
|
||||||
|
///
|
||||||
|
/// ## Parameters
|
||||||
|
/// - `TenantId(tenant_id): TenantId`(`Uuid`):当前租户 ID。
|
||||||
|
/// - `State(state): State<AppState>`:应用状态。
|
||||||
|
/// - `AuthContext { tenant_id: auth_tenant_id, user_id, .. }`:认证上下文。
|
||||||
|
/// - `Path(role_id): Path<Uuid>`:目标角色 ID。
|
||||||
|
/// - `Json(payload): Json<UpdateRoleRequest>`:可选更新字段(`name`/`description`)。
|
||||||
|
///
|
||||||
|
/// ## Returns
|
||||||
|
/// - `Ok(AppResponse<RoleResponse>)`:成功返回 `200`,`data` 为更新后的角色信息。
|
||||||
|
///
|
||||||
|
/// ## Errors
|
||||||
|
/// - `Err(AppError::PermissionDenied("tenant:mismatch"))`:跨租户访问被拒绝。
|
||||||
|
/// - `Err(AppError::PermissionDenied("role:write"))`:调用方缺少 `role:write` 权限。
|
||||||
|
/// - `Err(AppError::PermissionDenied("role:system_immutable"))`:系统角色不可修改。
|
||||||
|
/// - `Err(AppError::AlreadyExists(_))`:角色名冲突。
|
||||||
|
/// - `Err(AppError::NotFound(_))`:角色不存在。
|
||||||
|
/// - `Err(AppError::DbError(_))`:数据库写入失败。
|
||||||
pub async fn update_role_handler(
|
pub async fn update_role_handler(
|
||||||
TenantId(tenant_id): TenantId,
|
TenantId(tenant_id): TenantId,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
@@ -258,6 +311,26 @@ pub async fn update_role_handler(
|
|||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[instrument(skip(state))]
|
#[instrument(skip(state))]
|
||||||
|
/// 删除角色(Role)。
|
||||||
|
///
|
||||||
|
/// 仅允许删除 **自定义角色**;系统角色(`is_system=true`)不可删除。
|
||||||
|
/// 删除角色会级联删除 `user_roles` 与 `role_permissions` 关联(由外键约束实现)。
|
||||||
|
///
|
||||||
|
/// ## Parameters
|
||||||
|
/// - `TenantId(tenant_id): TenantId`(`Uuid`):当前租户 ID。
|
||||||
|
/// - `State(state): State<AppState>`:应用状态。
|
||||||
|
/// - `AuthContext { tenant_id: auth_tenant_id, user_id, .. }`:认证上下文。
|
||||||
|
/// - `Path(role_id): Path<Uuid>`:目标角色 ID。
|
||||||
|
///
|
||||||
|
/// ## Returns
|
||||||
|
/// - `Ok(AppResponse<serde_json::Value>)`:成功返回 `200`,`data` 为 `{}`。
|
||||||
|
///
|
||||||
|
/// ## Errors
|
||||||
|
/// - `Err(AppError::PermissionDenied("tenant:mismatch"))`:跨租户访问被拒绝。
|
||||||
|
/// - `Err(AppError::PermissionDenied("role:write"))`:调用方缺少 `role:write` 权限。
|
||||||
|
/// - `Err(AppError::PermissionDenied("role:system_immutable"))`:系统角色不可删除。
|
||||||
|
/// - `Err(AppError::NotFound(_))`:角色不存在。
|
||||||
|
/// - `Err(AppError::DbError(_))`:数据库删除失败。
|
||||||
pub async fn delete_role_handler(
|
pub async fn delete_role_handler(
|
||||||
TenantId(tenant_id): TenantId,
|
TenantId(tenant_id): TenantId,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
@@ -304,6 +377,38 @@ pub async fn delete_role_handler(
|
|||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[instrument(skip(state, payload))]
|
#[instrument(skip(state, payload))]
|
||||||
|
/// 为角色批量授予权限(Role → Permission 绑定)。
|
||||||
|
///
|
||||||
|
/// 将 `permission_codes` 批量写入 `role_permissions`(幂等:重复绑定不会报错)。
|
||||||
|
/// 仅允许对 **自定义角色** 执行此操作;系统角色不可通过 API 修改权限集。
|
||||||
|
///
|
||||||
|
/// ## Parameters
|
||||||
|
/// - `TenantId(tenant_id): TenantId`(`Uuid`):当前租户 ID。
|
||||||
|
/// - `State(state): State<AppState>`:应用状态。
|
||||||
|
/// - `AuthContext { tenant_id: auth_tenant_id, user_id, .. }`:认证上下文。
|
||||||
|
/// - `Path(role_id): Path<Uuid>`:目标角色 ID。
|
||||||
|
/// - `Json(payload): Json<RolePermissionsRequest>`:待授予的权限码数组(`Vec<String>`)。
|
||||||
|
///
|
||||||
|
/// ## Returns
|
||||||
|
/// - `Ok(AppResponse<serde_json::Value>)`:成功返回 `200`,`data` 为 `{}`。
|
||||||
|
///
|
||||||
|
/// ## Errors
|
||||||
|
/// - `Err(AppError::PermissionDenied("tenant:mismatch"))`:跨租户访问被拒绝。
|
||||||
|
/// - `Err(AppError::PermissionDenied("role:write"))`:调用方缺少 `role:write` 权限。
|
||||||
|
/// - `Err(AppError::PermissionDenied("role:system_immutable"))`:系统角色不可变更权限集。
|
||||||
|
/// - `Err(AppError::BadRequest(_))`:存在非法的 `permission_codes`(权限码未在 `permissions` 表中定义)。
|
||||||
|
/// - `Err(AppError::NotFound(_))`:角色不存在。
|
||||||
|
/// - `Err(AppError::DbError(_))`:数据库写入失败。
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
/// ```rust,ignore
|
||||||
|
/// // POST /roles/{role_id}/permissions/grant
|
||||||
|
/// // Body:
|
||||||
|
/// // { "permission_codes": ["cms:article:create", "cms:article:publish", "cms:*:*"] }
|
||||||
|
/// //
|
||||||
|
/// // 说明:
|
||||||
|
/// // - 通配符权限(如 cms:*:*)只有在 permissions 表中存在并被绑定到角色时才会生效。
|
||||||
|
/// ```
|
||||||
pub async fn grant_role_permissions_handler(
|
pub async fn grant_role_permissions_handler(
|
||||||
TenantId(tenant_id): TenantId,
|
TenantId(tenant_id): TenantId,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
@@ -351,6 +456,27 @@ pub async fn grant_role_permissions_handler(
|
|||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[instrument(skip(state, payload))]
|
#[instrument(skip(state, payload))]
|
||||||
|
/// 从角色批量回收权限(Role → Permission 解绑)。
|
||||||
|
///
|
||||||
|
/// 从 `role_permissions` 删除指定 `permission_codes` 的关联(幂等:不存在的关联不会报错)。
|
||||||
|
/// 仅允许对 **自定义角色** 执行此操作;系统角色不可通过 API 修改权限集。
|
||||||
|
///
|
||||||
|
/// ## Parameters
|
||||||
|
/// - `TenantId(tenant_id): TenantId`(`Uuid`):当前租户 ID。
|
||||||
|
/// - `State(state): State<AppState>`:应用状态。
|
||||||
|
/// - `AuthContext { tenant_id: auth_tenant_id, user_id, .. }`:认证上下文。
|
||||||
|
/// - `Path(role_id): Path<Uuid>`:目标角色 ID。
|
||||||
|
/// - `Json(payload): Json<RolePermissionsRequest>`:待回收的权限码数组(`Vec<String>`)。
|
||||||
|
///
|
||||||
|
/// ## Returns
|
||||||
|
/// - `Ok(AppResponse<serde_json::Value>)`:成功返回 `200`,`data` 为 `{}`。
|
||||||
|
///
|
||||||
|
/// ## Errors
|
||||||
|
/// - `Err(AppError::PermissionDenied("tenant:mismatch"))`:跨租户访问被拒绝。
|
||||||
|
/// - `Err(AppError::PermissionDenied("role:write"))`:调用方缺少 `role:write` 权限。
|
||||||
|
/// - `Err(AppError::PermissionDenied("role:system_immutable"))`:系统角色不可变更权限集。
|
||||||
|
/// - `Err(AppError::NotFound(_))`:角色不存在。
|
||||||
|
/// - `Err(AppError::DbError(_))`:数据库写入失败。
|
||||||
pub async fn revoke_role_permissions_handler(
|
pub async fn revoke_role_permissions_handler(
|
||||||
TenantId(tenant_id): TenantId,
|
TenantId(tenant_id): TenantId,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
@@ -398,6 +524,34 @@ pub async fn revoke_role_permissions_handler(
|
|||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[instrument(skip(state, payload))]
|
#[instrument(skip(state, payload))]
|
||||||
|
/// 批量把角色授予用户(User ← Role 绑定)。
|
||||||
|
///
|
||||||
|
/// 将 `user_ids` 批量写入 `user_roles`(幂等:重复授予不会报错)。
|
||||||
|
/// 该接口用于“按角色”为多个用户授权,适用于组织/部门批量开通权限的场景。
|
||||||
|
///
|
||||||
|
/// ## Parameters
|
||||||
|
/// - `TenantId(tenant_id): TenantId`(`Uuid`):当前租户 ID。
|
||||||
|
/// - `State(state): State<AppState>`:应用状态。
|
||||||
|
/// - `AuthContext { tenant_id: auth_tenant_id, user_id, .. }`:认证上下文(`user_id` 为操作者)。
|
||||||
|
/// - `Path(role_id): Path<Uuid>`:目标角色 ID。
|
||||||
|
/// - `Json(payload): Json<RoleUsersRequest>`:待授予用户 ID 列表(`Vec<Uuid>`)。
|
||||||
|
///
|
||||||
|
/// ## Returns
|
||||||
|
/// - `Ok(AppResponse<serde_json::Value>)`:成功返回 `200`,`data` 为 `{}`。
|
||||||
|
///
|
||||||
|
/// ## Errors
|
||||||
|
/// - `Err(AppError::PermissionDenied("tenant:mismatch"))`:跨租户访问被拒绝。
|
||||||
|
/// - `Err(AppError::PermissionDenied("user:write"))`:调用方缺少 `user:write` 权限。
|
||||||
|
/// - `Err(AppError::NotFound(_))`:角色不存在。
|
||||||
|
/// - `Err(AppError::BadRequest(_))`:存在非法 `user_ids`(用户不在当前租户内)。
|
||||||
|
/// - `Err(AppError::DbError(_))`:数据库写入失败。
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
/// ```rust,ignore
|
||||||
|
/// // POST /roles/{role_id}/users/grant
|
||||||
|
/// // Body:
|
||||||
|
/// // { "user_ids": ["<user_uuid_1>", "<user_uuid_2>"] }
|
||||||
|
/// ```
|
||||||
pub async fn grant_role_users_handler(
|
pub async fn grant_role_users_handler(
|
||||||
TenantId(tenant_id): TenantId,
|
TenantId(tenant_id): TenantId,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
@@ -445,6 +599,25 @@ pub async fn grant_role_users_handler(
|
|||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[instrument(skip(state, payload))]
|
#[instrument(skip(state, payload))]
|
||||||
|
/// 批量从用户回收角色(User ← Role 解绑)。
|
||||||
|
///
|
||||||
|
/// 从 `user_roles` 删除指定 `user_ids` 的角色关联(幂等:不存在的关联不会报错)。
|
||||||
|
///
|
||||||
|
/// ## Parameters
|
||||||
|
/// - `TenantId(tenant_id): TenantId`(`Uuid`):当前租户 ID。
|
||||||
|
/// - `State(state): State<AppState>`:应用状态。
|
||||||
|
/// - `AuthContext { tenant_id: auth_tenant_id, user_id, .. }`:认证上下文(`user_id` 为操作者)。
|
||||||
|
/// - `Path(role_id): Path<Uuid>`:目标角色 ID。
|
||||||
|
/// - `Json(payload): Json<RoleUsersRequest>`:待回收用户 ID 列表(`Vec<Uuid>`)。
|
||||||
|
///
|
||||||
|
/// ## Returns
|
||||||
|
/// - `Ok(AppResponse<serde_json::Value>)`:成功返回 `200`,`data` 为 `{}`。
|
||||||
|
///
|
||||||
|
/// ## Errors
|
||||||
|
/// - `Err(AppError::PermissionDenied("tenant:mismatch"))`:跨租户访问被拒绝。
|
||||||
|
/// - `Err(AppError::PermissionDenied("user:write"))`:调用方缺少 `user:write` 权限。
|
||||||
|
/// - `Err(AppError::NotFound(_))`:角色不存在。
|
||||||
|
/// - `Err(AppError::DbError(_))`:数据库写入失败。
|
||||||
pub async fn revoke_role_users_handler(
|
pub async fn revoke_role_users_handler(
|
||||||
TenantId(tenant_id): TenantId,
|
TenantId(tenant_id): TenantId,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
|
|||||||
Reference in New Issue
Block a user