From e36794aed12863797bd0292cfd35bfcb9f45c5af Mon Sep 17 00:00:00 2001 From: xuans Date: Tue, 29 Sep 2026 16:59:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=A1=A5=E5=85=85=EF=BC=9A?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E5=9F=9F=E5=90=8D=E5=AE=A1=E8=AE=A1=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E4=BA=8B=E5=8A=A1=E5=9B=9E=E6=BB=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加 SQLite 审计触发器拒绝场景,覆盖域名新增、修改、删除失败时业务变更完整回滚。 --- .../project_domain_repository_test.go | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/backend/internal/repository/project_domain_repository_test.go b/backend/internal/repository/project_domain_repository_test.go index 60750c5..23ace7e 100644 --- a/backend/internal/repository/project_domain_repository_test.go +++ b/backend/internal/repository/project_domain_repository_test.go @@ -70,6 +70,44 @@ func TestProjectDomainRepositorySQLite(t *testing.T) { if _, err := db.DB.ExecContext(context.Background(), Rebind(cfg.Driver, `UPDATE tasks SET status = 'success' WHERE id = ?`), "domain-active-task"); err != nil { t.Fatal(err) } + trigger := `CREATE TRIGGER reject_project_domain_audit BEFORE INSERT ON audit_logs BEGIN SELECT RAISE(ABORT, 'audit-failure'); END` + if _, err := db.DB.ExecContext(t.Context(), trigger); err != nil { + t.Fatal(err) + } + if err := writer.UpdateProjectDomain(t.Context(), "domain-manager", item); err == nil { + t.Fatal("审计失败时更新域名不应成功") + } + stored, err = NewSQLDomainRepository(db.DB).GetByID(t.Context(), item.ID) + if err != nil || stored.Name != "updated.example.test" { + t.Fatalf("审计失败后域名更新未回滚:%+v,%v", stored, err) + } + newItem, err := domain.NewDomain("audit-create.example.test", domain.CertificateSingle, nil) + if err != nil { + t.Fatal(err) + } + newItem.ID = "audit-create-domain" + newItem.ProjectID = "domain-project" + if err := writer.CreateProjectDomain(t.Context(), "domain-manager", newItem); err == nil { + t.Fatal("审计失败时创建域名不应成功") + } + if _, err := NewSQLDomainRepository(db.DB).GetByID(t.Context(), newItem.ID); !errors.Is(err, sql.ErrNoRows) { + t.Fatalf("审计失败后域名创建未回滚:%v", err) + } + if _, err := db.DB.ExecContext(t.Context(), `DROP TRIGGER reject_project_domain_audit`); err != nil { + t.Fatal(err) + } + if _, err := db.DB.ExecContext(t.Context(), trigger); err != nil { + t.Fatal(err) + } + if err := writer.DeleteProjectDomain(t.Context(), "domain-manager", item.ID); err == nil { + t.Fatal("审计失败时删除域名不应成功") + } + if _, err := NewSQLDomainRepository(db.DB).GetByID(t.Context(), item.ID); err != nil { + t.Fatalf("审计失败后域名删除未回滚:%v", err) + } + if _, err := db.DB.ExecContext(t.Context(), `DROP TRIGGER reject_project_domain_audit`); err != nil { + t.Fatal(err) + } if err := writer.DeleteProjectDomain(t.Context(), "domain-manager", item.ID); err != nil { t.Fatal(err) }