Files
Agent-System/internal/server/auth_phase1_test.go
T
weichenandCursor 7fdbee6c0c test(server): adapt fixtures to IAM dual-gate fail-closed
Boot memory IAM only via explicit test env opt-in; strict auth cases
disable AllowInMemory after startup.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 09:42:07 +00:00

140 lines
4.2 KiB
Go

package server_test
import (
"bytes"
"encoding/json"
"net/http"
"testing"
"chat-agent-system/internal/auth"
)
func adminToken(t *testing.T, baseURL string) string {
t.Helper()
body, _ := json.Marshal(map[string]string{"username": "admin", "password": "admin123"})
resp, err := http.Post(baseURL+"/api/v1/auth/login", "application/json", bytes.NewReader(body))
if err != nil {
t.Fatalf("admin login: %v", err)
}
defer resp.Body.Close()
var session auth.SessionInfo
if err := json.NewDecoder(resp.Body).Decode(&session); err != nil {
t.Fatalf("decode admin session: %v", err)
}
return session.Token
}
func TestAuthHandlers_DisabledUserTokenReturns401(t *testing.T) {
ts, authSvc := setupTestServer(t)
loginBody, _ := json.Marshal(map[string]string{"username": "zhanggong", "password": "123456"})
resp, err := http.Post(ts.URL+"/api/v1/auth/login", "application/json", bytes.NewReader(loginBody))
if err != nil {
t.Fatalf("user login: %v", err)
}
if resp.StatusCode != http.StatusOK {
t.Fatalf("expected engineer login 200, got %d", resp.StatusCode)
}
var userSession auth.SessionInfo
_ = json.NewDecoder(resp.Body).Decode(&userSession)
adminTok := adminToken(t, ts.URL)
disableBody, _ := json.Marshal(map[string]string{"status": string(auth.StatusDisabled)})
req, _ := http.NewRequest(http.MethodPut, ts.URL+"/api/v1/admin/users/2/status", bytes.NewReader(disableBody))
req.Header.Set("Authorization", "Bearer "+adminTok)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
disableResp, err := client.Do(req)
if err != nil {
t.Fatalf("disable user: %v", err)
}
disableResp.Body.Close()
if disableResp.StatusCode != http.StatusOK {
t.Fatalf("expected disable 200, got %d", disableResp.StatusCode)
}
meReq, _ := http.NewRequest(http.MethodGet, ts.URL+"/api/v1/auth/me", nil)
meReq.Header.Set("Authorization", "Bearer "+userSession.Token)
meResp, err := client.Do(meReq)
if err != nil {
t.Fatalf("me after disable: %v", err)
}
defer meResp.Body.Close()
if meResp.StatusCode != http.StatusUnauthorized {
t.Fatalf("expected 401 after disable, got %d", meResp.StatusCode)
}
u, err := authSvc.GetUserByID(t.Context(), 2)
if err != nil || u.Status != auth.StatusDisabled {
t.Fatalf("user should remain disabled in store")
}
}
func TestAuthHandlers_AdminListRoles(t *testing.T) {
ts, _ := setupTestServer(t)
req, _ := http.NewRequest(http.MethodGet, ts.URL+"/api/v1/admin/roles", nil)
req.Header.Set("Authorization", "Bearer "+adminToken(t, ts.URL))
resp, err := (&http.Client{}).Do(req)
if err != nil {
t.Fatalf("list roles: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Fatalf("expected 200, got %d", resp.StatusCode)
}
var body map[string]any
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
t.Fatalf("decode: %v", err)
}
roles, ok := body["roles"].([]any)
if !ok || len(roles) == 0 {
t.Fatalf("expected roles array, got %v", body["roles"])
}
}
func TestAuthHandlers_ListSessions(t *testing.T) {
ts, _ := setupTestServer(t)
tok := adminToken(t, ts.URL)
req, _ := http.NewRequest(http.MethodGet, ts.URL+"/api/v1/auth/sessions", nil)
req.Header.Set("Authorization", "Bearer "+tok)
resp, err := (&http.Client{}).Do(req)
if err != nil {
t.Fatalf("list sessions: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Fatalf("expected 200, got %d", resp.StatusCode)
}
var body map[string]any
_ = json.NewDecoder(resp.Body).Decode(&body)
sessions, ok := body["sessions"].([]any)
if !ok {
t.Fatalf("expected sessions array")
}
if len(sessions) == 0 {
t.Fatal("expected at least one active session")
}
}
func TestAuthHandlers_LoginReturnsCapabilitiesFallback(t *testing.T) {
ts, _ := setupTestServer(t)
req, _ := http.NewRequest(http.MethodGet, ts.URL+"/api/v1/auth/me", nil)
req.Header.Set("Authorization", "Bearer "+adminToken(t, ts.URL))
resp, err := (&http.Client{}).Do(req)
if err != nil {
t.Fatalf("me: %v", err)
}
defer resp.Body.Close()
var body map[string]any
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
t.Fatalf("decode: %v", err)
}
caps, ok := body["capabilities"].([]any)
if !ok || len(caps) == 0 {
t.Fatalf("expected non-empty capabilities fallback for admin, got %v", body["capabilities"])
}
}