package httpserver import ( "context" "net/http" "net/http/httptest" "testing" "git.yuntuo.hk/k2safe/orbit/internal/consoleauth" core "git.yuntuo.hk/k2safe/orbit/model" "git.yuntuo.hk/k2safe/orbit/platform/auth" ) type fakeConsoleScopes struct{ calls int } func (s *fakeConsoleScopes) ResolveScope(_ context.Context, t auth.Token, target core.ID) (auth.Token, error) { s.calls++ t.Console = &auth.ConsoleIdentity{SessionNamespaceID: t.NamespaceID, Username: "admin", UserID: t.CredentialID} t.NamespaceID = target return t, nil } func (*fakeConsoleScopes) GetScope(context.Context, auth.Token, core.ID) (consoleauth.Scope, error) { return consoleauth.Scope{}, nil } func TestConsoleScopeOnlyBridgesCookieManagementRequests(t *testing.T) { ns, _ := core.NewID() cred, _ := core.NewID() target, _ := core.NewID() raw, _, _ := auth.Issue(ns, cred) for _, tc := range []struct { name, method, path, origin, bearer string cookie, marker bool status int }{ {"read", "GET", "/v1/tasks", "", "", true, true, 200}, {"control", "POST", "/v1/tasks/task:cancel", "http://example.com", "", true, true, 200}, {"SDK", "GET", "/v1/tasks", "", "Bearer " + raw, false, true, 403}, {"ambiguous", "GET", "/v1/tasks", "", "Bearer " + raw, true, true, 403}, {"anonymous", "GET", "/v1/tasks", "", "", false, true, 401}, {"missing-marker", "GET", "/v1/tasks", "", "", true, false, 403}, {"cross-origin", "POST", "/v1/tasks/task:cancel", "https://other.invalid", "", true, true, 403}, {"worker", "GET", "/v1/workers/connect", "", "", true, true, 403}, {"create", "POST", "/v1/tasks", "", "", true, true, 403}, {"onboarding", "POST", "/console/applications/prepare", "", "", true, true, 403}, } { t.Run(tc.name, func(t *testing.T) { scope := &fakeConsoleScopes{} handler := ConsoleSessionMiddleware(wrap(func(r *http.Request, tok auth.Token) (any, int, error) { if tok.NamespaceID != target || tok.Console == nil || tok.Console.SessionNamespaceID != ns { t.Fatal("scope lost") } return map[string]bool{"ok": true}, 200, nil }), &fakeConsoleAuth{valid: true}, scope) req := httptest.NewRequest(tc.method, tc.path, nil) req.Header.Set("X-Orbit-Namespace", string(target)) if tc.marker { req.Header.Set("X-Orbit-Console", "1") } if tc.origin != "" { req.Header.Set("Origin", tc.origin) } if tc.bearer != "" { req.Header.Set("Authorization", tc.bearer) } if tc.cookie { req.AddCookie(&http.Cookie{Name: consoleSessionCookie, Value: raw}) } res := httptest.NewRecorder() handler.ServeHTTP(res, req) if res.Code != tc.status { t.Fatalf("HTTP %d: %s", res.Code, res.Body.String()) } if tc.status != 200 && scope.calls != 0 { t.Fatal("rejected request reached scope resolver") } }) } }