code.gitea.io/gitea@v1.22.3/modules/setting/service.go (about)

     1  // Copyright 2019 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package setting
     5  
     6  import (
     7  	"regexp"
     8  	"strings"
     9  	"time"
    10  
    11  	"code.gitea.io/gitea/modules/log"
    12  	"code.gitea.io/gitea/modules/structs"
    13  
    14  	"github.com/gobwas/glob"
    15  )
    16  
    17  // enumerates all the types of captchas
    18  const (
    19  	ImageCaptcha = "image"
    20  	ReCaptcha    = "recaptcha"
    21  	HCaptcha     = "hcaptcha"
    22  	MCaptcha     = "mcaptcha"
    23  	CfTurnstile  = "cfturnstile"
    24  )
    25  
    26  // Service settings
    27  var Service = struct {
    28  	DefaultUserVisibility                   string
    29  	DefaultUserVisibilityMode               structs.VisibleType
    30  	AllowedUserVisibilityModes              []string
    31  	AllowedUserVisibilityModesSlice         AllowedVisibility `ini:"-"`
    32  	DefaultOrgVisibility                    string
    33  	DefaultOrgVisibilityMode                structs.VisibleType
    34  	ActiveCodeLives                         int
    35  	ResetPwdCodeLives                       int
    36  	RegisterEmailConfirm                    bool
    37  	RegisterManualConfirm                   bool
    38  	EmailDomainAllowList                    []glob.Glob
    39  	EmailDomainBlockList                    []glob.Glob
    40  	DisableRegistration                     bool
    41  	AllowOnlyInternalRegistration           bool
    42  	AllowOnlyExternalRegistration           bool
    43  	ShowRegistrationButton                  bool
    44  	ShowMilestonesDashboardPage             bool
    45  	RequireSignInView                       bool
    46  	EnableNotifyMail                        bool
    47  	EnableBasicAuth                         bool
    48  	EnableReverseProxyAuth                  bool
    49  	EnableReverseProxyAuthAPI               bool
    50  	EnableReverseProxyAutoRegister          bool
    51  	EnableReverseProxyEmail                 bool
    52  	EnableReverseProxyFullName              bool
    53  	EnableCaptcha                           bool
    54  	RequireCaptchaForLogin                  bool
    55  	RequireExternalRegistrationCaptcha      bool
    56  	RequireExternalRegistrationPassword     bool
    57  	CaptchaType                             string
    58  	RecaptchaSecret                         string
    59  	RecaptchaSitekey                        string
    60  	RecaptchaURL                            string
    61  	CfTurnstileSecret                       string
    62  	CfTurnstileSitekey                      string
    63  	HcaptchaSecret                          string
    64  	HcaptchaSitekey                         string
    65  	McaptchaSecret                          string
    66  	McaptchaSitekey                         string
    67  	McaptchaURL                             string
    68  	DefaultKeepEmailPrivate                 bool
    69  	DefaultAllowCreateOrganization          bool
    70  	DefaultUserIsRestricted                 bool
    71  	EnableTimetracking                      bool
    72  	DefaultEnableTimetracking               bool
    73  	DefaultEnableDependencies               bool
    74  	AllowCrossRepositoryDependencies        bool
    75  	DefaultAllowOnlyContributorsToTrackTime bool
    76  	NoReplyAddress                          string
    77  	UserLocationMapURL                      string
    78  	EnableUserHeatmap                       bool
    79  	AutoWatchNewRepos                       bool
    80  	AutoWatchOnChanges                      bool
    81  	DefaultOrgMemberVisible                 bool
    82  	UserDeleteWithCommentsMaxTime           time.Duration
    83  	ValidSiteURLSchemes                     []string
    84  
    85  	// OpenID settings
    86  	EnableOpenIDSignIn bool
    87  	EnableOpenIDSignUp bool
    88  	OpenIDWhitelist    []*regexp.Regexp
    89  	OpenIDBlacklist    []*regexp.Regexp
    90  
    91  	// Explore page settings
    92  	Explore struct {
    93  		RequireSigninView bool `ini:"REQUIRE_SIGNIN_VIEW"`
    94  		DisableUsersPage  bool `ini:"DISABLE_USERS_PAGE"`
    95  	} `ini:"service.explore"`
    96  }{
    97  	AllowedUserVisibilityModesSlice: []bool{true, true, true},
    98  }
    99  
   100  // AllowedVisibility store in a 3 item bool array what is allowed
   101  type AllowedVisibility []bool
   102  
   103  // IsAllowedVisibility check if a AllowedVisibility allow a specific VisibleType
   104  func (a AllowedVisibility) IsAllowedVisibility(t structs.VisibleType) bool {
   105  	if int(t) >= len(a) {
   106  		return false
   107  	}
   108  	return a[t]
   109  }
   110  
   111  // ToVisibleTypeSlice convert a AllowedVisibility into a VisibleType slice
   112  func (a AllowedVisibility) ToVisibleTypeSlice() (result []structs.VisibleType) {
   113  	for i, v := range a {
   114  		if v {
   115  			result = append(result, structs.VisibleType(i))
   116  		}
   117  	}
   118  	return result
   119  }
   120  
   121  func CompileEmailGlobList(sec ConfigSection, keys ...string) (globs []glob.Glob) {
   122  	for _, key := range keys {
   123  		list := sec.Key(key).Strings(",")
   124  		for _, s := range list {
   125  			if g, err := glob.Compile(s); err == nil {
   126  				globs = append(globs, g)
   127  			} else {
   128  				log.Error("Skip invalid email allow/block list expression %q: %v", s, err)
   129  			}
   130  		}
   131  	}
   132  	return globs
   133  }
   134  
   135  func loadServiceFrom(rootCfg ConfigProvider) {
   136  	sec := rootCfg.Section("service")
   137  	Service.ActiveCodeLives = sec.Key("ACTIVE_CODE_LIVE_MINUTES").MustInt(180)
   138  	Service.ResetPwdCodeLives = sec.Key("RESET_PASSWD_CODE_LIVE_MINUTES").MustInt(180)
   139  	Service.DisableRegistration = sec.Key("DISABLE_REGISTRATION").MustBool()
   140  	Service.AllowOnlyInternalRegistration = sec.Key("ALLOW_ONLY_INTERNAL_REGISTRATION").MustBool()
   141  	Service.AllowOnlyExternalRegistration = sec.Key("ALLOW_ONLY_EXTERNAL_REGISTRATION").MustBool()
   142  	if Service.AllowOnlyExternalRegistration && Service.AllowOnlyInternalRegistration {
   143  		log.Warn("ALLOW_ONLY_INTERNAL_REGISTRATION and ALLOW_ONLY_EXTERNAL_REGISTRATION are true - disabling registration")
   144  		Service.DisableRegistration = true
   145  	}
   146  	if !sec.Key("REGISTER_EMAIL_CONFIRM").MustBool() {
   147  		Service.RegisterManualConfirm = sec.Key("REGISTER_MANUAL_CONFIRM").MustBool(false)
   148  	} else {
   149  		Service.RegisterManualConfirm = false
   150  	}
   151  	if sec.HasKey("EMAIL_DOMAIN_WHITELIST") {
   152  		deprecatedSetting(rootCfg, "service", "EMAIL_DOMAIN_WHITELIST", "service", "EMAIL_DOMAIN_ALLOWLIST", "1.21")
   153  	}
   154  	Service.EmailDomainAllowList = CompileEmailGlobList(sec, "EMAIL_DOMAIN_WHITELIST", "EMAIL_DOMAIN_ALLOWLIST")
   155  	Service.EmailDomainBlockList = CompileEmailGlobList(sec, "EMAIL_DOMAIN_BLOCKLIST")
   156  	Service.ShowRegistrationButton = sec.Key("SHOW_REGISTRATION_BUTTON").MustBool(!(Service.DisableRegistration || Service.AllowOnlyExternalRegistration))
   157  	Service.ShowMilestonesDashboardPage = sec.Key("SHOW_MILESTONES_DASHBOARD_PAGE").MustBool(true)
   158  	Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool()
   159  	Service.EnableBasicAuth = sec.Key("ENABLE_BASIC_AUTHENTICATION").MustBool(true)
   160  	Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool()
   161  	Service.EnableReverseProxyAuthAPI = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION_API").MustBool()
   162  	Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool()
   163  	Service.EnableReverseProxyEmail = sec.Key("ENABLE_REVERSE_PROXY_EMAIL").MustBool()
   164  	Service.EnableReverseProxyFullName = sec.Key("ENABLE_REVERSE_PROXY_FULL_NAME").MustBool()
   165  	Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool(false)
   166  	Service.RequireCaptchaForLogin = sec.Key("REQUIRE_CAPTCHA_FOR_LOGIN").MustBool(false)
   167  	Service.RequireExternalRegistrationCaptcha = sec.Key("REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA").MustBool(Service.EnableCaptcha)
   168  	Service.RequireExternalRegistrationPassword = sec.Key("REQUIRE_EXTERNAL_REGISTRATION_PASSWORD").MustBool()
   169  	Service.CaptchaType = sec.Key("CAPTCHA_TYPE").MustString(ImageCaptcha)
   170  	Service.RecaptchaSecret = sec.Key("RECAPTCHA_SECRET").MustString("")
   171  	Service.RecaptchaSitekey = sec.Key("RECAPTCHA_SITEKEY").MustString("")
   172  	Service.RecaptchaURL = sec.Key("RECAPTCHA_URL").MustString("https://www.google.com/recaptcha/")
   173  	Service.CfTurnstileSecret = sec.Key("CF_TURNSTILE_SECRET").MustString("")
   174  	Service.CfTurnstileSitekey = sec.Key("CF_TURNSTILE_SITEKEY").MustString("")
   175  	Service.HcaptchaSecret = sec.Key("HCAPTCHA_SECRET").MustString("")
   176  	Service.HcaptchaSitekey = sec.Key("HCAPTCHA_SITEKEY").MustString("")
   177  	Service.McaptchaURL = sec.Key("MCAPTCHA_URL").MustString("https://demo.mcaptcha.org/")
   178  	Service.McaptchaSecret = sec.Key("MCAPTCHA_SECRET").MustString("")
   179  	Service.McaptchaSitekey = sec.Key("MCAPTCHA_SITEKEY").MustString("")
   180  	Service.DefaultKeepEmailPrivate = sec.Key("DEFAULT_KEEP_EMAIL_PRIVATE").MustBool()
   181  	Service.DefaultAllowCreateOrganization = sec.Key("DEFAULT_ALLOW_CREATE_ORGANIZATION").MustBool(true)
   182  	Service.DefaultUserIsRestricted = sec.Key("DEFAULT_USER_IS_RESTRICTED").MustBool(false)
   183  	Service.EnableTimetracking = sec.Key("ENABLE_TIMETRACKING").MustBool(true)
   184  	if Service.EnableTimetracking {
   185  		Service.DefaultEnableTimetracking = sec.Key("DEFAULT_ENABLE_TIMETRACKING").MustBool(true)
   186  	}
   187  	Service.DefaultEnableDependencies = sec.Key("DEFAULT_ENABLE_DEPENDENCIES").MustBool(true)
   188  	Service.AllowCrossRepositoryDependencies = sec.Key("ALLOW_CROSS_REPOSITORY_DEPENDENCIES").MustBool(true)
   189  	Service.DefaultAllowOnlyContributorsToTrackTime = sec.Key("DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME").MustBool(true)
   190  	Service.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply." + Domain)
   191  	Service.UserLocationMapURL = sec.Key("USER_LOCATION_MAP_URL").String()
   192  	Service.EnableUserHeatmap = sec.Key("ENABLE_USER_HEATMAP").MustBool(true)
   193  	Service.AutoWatchNewRepos = sec.Key("AUTO_WATCH_NEW_REPOS").MustBool(true)
   194  	Service.AutoWatchOnChanges = sec.Key("AUTO_WATCH_ON_CHANGES").MustBool(false)
   195  	modes := sec.Key("ALLOWED_USER_VISIBILITY_MODES").Strings(",")
   196  	if len(modes) != 0 {
   197  		Service.AllowedUserVisibilityModes = []string{}
   198  		Service.AllowedUserVisibilityModesSlice = []bool{false, false, false}
   199  		for _, sMode := range modes {
   200  			if tp, ok := structs.VisibilityModes[sMode]; ok { // remove unsupported modes
   201  				Service.AllowedUserVisibilityModes = append(Service.AllowedUserVisibilityModes, sMode)
   202  				Service.AllowedUserVisibilityModesSlice[tp] = true
   203  			} else {
   204  				log.Warn("ALLOWED_USER_VISIBILITY_MODES %s is unsupported", sMode)
   205  			}
   206  		}
   207  	}
   208  
   209  	if len(Service.AllowedUserVisibilityModes) == 0 {
   210  		Service.AllowedUserVisibilityModes = []string{"public", "limited", "private"}
   211  		Service.AllowedUserVisibilityModesSlice = []bool{true, true, true}
   212  	}
   213  
   214  	Service.DefaultUserVisibility = sec.Key("DEFAULT_USER_VISIBILITY").String()
   215  	if Service.DefaultUserVisibility == "" {
   216  		Service.DefaultUserVisibility = Service.AllowedUserVisibilityModes[0]
   217  	} else if !Service.AllowedUserVisibilityModesSlice[structs.VisibilityModes[Service.DefaultUserVisibility]] {
   218  		log.Warn("DEFAULT_USER_VISIBILITY %s is wrong or not in ALLOWED_USER_VISIBILITY_MODES, using first allowed", Service.DefaultUserVisibility)
   219  		Service.DefaultUserVisibility = Service.AllowedUserVisibilityModes[0]
   220  	}
   221  	Service.DefaultUserVisibilityMode = structs.VisibilityModes[Service.DefaultUserVisibility]
   222  	Service.DefaultOrgVisibility = sec.Key("DEFAULT_ORG_VISIBILITY").In("public", structs.ExtractKeysFromMapString(structs.VisibilityModes))
   223  	Service.DefaultOrgVisibilityMode = structs.VisibilityModes[Service.DefaultOrgVisibility]
   224  	Service.DefaultOrgMemberVisible = sec.Key("DEFAULT_ORG_MEMBER_VISIBLE").MustBool()
   225  	Service.UserDeleteWithCommentsMaxTime = sec.Key("USER_DELETE_WITH_COMMENTS_MAX_TIME").MustDuration(0)
   226  	sec.Key("VALID_SITE_URL_SCHEMES").MustString("http,https")
   227  	Service.ValidSiteURLSchemes = sec.Key("VALID_SITE_URL_SCHEMES").Strings(",")
   228  	schemes := make([]string, 0, len(Service.ValidSiteURLSchemes))
   229  	for _, scheme := range Service.ValidSiteURLSchemes {
   230  		scheme = strings.ToLower(strings.TrimSpace(scheme))
   231  		if scheme != "" {
   232  			schemes = append(schemes, scheme)
   233  		}
   234  	}
   235  	Service.ValidSiteURLSchemes = schemes
   236  
   237  	mustMapSetting(rootCfg, "service.explore", &Service.Explore)
   238  
   239  	loadOpenIDSetting(rootCfg)
   240  }
   241  
   242  func loadOpenIDSetting(rootCfg ConfigProvider) {
   243  	sec := rootCfg.Section("openid")
   244  	Service.EnableOpenIDSignIn = sec.Key("ENABLE_OPENID_SIGNIN").MustBool(!InstallLock)
   245  	Service.EnableOpenIDSignUp = sec.Key("ENABLE_OPENID_SIGNUP").MustBool(!Service.DisableRegistration && Service.EnableOpenIDSignIn)
   246  	pats := sec.Key("WHITELISTED_URIS").Strings(" ")
   247  	if len(pats) != 0 {
   248  		Service.OpenIDWhitelist = make([]*regexp.Regexp, len(pats))
   249  		for i, p := range pats {
   250  			Service.OpenIDWhitelist[i] = regexp.MustCompilePOSIX(p)
   251  		}
   252  	}
   253  	pats = sec.Key("BLACKLISTED_URIS").Strings(" ")
   254  	if len(pats) != 0 {
   255  		Service.OpenIDBlacklist = make([]*regexp.Regexp, len(pats))
   256  		for i, p := range pats {
   257  			Service.OpenIDBlacklist[i] = regexp.MustCompilePOSIX(p)
   258  		}
   259  	}
   260  }