Lets an external reader (sqlite3 CLI, DB Browser, DataGrip) inspect the database file concurrently without "database is locked" errors while geniusrund is running. Doesn't change in-process concurrency -- queries are already fully serialized via SetMaxOpenConns(1). auth: fix flaky tampered-cookie tests Both tests corrupted a signed cookie by blindly overwriting its last character with "x", which is occasionally a no-op if that character (part of the token's signature, so effectively randomized by the embedded timestamp) already happened to be "x" -- silently passing without having tampered with anything. Confirmed via 15 repeated runs (3 spurious passes) before the fix and 30 clean runs after. flipLastChar now guarantees the byte actually changes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
75 lines
2.1 KiB
Go
75 lines
2.1 KiB
Go
package auth
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func protectedTestHandler() http.Handler {
|
|
return RequireSession([]byte(testSecret))(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
claims, ok := ClaimsFromContext(r.Context())
|
|
if !ok {
|
|
http.Error(w, "no claims in context", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.Write([]byte(claims.Name))
|
|
}))
|
|
}
|
|
|
|
func TestRequireSession_NoCookie(t *testing.T) {
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
rec := httptest.NewRecorder()
|
|
protectedTestHandler().ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusUnauthorized {
|
|
t.Fatalf("status = %d, want 401", rec.Code)
|
|
}
|
|
}
|
|
|
|
func TestRequireSession_ValidCookie(t *testing.T) {
|
|
cookie, err := MintSessionCookie(Claims{Sub: "u1", Name: "Alice", Email: "alice@example.com"}, []byte(testSecret), time.Hour, false)
|
|
if err != nil {
|
|
t.Fatalf("mint: %v", err)
|
|
}
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
req.AddCookie(cookie)
|
|
rec := httptest.NewRecorder()
|
|
protectedTestHandler().ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, want 200, body = %s", rec.Code, rec.Body.String())
|
|
}
|
|
if rec.Body.String() != "Alice" {
|
|
t.Fatalf("body = %q, want Alice", rec.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestRequireSession_ExpiredCookie(t *testing.T) {
|
|
cookie, err := MintSessionCookie(Claims{Sub: "u1"}, []byte(testSecret), -time.Hour, false)
|
|
if err != nil {
|
|
t.Fatalf("mint: %v", err)
|
|
}
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
req.AddCookie(cookie)
|
|
rec := httptest.NewRecorder()
|
|
protectedTestHandler().ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusUnauthorized {
|
|
t.Fatalf("status = %d, want 401", rec.Code)
|
|
}
|
|
}
|
|
|
|
func TestRequireSession_TamperedCookie(t *testing.T) {
|
|
cookie, err := MintSessionCookie(Claims{Sub: "u1"}, []byte(testSecret), time.Hour, false)
|
|
if err != nil {
|
|
t.Fatalf("mint: %v", err)
|
|
}
|
|
cookie.Value = flipLastChar(cookie.Value)
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
req.AddCookie(cookie)
|
|
rec := httptest.NewRecorder()
|
|
protectedTestHandler().ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusUnauthorized {
|
|
t.Fatalf("status = %d, want 401", rec.Code)
|
|
}
|
|
}
|