13070a275d
Closes #2: bootstrap JWTs cannot mutate admin APIs except change-password, production requires ADMIN_PASSWORD on first boot, admin binds loopback.
94 lines
2.0 KiB
Go
94 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"testing"
|
|
|
|
"helix-proxy/internal/auth"
|
|
"helix-proxy/internal/certificate"
|
|
"helix-proxy/internal/config"
|
|
"helix-proxy/internal/proxy"
|
|
"helix-proxy/internal/store"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
)
|
|
|
|
// testServerMode selects API-only vs full admin router (API + SPA).
|
|
type testServerMode int
|
|
|
|
const (
|
|
testServerAPI testServerMode = iota
|
|
testServerAdmin
|
|
)
|
|
|
|
type apiTestEnv struct {
|
|
BaseURL string
|
|
Store store.Store
|
|
Engine *proxy.Engine
|
|
Certs *certificate.Manager
|
|
JWT *auth.JWTManager
|
|
}
|
|
|
|
// newTestServer boots a temp store/engine and httptest server with the chosen router.
|
|
func newTestServer(t *testing.T, mode testServerMode) *apiTestEnv {
|
|
t.Helper()
|
|
if _, ok := os.LookupEnv("PROXY_MODE"); !ok {
|
|
t.Setenv("PROXY_MODE", "development")
|
|
}
|
|
if _, ok := os.LookupEnv("ADMIN_PASSWORD"); !ok {
|
|
t.Setenv("ADMIN_PASSWORD", testAdminPassword)
|
|
}
|
|
tmp := t.TempDir()
|
|
config.ResetForTest()
|
|
t.Setenv("DATA_DIR", tmp)
|
|
if err := config.EnsureDataDirs(); err != nil {
|
|
t.Fatalf("ensure dirs: %v", err)
|
|
}
|
|
st, err := store.New()
|
|
if err != nil {
|
|
t.Fatalf("store: %v", err)
|
|
}
|
|
if err := applyInitialAdminPassword(st); err != nil {
|
|
t.Fatalf("admin password: %v", err)
|
|
}
|
|
eng := proxy.NewEngine(st)
|
|
eng.ReloadFromStore()
|
|
cm := certificate.NewManager(st)
|
|
jwtMgr := auth.NewJWTManager("test-jwt-secret")
|
|
|
|
var handler http.Handler
|
|
switch mode {
|
|
case testServerAdmin:
|
|
handler = newAdminRouter(st, eng, cm, jwtMgr)
|
|
default:
|
|
r := chi.NewRouter()
|
|
mountAPI(r, st, eng, cm, jwtMgr)
|
|
handler = r
|
|
}
|
|
|
|
srv := httptest.NewServer(handler)
|
|
t.Cleanup(func() {
|
|
srv.Close()
|
|
if c, ok := st.(interface{ Close() error }); ok {
|
|
_ = c.Close()
|
|
}
|
|
})
|
|
return &apiTestEnv{
|
|
BaseURL: srv.URL,
|
|
Store: st,
|
|
Engine: eng,
|
|
Certs: cm,
|
|
JWT: jwtMgr,
|
|
}
|
|
}
|
|
|
|
func newAPITestServer(t *testing.T) *apiTestEnv {
|
|
return newTestServer(t, testServerAPI)
|
|
}
|
|
|
|
func newAdminTestServer(t *testing.T) *apiTestEnv {
|
|
return newTestServer(t, testServerAdmin)
|
|
}
|