123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- // 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
- 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
- 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.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.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, 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)
- }
- }
- }
|