refactor: "install" page (#39400)

1. remove useless options
2. set AppDataPath instead of repo root path
3. make "disable self-registration" default enabled
4. avoid writing corrupted ini file
5. avoid auto-sign-in the existing admin user
This commit is contained in:
wxiaoguang
2026-09-23 23:14:31 +00:00
committed by GitHub
parent 71065941a9
commit f14cedc4fa
35 changed files with 261 additions and 439 deletions
+1 -15
View File
@@ -3,13 +3,6 @@
package setting
import (
"net/url"
"path"
"gitea.dev/modules/log"
)
// API settings
var API = struct {
EnableSwagger bool
@@ -31,12 +24,5 @@ var API = struct {
func loadAPIFrom(rootCfg ConfigProvider) {
mustMapSetting(rootCfg, "api", &API)
defaultAppURL := string(Protocol) + "://" + Domain + ":" + HTTPPort
u, err := url.Parse(rootCfg.Section("server").Key("ROOT_URL").MustString(defaultAppURL))
if err != nil {
log.Fatal("Invalid ROOT_URL '%s': %s", AppURL, err)
}
u.Path = path.Join(u.Path, "api", "swagger")
API.SwaggerURL = u.String()
API.SwaggerURL = AppURL + "api/swagger"
}
+32 -34
View File
@@ -49,7 +49,8 @@ const (
var (
// AppURL is the Application ROOT_URL. It always has a '/' suffix
// It maps to ini:"ROOT_URL"
AppURL string
AppURL string
AppDomain string
// PublicURLDetection controls how to use the HTTP request headers to detect public URL
PublicURLDetection string
@@ -80,7 +81,6 @@ var (
ProxyProtocolTLSBridging bool
ProxyProtocolHeaderTimeout time.Duration
ProxyProtocolAcceptUnknown bool
Domain string
HTTPAddr string
HTTPPort string
LocalUseProxyProtocol bool
@@ -114,11 +114,39 @@ var (
StaticURLPrefix string // no trailing slash, defaults to AppSubURL, the URL can be relative or absolute
)
func loadServerDomainAndURL(sec ConfigSection, protocol string) {
defaultAppURL := protocol + "://localhost:" + HTTPPort
AppURL = sec.Key("ROOT_URL").MustString(defaultAppURL)
PublicURLDetection = sec.Key("PUBLIC_URL_DETECTION").MustString(PublicURLAuto)
if PublicURLDetection != PublicURLAuto && PublicURLDetection != PublicURLLegacy && PublicURLDetection != PublicURLNever {
log.Fatal("Invalid PUBLIC_URL_DETECTION value: %s", PublicURLDetection)
}
// Check validity of AppURL
appURL, err := url.Parse(AppURL)
if err != nil {
log.Fatal("Invalid ROOT_URL %q: %s", AppURL, err)
}
// Remove default ports from AppURL.
// (scheme-based URL normalization, RFC 3986 section 6.2.3)
if (appURL.Scheme == string(HTTP) && appURL.Port() == "80") || (appURL.Scheme == string(HTTPS) && appURL.Port() == "443") {
appURL.Host = appURL.Hostname()
}
// This should be TrimRight to ensure that there is only a single '/' at the end of AppURL.
AppURL = strings.TrimRight(appURL.String(), "/") + "/"
// AppSubURL should start with '/' and end without '/', such as '/{subpath}'.
// This value is empty if site does not have sub-url.
AppSubURL = strings.TrimSuffix(appURL.Path, "/")
UseSubURLPath = sec.Key("USE_SUB_URL_PATH").MustBool(false)
StaticURLPrefix = strings.TrimSuffix(sec.Key("STATIC_URL_PREFIX").MustString(AppSubURL), "/")
AppDomain = appURL.Hostname()
}
func loadServerFrom(rootCfg ConfigProvider) {
sec := rootCfg.Section("server")
AppName = rootCfg.Section("").Key("APP_NAME").MustString("Gitea: Git with a cup of tea")
Domain = sec.Key("DOMAIN").MustString("localhost")
HTTPAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0")
HTTPPort = sec.Key("HTTP_PORT").MustString("3000")
@@ -217,37 +245,7 @@ func loadServerFrom(rootCfg ConfigProvider) {
PerWriteTimeout = sec.Key("PER_WRITE_TIMEOUT").MustDuration(PerWriteTimeout)
PerWritePerKbTimeout = sec.Key("PER_WRITE_PER_KB_TIMEOUT").MustDuration(PerWritePerKbTimeout)
defaultAppURL := string(Protocol) + "://" + Domain + ":" + HTTPPort
AppURL = sec.Key("ROOT_URL").MustString(defaultAppURL)
PublicURLDetection = sec.Key("PUBLIC_URL_DETECTION").MustString(PublicURLAuto)
if PublicURLDetection != PublicURLAuto && PublicURLDetection != PublicURLLegacy && PublicURLDetection != PublicURLNever {
log.Fatal("Invalid PUBLIC_URL_DETECTION value: %s", PublicURLDetection)
}
// Check validity of AppURL
appURL, err := url.Parse(AppURL)
if err != nil {
log.Fatal("Invalid ROOT_URL %q: %s", AppURL, err)
}
// Remove default ports from AppURL.
// (scheme-based URL normalization, RFC 3986 section 6.2.3)
if (appURL.Scheme == string(HTTP) && appURL.Port() == "80") || (appURL.Scheme == string(HTTPS) && appURL.Port() == "443") {
appURL.Host = appURL.Hostname()
}
// This should be TrimRight to ensure that there is only a single '/' at the end of AppURL.
AppURL = strings.TrimRight(appURL.String(), "/") + "/"
// AppSubURL should start with '/' and end without '/', such as '/{subpath}'.
// This value is empty if site does not have sub-url.
AppSubURL = strings.TrimSuffix(appURL.Path, "/")
UseSubURLPath = sec.Key("USE_SUB_URL_PATH").MustBool(false)
StaticURLPrefix = strings.TrimSuffix(sec.Key("STATIC_URL_PREFIX").MustString(AppSubURL), "/")
// Check if Domain differs from AppURL domain than update it to AppURL's domain
urlHostname := appURL.Hostname()
if urlHostname != Domain && net.ParseIP(urlHostname) == nil && urlHostname != "" {
Domain = urlHostname
}
loadServerDomainAndURL(sec, string(Protocol))
var defaultLocalURL string
switch Protocol {
+4 -4
View File
@@ -145,7 +145,7 @@ 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.DisableRegistration = sec.Key("DISABLE_REGISTRATION").MustBool(true)
Service.AllowOnlyInternalRegistration = sec.Key("ALLOW_ONLY_INTERNAL_REGISTRATION").MustBool()
Service.AllowOnlyExternalRegistration = sec.Key("ALLOW_ONLY_EXTERNAL_REGISTRATION").MustBool()
if Service.AllowOnlyExternalRegistration && Service.AllowOnlyInternalRegistration {
@@ -209,7 +209,7 @@ func loadServiceFrom(rootCfg ConfigProvider) {
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.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply." + AppDomain)
Service.UserLocationMapURL = sec.Key("USER_LOCATION_MAP_URL").String()
Service.EnableUserHeatmap = sec.Key("ENABLE_USER_HEATMAP").MustBool(true)
Service.AutoWatchNewRepos = sec.Key("AUTO_WATCH_NEW_REPOS").MustBool(true)
@@ -263,8 +263,8 @@ func loadServiceFrom(rootCfg ConfigProvider) {
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)
Service.EnableOpenIDSignIn = sec.Key("ENABLE_OPENID_SIGNIN").MustBool(false)
Service.EnableOpenIDSignUp = sec.Key("ENABLE_OPENID_SIGNUP").MustBool(false)
pats := sec.Key("WHITELISTED_URIS").Strings(" ")
if len(pats) != 0 {
Service.OpenIDWhitelist = make([]*regexp.Regexp, len(pats))
+1 -1
View File
@@ -42,7 +42,7 @@ var SessionConfig = struct {
func loadSessionFrom(rootCfg ConfigProvider) {
sec := rootCfg.Section("session")
SessionConfig.Provider = sec.Key("PROVIDER").In("memory", []string{"memory", "file", "redis", "mysql", "postgres", "couchbase", "memcache", "db"})
SessionConfig.Provider = sec.Key("PROVIDER").In("file", []string{"memory", "file", "redis", "mysql", "postgres", "couchbase", "memcache", "db"})
switch SessionConfig.Provider {
case "redis":
+7 -4
View File
@@ -7,6 +7,7 @@ package setting
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"time"
@@ -71,22 +72,24 @@ func PrepareAppDataPath() error {
// The correct behavior should be: creating parent directories is end users' duty. We only create sub-directories in existing parent directories.
// For quickstart, the parent directories should be created automatically for first startup (eg: a flag or a check of INSTALL_LOCK).
// Now we can take the first step to do correctly (using Mkdir) in other packages, and prepare the AppDataPath here, then make a refactor in future.
if !filepath.IsAbs(AppDataPath) {
return fmt.Errorf("app data path %q must be an absolute path", AppDataPath)
}
st, err := os.Stat(AppDataPath)
if os.IsNotExist(err) {
err = os.MkdirAll(AppDataPath, os.ModePerm)
if err != nil {
return fmt.Errorf("unable to create the APP_DATA_PATH directory: %q, Error: %w", AppDataPath, err)
return fmt.Errorf("unable to create the app data path directory: %q, Error: %w", AppDataPath, err)
}
return nil
}
if err != nil {
return fmt.Errorf("unable to use APP_DATA_PATH %q. Error: %w", AppDataPath, err)
return fmt.Errorf("unable to use app data path %q. Error: %w", AppDataPath, err)
}
if !st.IsDir() /* also works for symlink */ {
return fmt.Errorf("the APP_DATA_PATH %q is not a directory (or symlink to a directory) and can't be used", AppDataPath)
return fmt.Errorf("the app data path %q is not a directory (or symlink to a directory) and can't be used", AppDataPath)
}
return nil
+2 -6
View File
@@ -93,19 +93,15 @@ func parseAuthorizedPrincipalsAllow(values []string) ([]string, bool) {
}
func loadSSHFrom(rootCfg ConfigProvider) {
sec := rootCfg.Section("server")
if len(SSH.Domain) == 0 {
SSH.Domain = Domain
}
homeDir, err := util.HomeDir()
if err != nil {
log.Fatal("Failed to get home directory: %v", err)
}
homeDir = strings.ReplaceAll(homeDir, "\\", "/")
SSH.RootPath = filepath.Join(homeDir, ".ssh")
SSH.Domain = AppDomain
sec := rootCfg.Section("server")
if err = sec.MapTo(&SSH); err != nil {
log.Fatal("Failed to map SSH settings: %v", err)
}