diff --git a/models/auth/oauth2.go b/models/auth/oauth2.go index 1b6d68879a..9c419eff69 100644 --- a/models/auth/oauth2.go +++ b/models/auth/oauth2.go @@ -132,6 +132,15 @@ func (app *OAuth2Application) TableName() string { // ContainsRedirectURI checks if redirectURI is allowed for app 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 { uri, err := url.Parse(redirectURI) // ignore port for http loopback uris following https://datatracker.ietf.org/doc/html/rfc8252#section-7.3 @@ -140,13 +149,13 @@ func (app *OAuth2Application) ContainsRedirectURI(redirectURI string) bool { if ip != nil && ip.IsLoopback() { // strip port uri.Host = uri.Hostname() - if util.SliceContainsString(app.RedirectURIs, uri.String(), true) { + if contains(uri.String()) { return true } } } } - return util.SliceContainsString(app.RedirectURIs, redirectURI, true) + return contains(redirectURI) } // Base32 characters, but lowercased. diff --git a/models/auth/oauth2_test.go b/models/auth/oauth2_test.go index 80d0e9baa4..b8f0bc12c6 100644 --- a/models/auth/oauth2_test.go +++ b/models/auth/oauth2_test.go @@ -63,6 +63,18 @@ func TestOAuth2Application_ContainsRedirectURI_WithPort(t *testing.T) { 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) { assert.NoError(t, unittest.PrepareTestDatabase()) app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1})