Files
wonderwall/pkg/openid/client/logout.go
2026-01-16 09:18:30 +01:00

73 lines
1.7 KiB
Go

package client
import (
"encoding/json"
"fmt"
"net/http"
"github.com/nais/wonderwall/internal/crypto"
"github.com/nais/wonderwall/pkg/cookie"
"github.com/nais/wonderwall/pkg/openid"
urlpkg "github.com/nais/wonderwall/pkg/url"
)
type Logout struct {
*Client
Cookie *openid.LogoutCookie
LogoutHint string
callbackURL string
}
func NewLogout(c *Client, r *http.Request) (*Logout, error) {
callbackURL, err := urlpkg.LogoutCallback(r)
if err != nil {
return nil, fmt.Errorf("generating logout callback url: %w", err)
}
state, err := crypto.Text(32)
if err != nil {
return nil, fmt.Errorf("generating state: %w", err)
}
logoutCookie := &openid.LogoutCookie{
State: state,
}
return &Logout{
Client: c,
Cookie: logoutCookie,
LogoutHint: r.URL.Query().Get("logout_hint"),
callbackURL: callbackURL,
}, nil
}
func (in *Logout) SingleLogoutURL(idToken string) string {
endSessionEndpoint := in.cfg.Provider().EndSessionEndpointURL()
v := endSessionEndpoint.Query()
v.Set("post_logout_redirect_uri", in.callbackURL)
v.Set("state", in.Cookie.State)
if len(idToken) > 0 {
v.Set("id_token_hint", idToken)
}
if len(in.LogoutHint) > 0 {
v.Set("logout_hint", in.LogoutHint)
}
endSessionEndpoint.RawQuery = v.Encode()
return endSessionEndpoint.String()
}
func (in *Logout) SetCookie(w http.ResponseWriter, opts cookie.Options, crypter crypto.Crypter, canonicalRedirect string) error {
in.Cookie.RedirectTo = canonicalRedirect
logoutCookieJson, err := json.Marshal(in.Cookie)
if err != nil {
return fmt.Errorf("marshalling logout cookie: %w", err)
}
value := string(logoutCookieJson)
return cookie.EncryptAndSet(w, cookie.Logout, value, opts, crypter)
}