diff --git a/custom/conf/app.ini.sample b/custom/conf/app.ini.sample index c4dd741cacdd7..53041321168e2 100644 --- a/custom/conf/app.ini.sample +++ b/custom/conf/app.ini.sample @@ -249,6 +249,10 @@ MIN_PASSWORD_LENGTH = 6 IMPORT_LOCAL_PATHS = false ; Prevent all users (including admin) from creating custom git hooks DISABLE_GIT_HOOKS = false +; Store INTERNAL_TOKEN in a separate file. Will be stored in this config if not set +; formats allowed: +; - file:/path/to/my/internal_token +;INTERNAL_TOKEN_URI = [openid] ; diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 410cdfbfb529d..0ba3c551a160b 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -8,6 +8,8 @@ package setting import ( "encoding/base64" "fmt" + "io" + "io/ioutil" "net" "net/mail" "net/url" @@ -924,31 +926,7 @@ func NewContext() { MinPasswordLength = sec.Key("MIN_PASSWORD_LENGTH").MustInt(6) ImportLocalPaths = sec.Key("IMPORT_LOCAL_PATHS").MustBool(false) DisableGitHooks = sec.Key("DISABLE_GIT_HOOKS").MustBool(false) - InternalToken = sec.Key("INTERNAL_TOKEN").String() - if len(InternalToken) == 0 { - InternalToken, err = generate.NewInternalToken() - if err != nil { - log.Fatal(4, "Error generate internal token: %v", err) - } - - // Save secret - cfgSave := ini.Empty() - if com.IsFile(CustomConf) { - // Keeps custom settings if there is already something. - if err := cfgSave.Append(CustomConf); err != nil { - log.Error(4, "Failed to load custom conf '%s': %v", CustomConf, err) - } - } - - cfgSave.Section("security").Key("INTERNAL_TOKEN").SetValue(InternalToken) - - if err := os.MkdirAll(filepath.Dir(CustomConf), os.ModePerm); err != nil { - log.Fatal(4, "Failed to create '%s': %v", CustomConf, err) - } - if err := cfgSave.SaveTo(CustomConf); err != nil { - log.Fatal(4, "Error saving generated JWT Secret to custom config: %v", err) - } - } + InternalToken = loadInternalToken(sec) IterateBufferSize = Cfg.Section("database").Key("ITERATE_BUFFER_SIZE").MustInt(50) LogSQL = Cfg.Section("database").Key("LOG_SQL").MustBool(true) @@ -1160,6 +1138,75 @@ func NewContext() { U2F.AppID = sec.Key("APP_ID").MustString(strings.TrimRight(AppURL, "/")) } +func loadInternalToken(sec *ini.Section) string { + uri := sec.Key("INTERNAL_TOKEN_URI").String() + if len(uri) == 0 { + return loadOrGenerateInternalToken(sec) + } + tempURI, err := url.Parse(uri) + if err != nil { + log.Fatal(4, "Failed to parse INTERNAL_TOKEN_URI (%s). Falling back to INTERNAL_TOKEN: %v", uri, err) + } + switch tempURI.Scheme { + case "file": + fp, err := os.OpenFile(tempURI.RequestURI(), os.O_RDWR, 0600) + if err != nil { + log.Fatal(4, "Failed to open InternalTokenURI (%s): %v", uri, err) + } + defer fp.Close() + + buf, err := ioutil.ReadAll(fp) + if err != nil { + log.Fatal(4, "Failed to read InternalTokenURI (%s): %v", uri, err) + } + // No token in the file, generate one and store it. + if len(buf) == 0 { + token, err := generate.NewInternalToken() + if err != nil { + log.Fatal(4, "Error generate internal token: %v", err) + } + if _, err := io.WriteString(fp, token); err != nil { + log.Fatal(4, "Error writing to InternalTokenURI (%s): %v", uri, err) + } + return token + } + + return string(buf) + default: + log.Fatal(4, "Unsupported URI-Scheme %q (INTERNAL_TOKEN_URL = %q)", tempURI.Scheme, uri) + } +} + +func loadOrGenerateInternalToken(sec *ini.Section) string { + var err error + token := sec.Key("INTERNAL_TOKEN").String() + if len(token) == 0 { + token, err = generate.NewInternalToken() + if err != nil { + log.Fatal(4, "Error generate internal token: %v", err) + } + + // Save secret + cfgSave := ini.Empty() + if com.IsFile(CustomConf) { + // Keeps custom settings if there is already something. + if err := cfgSave.Append(CustomConf); err != nil { + log.Error(4, "Failed to load custom conf '%s': %v", CustomConf, err) + } + } + + cfgSave.Section("security").Key("INTERNAL_TOKEN").SetValue(token) + + if err := os.MkdirAll(filepath.Dir(CustomConf), os.ModePerm); err != nil { + log.Fatal(4, "Failed to create '%s': %v", CustomConf, err) + } + if err := cfgSave.SaveTo(CustomConf); err != nil { + log.Fatal(4, "Error saving generated INTERNAL_TOKEN to custom config: %v", err) + } + } + return token +} + // Service settings var Service struct { ActiveCodeLives int