From 9c5bb2b23760c8300060c80a68fe9c880b6e4c36 Mon Sep 17 00:00:00 2001 From: ayb Date: Fri, 19 Feb 2021 16:54:29 +0100 Subject: [PATCH 1/2] Added support for gopher URLs. --- modules/validation/helpers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/validation/helpers.go b/modules/validation/helpers.go index c22e667a2ebf9..877b5e5e66771 100644 --- a/modules/validation/helpers.go +++ b/modules/validation/helpers.go @@ -44,7 +44,7 @@ func isLoopbackIP(ip string) bool { // IsValidURL checks if URL is valid func IsValidURL(uri string) bool { if u, err := url.ParseRequestURI(uri); err != nil || - (u.Scheme != "http" && u.Scheme != "https") || + (u.Scheme != "http" && u.Scheme != "https" && u.Scheme != "gopher") || !validPort(portOnly(u.Host)) { return false } From 79c765d863569380f6429cb7c2c96a54fe56790e Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Wed, 23 Jun 2021 21:50:47 +0100 Subject: [PATCH 2/2] Add setting and make this user settable instead Signed-off-by: Andrew Thornton --- custom/conf/app.example.ini | 2 ++ .../doc/advanced/config-cheat-sheet.en-us.md | 1 + modules/setting/service.go | 12 +++++++++++ modules/validation/binding.go | 19 +++++++++++++++++ modules/validation/helpers.go | 21 ++++++++++++++++++- services/forms/user_form.go | 2 +- 6 files changed, 55 insertions(+), 2 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 38a27509f7441..6e2e27c4eb53b 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -705,6 +705,8 @@ PATH = ;; ;; Minimum amount of time a user must exist before comments are kept when the user is deleted. ;USER_DELETE_WITH_COMMENTS_MAX_TIME = 0 +;; Valid site url schemes for user profiles +;VALID_SITE_URL_SCHEMES=http,https ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index a33407d15a73d..a2b0347df6b2d 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -519,6 +519,7 @@ relation to port exhaustion. - `NO_REPLY_ADDRESS`: **noreply.DOMAIN** Value for the domain part of the user's email address in the git log if user has set KeepEmailPrivate to true. DOMAIN resolves to the value in server.DOMAIN. The user's email will be replaced with a concatenation of the user name in lower case, "@" and NO_REPLY_ADDRESS. - `USER_DELETE_WITH_COMMENTS_MAX_TIME`: **0** Minimum amount of time a user must exist before comments are kept when the user is deleted. +- `VALID_SITE_URL_SCHEMES`: **http, https**: Valid site url schemes for user profiles ### Service - Expore (`service.explore`) diff --git a/modules/setting/service.go b/modules/setting/service.go index 41e834e8e61ef..bd70c7e6ebe5b 100644 --- a/modules/setting/service.go +++ b/modules/setting/service.go @@ -6,6 +6,7 @@ package setting import ( "regexp" + "strings" "time" "code.gitea.io/gitea/modules/log" @@ -55,6 +56,7 @@ var Service struct { AutoWatchOnChanges bool DefaultOrgMemberVisible bool UserDeleteWithCommentsMaxTime time.Duration + ValidSiteURLSchemes []string // OpenID settings EnableOpenIDSignIn bool @@ -120,6 +122,16 @@ func newService() { Service.DefaultOrgVisibilityMode = structs.VisibilityModes[Service.DefaultOrgVisibility] Service.DefaultOrgMemberVisible = sec.Key("DEFAULT_ORG_MEMBER_VISIBLE").MustBool() Service.UserDeleteWithCommentsMaxTime = sec.Key("USER_DELETE_WITH_COMMENTS_MAX_TIME").MustDuration(0) + sec.Key("VALID_SITE_URL_SCHEMES").MustString("http,https") + Service.ValidSiteURLSchemes = sec.Key("VALID_SITE_URL_SCHEMES").Strings(",") + schemes := make([]string, len(Service.ValidSiteURLSchemes)) + for _, scheme := range Service.ValidSiteURLSchemes { + scheme = strings.ToLower(strings.TrimSpace(scheme)) + if scheme != "" { + schemes = append(schemes, scheme) + } + } + Service.ValidSiteURLSchemes = schemes if err := Cfg.Section("service.explore").MapTo(&Service.Explore); err != nil { log.Fatal("Failed to map service.explore settings: %v", err) diff --git a/modules/validation/binding.go b/modules/validation/binding.go index 5cfd994d2daeb..b5e3e3c139471 100644 --- a/modules/validation/binding.go +++ b/modules/validation/binding.go @@ -52,6 +52,7 @@ func CheckGitRefAdditionalRulesValid(name string) bool { func AddBindingRules() { addGitRefNameBindingRule() addValidURLBindingRule() + addValidSiteURLBindingRule() addGlobPatternRule() } @@ -97,6 +98,24 @@ func addValidURLBindingRule() { }) } +func addValidSiteURLBindingRule() { + // URL validation rule + binding.AddRule(&binding.Rule{ + IsMatch: func(rule string) bool { + return strings.HasPrefix(rule, "ValidSiteUrl") + }, + IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) { + str := fmt.Sprintf("%v", val) + if len(str) != 0 && !IsValidSiteURL(str) { + errs.Add([]string{name}, binding.ERR_URL, "Url") + return false, errs + } + + return true, errs + }, + }) +} + func addGlobPatternRule() { binding.AddRule(&binding.Rule{ IsMatch: func(rule string) bool { diff --git a/modules/validation/helpers.go b/modules/validation/helpers.go index 877b5e5e66771..343261aac5b59 100644 --- a/modules/validation/helpers.go +++ b/modules/validation/helpers.go @@ -44,7 +44,7 @@ func isLoopbackIP(ip string) bool { // IsValidURL checks if URL is valid func IsValidURL(uri string) bool { if u, err := url.ParseRequestURI(uri); err != nil || - (u.Scheme != "http" && u.Scheme != "https" && u.Scheme != "gopher") || + (u.Scheme != "http" && u.Scheme != "https") || !validPort(portOnly(u.Host)) { return false } @@ -52,6 +52,25 @@ func IsValidURL(uri string) bool { return true } +// IsValidSiteURL checks if URL is valid +func IsValidSiteURL(uri string) bool { + u, err := url.ParseRequestURI(uri) + if err != nil { + return false + } + + if !validPort(portOnly(u.Host)) { + return false + } + + for _, scheme := range setting.Service.ValidSiteURLSchemes { + if scheme == u.Scheme { + return true + } + } + return false +} + // IsAPIURL checks if URL is current Gitea instance API URL func IsAPIURL(uri string) bool { return strings.HasPrefix(strings.ToLower(uri), strings.ToLower(setting.AppURL+"api")) diff --git a/services/forms/user_form.go b/services/forms/user_form.go index 2c065dc5116a8..903a625da01e8 100644 --- a/services/forms/user_form.go +++ b/services/forms/user_form.go @@ -226,7 +226,7 @@ type UpdateProfileForm struct { Name string `binding:"AlphaDashDot;MaxSize(40)"` FullName string `binding:"MaxSize(100)"` KeepEmailPrivate bool - Website string `binding:"ValidUrl;MaxSize(255)"` + Website string `binding:"ValidSiteUrl;MaxSize(255)"` Location string `binding:"MaxSize(50)"` Language string Description string `binding:"MaxSize(255)"`