Return a distinct session_idle error from the API and reload to /login with a clear signed-out message.
84 lines
2.4 KiB
Go
84 lines
2.4 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"codeberg.org/SquidSE/ClusterCanvas/service/internal/auth"
|
|
"codeberg.org/SquidSE/ClusterCanvas/service/internal/settings"
|
|
)
|
|
|
|
func TestMiddlewareReturnsSessionIdle(t *testing.T) {
|
|
configDir := t.TempDir()
|
|
cookie := seedCompletedSetup(t, configDir)
|
|
|
|
keyBytes := make([]byte, 32)
|
|
for index := range keyBytes {
|
|
keyBytes[index] = byte(index + 1)
|
|
}
|
|
|
|
store, err := settings.LoadSessions(configDir, keyBytes)
|
|
if err != nil {
|
|
t.Fatalf("LoadSessions: %v", err)
|
|
}
|
|
if len(store.Sessions) != 1 {
|
|
t.Fatalf("expected 1 session, got %d", len(store.Sessions))
|
|
}
|
|
store.Sessions[0].LastSeenAt = time.Now().UTC().Add(-31 * time.Minute)
|
|
if err := settings.SaveSessions(configDir, store, keyBytes); err != nil {
|
|
t.Fatalf("SaveSessions: %v", err)
|
|
}
|
|
|
|
router := NewRouter(configDir)
|
|
request := withSession(httptest.NewRequest(http.MethodGet, "/api/v1/status", nil), cookie)
|
|
recorder := httptest.NewRecorder()
|
|
router.ServeHTTP(recorder, request)
|
|
|
|
if recorder.Code != http.StatusUnauthorized {
|
|
t.Fatalf("expected status %d, got %d body=%s", http.StatusUnauthorized, recorder.Code, recorder.Body.String())
|
|
}
|
|
|
|
var payload apiErrorResponse
|
|
if err := json.NewDecoder(recorder.Body).Decode(&payload); err != nil {
|
|
t.Fatalf("decode response: %v", err)
|
|
}
|
|
if payload.Error != "session_idle" {
|
|
t.Fatalf("expected session_idle, got %q", payload.Error)
|
|
}
|
|
|
|
cleared := false
|
|
for _, setCookie := range recorder.Result().Cookies() {
|
|
if setCookie.Name == auth.SessionCookieName && setCookie.MaxAge < 0 {
|
|
cleared = true
|
|
}
|
|
}
|
|
if !cleared {
|
|
t.Fatal("expected session cookie to be cleared")
|
|
}
|
|
}
|
|
|
|
func TestMiddlewareReturnsAuthenticationRequiredWithoutCookie(t *testing.T) {
|
|
configDir := t.TempDir()
|
|
_ = seedCompletedSetup(t, configDir)
|
|
|
|
router := NewRouter(configDir)
|
|
request := httptest.NewRequest(http.MethodGet, "/api/v1/status", nil)
|
|
recorder := httptest.NewRecorder()
|
|
router.ServeHTTP(recorder, request)
|
|
|
|
if recorder.Code != http.StatusUnauthorized {
|
|
t.Fatalf("expected status %d, got %d body=%s", http.StatusUnauthorized, recorder.Code, recorder.Body.String())
|
|
}
|
|
|
|
var payload apiErrorResponse
|
|
if err := json.NewDecoder(recorder.Body).Decode(&payload); err != nil {
|
|
t.Fatalf("decode response: %v", err)
|
|
}
|
|
if payload.Error != "authentication required" {
|
|
t.Fatalf("expected authentication required, got %q", payload.Error)
|
|
}
|
|
}
|