mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-08 14:34:49 +09:00
Support for Custom URI Schemes in OAuth2 Redirect URIs (#37356)
Fix #34349 By the way, remove `(ctx *APIContext) HasAPIError() ` and `(ctx *APIContext) GetErrMsg()` because they do nothing, the error handling has been done in API's middeware The existing OAuth2 tests were not quite right, refactored them together
This commit is contained in:
@@ -7,9 +7,13 @@ package forms
|
||||
import (
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/validation"
|
||||
"code.gitea.io/gitea/modules/web/middleware"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
|
||||
@@ -356,14 +360,29 @@ func (f *NewAccessTokenForm) Validate(req *http.Request, errs binding.Errors) bi
|
||||
// EditOAuth2ApplicationForm form for editing oauth2 applications
|
||||
type EditOAuth2ApplicationForm struct {
|
||||
Name string `binding:"Required;MaxSize(255)" form:"application_name"`
|
||||
RedirectURIs string `binding:"Required;ValidUrlList" form:"redirect_uris"`
|
||||
RedirectURIs string `binding:"Required" form:"redirect_uris"`
|
||||
ConfidentialClient bool `form:"confidential_client"`
|
||||
SkipSecondaryAuthorization bool `form:"skip_secondary_authorization"`
|
||||
}
|
||||
|
||||
func DetectInvalidOAuth2ApplicationRedirectURI(uris []string) (invalidURL string) {
|
||||
for _, u := range uris {
|
||||
scheme, _, ok := strings.Cut(u, ":")
|
||||
valid := ok && (validation.IsValidURL(u) || util.SliceContainsString(setting.OAuth2.CustomSchemes, scheme))
|
||||
if !valid {
|
||||
return u
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *EditOAuth2ApplicationForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
invalidURI := DetectInvalidOAuth2ApplicationRedirectURI(util.SplitTrimSpace(f.RedirectURIs, "\n"))
|
||||
if invalidURI != "" {
|
||||
errs = middleware.ReportValidationError(errs, ctx.Data, "RedirectURIs", binding.ERR_URL, ctx.Locale.TrString("form.url_error", invalidURI))
|
||||
}
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
|
||||
@@ -14,15 +14,9 @@ import (
|
||||
)
|
||||
|
||||
func TestRegisterForm_IsDomainAllowed_Empty(t *testing.T) {
|
||||
oldService := setting.Service
|
||||
defer func() {
|
||||
setting.Service = oldService
|
||||
}()
|
||||
|
||||
defer test.MockVariableValue(&setting.Service)()
|
||||
setting.Service.EmailDomainAllowList = nil
|
||||
|
||||
form := RegisterForm{}
|
||||
|
||||
assert.True(t, form.IsEmailDomainAllowed())
|
||||
}
|
||||
|
||||
@@ -87,3 +81,30 @@ func TestRegisterForm_IsDomainAllowed_BlockedEmail(t *testing.T) {
|
||||
assert.Equal(t, v.valid, form.IsEmailDomainAllowed())
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectInvalidOAuth2ApplicationRedirectURI(t *testing.T) {
|
||||
defer test.MockVariableValue(&setting.OAuth2.CustomSchemes)()
|
||||
setting.OAuth2.CustomSchemes = []string{"my-app"}
|
||||
assertValid := func(t *testing.T, s string, valid bool) {
|
||||
ret := DetectInvalidOAuth2ApplicationRedirectURI([]string{s})
|
||||
if valid {
|
||||
assert.Empty(t, ret)
|
||||
} else {
|
||||
assert.Equal(t, s, ret)
|
||||
}
|
||||
}
|
||||
assertValid(t, "my-app:", true)
|
||||
assertValid(t, "my-app:/foo", true)
|
||||
assertValid(t, "http://foo", true)
|
||||
assertValid(t, "https://foo", true)
|
||||
|
||||
assertValid(t, "my-app", false)
|
||||
assertValid(t, "ftp:", false)
|
||||
assertValid(t, "ftp://foo", false)
|
||||
assertValid(t, "https://[invalid", false)
|
||||
|
||||
ret := DetectInvalidOAuth2ApplicationRedirectURI([]string{"my-app:", "http://foo", "https://foo"})
|
||||
assert.Empty(t, ret)
|
||||
ret = DetectInvalidOAuth2ApplicationRedirectURI([]string{"my-app:", "http://foo", "invalid", "https://foo"})
|
||||
assert.Equal(t, "invalid", ret)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user