Skip to content

Commit ef44573

Browse files
[PLT-3581] Preserve existing query params in GetSignOutURL
url.Values{} was overwriting SignOutURL's query string entirely, dropping params like ?appId=5784 when adding the rd redirect. Use redirect.Query() to merge instead. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent d8f36d4 commit ef44573

2 files changed

Lines changed: 37 additions & 2 deletions

File tree

providers/sis.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,8 @@ func (p *SISProvider) GetSignOutURL(redirectURI string) string {
274274
// copy URL
275275
redirect := *p.SignOutURL
276276
if redirectURI != "" {
277-
v := url.Values{}
278-
v.Add("rd", redirectURI)
277+
v := redirect.Query()
278+
v.Set("rd", redirectURI)
279279
redirect.RawQuery = v.Encode()
280280
}
281281
return redirect.String()

providers/sis_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,41 @@ func TestSISProviderOverrides(t *testing.T) {
6161
assert.Equal(t, "profile", p.Data().Scope)
6262
}
6363

64+
func TestSISProviderGetSignOutURL(t *testing.T) {
65+
tests := []struct {
66+
name string
67+
signOutURL string
68+
redirectURI string
69+
expected string
70+
}{
71+
{
72+
name: "no redirect preserves sign-out URL as-is",
73+
signOutURL: "https://sis.example.com/sso/logout",
74+
redirectURI: "",
75+
expected: "https://sis.example.com/sso/logout",
76+
},
77+
{
78+
name: "redirect appended as rd param",
79+
signOutURL: "https://sis.example.com/sso/logout",
80+
redirectURI: "https://app.example.com/home",
81+
expected: "https://sis.example.com/sso/logout?rd=https%3A%2F%2Fapp.example.com%2Fhome",
82+
},
83+
{
84+
name: "existing query params preserved when adding rd",
85+
signOutURL: "https://autentica.example.com/logout?appId=5784",
86+
redirectURI: "https://app.example.com/home",
87+
expected: "https://autentica.example.com/logout?appId=5784&rd=https%3A%2F%2Fapp.example.com%2Fhome",
88+
},
89+
}
90+
for _, tt := range tests {
91+
t.Run(tt.name, func(t *testing.T) {
92+
u, _ := url.Parse(tt.signOutURL)
93+
p := NewSISProvider(&ProviderData{SignOutURL: u}, options.SISOptions{})
94+
assert.Equal(t, tt.expected, p.GetSignOutURL(tt.redirectURI))
95+
})
96+
}
97+
}
98+
6499
func TestSISProviderRedeem(t *testing.T) {
65100
b := testSISBackend(map[string]string{
66101
"/sso/oauth2.0/accessToken": "access_token=imaginary_access_token&expires=10000",

0 commit comments

Comments
 (0)