package middleware import ( apierrors "git.yuntuo.hk/k2safe/go-omni/errors" "git.yuntuo.hk/k2safe/go-omni/httpx" "net/http/httptest" "testing" ) func TestAuthFailsClosedAndDoesNotLeakKey(t *testing.T) { t.Setenv("USER_SERVICE_API_TOKEN", "") if _, err := NewAuthFromEnv(); err == nil { t.Fatal("missing credential accepted") } token := "test-key-012345678901234567890123456789" t.Setenv("USER_SERVICE_API_TOKEN", token) middleware, err := NewAuthFromEnv() if err != nil { t.Fatal(err) } for _, header := range []string{"", "Basic " + token, "Bearer wrong", "Bearer " + token} { called := false r := httptest.NewRequest("GET", "/", nil) r.Header.Set("Authorization", header) c := httpx.NewContext(r, httptest.NewRecorder(), nil) err = middleware(func(*httpx.Context) error { called = true; return nil })(c) if header == "Bearer "+token { if err != nil || !called { t.Fatal("valid token rejected") } } else if err == nil || called || apierrors.From(err).Status != 401 { t.Fatal("unauthenticated request reached service") } } } func TestReadOnlyTokenCanReadButCannotWrite(t *testing.T) { admin := "admin-012345678901234567890123456789" read := "read-012345678901234567890123456789" t.Setenv("USER_SERVICE_API_TOKEN", admin) t.Setenv("USER_SERVICE_READ_TOKEN", read) middleware, err := NewAuthFromEnv() if err != nil { t.Fatal(err) } for _, method := range []string{"GET", "POST", "PUT", "DELETE"} { called := false r := httptest.NewRequest(method, "/api/v1/users", nil) r.Header.Set("Authorization", "Bearer "+read) err = middleware(func(*httpx.Context) error { called = true; return nil })(httpx.NewContext(r, httptest.NewRecorder(), nil)) if method == "GET" { if err != nil || !called { t.Fatal("read token rejected on GET") } } else if err == nil || called || apierrors.From(err).Status != 403 { t.Fatal("read token reached a write") } } t.Setenv("USER_SERVICE_READ_TOKEN", admin) if _, err = NewAuthFromEnv(); err == nil { t.Fatal("identical privilege tokens accepted") } }