From 935918c9ab68dccfbe3c66ab80754eb74d1f5d75 Mon Sep 17 00:00:00 2001 From: iven Date: Wed, 3 Jun 2026 00:55:00 +0800 Subject: [PATCH] =?UTF-8?q?fix(server):=20=E4=BF=AE=E5=A4=8D=20RLS=20?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E5=90=8D=20bug=20=E2=80=94=20app.current=5Ft?= =?UTF-8?q?enant=20=E2=86=92=20app.current=5Ftenant=5Fid=20+=20=E7=A9=BA?= =?UTF-8?q?=E5=80=BC=E4=BF=9D=E6=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 变量名从不存在的 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 --- .../m20260531_000183_diary_indexes_and_fts.rs | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/crates/erp-server/migration/src/m20260531_000183_diary_indexes_and_fts.rs b/crates/erp-server/migration/src/m20260531_000183_diary_indexes_and_fts.rs index e5de3ff..84d5215 100644 --- a/crates/erp-server/migration/src/m20260531_000183_diary_indexes_and_fts.rs +++ b/crates/erp-server/migration/src/m20260531_000183_diary_indexes_and_fts.rs @@ -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()))?; } // 日记全文搜索索引(标题 + 标签)