Added support for gopher URLs. (#14749)

* Added support for gopher URLs.

* Add setting and make this user settable instead

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
ayb 2021-06-26 00:38:27 +02:00 committed by GitHub
parent 1a1ce9b721
commit 9b33d18899
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 54 additions and 1 deletions

View file

@ -705,6 +705,8 @@ PATH =
;; ;;
;; Minimum amount of time a user must exist before comments are kept when the user is deleted. ;; Minimum amount of time a user must exist before comments are kept when the user is deleted.
;USER_DELETE_WITH_COMMENTS_MAX_TIME = 0 ;USER_DELETE_WITH_COMMENTS_MAX_TIME = 0
;; Valid site url schemes for user profiles
;VALID_SITE_URL_SCHEMES=http,https
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View file

@ -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. - `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. 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. - `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`) ### Service - Expore (`service.explore`)

View file

@ -6,6 +6,7 @@ package setting
import ( import (
"regexp" "regexp"
"strings"
"time" "time"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
@ -55,6 +56,7 @@ var Service struct {
AutoWatchOnChanges bool AutoWatchOnChanges bool
DefaultOrgMemberVisible bool DefaultOrgMemberVisible bool
UserDeleteWithCommentsMaxTime time.Duration UserDeleteWithCommentsMaxTime time.Duration
ValidSiteURLSchemes []string
// OpenID settings // OpenID settings
EnableOpenIDSignIn bool EnableOpenIDSignIn bool
@ -120,6 +122,16 @@ func newService() {
Service.DefaultOrgVisibilityMode = structs.VisibilityModes[Service.DefaultOrgVisibility] Service.DefaultOrgVisibilityMode = structs.VisibilityModes[Service.DefaultOrgVisibility]
Service.DefaultOrgMemberVisible = sec.Key("DEFAULT_ORG_MEMBER_VISIBLE").MustBool() Service.DefaultOrgMemberVisible = sec.Key("DEFAULT_ORG_MEMBER_VISIBLE").MustBool()
Service.UserDeleteWithCommentsMaxTime = sec.Key("USER_DELETE_WITH_COMMENTS_MAX_TIME").MustDuration(0) 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 { if err := Cfg.Section("service.explore").MapTo(&Service.Explore); err != nil {
log.Fatal("Failed to map service.explore settings: %v", err) log.Fatal("Failed to map service.explore settings: %v", err)

View file

@ -55,6 +55,7 @@ func CheckGitRefAdditionalRulesValid(name string) bool {
func AddBindingRules() { func AddBindingRules() {
addGitRefNameBindingRule() addGitRefNameBindingRule()
addValidURLBindingRule() addValidURLBindingRule()
addValidSiteURLBindingRule()
addGlobPatternRule() addGlobPatternRule()
addRegexPatternRule() addRegexPatternRule()
addGlobOrRegexPatternRule() addGlobOrRegexPatternRule()
@ -102,6 +103,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() { func addGlobPatternRule() {
binding.AddRule(&binding.Rule{ binding.AddRule(&binding.Rule{
IsMatch: func(rule string) bool { IsMatch: func(rule string) bool {

View file

@ -52,6 +52,25 @@ func IsValidURL(uri string) bool {
return true 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 // IsAPIURL checks if URL is current Gitea instance API URL
func IsAPIURL(uri string) bool { func IsAPIURL(uri string) bool {
return strings.HasPrefix(strings.ToLower(uri), strings.ToLower(setting.AppURL+"api")) return strings.HasPrefix(strings.ToLower(uri), strings.ToLower(setting.AppURL+"api"))

View file

@ -226,7 +226,7 @@ type UpdateProfileForm struct {
Name string `binding:"AlphaDashDot;MaxSize(40)"` Name string `binding:"AlphaDashDot;MaxSize(40)"`
FullName string `binding:"MaxSize(100)"` FullName string `binding:"MaxSize(100)"`
KeepEmailPrivate bool KeepEmailPrivate bool
Website string `binding:"ValidUrl;MaxSize(255)"` Website string `binding:"ValidSiteUrl;MaxSize(255)"`
Location string `binding:"MaxSize(50)"` Location string `binding:"MaxSize(50)"`
Language string Language string
Description string `binding:"MaxSize(255)"` Description string `binding:"MaxSize(255)"`