Files
sessiongurad/internal/auth/oidc_pkce_logout_test.go
jbergner f369ea5f52
All checks were successful
release-tag / release-image (push) Successful in 2m1s
release-main / release-images (push) Successful in 4m14s
Major Bugfix
2026-08-24 22:19:20 +02:00

86 lines
2.4 KiB
Go

package auth
import (
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"time"
"github.com/example/sessionguard/internal/model"
"golang.org/x/oauth2"
)
func TestManagerLoginUsesPKCES256(t *testing.T) {
m := &Manager{
cfg: model.OIDCConfig{SecureCookie: true},
oauth: oauth2.Config{
ClientID: "client-1",
RedirectURL: "https://director.example/oidc/callback",
Endpoint: oauth2.Endpoint{AuthURL: "https://login.example/authorize"},
},
pending: map[string]pending{},
logout: map[string]logoutSession{},
}
r := httptest.NewRequest("GET", "https://director.example/oidc/login", nil)
w := httptest.NewRecorder()
m.Login(w, r)
loc, err := url.Parse(w.Header().Get("Location"))
if err != nil {
t.Fatal(err)
}
if got := loc.Query().Get("code_challenge_method"); got != "S256" {
t.Fatalf("code_challenge_method=%q, want S256", got)
}
if got := loc.Query().Get("code_challenge"); got == "" {
t.Fatal("missing code_challenge")
}
state := loc.Query().Get("state")
m.mu.Lock()
p, ok := m.pending[state]
m.mu.Unlock()
if !ok || p.CodeVerifier == "" {
t.Fatal("PKCE verifier was not retained for callback exchange")
}
}
func TestManagerLogoutUsesIDTokenHintAndRegisteredRedirect(t *testing.T) {
const session = "signed-session-cookie"
m := &Manager{
cfg: model.OIDCConfig{
ClientID: "director-client",
LogoutRedirectURL: "https://director.example/",
SecureCookie: true,
},
endSession: "https://login.example/api/oidc/end-session",
pending: map[string]pending{},
logout: map[string]logoutSession{
session: logoutSession{IDToken: "header.payload.signature", Exp: time.Now().Add(time.Hour)},
},
}
r := httptest.NewRequest("GET", "https://director.example/logout", nil)
r.AddCookie(&http.Cookie{Name: "sg_session", Value: session})
w := httptest.NewRecorder()
m.Logout(w, r)
loc, err := url.Parse(w.Header().Get("Location"))
if err != nil {
t.Fatal(err)
}
q := loc.Query()
if q.Get("client_id") != "director-client" {
t.Fatalf("client_id=%q", q.Get("client_id"))
}
if q.Get("id_token_hint") != "header.payload.signature" {
t.Fatalf("id_token_hint=%q", q.Get("id_token_hint"))
}
if q.Get("post_logout_redirect_uri") != "https://director.example/" {
t.Fatalf("post_logout_redirect_uri=%q", q.Get("post_logout_redirect_uri"))
}
if !strings.Contains(w.Header().Get("Set-Cookie"), "sg_session=") {
t.Fatal("local session cookie was not cleared")
}
}