fix(server): 修复 RLS 变量名 bug — app.current_tenant → app.current_tenant_id + 空值保护

- 变量名从不存在的 app.current_tenant 修正为 app.current_tenant_id(与中间件一致)
- 添加空值保护:current_setting(...) != '' AND tenant_id = ...(与基座 m000088 严格模式一致)
- 移除 FORCE ROW LEVEL SECURITY,与基座表保持一致(允许迁移/管理操作绕过)
- 添加 DROP POLICY IF EXISTS 幂等保护

审计 ID: 4a-C01, 4b-C01, 4b-C02
This commit is contained in:
iven
2026-06-03 00:55:00 +08:00
parent d482497e49
commit 935918c9ab

View File

@@ -28,25 +28,29 @@ impl MigrationTrait for Migration {
];
for table in &diary_tables {
// 启用 RLS
// 启用 RLS(与基座 m000086 一致,不使用 FORCE允许迁移/管理操作绕过)
manager.get_connection().execute(sea_orm::Statement::from_string(
sea_orm::DatabaseBackend::Postgres,
format!("ALTER TABLE {table} ENABLE ROW LEVEL SECURITY"),
)).await.map_err(|e| DbErr::Custom(e.to_string()))?;
// 创建 RLS 策略tenant_id 隔离
// 删除已有策略(幂等,防止重复创建报错)
manager.get_connection().execute(sea_orm::Statement::from_string(
sea_orm::DatabaseBackend::Postgres,
format!("DROP POLICY IF EXISTS tenant_isolation ON {table}"),
)).await.map_err(|e| DbErr::Custom(e.to_string()))?;
// 创建 RLS 策略:与基座 m000088 严格模式一致
// 要求 app.current_tenant_id 已设置且非空,与 tenant_id 匹配
manager.get_connection().execute(sea_orm::Statement::from_string(
sea_orm::DatabaseBackend::Postgres,
format!(
"CREATE POLICY tenant_isolation ON {table} USING (tenant_id = current_setting('app.current_tenant')::uuid)"
"CREATE POLICY tenant_isolation ON {table} USING (\
current_setting('app.current_tenant_id', true) != '' \
AND tenant_id = current_setting('app.current_tenant_id', true)::uuid\
)"
),
)).await.map_err(|e| DbErr::Custom(e.to_string()))?;
// 允许超级用户绕过 RLS迁移和管理用
manager.get_connection().execute(sea_orm::Statement::from_string(
sea_orm::DatabaseBackend::Postgres,
format!("ALTER TABLE {table} FORCE ROW LEVEL SECURITY"),
)).await.map_err(|e| DbErr::Custom(e.to_string()))?;
}
// 日记全文搜索索引(标题 + 标签)