fix(handlers): add handlers

This commit is contained in:
2026-01-30 16:31:53 +08:00
parent bb82c75834
commit ce12b997f4
38 changed files with 3746 additions and 317 deletions

View File

@@ -0,0 +1,79 @@
use common_telemetry::AppError;
use sqlx::PgPool;
use tracing::instrument;
use uuid::Uuid;
#[derive(Clone)]
pub struct AuthorizationService {
pool: PgPool,
}
impl AuthorizationService {
/// 创建权限服务实例。
pub fn new(pool: PgPool) -> Self {
Self { pool }
}
#[instrument(skip(self))]
/// 获取用户在指定租户下的权限编码集合(去重)。
///
/// 说明:
/// - 权限来源于用户所属角色user_roles → roles及角色绑定权限role_permissions → permissions
///
/// 输入:
/// - `tenant_id`:租户 ID
/// - `user_id`:用户 ID
///
/// 输出:
/// - 权限编码数组(如 `tenant:read` / `user:write`
///
/// 异常:
/// - 数据库查询失败
pub async fn list_permissions_for_user(
&self,
tenant_id: Uuid,
user_id: Uuid,
) -> Result<Vec<String>, AppError> {
let query = r#"
SELECT DISTINCT p.code
FROM permissions p
JOIN role_permissions rp ON rp.permission_id = p.id
JOIN user_roles ur ON ur.role_id = rp.role_id
JOIN roles r ON r.id = ur.role_id
WHERE r.tenant_id = $1 AND ur.user_id = $2
"#;
let rows = sqlx::query_scalar::<_, String>(query)
.bind(tenant_id)
.bind(user_id)
.fetch_all(&self.pool)
.await?;
Ok(rows)
}
#[instrument(skip(self))]
/// 校验用户是否具备指定权限,不满足则直接返回权限拒绝错误。
///
/// 业务规则:
/// - 若用户权限集合中不包含 `permission_code`,返回 `PermissionDenied(permission_code)`。
///
/// 输入:
/// - `tenant_id`:租户 ID
/// - `user_id`:用户 ID
/// - `permission_code`:权限编码
///
/// 输出:
/// - 成功返回 `()`;失败返回权限拒绝错误
pub async fn require_permission(
&self,
tenant_id: Uuid,
user_id: Uuid,
permission_code: &str,
) -> Result<(), AppError> {
let permissions = self.list_permissions_for_user(tenant_id, user_id).await?;
if permissions.iter().any(|p| p == permission_code) {
Ok(())
} else {
Err(AppError::PermissionDenied(permission_code.to_string()))
}
}
}