Ignore the trailing slashes when comparing oauth2 redirect_uri (#26597) (#26618)

Backport #26597 by @wxiaoguang

Fix #26526

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit 4aed0e6b074b538ba71ba0560a416f282b3cc30b)
This commit is contained in:
Giteabot 2023-08-21 14:19:43 +08:00 committed by Earl Warren
parent ec4b6d7d04
commit 2f6d011503
No known key found for this signature in database
GPG key ID: 0579CB2928A78A00
2 changed files with 23 additions and 2 deletions

View file

@ -53,6 +53,15 @@ func (app *OAuth2Application) TableName() string {
// ContainsRedirectURI checks if redirectURI is allowed for app // ContainsRedirectURI checks if redirectURI is allowed for app
func (app *OAuth2Application) ContainsRedirectURI(redirectURI string) bool { func (app *OAuth2Application) ContainsRedirectURI(redirectURI string) bool {
contains := func(s string) bool {
s = strings.TrimSuffix(strings.ToLower(s), "/")
for _, u := range app.RedirectURIs {
if strings.TrimSuffix(strings.ToLower(u), "/") == s {
return true
}
}
return false
}
if !app.ConfidentialClient { if !app.ConfidentialClient {
uri, err := url.Parse(redirectURI) uri, err := url.Parse(redirectURI)
// ignore port for http loopback uris following https://datatracker.ietf.org/doc/html/rfc8252#section-7.3 // ignore port for http loopback uris following https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
@ -61,13 +70,13 @@ func (app *OAuth2Application) ContainsRedirectURI(redirectURI string) bool {
if ip != nil && ip.IsLoopback() { if ip != nil && ip.IsLoopback() {
// strip port // strip port
uri.Host = uri.Hostname() uri.Host = uri.Hostname()
if util.SliceContainsString(app.RedirectURIs, uri.String(), true) { if contains(uri.String()) {
return true return true
} }
} }
} }
} }
return util.SliceContainsString(app.RedirectURIs, redirectURI, true) return contains(redirectURI)
} }
// Base32 characters, but lowercased. // Base32 characters, but lowercased.

View file

@ -63,6 +63,18 @@ func TestOAuth2Application_ContainsRedirectURI_WithPort(t *testing.T) {
assert.False(t, app.ContainsRedirectURI(":")) assert.False(t, app.ContainsRedirectURI(":"))
} }
func TestOAuth2Application_ContainsRedirect_Slash(t *testing.T) {
app := &auth_model.OAuth2Application{RedirectURIs: []string{"http://127.0.0.1"}}
assert.True(t, app.ContainsRedirectURI("http://127.0.0.1"))
assert.True(t, app.ContainsRedirectURI("http://127.0.0.1/"))
assert.False(t, app.ContainsRedirectURI("http://127.0.0.1/other"))
app = &auth_model.OAuth2Application{RedirectURIs: []string{"http://127.0.0.1/"}}
assert.True(t, app.ContainsRedirectURI("http://127.0.0.1"))
assert.True(t, app.ContainsRedirectURI("http://127.0.0.1/"))
assert.False(t, app.ContainsRedirectURI("http://127.0.0.1/other"))
}
func TestOAuth2Application_ValidateClientSecret(t *testing.T) { func TestOAuth2Application_ValidateClientSecret(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1}) app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1})