refactor: drop the ignored secure toggle parameter from session.NewManager
All checks were successful
check / check (push) Successful in 1m48s
All checks were successful
check / check (push) Successful in 1m48s
Per review on PR #48: pre-1.0 there is no installed base to keep compiling against, so remove the dead parameter in one pass instead of deferring. NewManager now takes only the signing key. Update the handlers.go call site and its stale comment, mechanically update the NewManager call shapes in the session tests (assertions unchanged), collapse the now-meaningless constructor-argument loop in the cookie attributes test, and drop the moot P1 Future Step from TODO.md. Reviewer-directed test call-site updates; cookie behavior is unchanged from the previous commit (always Secure/HttpOnly/SameSite=Strict).
This commit is contained in:
@@ -8,85 +8,75 @@ import (
|
||||
|
||||
// TestSessionCookieAttributesAlwaysSecure verifies that every cookie
|
||||
// emitted by the session manager carries HttpOnly, Secure, and a
|
||||
// SameSite mode of Lax or stricter, regardless of how the manager was
|
||||
// constructed. Session cookies contain the authentication state and
|
||||
// must never be exposed to script (HttpOnly), sent over plaintext HTTP
|
||||
// (Secure), or attached to cross-site requests (SameSite). No
|
||||
// constructor argument may weaken these attributes.
|
||||
// SameSite mode of Lax or stricter. Session cookies contain the
|
||||
// authentication state and must never be exposed to script (HttpOnly),
|
||||
// sent over plaintext HTTP (Secure), or attached to cross-site
|
||||
// requests (SameSite). Nothing may weaken these attributes.
|
||||
//
|
||||
// This covers both cookie-writing paths: CreateSession (the login
|
||||
// set-cookie path) and ClearSession (the logout delete-cookie path).
|
||||
func TestSessionCookieAttributesAlwaysSecure(t *testing.T) {
|
||||
for _, constructorBoolArg := range []bool{false, true} {
|
||||
mgr, err := NewManager("test-signing-key-12345", constructorBoolArg)
|
||||
if err != nil {
|
||||
t.Fatalf("NewManager() error = %v", err)
|
||||
}
|
||||
mgr, err := NewManager("test-signing-key-12345")
|
||||
if err != nil {
|
||||
t.Fatalf("NewManager() error = %v", err)
|
||||
}
|
||||
|
||||
writePaths := []struct {
|
||||
name string
|
||||
setCookie func(t *testing.T, w http.ResponseWriter)
|
||||
}{
|
||||
{
|
||||
name: "CreateSession",
|
||||
setCookie: func(t *testing.T, w http.ResponseWriter) {
|
||||
t.Helper()
|
||||
if err := mgr.CreateSession(w); err != nil {
|
||||
t.Fatalf("CreateSession() error = %v", err)
|
||||
}
|
||||
},
|
||||
writePaths := []struct {
|
||||
name string
|
||||
setCookie func(t *testing.T, w http.ResponseWriter)
|
||||
}{
|
||||
{
|
||||
name: "CreateSession",
|
||||
setCookie: func(t *testing.T, w http.ResponseWriter) {
|
||||
t.Helper()
|
||||
if err := mgr.CreateSession(w); err != nil {
|
||||
t.Fatalf("CreateSession() error = %v", err)
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "ClearSession",
|
||||
setCookie: func(t *testing.T, w http.ResponseWriter) {
|
||||
t.Helper()
|
||||
mgr.ClearSession(w)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ClearSession",
|
||||
setCookie: func(t *testing.T, w http.ResponseWriter) {
|
||||
t.Helper()
|
||||
mgr.ClearSession(w)
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
for _, writePath := range writePaths {
|
||||
testName := writePath.name
|
||||
if constructorBoolArg {
|
||||
testName += "/constructorBoolArg=true"
|
||||
} else {
|
||||
testName += "/constructorBoolArg=false"
|
||||
for _, writePath := range writePaths {
|
||||
t.Run(writePath.name, func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
writePath.setCookie(t, w)
|
||||
|
||||
var sessionCookie *http.Cookie
|
||||
for _, c := range w.Result().Cookies() {
|
||||
if c.Name == CookieName {
|
||||
sessionCookie = c
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
t.Run(testName, func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
writePath.setCookie(t, w)
|
||||
if sessionCookie == nil {
|
||||
t.Fatalf("no cookie named %q was set", CookieName)
|
||||
}
|
||||
|
||||
var sessionCookie *http.Cookie
|
||||
for _, c := range w.Result().Cookies() {
|
||||
if c.Name == CookieName {
|
||||
sessionCookie = c
|
||||
t.Logf("cookie attributes: HttpOnly=%v Secure=%v SameSite=%v",
|
||||
sessionCookie.HttpOnly, sessionCookie.Secure, sessionCookie.SameSite)
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
if !sessionCookie.HttpOnly {
|
||||
t.Error("session cookie must have HttpOnly set")
|
||||
}
|
||||
|
||||
if sessionCookie == nil {
|
||||
t.Fatalf("no cookie named %q was set", CookieName)
|
||||
}
|
||||
if !sessionCookie.Secure {
|
||||
t.Error("session cookie must have Secure set")
|
||||
}
|
||||
|
||||
t.Logf("cookie attributes: HttpOnly=%v Secure=%v SameSite=%v",
|
||||
sessionCookie.HttpOnly, sessionCookie.Secure, sessionCookie.SameSite)
|
||||
|
||||
if !sessionCookie.HttpOnly {
|
||||
t.Error("session cookie must have HttpOnly set")
|
||||
}
|
||||
|
||||
if !sessionCookie.Secure {
|
||||
t.Error("session cookie must have Secure set")
|
||||
}
|
||||
|
||||
if sessionCookie.SameSite != http.SameSiteLaxMode &&
|
||||
sessionCookie.SameSite != http.SameSiteStrictMode {
|
||||
t.Errorf("session cookie SameSite = %v, want Lax (%v) or Strict (%v)",
|
||||
sessionCookie.SameSite, http.SameSiteLaxMode, http.SameSiteStrictMode)
|
||||
}
|
||||
})
|
||||
}
|
||||
if sessionCookie.SameSite != http.SameSiteLaxMode &&
|
||||
sessionCookie.SameSite != http.SameSiteStrictMode {
|
||||
t.Errorf("session cookie SameSite = %v, want Lax (%v) or Strict (%v)",
|
||||
sessionCookie.SameSite, http.SameSiteLaxMode, http.SameSiteStrictMode)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user