mirror of
https://github.com/nais/wonderwall.git
synced 2026-02-14 09:39:52 +00:00
feat(openid): support logout_hint for RP-initiated logouts
This commit is contained in:
@@ -13,12 +13,14 @@ import (
|
||||
|
||||
type Logout struct {
|
||||
*Client
|
||||
Cookie *openid.LogoutCookie
|
||||
logoutCallbackURL string
|
||||
Cookie *openid.LogoutCookie
|
||||
LogoutHint string
|
||||
|
||||
callbackURL string
|
||||
}
|
||||
|
||||
func NewLogout(c *Client, r *http.Request) (*Logout, error) {
|
||||
logoutCallbackURL, err := urlpkg.LogoutCallback(r)
|
||||
callbackURL, err := urlpkg.LogoutCallback(r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("generating logout callback url: %w", err)
|
||||
}
|
||||
@@ -33,21 +35,25 @@ func NewLogout(c *Client, r *http.Request) (*Logout, error) {
|
||||
}
|
||||
|
||||
return &Logout{
|
||||
Client: c,
|
||||
Cookie: logoutCookie,
|
||||
logoutCallbackURL: logoutCallbackURL,
|
||||
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.logoutCallbackURL)
|
||||
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()
|
||||
|
||||
@@ -70,6 +70,37 @@ func TestLogout_SingleLogoutURL(t *testing.T) {
|
||||
logoutUrl.RawQuery = ""
|
||||
assert.Equal(t, EndSessionEndpoint, logoutUrl.String())
|
||||
})
|
||||
|
||||
t.Run("with logout_hint claim", func(t *testing.T) {
|
||||
logout := newLogout(t)
|
||||
logout.LogoutHint = "some-logout-hint"
|
||||
idToken := ""
|
||||
state := logout.Cookie.State
|
||||
|
||||
raw := logout.SingleLogoutURL(idToken)
|
||||
assert.NotEmpty(t, raw)
|
||||
|
||||
logoutUrl, err := url.Parse(raw)
|
||||
assert.NoError(t, err)
|
||||
|
||||
query := logoutUrl.Query()
|
||||
assert.Len(t, query, 3)
|
||||
|
||||
assert.Contains(t, query, "logout_hint")
|
||||
assert.Equal(t, logout.LogoutHint, query.Get("logout_hint"))
|
||||
|
||||
assert.NotContains(t, query, "id_token_hint")
|
||||
assert.Equal(t, idToken, query.Get("id_token_hint"))
|
||||
|
||||
assert.Contains(t, query, "post_logout_redirect_uri")
|
||||
assert.Equal(t, LogoutCallbackURI, query.Get("post_logout_redirect_uri"))
|
||||
|
||||
assert.Contains(t, query, "state")
|
||||
assert.Equal(t, state, query.Get("state"))
|
||||
|
||||
logoutUrl.RawQuery = ""
|
||||
assert.Equal(t, EndSessionEndpoint, logoutUrl.String())
|
||||
})
|
||||
}
|
||||
|
||||
func newLogout(t *testing.T) *client.Logout {
|
||||
|
||||
Reference in New Issue
Block a user