Refactor config provider (#24245)
This PR introduces more abstract about `ConfigProvider` and hides more `ini` references. --------- Co-authored-by: delvh <dev.lh@web.de>
This commit is contained in:
parent
56d4893b2a
commit
5cf7da63ee
17 changed files with 227 additions and 164 deletions
|
@ -24,7 +24,6 @@ import (
|
||||||
|
|
||||||
"github.com/felixge/fgprof"
|
"github.com/felixge/fgprof"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
ini "gopkg.in/ini.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// PIDFile could be set from build tag
|
// PIDFile could be set from build tag
|
||||||
|
@ -223,9 +222,10 @@ func setPort(port string) error {
|
||||||
defaultLocalURL += ":" + setting.HTTPPort + "/"
|
defaultLocalURL += ":" + setting.HTTPPort + "/"
|
||||||
|
|
||||||
// Save LOCAL_ROOT_URL if port changed
|
// Save LOCAL_ROOT_URL if port changed
|
||||||
setting.CreateOrAppendToCustomConf("server.LOCAL_ROOT_URL", func(cfg *ini.File) {
|
setting.CfgProvider.Section("server").Key("LOCAL_ROOT_URL").SetValue(defaultLocalURL)
|
||||||
cfg.Section("server").Key("LOCAL_ROOT_URL").SetValue(defaultLocalURL)
|
if err := setting.CfgProvider.Save(); err != nil {
|
||||||
})
|
return fmt.Errorf("Failed to save config file: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ import (
|
||||||
_ "code.gitea.io/gitea/models"
|
_ "code.gitea.io/gitea/models"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/ini.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
|
@ -27,7 +26,7 @@ func TestMain(m *testing.M) {
|
||||||
|
|
||||||
func TestBleveSearchIssues(t *testing.T) {
|
func TestBleveSearchIssues(t *testing.T) {
|
||||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
setting.CfgProvider = ini.Empty()
|
setting.CfgProvider = setting.NewEmptyConfigProvider()
|
||||||
|
|
||||||
tmpIndexerDir := t.TempDir()
|
tmpIndexerDir := t.TempDir()
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ import (
|
||||||
_ "code.gitea.io/gitea/models"
|
_ "code.gitea.io/gitea/models"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/ini.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
|
@ -29,7 +28,7 @@ func TestMain(m *testing.M) {
|
||||||
|
|
||||||
func TestRepoStatsIndex(t *testing.T) {
|
func TestRepoStatsIndex(t *testing.T) {
|
||||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
setting.CfgProvider = ini.Empty()
|
setting.CfgProvider = setting.NewEmptyConfigProvider()
|
||||||
|
|
||||||
setting.LoadQueueSettings()
|
setting.LoadQueueSettings()
|
||||||
|
|
||||||
|
|
|
@ -4,20 +4,157 @@
|
||||||
package setting
|
package setting
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
ini "gopkg.in/ini.v1"
|
ini "gopkg.in/ini.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ConfigSection interface {
|
||||||
|
Name() string
|
||||||
|
MapTo(interface{}) error
|
||||||
|
HasKey(key string) bool
|
||||||
|
NewKey(name, value string) (*ini.Key, error)
|
||||||
|
Key(key string) *ini.Key
|
||||||
|
Keys() []*ini.Key
|
||||||
|
ChildSections() []*ini.Section
|
||||||
|
}
|
||||||
|
|
||||||
// ConfigProvider represents a config provider
|
// ConfigProvider represents a config provider
|
||||||
type ConfigProvider interface {
|
type ConfigProvider interface {
|
||||||
Section(section string) *ini.Section
|
Section(section string) ConfigSection
|
||||||
NewSection(name string) (*ini.Section, error)
|
NewSection(name string) (ConfigSection, error)
|
||||||
GetSection(name string) (*ini.Section, error)
|
GetSection(name string) (ConfigSection, error)
|
||||||
|
DeleteSection(name string) error
|
||||||
|
Save() error
|
||||||
|
}
|
||||||
|
|
||||||
|
type iniFileConfigProvider struct {
|
||||||
|
*ini.File
|
||||||
|
filepath string // the ini file path
|
||||||
|
newFile bool // whether the file has not existed previously
|
||||||
|
allowEmpty bool // whether not finding configuration files is allowed (only true for the tests)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEmptyConfigProvider create a new empty config provider
|
||||||
|
func NewEmptyConfigProvider() ConfigProvider {
|
||||||
|
cp, _ := newConfigProviderFromData("")
|
||||||
|
return cp
|
||||||
|
}
|
||||||
|
|
||||||
|
// newConfigProviderFromData this function is only for testing
|
||||||
|
func newConfigProviderFromData(configContent string) (ConfigProvider, error) {
|
||||||
|
var cfg *ini.File
|
||||||
|
var err error
|
||||||
|
if configContent == "" {
|
||||||
|
cfg = ini.Empty()
|
||||||
|
} else {
|
||||||
|
cfg, err = ini.Load(strings.NewReader(configContent))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cfg.NameMapper = ini.SnackCase
|
||||||
|
return &iniFileConfigProvider{
|
||||||
|
File: cfg,
|
||||||
|
newFile: true,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// newConfigProviderFromFile load configuration from file.
|
||||||
|
// NOTE: do not print any log except error.
|
||||||
|
func newConfigProviderFromFile(customConf string, allowEmpty bool, extraConfig string) (*iniFileConfigProvider, error) {
|
||||||
|
cfg := ini.Empty()
|
||||||
|
newFile := true
|
||||||
|
|
||||||
|
if customConf != "" {
|
||||||
|
isFile, err := util.IsFile(customConf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to check if %s is a file. Error: %v", customConf, err)
|
||||||
|
}
|
||||||
|
if isFile {
|
||||||
|
if err := cfg.Append(customConf); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to load custom conf '%s': %v", customConf, err)
|
||||||
|
}
|
||||||
|
newFile = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if newFile && !allowEmpty {
|
||||||
|
return nil, fmt.Errorf("unable to find configuration file: %q, please ensure you are running in the correct environment or set the correct configuration file with -c", CustomConf)
|
||||||
|
}
|
||||||
|
|
||||||
|
if extraConfig != "" {
|
||||||
|
if err := cfg.Append([]byte(extraConfig)); err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to append more config: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.NameMapper = ini.SnackCase
|
||||||
|
return &iniFileConfigProvider{
|
||||||
|
File: cfg,
|
||||||
|
filepath: customConf,
|
||||||
|
newFile: newFile,
|
||||||
|
allowEmpty: allowEmpty,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *iniFileConfigProvider) Section(section string) ConfigSection {
|
||||||
|
return p.File.Section(section)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *iniFileConfigProvider) NewSection(name string) (ConfigSection, error) {
|
||||||
|
return p.File.NewSection(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *iniFileConfigProvider) GetSection(name string) (ConfigSection, error) {
|
||||||
|
return p.File.GetSection(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *iniFileConfigProvider) DeleteSection(name string) error {
|
||||||
|
p.File.DeleteSection(name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save save the content into file
|
||||||
|
func (p *iniFileConfigProvider) Save() error {
|
||||||
|
if p.filepath == "" {
|
||||||
|
if !p.allowEmpty {
|
||||||
|
return fmt.Errorf("custom config path must not be empty")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.newFile {
|
||||||
|
if err := os.MkdirAll(filepath.Dir(CustomConf), os.ModePerm); err != nil {
|
||||||
|
return fmt.Errorf("failed to create '%s': %v", CustomConf, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := p.SaveTo(p.filepath); err != nil {
|
||||||
|
return fmt.Errorf("failed to save '%s': %v", p.filepath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change permissions to be more restrictive
|
||||||
|
fi, err := os.Stat(CustomConf)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to determine current conf file permissions: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if fi.Mode().Perm() > 0o600 {
|
||||||
|
if err = os.Chmod(CustomConf, 0o600); err != nil {
|
||||||
|
log.Warn("Failed changing conf file permissions to -rw-------. Consider changing them manually.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// a file is an implementation ConfigProvider and other implementations are possible, i.e. from docker, k8s, …
|
// a file is an implementation ConfigProvider and other implementations are possible, i.e. from docker, k8s, …
|
||||||
var _ ConfigProvider = &ini.File{}
|
var _ ConfigProvider = &iniFileConfigProvider{}
|
||||||
|
|
||||||
func mustMapSetting(rootCfg ConfigProvider, sectionName string, setting interface{}) {
|
func mustMapSetting(rootCfg ConfigProvider, sectionName string, setting interface{}) {
|
||||||
if err := rootCfg.Section(sectionName).MapTo(setting); err != nil {
|
if err := rootCfg.Section(sectionName).MapTo(setting); err != nil {
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
ini "gopkg.in/ini.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_getCronSettings(t *testing.T) {
|
func Test_getCronSettings(t *testing.T) {
|
||||||
|
@ -23,11 +22,11 @@ func Test_getCronSettings(t *testing.T) {
|
||||||
|
|
||||||
iniStr := `
|
iniStr := `
|
||||||
[cron.test]
|
[cron.test]
|
||||||
Base = true
|
BASE = true
|
||||||
Second = white rabbit
|
SECOND = white rabbit
|
||||||
Extend = true
|
EXTEND = true
|
||||||
`
|
`
|
||||||
cfg, err := ini.Load([]byte(iniStr))
|
cfg, err := newConfigProviderFromData(iniStr)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
extended := &Extended{
|
extended := &Extended{
|
||||||
|
|
|
@ -9,8 +9,6 @@ import (
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/generate"
|
"code.gitea.io/gitea/modules/generate"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
|
||||||
ini "gopkg.in/ini.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// LFS represents the configuration for Git LFS
|
// LFS represents the configuration for Git LFS
|
||||||
|
@ -38,8 +36,7 @@ func loadLFSFrom(rootCfg ConfigProvider) {
|
||||||
// DEPRECATED should not be removed because users maybe upgrade from lower version to the latest version
|
// DEPRECATED should not be removed because users maybe upgrade from lower version to the latest version
|
||||||
// if these are removed, the warning will not be shown
|
// if these are removed, the warning will not be shown
|
||||||
deprecatedSetting(rootCfg, "server", "LFS_CONTENT_PATH", "lfs", "PATH", "v1.19.0")
|
deprecatedSetting(rootCfg, "server", "LFS_CONTENT_PATH", "lfs", "PATH", "v1.19.0")
|
||||||
lfsSec.Key("PATH").MustString(
|
lfsSec.Key("PATH").MustString(sec.Key("LFS_CONTENT_PATH").String())
|
||||||
sec.Key("LFS_CONTENT_PATH").String())
|
|
||||||
|
|
||||||
LFS.Storage = getStorage(rootCfg, "lfs", storageType, lfsSec)
|
LFS.Storage = getStorage(rootCfg, "lfs", storageType, lfsSec)
|
||||||
|
|
||||||
|
@ -62,9 +59,11 @@ func loadLFSFrom(rootCfg ConfigProvider) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save secret
|
// Save secret
|
||||||
CreateOrAppendToCustomConf("server.LFS_JWT_SECRET", func(cfg *ini.File) {
|
sec.Key("LFS_JWT_SECRET").SetValue(LFS.JWTSecretBase64)
|
||||||
cfg.Section("server").Key("LFS_JWT_SECRET").SetValue(LFS.JWTSecretBase64)
|
if err := rootCfg.Save(); err != nil {
|
||||||
})
|
log.Fatal("Error saving JWT Secret for custom config: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,6 @@ import (
|
||||||
"code.gitea.io/gitea/modules/json"
|
"code.gitea.io/gitea/modules/json"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
ini "gopkg.in/ini.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -131,12 +129,12 @@ type LogDescription struct {
|
||||||
SubLogDescriptions []SubLogDescription
|
SubLogDescriptions []SubLogDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLogLevel(section *ini.Section, key string, defaultValue log.Level) log.Level {
|
func getLogLevel(section ConfigSection, key string, defaultValue log.Level) log.Level {
|
||||||
value := section.Key(key).MustString(defaultValue.String())
|
value := section.Key(key).MustString(defaultValue.String())
|
||||||
return log.FromString(value)
|
return log.FromString(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getStacktraceLogLevel(section *ini.Section, key, defaultValue string) string {
|
func getStacktraceLogLevel(section ConfigSection, key, defaultValue string) string {
|
||||||
value := section.Key(key).MustString(defaultValue)
|
value := section.Key(key).MustString(defaultValue)
|
||||||
return log.FromString(value).String()
|
return log.FromString(value).String()
|
||||||
}
|
}
|
||||||
|
@ -165,7 +163,7 @@ func loadLogFrom(rootCfg ConfigProvider) {
|
||||||
Log.EnableXORMLog = rootCfg.Section("log").Key("ENABLE_XORM_LOG").MustBool(true)
|
Log.EnableXORMLog = rootCfg.Section("log").Key("ENABLE_XORM_LOG").MustBool(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateLogConfig(sec *ini.Section, name string, defaults defaultLogOptions) (mode, jsonConfig, levelName string) {
|
func generateLogConfig(sec ConfigSection, name string, defaults defaultLogOptions) (mode, jsonConfig, levelName string) {
|
||||||
level := getLogLevel(sec, "LEVEL", Log.Level)
|
level := getLogLevel(sec, "LEVEL", Log.Level)
|
||||||
levelName = level.String()
|
levelName = level.String()
|
||||||
stacktraceLevelName := getStacktraceLogLevel(sec, "STACKTRACE_LEVEL", Log.StacktraceLogLevel)
|
stacktraceLevelName := getStacktraceLogLevel(sec, "STACKTRACE_LEVEL", Log.StacktraceLogLevel)
|
||||||
|
|
|
@ -7,11 +7,10 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
ini "gopkg.in/ini.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_loadMailerFrom(t *testing.T) {
|
func Test_loadMailerFrom(t *testing.T) {
|
||||||
iniFile := ini.Empty()
|
iniFile := NewEmptyConfigProvider()
|
||||||
kases := map[string]*Mailer{
|
kases := map[string]*Mailer{
|
||||||
"smtp.mydomain.com": {
|
"smtp.mydomain.com": {
|
||||||
SMTPAddr: "smtp.mydomain.com",
|
SMTPAddr: "smtp.mydomain.com",
|
||||||
|
|
|
@ -8,8 +8,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
|
||||||
"gopkg.in/ini.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ExternalMarkupRenderers represents the external markup renderers
|
// ExternalMarkupRenderers represents the external markup renderers
|
||||||
|
@ -82,7 +80,7 @@ func loadMarkupFrom(rootCfg ConfigProvider) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMarkupSanitizer(name string, sec *ini.Section) {
|
func newMarkupSanitizer(name string, sec ConfigSection) {
|
||||||
rule, ok := createMarkupSanitizerRule(name, sec)
|
rule, ok := createMarkupSanitizerRule(name, sec)
|
||||||
if ok {
|
if ok {
|
||||||
if strings.HasPrefix(name, "sanitizer.") {
|
if strings.HasPrefix(name, "sanitizer.") {
|
||||||
|
@ -99,7 +97,7 @@ func newMarkupSanitizer(name string, sec *ini.Section) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMarkupSanitizerRule(name string, sec *ini.Section) (MarkupSanitizerRule, bool) {
|
func createMarkupSanitizerRule(name string, sec ConfigSection) (MarkupSanitizerRule, bool) {
|
||||||
var rule MarkupSanitizerRule
|
var rule MarkupSanitizerRule
|
||||||
|
|
||||||
ok := false
|
ok := false
|
||||||
|
@ -141,7 +139,7 @@ func createMarkupSanitizerRule(name string, sec *ini.Section) (MarkupSanitizerRu
|
||||||
return rule, true
|
return rule, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMarkupRenderer(name string, sec *ini.Section) {
|
func newMarkupRenderer(name string, sec ConfigSection) {
|
||||||
extensionReg := regexp.MustCompile(`\.\w`)
|
extensionReg := regexp.MustCompile(`\.\w`)
|
||||||
|
|
||||||
extensions := sec.Key("FILE_EXTENSIONS").Strings(",")
|
extensions := sec.Key("FILE_EXTENSIONS").Strings(",")
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
package setting
|
package setting
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
"math"
|
"math"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/generate"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
|
||||||
"gopkg.in/ini.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// OAuth2UsernameType is enum describing the way gitea 'name' should be generated from oauth2 data
|
// OAuth2UsernameType is enum describing the way gitea 'name' should be generated from oauth2 data
|
||||||
|
@ -80,7 +80,7 @@ func loadOAuth2ClientFrom(rootCfg ConfigProvider) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseScopes(sec *ini.Section, name string) []string {
|
func parseScopes(sec ConfigSection, name string) []string {
|
||||||
parts := sec.Key(name).Strings(" ")
|
parts := sec.Key(name).Strings(" ")
|
||||||
scopes := make([]string, 0, len(parts))
|
scopes := make([]string, 0, len(parts))
|
||||||
for _, scope := range parts {
|
for _, scope := range parts {
|
||||||
|
@ -119,4 +119,19 @@ func loadOAuth2From(rootCfg ConfigProvider) {
|
||||||
if !filepath.IsAbs(OAuth2.JWTSigningPrivateKeyFile) {
|
if !filepath.IsAbs(OAuth2.JWTSigningPrivateKeyFile) {
|
||||||
OAuth2.JWTSigningPrivateKeyFile = filepath.Join(AppDataPath, OAuth2.JWTSigningPrivateKeyFile)
|
OAuth2.JWTSigningPrivateKeyFile = filepath.Join(AppDataPath, OAuth2.JWTSigningPrivateKeyFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := make([]byte, 32)
|
||||||
|
n, err := base64.RawURLEncoding.Decode(key, []byte(OAuth2.JWTSecretBase64))
|
||||||
|
if err != nil || n != 32 {
|
||||||
|
key, err = generate.NewJwtSecret()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("error generating JWT secret: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
secretBase64 := base64.RawURLEncoding.EncodeToString(key)
|
||||||
|
rootCfg.Section("oauth2").Key("JWT_SECRET").SetValue(secretBase64)
|
||||||
|
if err := rootCfg.Save(); err != nil {
|
||||||
|
log.Fatal("save oauth2.JWT_SECRET failed: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import (
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
|
||||||
"github.com/dustin/go-humanize"
|
"github.com/dustin/go-humanize"
|
||||||
ini "gopkg.in/ini.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Package registry settings
|
// Package registry settings
|
||||||
|
@ -86,7 +85,7 @@ func loadPackagesFrom(rootCfg ConfigProvider) {
|
||||||
Packages.LimitSizeVagrant = mustBytes(sec, "LIMIT_SIZE_VAGRANT")
|
Packages.LimitSizeVagrant = mustBytes(sec, "LIMIT_SIZE_VAGRANT")
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustBytes(section *ini.Section, key string) int64 {
|
func mustBytes(section ConfigSection, key string) int64 {
|
||||||
const noLimit = "-1"
|
const noLimit = "-1"
|
||||||
|
|
||||||
value := section.Key(key).MustString(noLimit)
|
value := section.Key(key).MustString(noLimit)
|
||||||
|
|
|
@ -10,8 +10,6 @@ import (
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/container"
|
"code.gitea.io/gitea/modules/container"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
|
||||||
ini "gopkg.in/ini.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// QueueSettings represent the settings for a queue from the ini
|
// QueueSettings represent the settings for a queue from the ini
|
||||||
|
@ -195,7 +193,7 @@ func handleOldLengthConfiguration(rootCfg ConfigProvider, queueName, oldSection,
|
||||||
// toDirectlySetKeysSet returns a set of keys directly set by this section
|
// toDirectlySetKeysSet returns a set of keys directly set by this section
|
||||||
// Note: we cannot use section.HasKey(...) as that will immediately set the Key if a parent section has the Key
|
// Note: we cannot use section.HasKey(...) as that will immediately set the Key if a parent section has the Key
|
||||||
// but this section does not.
|
// but this section does not.
|
||||||
func toDirectlySetKeysSet(section *ini.Section) container.Set[string] {
|
func toDirectlySetKeysSet(section ConfigSection) container.Set[string] {
|
||||||
sections := make(container.Set[string])
|
sections := make(container.Set[string])
|
||||||
for _, key := range section.Keys() {
|
for _, key := range section.Keys() {
|
||||||
sections.Add(key.Name())
|
sections.Add(key.Name())
|
||||||
|
|
|
@ -11,8 +11,6 @@ import (
|
||||||
"code.gitea.io/gitea/modules/auth/password/hash"
|
"code.gitea.io/gitea/modules/auth/password/hash"
|
||||||
"code.gitea.io/gitea/modules/generate"
|
"code.gitea.io/gitea/modules/generate"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
|
||||||
ini "gopkg.in/ini.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -43,7 +41,7 @@ var (
|
||||||
|
|
||||||
// loadSecret load the secret from ini by uriKey or verbatimKey, only one of them could be set
|
// 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.
|
// 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 {
|
func loadSecret(sec ConfigSection, uriKey, verbatimKey string) string {
|
||||||
// don't allow setting both URI and verbatim string
|
// don't allow setting both URI and verbatim string
|
||||||
uri := sec.Key(uriKey).String()
|
uri := sec.Key(uriKey).String()
|
||||||
verbatim := sec.Key(verbatimKey).String()
|
verbatim := sec.Key(verbatimKey).String()
|
||||||
|
@ -84,16 +82,17 @@ func loadSecret(sec *ini.Section, uriKey, verbatimKey string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// generateSaveInternalToken generates and saves the internal token to app.ini
|
// generateSaveInternalToken generates and saves the internal token to app.ini
|
||||||
func generateSaveInternalToken() {
|
func generateSaveInternalToken(rootCfg ConfigProvider) {
|
||||||
token, err := generate.NewInternalToken()
|
token, err := generate.NewInternalToken()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error generate internal token: %v", err)
|
log.Fatal("Error generate internal token: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalToken = token
|
InternalToken = token
|
||||||
CreateOrAppendToCustomConf("security.INTERNAL_TOKEN", func(cfg *ini.File) {
|
rootCfg.Section("security").Key("INTERNAL_TOKEN").SetValue(token)
|
||||||
cfg.Section("security").Key("INTERNAL_TOKEN").SetValue(token)
|
if err := rootCfg.Save(); err != nil {
|
||||||
})
|
log.Fatal("Error saving internal token: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadSecurityFrom(rootCfg ConfigProvider) {
|
func loadSecurityFrom(rootCfg ConfigProvider) {
|
||||||
|
@ -141,7 +140,7 @@ func loadSecurityFrom(rootCfg ConfigProvider) {
|
||||||
if InstallLock && InternalToken == "" {
|
if InstallLock && InternalToken == "" {
|
||||||
// if Gitea has been installed but the InternalToken hasn't been generated (upgrade from an old release), we should generate
|
// if Gitea has been installed but the InternalToken hasn't been generated (upgrade from an old release), we should generate
|
||||||
// some users do cluster deployment, they still depend on this auto-generating behavior.
|
// some users do cluster deployment, they still depend on this auto-generating behavior.
|
||||||
generateSaveInternalToken()
|
generateSaveInternalToken(rootCfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfgdata := sec.Key("PASSWORD_COMPLEXITY").Strings(",")
|
cfgdata := sec.Key("PASSWORD_COMPLEXITY").Strings(",")
|
||||||
|
|
|
@ -18,9 +18,6 @@ import (
|
||||||
"code.gitea.io/gitea/modules/auth/password/hash"
|
"code.gitea.io/gitea/modules/auth/password/hash"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/user"
|
"code.gitea.io/gitea/modules/user"
|
||||||
"code.gitea.io/gitea/modules/util"
|
|
||||||
|
|
||||||
ini "gopkg.in/ini.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// settings
|
// settings
|
||||||
|
@ -208,17 +205,29 @@ func PrepareAppDataPath() error {
|
||||||
|
|
||||||
// InitProviderFromExistingFile initializes config provider from an existing config file (app.ini)
|
// InitProviderFromExistingFile initializes config provider from an existing config file (app.ini)
|
||||||
func InitProviderFromExistingFile() {
|
func InitProviderFromExistingFile() {
|
||||||
CfgProvider = newFileProviderFromConf(CustomConf, false, "")
|
var err error
|
||||||
|
CfgProvider, err = newConfigProviderFromFile(CustomConf, false, "")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("InitProviderFromExistingFile: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitProviderAllowEmpty initializes config provider from file, it's also fine that if the config file (app.ini) doesn't exist
|
// InitProviderAllowEmpty initializes config provider from file, it's also fine that if the config file (app.ini) doesn't exist
|
||||||
func InitProviderAllowEmpty() {
|
func InitProviderAllowEmpty() {
|
||||||
CfgProvider = newFileProviderFromConf(CustomConf, true, "")
|
var err error
|
||||||
|
CfgProvider, err = newConfigProviderFromFile(CustomConf, true, "")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("InitProviderAllowEmpty: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitProviderAndLoadCommonSettingsForTest initializes config provider and load common setttings for tests
|
// InitProviderAndLoadCommonSettingsForTest initializes config provider and load common setttings for tests
|
||||||
func InitProviderAndLoadCommonSettingsForTest(extraConfigs ...string) {
|
func InitProviderAndLoadCommonSettingsForTest(extraConfigs ...string) {
|
||||||
CfgProvider = newFileProviderFromConf(CustomConf, true, strings.Join(extraConfigs, "\n"))
|
var err error
|
||||||
|
CfgProvider, err = newConfigProviderFromFile(CustomConf, true, strings.Join(extraConfigs, "\n"))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("InitProviderAndLoadCommonSettingsForTest: %v", err)
|
||||||
|
}
|
||||||
loadCommonSettingsFrom(CfgProvider)
|
loadCommonSettingsFrom(CfgProvider)
|
||||||
if err := PrepareAppDataPath(); err != nil {
|
if err := PrepareAppDataPath(); err != nil {
|
||||||
log.Fatal("Can not prepare APP_DATA_PATH: %v", err)
|
log.Fatal("Can not prepare APP_DATA_PATH: %v", err)
|
||||||
|
@ -229,33 +238,6 @@ func InitProviderAndLoadCommonSettingsForTest(extraConfigs ...string) {
|
||||||
PasswordHashAlgo, _ = hash.SetDefaultPasswordHashAlgorithm("dummy")
|
PasswordHashAlgo, _ = hash.SetDefaultPasswordHashAlgorithm("dummy")
|
||||||
}
|
}
|
||||||
|
|
||||||
// newFileProviderFromConf initializes configuration context.
|
|
||||||
// NOTE: do not print any log except error.
|
|
||||||
func newFileProviderFromConf(customConf string, allowEmpty bool, extraConfig string) *ini.File {
|
|
||||||
cfg := ini.Empty()
|
|
||||||
|
|
||||||
isFile, err := util.IsFile(customConf)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Unable to check if %s is a file. Error: %v", customConf, err)
|
|
||||||
}
|
|
||||||
if isFile {
|
|
||||||
if err := cfg.Append(customConf); err != nil {
|
|
||||||
log.Fatal("Failed to load custom conf '%s': %v", customConf, err)
|
|
||||||
}
|
|
||||||
} else if !allowEmpty {
|
|
||||||
log.Fatal("Unable to find configuration file: %q.\nEnsure you are running in the correct environment or set the correct configuration file with -c.", CustomConf)
|
|
||||||
} // else: no config file, a config file might be created at CustomConf later (might not)
|
|
||||||
|
|
||||||
if extraConfig != "" {
|
|
||||||
if err = cfg.Append([]byte(extraConfig)); err != nil {
|
|
||||||
log.Fatal("Unable to append more config: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.NameMapper = ini.SnackCase
|
|
||||||
return cfg
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadCommonSettings loads common configurations from a configuration provider.
|
// LoadCommonSettings loads common configurations from a configuration provider.
|
||||||
func LoadCommonSettings() {
|
func LoadCommonSettings() {
|
||||||
loadCommonSettingsFrom(CfgProvider)
|
loadCommonSettingsFrom(CfgProvider)
|
||||||
|
@ -319,51 +301,6 @@ func loadRunModeFrom(rootCfg ConfigProvider) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOrAppendToCustomConf creates or updates the custom config.
|
|
||||||
// Use the callback to set individual values.
|
|
||||||
func CreateOrAppendToCustomConf(purpose string, callback func(cfg *ini.File)) {
|
|
||||||
if CustomConf == "" {
|
|
||||||
log.Error("Custom config path must not be empty")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg := ini.Empty()
|
|
||||||
isFile, err := util.IsFile(CustomConf)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Unable to check if %s is a file. Error: %v", CustomConf, err)
|
|
||||||
}
|
|
||||||
if isFile {
|
|
||||||
if err := cfg.Append(CustomConf); err != nil {
|
|
||||||
log.Error("failed to load custom conf %s: %v", CustomConf, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(cfg)
|
|
||||||
|
|
||||||
if err := os.MkdirAll(filepath.Dir(CustomConf), os.ModePerm); err != nil {
|
|
||||||
log.Fatal("failed to create '%s': %v", CustomConf, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := cfg.SaveTo(CustomConf); err != nil {
|
|
||||||
log.Fatal("error saving to custom config: %v", err)
|
|
||||||
}
|
|
||||||
log.Info("Settings for %s saved to: %q", purpose, CustomConf)
|
|
||||||
|
|
||||||
// Change permissions to be more restrictive
|
|
||||||
fi, err := os.Stat(CustomConf)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Failed to determine current conf file permissions: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if fi.Mode().Perm() > 0o600 {
|
|
||||||
if err = os.Chmod(CustomConf, 0o600); err != nil {
|
|
||||||
log.Warn("Failed changing conf file permissions to -rw-------. Consider changing them manually.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadSettings initializes the settings for normal start up
|
// LoadSettings initializes the settings for normal start up
|
||||||
func LoadSettings() {
|
func LoadSettings() {
|
||||||
loadDBSetting(CfgProvider)
|
loadDBSetting(CfgProvider)
|
||||||
|
|
|
@ -6,15 +6,13 @@ package setting
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
ini "gopkg.in/ini.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Storage represents configuration of storages
|
// Storage represents configuration of storages
|
||||||
type Storage struct {
|
type Storage struct {
|
||||||
Type string
|
Type string
|
||||||
Path string
|
Path string
|
||||||
Section *ini.Section
|
Section ConfigSection
|
||||||
ServeDirect bool
|
ServeDirect bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +28,7 @@ func (s *Storage) MapTo(v interface{}) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getStorage(rootCfg ConfigProvider, name, typ string, targetSec *ini.Section) Storage {
|
func getStorage(rootCfg ConfigProvider, name, typ string, targetSec ConfigSection) Storage {
|
||||||
const sectionName = "storage"
|
const sectionName = "storage"
|
||||||
sec := rootCfg.Section(sectionName)
|
sec := rootCfg.Section(sectionName)
|
||||||
|
|
||||||
|
@ -52,7 +50,7 @@ func getStorage(rootCfg ConfigProvider, name, typ string, targetSec *ini.Section
|
||||||
storage.Section = targetSec
|
storage.Section = targetSec
|
||||||
storage.Type = typ
|
storage.Type = typ
|
||||||
|
|
||||||
overrides := make([]*ini.Section, 0, 3)
|
overrides := make([]ConfigSection, 0, 3)
|
||||||
nameSec, err := rootCfg.GetSection(sectionName + "." + name)
|
nameSec, err := rootCfg.GetSection(sectionName + "." + name)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
overrides = append(overrides, nameSec)
|
overrides = append(overrides, nameSec)
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
ini "gopkg.in/ini.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_getStorageCustomType(t *testing.T) {
|
func Test_getStorageCustomType(t *testing.T) {
|
||||||
|
@ -20,7 +19,7 @@ MINIO_BUCKET = gitea-attachment
|
||||||
STORAGE_TYPE = minio
|
STORAGE_TYPE = minio
|
||||||
MINIO_ENDPOINT = my_minio:9000
|
MINIO_ENDPOINT = my_minio:9000
|
||||||
`
|
`
|
||||||
cfg, err := ini.Load([]byte(iniStr))
|
cfg, err := newConfigProviderFromData(iniStr)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
sec := cfg.Section("attachment")
|
sec := cfg.Section("attachment")
|
||||||
|
@ -43,7 +42,7 @@ MINIO_BUCKET = gitea-attachment
|
||||||
[storage.minio]
|
[storage.minio]
|
||||||
MINIO_BUCKET = gitea
|
MINIO_BUCKET = gitea
|
||||||
`
|
`
|
||||||
cfg, err := ini.Load([]byte(iniStr))
|
cfg, err := newConfigProviderFromData(iniStr)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
sec := cfg.Section("attachment")
|
sec := cfg.Section("attachment")
|
||||||
|
@ -65,7 +64,7 @@ MINIO_BUCKET = gitea-minio
|
||||||
[storage]
|
[storage]
|
||||||
MINIO_BUCKET = gitea
|
MINIO_BUCKET = gitea
|
||||||
`
|
`
|
||||||
cfg, err := ini.Load([]byte(iniStr))
|
cfg, err := newConfigProviderFromData(iniStr)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
sec := cfg.Section("attachment")
|
sec := cfg.Section("attachment")
|
||||||
|
@ -88,7 +87,7 @@ MINIO_BUCKET = gitea
|
||||||
[storage]
|
[storage]
|
||||||
STORAGE_TYPE = local
|
STORAGE_TYPE = local
|
||||||
`
|
`
|
||||||
cfg, err := ini.Load([]byte(iniStr))
|
cfg, err := newConfigProviderFromData(iniStr)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
sec := cfg.Section("attachment")
|
sec := cfg.Section("attachment")
|
||||||
|
@ -100,7 +99,7 @@ STORAGE_TYPE = local
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_getStorageGetDefaults(t *testing.T) {
|
func Test_getStorageGetDefaults(t *testing.T) {
|
||||||
cfg, err := ini.Load([]byte(""))
|
cfg, err := newConfigProviderFromData("")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
sec := cfg.Section("attachment")
|
sec := cfg.Section("attachment")
|
||||||
|
@ -121,7 +120,7 @@ MINIO_BUCKET = gitea-attachment
|
||||||
[storage]
|
[storage]
|
||||||
MINIO_BUCKET = gitea-storage
|
MINIO_BUCKET = gitea-storage
|
||||||
`
|
`
|
||||||
cfg, err := ini.Load([]byte(iniStr))
|
cfg, err := newConfigProviderFromData(iniStr)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -155,7 +154,7 @@ STORAGE_TYPE = lfs
|
||||||
[storage.lfs]
|
[storage.lfs]
|
||||||
MINIO_BUCKET = gitea-storage
|
MINIO_BUCKET = gitea-storage
|
||||||
`
|
`
|
||||||
cfg, err := ini.Load([]byte(iniStr))
|
cfg, err := newConfigProviderFromData(iniStr)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -179,7 +178,7 @@ func Test_getStorageInheritStorageType(t *testing.T) {
|
||||||
[storage]
|
[storage]
|
||||||
STORAGE_TYPE = minio
|
STORAGE_TYPE = minio
|
||||||
`
|
`
|
||||||
cfg, err := ini.Load([]byte(iniStr))
|
cfg, err := newConfigProviderFromData(iniStr)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
sec := cfg.Section("attachment")
|
sec := cfg.Section("attachment")
|
||||||
|
@ -194,7 +193,7 @@ func Test_getStorageInheritNameSectionType(t *testing.T) {
|
||||||
[storage.attachments]
|
[storage.attachments]
|
||||||
STORAGE_TYPE = minio
|
STORAGE_TYPE = minio
|
||||||
`
|
`
|
||||||
cfg, err := ini.Load([]byte(iniStr))
|
cfg, err := newConfigProviderFromData(iniStr)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
sec := cfg.Section("attachment")
|
sec := cfg.Section("attachment")
|
||||||
|
|
|
@ -18,14 +18,12 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/generate"
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt/v4"
|
"github.com/golang-jwt/jwt/v4"
|
||||||
"github.com/minio/sha256-simd"
|
"github.com/minio/sha256-simd"
|
||||||
ini "gopkg.in/ini.v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrInvalidAlgorithmType represents an invalid algorithm error.
|
// ErrInvalidAlgorithmType represents an invalid algorithm error.
|
||||||
|
@ -316,8 +314,7 @@ func InitSigningKey() error {
|
||||||
case "HS384":
|
case "HS384":
|
||||||
fallthrough
|
fallthrough
|
||||||
case "HS512":
|
case "HS512":
|
||||||
key, err = loadOrCreateSymmetricKey()
|
key, err = loadSymmetricKey()
|
||||||
|
|
||||||
case "RS256":
|
case "RS256":
|
||||||
fallthrough
|
fallthrough
|
||||||
case "RS384":
|
case "RS384":
|
||||||
|
@ -332,7 +329,6 @@ func InitSigningKey() error {
|
||||||
fallthrough
|
fallthrough
|
||||||
case "EdDSA":
|
case "EdDSA":
|
||||||
key, err = loadOrCreateAsymmetricKey()
|
key, err = loadOrCreateAsymmetricKey()
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ErrInvalidAlgorithmType{setting.OAuth2.JWTSigningAlgorithm}
|
return ErrInvalidAlgorithmType{setting.OAuth2.JWTSigningAlgorithm}
|
||||||
}
|
}
|
||||||
|
@ -351,22 +347,16 @@ func InitSigningKey() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadOrCreateSymmetricKey checks if the configured secret is valid.
|
// loadSymmetricKey checks if the configured secret is valid.
|
||||||
// If it is not valid a new secret is created and saved in the configuration file.
|
// If it is not valid, it will return an error.
|
||||||
func loadOrCreateSymmetricKey() (interface{}, error) {
|
func loadSymmetricKey() (interface{}, error) {
|
||||||
key := make([]byte, 32)
|
key := make([]byte, 32)
|
||||||
n, err := base64.RawURLEncoding.Decode(key, []byte(setting.OAuth2.JWTSecretBase64))
|
n, err := base64.RawURLEncoding.Decode(key, []byte(setting.OAuth2.JWTSecretBase64))
|
||||||
if err != nil || n != 32 {
|
if err != nil {
|
||||||
key, err = generate.NewJwtSecret()
|
return nil, err
|
||||||
if err != nil {
|
}
|
||||||
log.Fatal("error generating JWT secret: %v", err)
|
if n != 32 {
|
||||||
return nil, err
|
return nil, fmt.Errorf("JWT secret must be 32 bytes long")
|
||||||
}
|
|
||||||
|
|
||||||
setting.CreateOrAppendToCustomConf("oauth2.JWT_SECRET", func(cfg *ini.File) {
|
|
||||||
secretBase64 := base64.RawURLEncoding.EncodeToString(key)
|
|
||||||
cfg.Section("oauth2").Key("JWT_SECRET").SetValue(secretBase64)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return key, nil
|
return key, nil
|
||||||
|
|
Loading…
Reference in a new issue