新增数据库驱动的 SecurityEventConnectionManager,复用 RFC 7662 机器 Client,自动完成 Discovery、Push Bearer 生成、Stream 创建、Verification、首次启用、零停机轮换和安全退役。 增加文件与 Kubernetes SecretStore、最小权限 RBAC、动态 Receiver/撤销水位/内省降级,以及系统设置管理页面。已通过全量 Go 测试、go vet、关键包竞态测试、27 个 Web 测试、类型检查、生产构建、Compose 和 Kubernetes dry-run。
52 lines
1.8 KiB
Go
52 lines
1.8 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/easyai/easyai-ai-gateway/apps/api/internal/config"
|
|
)
|
|
|
|
func TestSecurityEventConnectionWriteHeaders(t *testing.T) {
|
|
request := httptest.NewRequest(http.MethodPost, "/connection/verify", nil)
|
|
recorder := httptest.NewRecorder()
|
|
if _, ok := requiredConnectionIdempotencyKey(recorder, request); ok || recorder.Code != http.StatusBadRequest {
|
|
t.Fatalf("missing Idempotency-Key status=%d", recorder.Code)
|
|
}
|
|
|
|
request = httptest.NewRequest(http.MethodPost, "/connection/verify", nil)
|
|
request.Header.Set("If-Match", `W/"7"`)
|
|
recorder = httptest.NewRecorder()
|
|
if !matchConnectionVersion(recorder, request, 7) {
|
|
t.Fatalf("valid weak ETag was rejected: status=%d", recorder.Code)
|
|
}
|
|
|
|
request.Header.Set("If-Match", `"6"`)
|
|
recorder = httptest.NewRecorder()
|
|
if matchConnectionVersion(recorder, request, 7) || recorder.Code != http.StatusPreconditionFailed {
|
|
t.Fatalf("stale ETag status=%d", recorder.Code)
|
|
}
|
|
if normalizedConnectionETag(`W/"7"`) != "7" ||
|
|
securityEventOperationHash("verify", "7") == securityEventOperationHash("verify", "8") {
|
|
t.Fatal("security event idempotency request fingerprint is not stable")
|
|
}
|
|
}
|
|
|
|
func TestSecurityEventPrerequisitesNeverExposeSecrets(t *testing.T) {
|
|
server := &Server{cfg: config.Config{
|
|
OIDCEnabled: true, OIDCIssuer: "https://auth.example/issuer/shared", OIDCTenantID: "stable-tenant",
|
|
OIDCIntrospectionClientID: "gateway-machine", OIDCIntrospectionClientSecret: "must-not-escape",
|
|
PublicBaseURL: "https://gateway.example",
|
|
}}
|
|
payload, err := json.Marshal(server.securityEventPrerequisites())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if strings.Contains(string(payload), "must-not-escape") || strings.Contains(strings.ToLower(string(payload)), "secret") {
|
|
t.Fatalf("secret escaped in prerequisites: %s", payload)
|
|
}
|
|
}
|