feat(auth): data_scope 行级数据权限 — DataScope 枚举 + 中间件加载
- TenantContext 新增 permission_data_scopes: HashMap<String, DataScope> - DataScope 枚举: All/SelfOnly/Department/DepartmentTree - JWT 中间件查询 role_permissions.data_scope 填充到上下文 - rbac::get_data_scope() 供 service 层按权限获取数据范围 - 默认 All,完全向后兼容现有行为
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use crate::error::AppError;
|
||||
use crate::types::TenantContext;
|
||||
use crate::types::{DataScope, TenantContext};
|
||||
|
||||
/// Check whether the `TenantContext` includes the specified permission code.
|
||||
///
|
||||
@@ -38,6 +38,16 @@ pub fn require_role(ctx: &TenantContext, role: &str) -> Result<(), AppError> {
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取指定权限的数据范围。默认 All(向后兼容)。
|
||||
///
|
||||
/// Service 层根据返回值追加对应的查询过滤条件。
|
||||
pub fn get_data_scope(ctx: &TenantContext, permission: &str) -> DataScope {
|
||||
ctx.permission_data_scopes
|
||||
.get(permission)
|
||||
.cloned()
|
||||
.unwrap_or(DataScope::All)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -50,6 +60,7 @@ mod tests {
|
||||
roles: roles.into_iter().map(String::from).collect(),
|
||||
permissions: permissions.into_iter().map(String::from).collect(),
|
||||
department_ids: vec![],
|
||||
permission_data_scopes: std::collections::HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use uuid::Uuid;
|
||||
|
||||
/// 所有数据库实体的公共字段
|
||||
@@ -114,6 +115,7 @@ mod tests {
|
||||
roles: vec!["admin".to_string()],
|
||||
permissions: vec!["user.read".to_string()],
|
||||
department_ids: vec![],
|
||||
permission_data_scopes: HashMap::new(),
|
||||
};
|
||||
assert_eq!(ctx.roles.len(), 1);
|
||||
assert_eq!(ctx.permissions.len(), 1);
|
||||
@@ -148,6 +150,30 @@ impl<T: Serialize> ApiResponse<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// 行级数据权限范围
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum DataScope {
|
||||
/// 查看所有数据
|
||||
All,
|
||||
/// 仅查看自己创建的数据
|
||||
SelfOnly,
|
||||
/// 仅查看本部门数据
|
||||
Department,
|
||||
/// 查看本部门及下属部门数据
|
||||
DepartmentTree,
|
||||
}
|
||||
|
||||
impl DataScope {
|
||||
pub fn from_str(s: &str) -> Self {
|
||||
match s {
|
||||
"self" => Self::SelfOnly,
|
||||
"department" => Self::Department,
|
||||
"department_tree" => Self::DepartmentTree,
|
||||
_ => Self::All,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 租户上下文(中间件注入)
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TenantContext {
|
||||
@@ -157,4 +183,6 @@ pub struct TenantContext {
|
||||
pub permissions: Vec<String>,
|
||||
/// 用户所属部门 ID 列表(行级数据权限使用)
|
||||
pub department_ids: Vec<Uuid>,
|
||||
/// 每个权限码对应的数据范围(从 role_permissions.data_scope 加载)
|
||||
pub permission_data_scopes: HashMap<String, DataScope>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user