Files
chorus/portal/session/manager_test.go
T

69 lines
2.3 KiB
Go

package session
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
)
func TestSessionRotationCookieAndCSRF(t *testing.T) {
manager, err := New([]byte(strings.Repeat("k", 32)), time.Hour, true)
if err != nil {
t.Fatal(err)
}
request := httptest.NewRequest(http.MethodGet, "https://chorus.test/api/session", nil)
response := httptest.NewRecorder()
anonymous, err := manager.Ensure(response, request)
if err != nil {
t.Fatal(err)
}
cookie := response.Result().Cookies()[0]
if !cookie.HttpOnly || !cookie.Secure || cookie.SameSite != http.SameSiteLaxMode || anonymous.UserID != 0 {
t.Fatalf("cookie/state = %#v %#v", cookie, anonymous)
}
request.AddCookie(cookie)
loginResponse := httptest.NewRecorder()
authenticated, err := manager.Authenticate(loginResponse, request, 42)
if err != nil {
t.Fatal(err)
}
if authenticated.ID == anonymous.ID || authenticated.CSRFToken == anonymous.CSRFToken {
t.Fatal("login did not rotate session and CSRF")
}
if _, ok := manager.Get(request); ok {
t.Fatal("old session remained valid")
}
newCookie := loginResponse.Result().Cookies()[0]
csrfRequest := httptest.NewRequest(http.MethodPost, "https://chorus.test/api", nil)
csrfRequest.AddCookie(newCookie)
csrfRequest.Header.Set("X-CSRF-Token", authenticated.CSRFToken)
if state, ok := manager.Get(csrfRequest); !ok || !manager.ValidateCSRF(csrfRequest, state) {
t.Fatal("new session CSRF was rejected")
}
csrfRequest.Header.Set("X-CSRF-Token", "tampered")
if manager.ValidateCSRF(csrfRequest, authenticated) {
t.Fatal("tampered CSRF was accepted")
}
}
func TestTamperedAndExpiredCookie(t *testing.T) {
manager, _ := New([]byte(strings.Repeat("k", 32)), time.Millisecond, false)
response := httptest.NewRecorder()
state, _ := manager.Ensure(response, httptest.NewRequest(http.MethodGet, "http://test/", nil))
cookie := response.Result().Cookies()[0]
cookie.Value += "x"
request := httptest.NewRequest(http.MethodGet, "http://test/", nil)
request.AddCookie(cookie)
if _, ok := manager.Get(request); ok {
t.Fatal("tampered cookie accepted")
}
manager.now = func() time.Time { return state.ExpiresAt.Add(time.Second) }
validCookie := response.Result().Cookies()[0]
request = httptest.NewRequest(http.MethodGet, "http://test/", nil)
request.AddCookie(validCookie)
if _, ok := manager.Get(request); ok {
t.Fatal("expired session accepted")
}
}