Files
easyai-ai-gateway/apps/api/internal/store/admin_task_redaction_test.go
T
wangbo fe56aa46b9 fix(errors): 区分平台限流并保留上游状态码
原因:公开错误层将平台并发限流误标为上游限流,并把多种上游 4xx 统一压成 400,影响定位和客户端处理。

影响:新增公开错误 source,平台限流使用 gateway_rate_limited,上游请求按安全分类返回对应状态;数据库与管理端继续保留原始错误码、消息和状态用于审计。

验证:Go 全量测试、pnpm test、pnpm lint、pnpm build、pnpm openapi、gofmt 和 diff 检查均通过。
2026-08-04 10:46:46 +08:00

95 lines
3.3 KiB
Go

package store
import (
"strings"
"testing"
)
func TestMaskAdminGatewayTaskRecursivelyMasksSecretsWithoutMutatingSource(t *testing.T) {
source := AdminGatewayTask{
GatewayTask: GatewayTask{
ErrorCode: "http_404",
ErrorMessage: "404 page not found from upstream route /private/v1/images",
Request: map[string]any{
"model": "example",
"headers": map[string]any{
"Authorization": "Bearer private",
"X-Api-Key": "secret-key",
},
"usage": map[string]any{"input_tokens": float64(12)},
},
Result: map[string]any{
"nested": []any{map[string]any{"password": "private-password"}},
},
Attempts: []TaskAttempt{{
ErrorCode: "http_404",
ErrorMessage: "404 page not found from upstream route /private/v1/images",
RequestSnapshot: map[string]any{"client_secret": "private-client-secret"},
}},
},
}
masked := MaskAdminGatewayTask(source)
if masked.ErrorCode != source.ErrorCode || masked.ErrorMessage != source.ErrorMessage || masked.Attempts[0].ErrorMessage != source.Attempts[0].ErrorMessage {
t.Fatalf("admin error audit fields must preserve raw upstream values: %#v", masked)
}
headers := masked.Request["headers"].(map[string]any)
if headers["Authorization"] != maskedAdminTaskValue || headers["X-Api-Key"] != maskedAdminTaskValue {
t.Fatalf("sensitive headers were not masked: %#v", headers)
}
if masked.Request["usage"].(map[string]any)["input_tokens"] != float64(12) {
t.Fatalf("token usage must remain visible: %#v", masked.Request)
}
nested := masked.Result["nested"].([]any)[0].(map[string]any)
if nested["password"] != maskedAdminTaskValue {
t.Fatalf("nested password was not masked: %#v", nested)
}
if masked.Attempts[0].RequestSnapshot["client_secret"] != maskedAdminTaskValue {
t.Fatalf("attempt snapshot secret was not masked: %#v", masked.Attempts[0])
}
if source.Request["headers"].(map[string]any)["Authorization"] != "Bearer private" {
t.Fatal("masking mutated the source request")
}
if source.Attempts[0].RequestSnapshot["client_secret"] != "private-client-secret" {
t.Fatal("masking mutated the source attempts")
}
}
func TestBuildAdminTaskWhereUsesSharedPlaceholdersAndAllFilters(t *testing.T) {
where, args := buildAdminTaskWhere(AdminTaskListFilter{
Query: "needle",
GatewayTenant: "00000000-0000-0000-0000-000000000001",
GatewayUser: "00000000-0000-0000-0000-000000000002",
UserGroup: "00000000-0000-0000-0000-000000000003",
Status: "failed",
Platform: "00000000-0000-0000-0000-000000000004",
Model: "model-a",
ModelType: "image_generate",
RunMode: "production",
BillingStatus: "settled",
APIKey: "ops",
})
sql := strings.Join(where, "\n")
if strings.Contains(sql, "%!") || strings.Contains(sql, "$%d") {
t.Fatalf("SQL contains an unresolved placeholder: %s", sql)
}
if len(args) != 11 {
t.Fatalf("argument count=%d, want 11", len(args))
}
if strings.Count(sql, "$1") < 10 {
t.Fatalf("keyword search should reuse one placeholder, got: %s", sql)
}
for _, fragment := range []string{
"t.gateway_tenant_id",
"t.gateway_user_id",
"t.user_group_id",
"platform_attempt.platform_id",
"t.billing_status",
"t.api_key_prefix",
} {
if !strings.Contains(sql, fragment) {
t.Fatalf("SQL is missing %q: %s", fragment, sql)
}
}
}