取消跨主体专属占用,按租户、用户组、用户、当前 API Key 和 scope 分层求交,并在任务落库前统一校验候选。\n\n增加旧 allow 规则归档清理迁移、脱敏审计工具和回滚运行手册,补齐主体隔离、deny 优先及列表与运行时一致性测试。
70 lines
2.3 KiB
Go
70 lines
2.3 KiB
Go
package accessruleaudit
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestVerifyMigrationAcceptsMatchingArchiveAndUnchangedDeny(t *testing.T) {
|
|
before := auditSnapshot(3, "allow-before", 2, "deny-before", nil)
|
|
after := auditSnapshot(0, "", 2, "deny-before", &ArchiveManifest{
|
|
MigrationBatch: MigrationBatch,
|
|
ManifestAllowCount: 3,
|
|
ManifestAllowSHA: sha256Hex("allow-before"),
|
|
ArchivedAllowCount: 3,
|
|
ArchivedAllowSHA: sha256Hex("allow-before"),
|
|
ManifestDenyCount: 2,
|
|
ManifestDenySHA: sha256Hex("deny-before"),
|
|
Consistent: true,
|
|
})
|
|
if err := VerifyMigration(before, after); err != nil {
|
|
t.Fatalf("verify matching migration: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestVerifyMigrationRejectsChangedDenyOrMissingArchive(t *testing.T) {
|
|
before := auditSnapshot(1, "allow", 1, "deny", nil)
|
|
withoutArchive := auditSnapshot(0, "", 1, "deny", nil)
|
|
if err := VerifyMigration(before, withoutArchive); err == nil {
|
|
t.Fatal("missing archive must fail verification")
|
|
}
|
|
changedDeny := auditSnapshot(0, "", 1, "changed-deny", &ArchiveManifest{
|
|
MigrationBatch: MigrationBatch,
|
|
ManifestAllowCount: 1,
|
|
ManifestAllowSHA: sha256Hex("allow"),
|
|
ArchivedAllowCount: 1,
|
|
ArchivedAllowSHA: sha256Hex("allow"),
|
|
ManifestDenyCount: 1,
|
|
ManifestDenySHA: sha256Hex("deny"),
|
|
Consistent: true,
|
|
})
|
|
if err := VerifyMigration(before, changedDeny); err == nil {
|
|
t.Fatal("changed deny hash must fail verification")
|
|
}
|
|
}
|
|
|
|
func auditSnapshot(allowCount int64, allowSeed string, denyCount int64, denySeed string, archive *ArchiveManifest) Snapshot {
|
|
counts := make([]RuleCount, 0, 2)
|
|
if allowCount > 0 {
|
|
counts = append(counts, RuleCount{SubjectType: "api_key", Effect: "allow", ResourceType: "platform_model", Status: "active", Count: allowCount})
|
|
}
|
|
if denyCount > 0 {
|
|
counts = append(counts, RuleCount{SubjectType: "api_key", Effect: "deny", ResourceType: "platform_model", Status: "active", Count: denyCount})
|
|
}
|
|
return Snapshot{
|
|
SchemaVersion: SchemaVersion,
|
|
GeneratedAt: time.Date(2026, 8, 3, 0, 0, 0, 0, time.UTC),
|
|
SecretSafe: true,
|
|
Live: RuleSet{
|
|
Total: allowCount + denyCount,
|
|
SHA256: sha256Hex("all-" + allowSeed + "-" + denySeed),
|
|
AllowCount: allowCount,
|
|
AllowSHA256: sha256Hex(allowSeed),
|
|
DenyCount: denyCount,
|
|
DenySHA256: sha256Hex(denySeed),
|
|
Counts: counts,
|
|
},
|
|
Archive: archive,
|
|
}
|
|
}
|