diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 043acb733d52..2e5bb17b6a86 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -1158,6 +1158,8 @@ func parseAuthorizedPrincipalsAllow(values []string) ([]string, bool) { return authorizedPrincipalsAllow, true } +// loadSecret load the secret from ini by uriKey or verbatimKey, only one of them could be set +// If the secret is loaded from uriKey (file), the file should be non-empty, to guarantee the behavior stable and clear. func loadSecret(sec *ini.Section, uriKey, verbatimKey string) string { // don't allow setting both URI and verbatim string uri := sec.Key(uriKey).String() @@ -1181,7 +1183,15 @@ func loadSecret(sec *ini.Section, uriKey, verbatimKey string) string { if err != nil { log.Fatal("Failed to read %s (%s): %v", uriKey, tempURI.RequestURI(), err) } - return strings.TrimSpace(string(buf)) + val := strings.TrimSpace(string(buf)) + if val == "" { + // The file shouldn't be empty, otherwise we can not know whether the user has ever set the KEY or KEY_URI + // For example: if INTERNAL_TOKEN_URI=file:///empty-file, + // Then if the token is re-generated during installation and saved to INTERNAL_TOKEN + // Then INTERNAL_TOKEN and INTERNAL_TOKEN_URI both exist, that's a fatal error (they shouldn't) + log.Fatal("Failed to read %s (%s): the file is empty", uriKey, tempURI.RequestURI()) + } + return val // only file URIs are allowed default: diff --git a/routers/install/install.go b/routers/install/install.go index 6bac5b5ff7f4..184dc5bae185 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -474,12 +474,16 @@ func SubmitInstall(ctx *context.Context) { cfg.Section("security").Key("INSTALL_LOCK").SetValue("true") - var internalToken string - if internalToken, err = generate.NewInternalToken(); err != nil { - ctx.RenderWithErr(ctx.Tr("install.internal_token_failed", err), tplInstall, &form) - return + // the internal token could be read from INTERNAL_TOKEN or INTERNAL_TOKEN_URI (the file is guaranteed to be non-empty) + // if there is no InternalToken, generate one and save to security.INTERNAL_TOKEN + if setting.InternalToken == "" { + var internalToken string + if internalToken, err = generate.NewInternalToken(); err != nil { + ctx.RenderWithErr(ctx.Tr("install.internal_token_failed", err), tplInstall, &form) + return + } + cfg.Section("security").Key("INTERNAL_TOKEN").SetValue(internalToken) } - cfg.Section("security").Key("INTERNAL_TOKEN").SetValue(internalToken) // if there is already a SECRET_KEY, we should not overwrite it, otherwise the encrypted data will not be able to be decrypted if setting.SecretKey == "" {