mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-10-24 02:52:37 +00:00
Follow-up tod58c542579for Forgejo. By default, Gitea does not select any map service that can be used to introduce a 'Show this place on a map' button in the location field of a user profile. Before I tried upstreaming this change to Gitea, this was the case in Forgejo. This patch essentially recovers this functionality, which is nice for public-facing instances and communities. Links to original PRs: - https://codeberg.org/forgejo/forgejo/pulls/1076 - https://github.com/go-gitea/gitea/pull/26214 (cherry picked from commitbb187d5f61) (cherry picked from commitce02ef9078) (cherry picked from commit6b75c40e25) (cherry picked from commit6bc8e9f573) (cherry picked from commit063f8afdf7) (cherry picked from commitc5cc736b72) (cherry picked from commit7b1bb4bedc) (cherry picked from commit2a022dceb4) (cherry picked from commita946c142d2) (cherry picked from commit8a4ea0c7ab)
260 lines
12 KiB
Go
260 lines
12 KiB
Go
// Copyright 2019 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package setting
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
"time"
|
|
|
|
"code.gitea.io/gitea/modules/log"
|
|
"code.gitea.io/gitea/modules/structs"
|
|
|
|
"github.com/gobwas/glob"
|
|
)
|
|
|
|
// enumerates all the types of captchas
|
|
const (
|
|
ImageCaptcha = "image"
|
|
ReCaptcha = "recaptcha"
|
|
HCaptcha = "hcaptcha"
|
|
MCaptcha = "mcaptcha"
|
|
CfTurnstile = "cfturnstile"
|
|
)
|
|
|
|
// Service settings
|
|
var Service = struct {
|
|
DefaultUserVisibility string
|
|
DefaultUserVisibilityMode structs.VisibleType
|
|
AllowedUserVisibilityModes []string
|
|
AllowedUserVisibilityModesSlice AllowedVisibility `ini:"-"`
|
|
DefaultOrgVisibility string
|
|
DefaultOrgVisibilityMode structs.VisibleType
|
|
ActiveCodeLives int
|
|
ResetPwdCodeLives int
|
|
RegisterEmailConfirm bool
|
|
RegisterManualConfirm bool
|
|
EmailDomainAllowList []glob.Glob
|
|
EmailDomainBlockList []glob.Glob
|
|
DisableRegistration bool
|
|
AllowOnlyInternalRegistration bool
|
|
AllowOnlyExternalRegistration bool
|
|
ShowRegistrationButton bool
|
|
ShowMilestonesDashboardPage bool
|
|
RequireSignInView bool
|
|
EnableNotifyMail bool
|
|
EnableBasicAuth bool
|
|
EnableReverseProxyAuth bool
|
|
EnableReverseProxyAuthAPI bool
|
|
EnableReverseProxyAutoRegister bool
|
|
EnableReverseProxyEmail bool
|
|
EnableReverseProxyFullName bool
|
|
EnableCaptcha bool
|
|
RequireCaptchaForLogin bool
|
|
RequireExternalRegistrationCaptcha bool
|
|
RequireExternalRegistrationPassword bool
|
|
CaptchaType string
|
|
RecaptchaSecret string
|
|
RecaptchaSitekey string
|
|
RecaptchaURL string
|
|
CfTurnstileSecret string
|
|
CfTurnstileSitekey string
|
|
HcaptchaSecret string
|
|
HcaptchaSitekey string
|
|
McaptchaSecret string
|
|
McaptchaSitekey string
|
|
McaptchaURL string
|
|
DefaultKeepEmailPrivate bool
|
|
DefaultAllowCreateOrganization bool
|
|
DefaultUserIsRestricted bool
|
|
EnableTimetracking bool
|
|
DefaultEnableTimetracking bool
|
|
DefaultEnableDependencies bool
|
|
AllowCrossRepositoryDependencies bool
|
|
DefaultAllowOnlyContributorsToTrackTime bool
|
|
NoReplyAddress string
|
|
UserLocationMapURL string
|
|
EnableUserHeatmap bool
|
|
AutoWatchNewRepos bool
|
|
AutoWatchOnChanges bool
|
|
DefaultOrgMemberVisible bool
|
|
UserDeleteWithCommentsMaxTime time.Duration
|
|
ValidSiteURLSchemes []string
|
|
|
|
// OpenID settings
|
|
EnableOpenIDSignIn bool
|
|
EnableOpenIDSignUp bool
|
|
OpenIDWhitelist []*regexp.Regexp
|
|
OpenIDBlacklist []*regexp.Regexp
|
|
|
|
// Explore page settings
|
|
Explore struct {
|
|
RequireSigninView bool `ini:"REQUIRE_SIGNIN_VIEW"`
|
|
DisableUsersPage bool `ini:"DISABLE_USERS_PAGE"`
|
|
} `ini:"service.explore"`
|
|
}{
|
|
AllowedUserVisibilityModesSlice: []bool{true, true, true},
|
|
}
|
|
|
|
// AllowedVisibility store in a 3 item bool array what is allowed
|
|
type AllowedVisibility []bool
|
|
|
|
// IsAllowedVisibility check if a AllowedVisibility allow a specific VisibleType
|
|
func (a AllowedVisibility) IsAllowedVisibility(t structs.VisibleType) bool {
|
|
if int(t) >= len(a) {
|
|
return false
|
|
}
|
|
return a[t]
|
|
}
|
|
|
|
// ToVisibleTypeSlice convert a AllowedVisibility into a VisibleType slice
|
|
func (a AllowedVisibility) ToVisibleTypeSlice() (result []structs.VisibleType) {
|
|
for i, v := range a {
|
|
if v {
|
|
result = append(result, structs.VisibleType(i))
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func CompileEmailGlobList(sec ConfigSection, keys ...string) (globs []glob.Glob) {
|
|
for _, key := range keys {
|
|
list := sec.Key(key).Strings(",")
|
|
for _, s := range list {
|
|
if g, err := glob.Compile(s); err == nil {
|
|
globs = append(globs, g)
|
|
} else {
|
|
log.Error("Skip invalid email allow/block list expression %q: %v", s, err)
|
|
}
|
|
}
|
|
}
|
|
return globs
|
|
}
|
|
|
|
func loadServiceFrom(rootCfg ConfigProvider) {
|
|
sec := rootCfg.Section("service")
|
|
Service.ActiveCodeLives = sec.Key("ACTIVE_CODE_LIVE_MINUTES").MustInt(180)
|
|
Service.ResetPwdCodeLives = sec.Key("RESET_PASSWD_CODE_LIVE_MINUTES").MustInt(180)
|
|
Service.DisableRegistration = sec.Key("DISABLE_REGISTRATION").MustBool()
|
|
Service.AllowOnlyInternalRegistration = sec.Key("ALLOW_ONLY_INTERNAL_REGISTRATION").MustBool()
|
|
Service.AllowOnlyExternalRegistration = sec.Key("ALLOW_ONLY_EXTERNAL_REGISTRATION").MustBool()
|
|
if Service.AllowOnlyExternalRegistration && Service.AllowOnlyInternalRegistration {
|
|
log.Warn("ALLOW_ONLY_INTERNAL_REGISTRATION and ALLOW_ONLY_EXTERNAL_REGISTRATION are true - disabling registration")
|
|
Service.DisableRegistration = true
|
|
}
|
|
if !sec.Key("REGISTER_EMAIL_CONFIRM").MustBool() {
|
|
Service.RegisterManualConfirm = sec.Key("REGISTER_MANUAL_CONFIRM").MustBool(false)
|
|
} else {
|
|
Service.RegisterManualConfirm = false
|
|
}
|
|
if sec.HasKey("EMAIL_DOMAIN_WHITELIST") {
|
|
deprecatedSetting(rootCfg, "service", "EMAIL_DOMAIN_WHITELIST", "service", "EMAIL_DOMAIN_ALLOWLIST", "1.21")
|
|
}
|
|
Service.EmailDomainAllowList = CompileEmailGlobList(sec, "EMAIL_DOMAIN_WHITELIST", "EMAIL_DOMAIN_ALLOWLIST")
|
|
Service.EmailDomainBlockList = CompileEmailGlobList(sec, "EMAIL_DOMAIN_BLOCKLIST")
|
|
Service.ShowRegistrationButton = sec.Key("SHOW_REGISTRATION_BUTTON").MustBool(!(Service.DisableRegistration || Service.AllowOnlyExternalRegistration))
|
|
Service.ShowMilestonesDashboardPage = sec.Key("SHOW_MILESTONES_DASHBOARD_PAGE").MustBool(true)
|
|
Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool()
|
|
Service.EnableBasicAuth = sec.Key("ENABLE_BASIC_AUTHENTICATION").MustBool(true)
|
|
Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool()
|
|
Service.EnableReverseProxyAuthAPI = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION_API").MustBool()
|
|
Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool()
|
|
Service.EnableReverseProxyEmail = sec.Key("ENABLE_REVERSE_PROXY_EMAIL").MustBool()
|
|
Service.EnableReverseProxyFullName = sec.Key("ENABLE_REVERSE_PROXY_FULL_NAME").MustBool()
|
|
Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool(false)
|
|
Service.RequireCaptchaForLogin = sec.Key("REQUIRE_CAPTCHA_FOR_LOGIN").MustBool(false)
|
|
Service.RequireExternalRegistrationCaptcha = sec.Key("REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA").MustBool(Service.EnableCaptcha)
|
|
Service.RequireExternalRegistrationPassword = sec.Key("REQUIRE_EXTERNAL_REGISTRATION_PASSWORD").MustBool()
|
|
Service.CaptchaType = sec.Key("CAPTCHA_TYPE").MustString(ImageCaptcha)
|
|
Service.RecaptchaSecret = sec.Key("RECAPTCHA_SECRET").MustString("")
|
|
Service.RecaptchaSitekey = sec.Key("RECAPTCHA_SITEKEY").MustString("")
|
|
Service.RecaptchaURL = sec.Key("RECAPTCHA_URL").MustString("https://www.google.com/recaptcha/")
|
|
Service.CfTurnstileSecret = sec.Key("CF_TURNSTILE_SECRET").MustString("")
|
|
Service.CfTurnstileSitekey = sec.Key("CF_TURNSTILE_SITEKEY").MustString("")
|
|
Service.HcaptchaSecret = sec.Key("HCAPTCHA_SECRET").MustString("")
|
|
Service.HcaptchaSitekey = sec.Key("HCAPTCHA_SITEKEY").MustString("")
|
|
Service.McaptchaURL = sec.Key("MCAPTCHA_URL").MustString("https://demo.mcaptcha.org/")
|
|
Service.McaptchaSecret = sec.Key("MCAPTCHA_SECRET").MustString("")
|
|
Service.McaptchaSitekey = sec.Key("MCAPTCHA_SITEKEY").MustString("")
|
|
Service.DefaultKeepEmailPrivate = sec.Key("DEFAULT_KEEP_EMAIL_PRIVATE").MustBool()
|
|
Service.DefaultAllowCreateOrganization = sec.Key("DEFAULT_ALLOW_CREATE_ORGANIZATION").MustBool(true)
|
|
Service.DefaultUserIsRestricted = sec.Key("DEFAULT_USER_IS_RESTRICTED").MustBool(false)
|
|
Service.EnableTimetracking = sec.Key("ENABLE_TIMETRACKING").MustBool(true)
|
|
if Service.EnableTimetracking {
|
|
Service.DefaultEnableTimetracking = sec.Key("DEFAULT_ENABLE_TIMETRACKING").MustBool(true)
|
|
}
|
|
Service.DefaultEnableDependencies = sec.Key("DEFAULT_ENABLE_DEPENDENCIES").MustBool(true)
|
|
Service.AllowCrossRepositoryDependencies = sec.Key("ALLOW_CROSS_REPOSITORY_DEPENDENCIES").MustBool(true)
|
|
Service.DefaultAllowOnlyContributorsToTrackTime = sec.Key("DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME").MustBool(true)
|
|
Service.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply." + Domain)
|
|
Service.UserLocationMapURL = sec.Key("USER_LOCATION_MAP_URL").MustString("https://www.openstreetmap.org/search?query=")
|
|
Service.EnableUserHeatmap = sec.Key("ENABLE_USER_HEATMAP").MustBool(true)
|
|
Service.AutoWatchNewRepos = sec.Key("AUTO_WATCH_NEW_REPOS").MustBool(true)
|
|
Service.AutoWatchOnChanges = sec.Key("AUTO_WATCH_ON_CHANGES").MustBool(false)
|
|
modes := sec.Key("ALLOWED_USER_VISIBILITY_MODES").Strings(",")
|
|
if len(modes) != 0 {
|
|
Service.AllowedUserVisibilityModes = []string{}
|
|
Service.AllowedUserVisibilityModesSlice = []bool{false, false, false}
|
|
for _, sMode := range modes {
|
|
if tp, ok := structs.VisibilityModes[sMode]; ok { // remove unsupported modes
|
|
Service.AllowedUserVisibilityModes = append(Service.AllowedUserVisibilityModes, sMode)
|
|
Service.AllowedUserVisibilityModesSlice[tp] = true
|
|
} else {
|
|
log.Warn("ALLOWED_USER_VISIBILITY_MODES %s is unsupported", sMode)
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(Service.AllowedUserVisibilityModes) == 0 {
|
|
Service.AllowedUserVisibilityModes = []string{"public", "limited", "private"}
|
|
Service.AllowedUserVisibilityModesSlice = []bool{true, true, true}
|
|
}
|
|
|
|
Service.DefaultUserVisibility = sec.Key("DEFAULT_USER_VISIBILITY").String()
|
|
if Service.DefaultUserVisibility == "" {
|
|
Service.DefaultUserVisibility = Service.AllowedUserVisibilityModes[0]
|
|
} else if !Service.AllowedUserVisibilityModesSlice[structs.VisibilityModes[Service.DefaultUserVisibility]] {
|
|
log.Warn("DEFAULT_USER_VISIBILITY %s is wrong or not in ALLOWED_USER_VISIBILITY_MODES, using first allowed", Service.DefaultUserVisibility)
|
|
Service.DefaultUserVisibility = Service.AllowedUserVisibilityModes[0]
|
|
}
|
|
Service.DefaultUserVisibilityMode = structs.VisibilityModes[Service.DefaultUserVisibility]
|
|
Service.DefaultOrgVisibility = sec.Key("DEFAULT_ORG_VISIBILITY").In("public", structs.ExtractKeysFromMapString(structs.VisibilityModes))
|
|
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, 0, len(Service.ValidSiteURLSchemes))
|
|
for _, scheme := range Service.ValidSiteURLSchemes {
|
|
scheme = strings.ToLower(strings.TrimSpace(scheme))
|
|
if scheme != "" {
|
|
schemes = append(schemes, scheme)
|
|
}
|
|
}
|
|
Service.ValidSiteURLSchemes = schemes
|
|
|
|
mustMapSetting(rootCfg, "service.explore", &Service.Explore)
|
|
|
|
loadOpenIDSetting(rootCfg)
|
|
}
|
|
|
|
func loadOpenIDSetting(rootCfg ConfigProvider) {
|
|
sec := rootCfg.Section("openid")
|
|
Service.EnableOpenIDSignIn = sec.Key("ENABLE_OPENID_SIGNIN").MustBool(!InstallLock)
|
|
Service.EnableOpenIDSignUp = sec.Key("ENABLE_OPENID_SIGNUP").MustBool(!Service.DisableRegistration && Service.EnableOpenIDSignIn)
|
|
pats := sec.Key("WHITELISTED_URIS").Strings(" ")
|
|
if len(pats) != 0 {
|
|
Service.OpenIDWhitelist = make([]*regexp.Regexp, len(pats))
|
|
for i, p := range pats {
|
|
Service.OpenIDWhitelist[i] = regexp.MustCompilePOSIX(p)
|
|
}
|
|
}
|
|
pats = sec.Key("BLACKLISTED_URIS").Strings(" ")
|
|
if len(pats) != 0 {
|
|
Service.OpenIDBlacklist = make([]*regexp.Regexp, len(pats))
|
|
for i, p := range pats {
|
|
Service.OpenIDBlacklist[i] = regexp.MustCompilePOSIX(p)
|
|
}
|
|
}
|
|
}
|