package httpapi import ( "context" "net/http" "net/http/httptest" "strings" "testing" "time" "knowledge-governance/internal/governance" ) func authorizationRequest(body string, role string, username string) *http.Request { request := httptest.NewRequest(http.MethodPost, "/api/v1/library/authorizations", strings.NewReader(body)) request.Header.Set("Content-Type", "application/json") ctx := context.WithValue(request.Context(), sessionKey{}, sessionIdentity{Username: username, Role: role}) return request.WithContext(ctx) } func TestLibraryAuthorizationRequiresAdmin(t *testing.T) { store := &fakeLibraryStore{} recorder := httptest.NewRecorder() libraryAuthorizationCreate(recorder, authorizationRequest(`{"scope":"internal","snapshot_id":"snap-1","expires_in_minutes":30}`, roleEngineer, "eng"), Config{Store: store}) if recorder.Code != http.StatusForbidden { t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String()) } if store.grant != nil { t.Fatal("non-admin must not create an authorization") } } func TestLibraryAuthorizationBindsScopeSnapshotAndDigest(t *testing.T) { store := &fakeLibraryStore{} recorder := httptest.NewRecorder() libraryAuthorizationCreate(recorder, authorizationRequest(`{"scope":"internal","snapshot_id":"snap-1","expires_in_minutes":30}`, roleAdmin, "admin"), Config{Store: store}) if recorder.Code != http.StatusCreated { t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String()) } want, err := librarySyncParamsDigest("internal", "snap-1") if err != nil { t.Fatal(err) } if store.grant.ParamsDigest != want || store.grant.SnapshotID != "snap-1" || store.grant.Scope != "internal" { t.Fatalf("grant not bound to request params: %+v", store.grant) } // 同一个授权不能用于另一个快照:摘要不同即查不到。 if _, found, _ := store.ActiveLibraryAuthorization(context.Background(), "internal", "snap-2", want, time.Now()); found { t.Fatal("grant must not authorize another snapshot") } if _, found, _ := store.ActiveLibraryAuthorization(context.Background(), "internal", "snap-1", "other-digest", time.Now()); found { t.Fatal("grant must not authorize different params") } } func TestLibraryAuthorizationRejectsUnboundedValidity(t *testing.T) { for _, body := range []string{ `{"scope":"internal","snapshot_id":"snap-1","expires_in_minutes":0}`, `{"scope":"internal","snapshot_id":"snap-1","expires_in_minutes":100000}`, } { store := &fakeLibraryStore{} recorder := httptest.NewRecorder() libraryAuthorizationCreate(recorder, authorizationRequest(body, roleAdmin, "admin"), Config{Store: store}) if recorder.Code != http.StatusBadRequest { t.Fatalf("body=%s status=%d", body, recorder.Code) } } } func TestLibraryAuthorizationExpiryIsEnforced(t *testing.T) { now := time.Now() item := governance.LibraryReleaseAuthorization{ID: "a", Scope: "internal", SnapshotID: "snap-1", ParamsDigest: "d", ExpiresAt: now.Add(-time.Minute)} if item.ValidAt(now) { t.Fatal("expired authorization must be invalid") } revoked := item revoked.ExpiresAt = now.Add(time.Hour) revokedAt := now revoked.RevokedAt = &revokedAt if revoked.ValidAt(now) { t.Fatal("revoked authorization must be invalid") } }