Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5cf7da6

Browse files
lunnydelvh
andauthoredApr 25, 2023
Refactor config provider (#24245)
This PR introduces more abstract about `ConfigProvider` and hides more `ini` references. --------- Co-authored-by: delvh <[email protected]>
1 parent 56d4893 commit 5cf7da6

File tree

17 files changed

+227
-164
lines changed

17 files changed

+227
-164
lines changed
 

‎cmd/web.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424

2525
"github.com/felixge/fgprof"
2626
"github.com/urfave/cli"
27-
ini "gopkg.in/ini.v1"
2827
)
2928

3029
// PIDFile could be set from build tag
@@ -223,9 +222,10 @@ func setPort(port string) error {
223222
defaultLocalURL += ":" + setting.HTTPPort + "/"
224223

225224
// Save LOCAL_ROOT_URL if port changed
226-
setting.CreateOrAppendToCustomConf("server.LOCAL_ROOT_URL", func(cfg *ini.File) {
227-
cfg.Section("server").Key("LOCAL_ROOT_URL").SetValue(defaultLocalURL)
228-
})
225+
setting.CfgProvider.Section("server").Key("LOCAL_ROOT_URL").SetValue(defaultLocalURL)
226+
if err := setting.CfgProvider.Save(); err != nil {
227+
return fmt.Errorf("Failed to save config file: %v", err)
228+
}
229229
}
230230
return nil
231231
}

‎modules/indexer/issues/indexer_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
_ "code.gitea.io/gitea/models"
1717

1818
"github.com/stretchr/testify/assert"
19-
"gopkg.in/ini.v1"
2019
)
2120

2221
func TestMain(m *testing.M) {
@@ -27,7 +26,7 @@ func TestMain(m *testing.M) {
2726

2827
func TestBleveSearchIssues(t *testing.T) {
2928
assert.NoError(t, unittest.PrepareTestDatabase())
30-
setting.CfgProvider = ini.Empty()
29+
setting.CfgProvider = setting.NewEmptyConfigProvider()
3130

3231
tmpIndexerDir := t.TempDir()
3332

‎modules/indexer/stats/indexer_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import (
1818
_ "code.gitea.io/gitea/models"
1919

2020
"github.com/stretchr/testify/assert"
21-
"gopkg.in/ini.v1"
2221
)
2322

2423
func TestMain(m *testing.M) {
@@ -29,7 +28,7 @@ func TestMain(m *testing.M) {
2928

3029
func TestRepoStatsIndex(t *testing.T) {
3130
assert.NoError(t, unittest.PrepareTestDatabase())
32-
setting.CfgProvider = ini.Empty()
31+
setting.CfgProvider = setting.NewEmptyConfigProvider()
3332

3433
setting.LoadQueueSettings()
3534

‎modules/setting/config_provider.go

Lines changed: 141 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,157 @@
44
package setting
55

66
import (
7+
"fmt"
8+
"os"
9+
"path/filepath"
10+
"strings"
11+
712
"code.gitea.io/gitea/modules/log"
13+
"code.gitea.io/gitea/modules/util"
814

915
ini "gopkg.in/ini.v1"
1016
)
1117

18+
type ConfigSection interface {
19+
Name() string
20+
MapTo(interface{}) error
21+
HasKey(key string) bool
22+
NewKey(name, value string) (*ini.Key, error)
23+
Key(key string) *ini.Key
24+
Keys() []*ini.Key
25+
ChildSections() []*ini.Section
26+
}
27+
1228
// ConfigProvider represents a config provider
1329
type ConfigProvider interface {
14-
Section(section string) *ini.Section
15-
NewSection(name string) (*ini.Section, error)
16-
GetSection(name string) (*ini.Section, error)
30+
Section(section string) ConfigSection
31+
NewSection(name string) (ConfigSection, error)
32+
GetSection(name string) (ConfigSection, error)
33+
DeleteSection(name string) error
34+
Save() error
35+
}
36+
37+
type iniFileConfigProvider struct {
38+
*ini.File
39+
filepath string // the ini file path
40+
newFile bool // whether the file has not existed previously
41+
allowEmpty bool // whether not finding configuration files is allowed (only true for the tests)
42+
}
43+
44+
// NewEmptyConfigProvider create a new empty config provider
45+
func NewEmptyConfigProvider() ConfigProvider {
46+
cp, _ := newConfigProviderFromData("")
47+
return cp
48+
}
49+
50+
// newConfigProviderFromData this function is only for testing
51+
func newConfigProviderFromData(configContent string) (ConfigProvider, error) {
52+
var cfg *ini.File
53+
var err error
54+
if configContent == "" {
55+
cfg = ini.Empty()
56+
} else {
57+
cfg, err = ini.Load(strings.NewReader(configContent))
58+
if err != nil {
59+
return nil, err
60+
}
61+
}
62+
cfg.NameMapper = ini.SnackCase
63+
return &iniFileConfigProvider{
64+
File: cfg,
65+
newFile: true,
66+
}, nil
67+
}
68+
69+
// newConfigProviderFromFile load configuration from file.
70+
// NOTE: do not print any log except error.
71+
func newConfigProviderFromFile(customConf string, allowEmpty bool, extraConfig string) (*iniFileConfigProvider, error) {
72+
cfg := ini.Empty()
73+
newFile := true
74+
75+
if customConf != "" {
76+
isFile, err := util.IsFile(customConf)
77+
if err != nil {
78+
return nil, fmt.Errorf("unable to check if %s is a file. Error: %v", customConf, err)
79+
}
80+
if isFile {
81+
if err := cfg.Append(customConf); err != nil {
82+
return nil, fmt.Errorf("failed to load custom conf '%s': %v", customConf, err)
83+
}
84+
newFile = false
85+
}
86+
}
87+
88+
if newFile && !allowEmpty {
89+
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)
90+
}
91+
92+
if extraConfig != "" {
93+
if err := cfg.Append([]byte(extraConfig)); err != nil {
94+
return nil, fmt.Errorf("unable to append more config: %v", err)
95+
}
96+
}
97+
98+
cfg.NameMapper = ini.SnackCase
99+
return &iniFileConfigProvider{
100+
File: cfg,
101+
filepath: customConf,
102+
newFile: newFile,
103+
allowEmpty: allowEmpty,
104+
}, nil
105+
}
106+
107+
func (p *iniFileConfigProvider) Section(section string) ConfigSection {
108+
return p.File.Section(section)
109+
}
110+
111+
func (p *iniFileConfigProvider) NewSection(name string) (ConfigSection, error) {
112+
return p.File.NewSection(name)
113+
}
114+
115+
func (p *iniFileConfigProvider) GetSection(name string) (ConfigSection, error) {
116+
return p.File.GetSection(name)
117+
}
118+
119+
func (p *iniFileConfigProvider) DeleteSection(name string) error {
120+
p.File.DeleteSection(name)
121+
return nil
122+
}
123+
124+
// Save save the content into file
125+
func (p *iniFileConfigProvider) Save() error {
126+
if p.filepath == "" {
127+
if !p.allowEmpty {
128+
return fmt.Errorf("custom config path must not be empty")
129+
}
130+
return nil
131+
}
132+
133+
if p.newFile {
134+
if err := os.MkdirAll(filepath.Dir(CustomConf), os.ModePerm); err != nil {
135+
return fmt.Errorf("failed to create '%s': %v", CustomConf, err)
136+
}
137+
}
138+
if err := p.SaveTo(p.filepath); err != nil {
139+
return fmt.Errorf("failed to save '%s': %v", p.filepath, err)
140+
}
141+
142+
// Change permissions to be more restrictive
143+
fi, err := os.Stat(CustomConf)
144+
if err != nil {
145+
return fmt.Errorf("failed to determine current conf file permissions: %v", err)
146+
}
147+
148+
if fi.Mode().Perm() > 0o600 {
149+
if err = os.Chmod(CustomConf, 0o600); err != nil {
150+
log.Warn("Failed changing conf file permissions to -rw-------. Consider changing them manually.")
151+
}
152+
}
153+
return nil
17154
}
18155

19156
// a file is an implementation ConfigProvider and other implementations are possible, i.e. from docker, k8s, …
20-
var _ ConfigProvider = &ini.File{}
157+
var _ ConfigProvider = &iniFileConfigProvider{}
21158

22159
func mustMapSetting(rootCfg ConfigProvider, sectionName string, setting interface{}) {
23160
if err := rootCfg.Section(sectionName).MapTo(setting); err != nil {

‎modules/setting/cron_test.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"testing"
88

99
"github.com/stretchr/testify/assert"
10-
ini "gopkg.in/ini.v1"
1110
)
1211

1312
func Test_getCronSettings(t *testing.T) {
@@ -23,11 +22,11 @@ func Test_getCronSettings(t *testing.T) {
2322

2423
iniStr := `
2524
[cron.test]
26-
Base = true
27-
Second = white rabbit
28-
Extend = true
25+
BASE = true
26+
SECOND = white rabbit
27+
EXTEND = true
2928
`
30-
cfg, err := ini.Load([]byte(iniStr))
29+
cfg, err := newConfigProviderFromData(iniStr)
3130
assert.NoError(t, err)
3231

3332
extended := &Extended{

‎modules/setting/lfs.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ import (
99

1010
"code.gitea.io/gitea/modules/generate"
1111
"code.gitea.io/gitea/modules/log"
12-
13-
ini "gopkg.in/ini.v1"
1412
)
1513

1614
// LFS represents the configuration for Git LFS
@@ -38,8 +36,7 @@ func loadLFSFrom(rootCfg ConfigProvider) {
3836
// DEPRECATED should not be removed because users maybe upgrade from lower version to the latest version
3937
// if these are removed, the warning will not be shown
4038
deprecatedSetting(rootCfg, "server", "LFS_CONTENT_PATH", "lfs", "PATH", "v1.19.0")
41-
lfsSec.Key("PATH").MustString(
42-
sec.Key("LFS_CONTENT_PATH").String())
39+
lfsSec.Key("PATH").MustString(sec.Key("LFS_CONTENT_PATH").String())
4340

4441
LFS.Storage = getStorage(rootCfg, "lfs", storageType, lfsSec)
4542

@@ -62,9 +59,11 @@ func loadLFSFrom(rootCfg ConfigProvider) {
6259
}
6360

6461
// Save secret
65-
CreateOrAppendToCustomConf("server.LFS_JWT_SECRET", func(cfg *ini.File) {
66-
cfg.Section("server").Key("LFS_JWT_SECRET").SetValue(LFS.JWTSecretBase64)
67-
})
62+
sec.Key("LFS_JWT_SECRET").SetValue(LFS.JWTSecretBase64)
63+
if err := rootCfg.Save(); err != nil {
64+
log.Fatal("Error saving JWT Secret for custom config: %v", err)
65+
return
66+
}
6867
}
6968
}
7069
}

‎modules/setting/log.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ import (
1515
"code.gitea.io/gitea/modules/json"
1616
"code.gitea.io/gitea/modules/log"
1717
"code.gitea.io/gitea/modules/util"
18-
19-
ini "gopkg.in/ini.v1"
2018
)
2119

2220
var (
@@ -131,12 +129,12 @@ type LogDescription struct {
131129
SubLogDescriptions []SubLogDescription
132130
}
133131

134-
func getLogLevel(section *ini.Section, key string, defaultValue log.Level) log.Level {
132+
func getLogLevel(section ConfigSection, key string, defaultValue log.Level) log.Level {
135133
value := section.Key(key).MustString(defaultValue.String())
136134
return log.FromString(value)
137135
}
138136

139-
func getStacktraceLogLevel(section *ini.Section, key, defaultValue string) string {
137+
func getStacktraceLogLevel(section ConfigSection, key, defaultValue string) string {
140138
value := section.Key(key).MustString(defaultValue)
141139
return log.FromString(value).String()
142140
}
@@ -165,7 +163,7 @@ func loadLogFrom(rootCfg ConfigProvider) {
165163
Log.EnableXORMLog = rootCfg.Section("log").Key("ENABLE_XORM_LOG").MustBool(true)
166164
}
167165

168-
func generateLogConfig(sec *ini.Section, name string, defaults defaultLogOptions) (mode, jsonConfig, levelName string) {
166+
func generateLogConfig(sec ConfigSection, name string, defaults defaultLogOptions) (mode, jsonConfig, levelName string) {
169167
level := getLogLevel(sec, "LEVEL", Log.Level)
170168
levelName = level.String()
171169
stacktraceLevelName := getStacktraceLogLevel(sec, "STACKTRACE_LEVEL", Log.StacktraceLogLevel)

‎modules/setting/mailer_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@ import (
77
"testing"
88

99
"github.com/stretchr/testify/assert"
10-
ini "gopkg.in/ini.v1"
1110
)
1211

1312
func Test_loadMailerFrom(t *testing.T) {
14-
iniFile := ini.Empty()
13+
iniFile := NewEmptyConfigProvider()
1514
kases := map[string]*Mailer{
1615
"smtp.mydomain.com": {
1716
SMTPAddr: "smtp.mydomain.com",

‎modules/setting/markup.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import (
88
"strings"
99

1010
"code.gitea.io/gitea/modules/log"
11-
12-
"gopkg.in/ini.v1"
1311
)
1412

1513
// ExternalMarkupRenderers represents the external markup renderers
@@ -82,7 +80,7 @@ func loadMarkupFrom(rootCfg ConfigProvider) {
8280
}
8381
}
8482

85-
func newMarkupSanitizer(name string, sec *ini.Section) {
83+
func newMarkupSanitizer(name string, sec ConfigSection) {
8684
rule, ok := createMarkupSanitizerRule(name, sec)
8785
if ok {
8886
if strings.HasPrefix(name, "sanitizer.") {
@@ -99,7 +97,7 @@ func newMarkupSanitizer(name string, sec *ini.Section) {
9997
}
10098
}
10199

102-
func createMarkupSanitizerRule(name string, sec *ini.Section) (MarkupSanitizerRule, bool) {
100+
func createMarkupSanitizerRule(name string, sec ConfigSection) (MarkupSanitizerRule, bool) {
103101
var rule MarkupSanitizerRule
104102

105103
ok := false
@@ -141,7 +139,7 @@ func createMarkupSanitizerRule(name string, sec *ini.Section) (MarkupSanitizerRu
141139
return rule, true
142140
}
143141

144-
func newMarkupRenderer(name string, sec *ini.Section) {
142+
func newMarkupRenderer(name string, sec ConfigSection) {
145143
extensionReg := regexp.MustCompile(`\.\w`)
146144

147145
extensions := sec.Key("FILE_EXTENSIONS").Strings(",")

‎modules/setting/oauth2.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
package setting
55

66
import (
7+
"encoding/base64"
78
"math"
89
"path/filepath"
910

11+
"code.gitea.io/gitea/modules/generate"
1012
"code.gitea.io/gitea/modules/log"
11-
12-
"gopkg.in/ini.v1"
1313
)
1414

1515
// OAuth2UsernameType is enum describing the way gitea 'name' should be generated from oauth2 data
@@ -80,7 +80,7 @@ func loadOAuth2ClientFrom(rootCfg ConfigProvider) {
8080
}
8181
}
8282

83-
func parseScopes(sec *ini.Section, name string) []string {
83+
func parseScopes(sec ConfigSection, name string) []string {
8484
parts := sec.Key(name).Strings(" ")
8585
scopes := make([]string, 0, len(parts))
8686
for _, scope := range parts {
@@ -119,4 +119,19 @@ func loadOAuth2From(rootCfg ConfigProvider) {
119119
if !filepath.IsAbs(OAuth2.JWTSigningPrivateKeyFile) {
120120
OAuth2.JWTSigningPrivateKeyFile = filepath.Join(AppDataPath, OAuth2.JWTSigningPrivateKeyFile)
121121
}
122+
123+
key := make([]byte, 32)
124+
n, err := base64.RawURLEncoding.Decode(key, []byte(OAuth2.JWTSecretBase64))
125+
if err != nil || n != 32 {
126+
key, err = generate.NewJwtSecret()
127+
if err != nil {
128+
log.Fatal("error generating JWT secret: %v", err)
129+
}
130+
131+
secretBase64 := base64.RawURLEncoding.EncodeToString(key)
132+
rootCfg.Section("oauth2").Key("JWT_SECRET").SetValue(secretBase64)
133+
if err := rootCfg.Save(); err != nil {
134+
log.Fatal("save oauth2.JWT_SECRET failed: %v", err)
135+
}
136+
}
122137
}

‎modules/setting/packages.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"code.gitea.io/gitea/modules/log"
1313

1414
"github.com/dustin/go-humanize"
15-
ini "gopkg.in/ini.v1"
1615
)
1716

1817
// Package registry settings
@@ -86,7 +85,7 @@ func loadPackagesFrom(rootCfg ConfigProvider) {
8685
Packages.LimitSizeVagrant = mustBytes(sec, "LIMIT_SIZE_VAGRANT")
8786
}
8887

89-
func mustBytes(section *ini.Section, key string) int64 {
88+
func mustBytes(section ConfigSection, key string) int64 {
9089
const noLimit = "-1"
9190

9291
value := section.Key(key).MustString(noLimit)

‎modules/setting/queue.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import (
1010

1111
"code.gitea.io/gitea/modules/container"
1212
"code.gitea.io/gitea/modules/log"
13-
14-
ini "gopkg.in/ini.v1"
1513
)
1614

1715
// QueueSettings represent the settings for a queue from the ini
@@ -195,7 +193,7 @@ func handleOldLengthConfiguration(rootCfg ConfigProvider, queueName, oldSection,
195193
// toDirectlySetKeysSet returns a set of keys directly set by this section
196194
// Note: we cannot use section.HasKey(...) as that will immediately set the Key if a parent section has the Key
197195
// but this section does not.
198-
func toDirectlySetKeysSet(section *ini.Section) container.Set[string] {
196+
func toDirectlySetKeysSet(section ConfigSection) container.Set[string] {
199197
sections := make(container.Set[string])
200198
for _, key := range section.Keys() {
201199
sections.Add(key.Name())

‎modules/setting/security.go

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ import (
1111
"code.gitea.io/gitea/modules/auth/password/hash"
1212
"code.gitea.io/gitea/modules/generate"
1313
"code.gitea.io/gitea/modules/log"
14-
15-
ini "gopkg.in/ini.v1"
1614
)
1715

1816
var (
@@ -43,7 +41,7 @@ var (
4341

4442
// loadSecret load the secret from ini by uriKey or verbatimKey, only one of them could be set
4543
// If the secret is loaded from uriKey (file), the file should be non-empty, to guarantee the behavior stable and clear.
46-
func loadSecret(sec *ini.Section, uriKey, verbatimKey string) string {
44+
func loadSecret(sec ConfigSection, uriKey, verbatimKey string) string {
4745
// don't allow setting both URI and verbatim string
4846
uri := sec.Key(uriKey).String()
4947
verbatim := sec.Key(verbatimKey).String()
@@ -84,16 +82,17 @@ func loadSecret(sec *ini.Section, uriKey, verbatimKey string) string {
8482
}
8583

8684
// generateSaveInternalToken generates and saves the internal token to app.ini
87-
func generateSaveInternalToken() {
85+
func generateSaveInternalToken(rootCfg ConfigProvider) {
8886
token, err := generate.NewInternalToken()
8987
if err != nil {
9088
log.Fatal("Error generate internal token: %v", err)
9189
}
9290

9391
InternalToken = token
94-
CreateOrAppendToCustomConf("security.INTERNAL_TOKEN", func(cfg *ini.File) {
95-
cfg.Section("security").Key("INTERNAL_TOKEN").SetValue(token)
96-
})
92+
rootCfg.Section("security").Key("INTERNAL_TOKEN").SetValue(token)
93+
if err := rootCfg.Save(); err != nil {
94+
log.Fatal("Error saving internal token: %v", err)
95+
}
9796
}
9897

9998
func loadSecurityFrom(rootCfg ConfigProvider) {
@@ -141,7 +140,7 @@ func loadSecurityFrom(rootCfg ConfigProvider) {
141140
if InstallLock && InternalToken == "" {
142141
// if Gitea has been installed but the InternalToken hasn't been generated (upgrade from an old release), we should generate
143142
// some users do cluster deployment, they still depend on this auto-generating behavior.
144-
generateSaveInternalToken()
143+
generateSaveInternalToken(rootCfg)
145144
}
146145

147146
cfgdata := sec.Key("PASSWORD_COMPLEXITY").Strings(",")

‎modules/setting/setting.go

Lines changed: 15 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ import (
1818
"code.gitea.io/gitea/modules/auth/password/hash"
1919
"code.gitea.io/gitea/modules/log"
2020
"code.gitea.io/gitea/modules/user"
21-
"code.gitea.io/gitea/modules/util"
22-
23-
ini "gopkg.in/ini.v1"
2421
)
2522

2623
// settings
@@ -208,17 +205,29 @@ func PrepareAppDataPath() error {
208205

209206
// InitProviderFromExistingFile initializes config provider from an existing config file (app.ini)
210207
func InitProviderFromExistingFile() {
211-
CfgProvider = newFileProviderFromConf(CustomConf, false, "")
208+
var err error
209+
CfgProvider, err = newConfigProviderFromFile(CustomConf, false, "")
210+
if err != nil {
211+
log.Fatal("InitProviderFromExistingFile: %v", err)
212+
}
212213
}
213214

214215
// InitProviderAllowEmpty initializes config provider from file, it's also fine that if the config file (app.ini) doesn't exist
215216
func InitProviderAllowEmpty() {
216-
CfgProvider = newFileProviderFromConf(CustomConf, true, "")
217+
var err error
218+
CfgProvider, err = newConfigProviderFromFile(CustomConf, true, "")
219+
if err != nil {
220+
log.Fatal("InitProviderAllowEmpty: %v", err)
221+
}
217222
}
218223

219224
// InitProviderAndLoadCommonSettingsForTest initializes config provider and load common setttings for tests
220225
func InitProviderAndLoadCommonSettingsForTest(extraConfigs ...string) {
221-
CfgProvider = newFileProviderFromConf(CustomConf, true, strings.Join(extraConfigs, "\n"))
226+
var err error
227+
CfgProvider, err = newConfigProviderFromFile(CustomConf, true, strings.Join(extraConfigs, "\n"))
228+
if err != nil {
229+
log.Fatal("InitProviderAndLoadCommonSettingsForTest: %v", err)
230+
}
222231
loadCommonSettingsFrom(CfgProvider)
223232
if err := PrepareAppDataPath(); err != nil {
224233
log.Fatal("Can not prepare APP_DATA_PATH: %v", err)
@@ -229,33 +238,6 @@ func InitProviderAndLoadCommonSettingsForTest(extraConfigs ...string) {
229238
PasswordHashAlgo, _ = hash.SetDefaultPasswordHashAlgorithm("dummy")
230239
}
231240

232-
// newFileProviderFromConf initializes configuration context.
233-
// NOTE: do not print any log except error.
234-
func newFileProviderFromConf(customConf string, allowEmpty bool, extraConfig string) *ini.File {
235-
cfg := ini.Empty()
236-
237-
isFile, err := util.IsFile(customConf)
238-
if err != nil {
239-
log.Error("Unable to check if %s is a file. Error: %v", customConf, err)
240-
}
241-
if isFile {
242-
if err := cfg.Append(customConf); err != nil {
243-
log.Fatal("Failed to load custom conf '%s': %v", customConf, err)
244-
}
245-
} else if !allowEmpty {
246-
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)
247-
} // else: no config file, a config file might be created at CustomConf later (might not)
248-
249-
if extraConfig != "" {
250-
if err = cfg.Append([]byte(extraConfig)); err != nil {
251-
log.Fatal("Unable to append more config: %v", err)
252-
}
253-
}
254-
255-
cfg.NameMapper = ini.SnackCase
256-
return cfg
257-
}
258-
259241
// LoadCommonSettings loads common configurations from a configuration provider.
260242
func LoadCommonSettings() {
261243
loadCommonSettingsFrom(CfgProvider)
@@ -319,51 +301,6 @@ func loadRunModeFrom(rootCfg ConfigProvider) {
319301
}
320302
}
321303

322-
// CreateOrAppendToCustomConf creates or updates the custom config.
323-
// Use the callback to set individual values.
324-
func CreateOrAppendToCustomConf(purpose string, callback func(cfg *ini.File)) {
325-
if CustomConf == "" {
326-
log.Error("Custom config path must not be empty")
327-
return
328-
}
329-
330-
cfg := ini.Empty()
331-
isFile, err := util.IsFile(CustomConf)
332-
if err != nil {
333-
log.Error("Unable to check if %s is a file. Error: %v", CustomConf, err)
334-
}
335-
if isFile {
336-
if err := cfg.Append(CustomConf); err != nil {
337-
log.Error("failed to load custom conf %s: %v", CustomConf, err)
338-
return
339-
}
340-
}
341-
342-
callback(cfg)
343-
344-
if err := os.MkdirAll(filepath.Dir(CustomConf), os.ModePerm); err != nil {
345-
log.Fatal("failed to create '%s': %v", CustomConf, err)
346-
return
347-
}
348-
if err := cfg.SaveTo(CustomConf); err != nil {
349-
log.Fatal("error saving to custom config: %v", err)
350-
}
351-
log.Info("Settings for %s saved to: %q", purpose, CustomConf)
352-
353-
// Change permissions to be more restrictive
354-
fi, err := os.Stat(CustomConf)
355-
if err != nil {
356-
log.Error("Failed to determine current conf file permissions: %v", err)
357-
return
358-
}
359-
360-
if fi.Mode().Perm() > 0o600 {
361-
if err = os.Chmod(CustomConf, 0o600); err != nil {
362-
log.Warn("Failed changing conf file permissions to -rw-------. Consider changing them manually.")
363-
}
364-
}
365-
}
366-
367304
// LoadSettings initializes the settings for normal start up
368305
func LoadSettings() {
369306
loadDBSetting(CfgProvider)

‎modules/setting/storage.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,13 @@ package setting
66
import (
77
"path/filepath"
88
"reflect"
9-
10-
ini "gopkg.in/ini.v1"
119
)
1210

1311
// Storage represents configuration of storages
1412
type Storage struct {
1513
Type string
1614
Path string
17-
Section *ini.Section
15+
Section ConfigSection
1816
ServeDirect bool
1917
}
2018

@@ -30,7 +28,7 @@ func (s *Storage) MapTo(v interface{}) error {
3028
return nil
3129
}
3230

33-
func getStorage(rootCfg ConfigProvider, name, typ string, targetSec *ini.Section) Storage {
31+
func getStorage(rootCfg ConfigProvider, name, typ string, targetSec ConfigSection) Storage {
3432
const sectionName = "storage"
3533
sec := rootCfg.Section(sectionName)
3634

@@ -52,7 +50,7 @@ func getStorage(rootCfg ConfigProvider, name, typ string, targetSec *ini.Section
5250
storage.Section = targetSec
5351
storage.Type = typ
5452

55-
overrides := make([]*ini.Section, 0, 3)
53+
overrides := make([]ConfigSection, 0, 3)
5654
nameSec, err := rootCfg.GetSection(sectionName + "." + name)
5755
if err == nil {
5856
overrides = append(overrides, nameSec)

‎modules/setting/storage_test.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"testing"
88

99
"github.com/stretchr/testify/assert"
10-
ini "gopkg.in/ini.v1"
1110
)
1211

1312
func Test_getStorageCustomType(t *testing.T) {
@@ -20,7 +19,7 @@ MINIO_BUCKET = gitea-attachment
2019
STORAGE_TYPE = minio
2120
MINIO_ENDPOINT = my_minio:9000
2221
`
23-
cfg, err := ini.Load([]byte(iniStr))
22+
cfg, err := newConfigProviderFromData(iniStr)
2423
assert.NoError(t, err)
2524

2625
sec := cfg.Section("attachment")
@@ -43,7 +42,7 @@ MINIO_BUCKET = gitea-attachment
4342
[storage.minio]
4443
MINIO_BUCKET = gitea
4544
`
46-
cfg, err := ini.Load([]byte(iniStr))
45+
cfg, err := newConfigProviderFromData(iniStr)
4746
assert.NoError(t, err)
4847

4948
sec := cfg.Section("attachment")
@@ -65,7 +64,7 @@ MINIO_BUCKET = gitea-minio
6564
[storage]
6665
MINIO_BUCKET = gitea
6766
`
68-
cfg, err := ini.Load([]byte(iniStr))
67+
cfg, err := newConfigProviderFromData(iniStr)
6968
assert.NoError(t, err)
7069

7170
sec := cfg.Section("attachment")
@@ -88,7 +87,7 @@ MINIO_BUCKET = gitea
8887
[storage]
8988
STORAGE_TYPE = local
9089
`
91-
cfg, err := ini.Load([]byte(iniStr))
90+
cfg, err := newConfigProviderFromData(iniStr)
9291
assert.NoError(t, err)
9392

9493
sec := cfg.Section("attachment")
@@ -100,7 +99,7 @@ STORAGE_TYPE = local
10099
}
101100

102101
func Test_getStorageGetDefaults(t *testing.T) {
103-
cfg, err := ini.Load([]byte(""))
102+
cfg, err := newConfigProviderFromData("")
104103
assert.NoError(t, err)
105104

106105
sec := cfg.Section("attachment")
@@ -121,7 +120,7 @@ MINIO_BUCKET = gitea-attachment
121120
[storage]
122121
MINIO_BUCKET = gitea-storage
123122
`
124-
cfg, err := ini.Load([]byte(iniStr))
123+
cfg, err := newConfigProviderFromData(iniStr)
125124
assert.NoError(t, err)
126125

127126
{
@@ -155,7 +154,7 @@ STORAGE_TYPE = lfs
155154
[storage.lfs]
156155
MINIO_BUCKET = gitea-storage
157156
`
158-
cfg, err := ini.Load([]byte(iniStr))
157+
cfg, err := newConfigProviderFromData(iniStr)
159158
assert.NoError(t, err)
160159

161160
{
@@ -179,7 +178,7 @@ func Test_getStorageInheritStorageType(t *testing.T) {
179178
[storage]
180179
STORAGE_TYPE = minio
181180
`
182-
cfg, err := ini.Load([]byte(iniStr))
181+
cfg, err := newConfigProviderFromData(iniStr)
183182
assert.NoError(t, err)
184183

185184
sec := cfg.Section("attachment")
@@ -194,7 +193,7 @@ func Test_getStorageInheritNameSectionType(t *testing.T) {
194193
[storage.attachments]
195194
STORAGE_TYPE = minio
196195
`
197-
cfg, err := ini.Load([]byte(iniStr))
196+
cfg, err := newConfigProviderFromData(iniStr)
198197
assert.NoError(t, err)
199198

200199
sec := cfg.Section("attachment")

‎services/auth/source/oauth2/jwtsigningkey.go

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,12 @@ import (
1818
"path/filepath"
1919
"strings"
2020

21-
"code.gitea.io/gitea/modules/generate"
2221
"code.gitea.io/gitea/modules/log"
2322
"code.gitea.io/gitea/modules/setting"
2423
"code.gitea.io/gitea/modules/util"
2524

2625
"github.com/golang-jwt/jwt/v4"
2726
"github.com/minio/sha256-simd"
28-
ini "gopkg.in/ini.v1"
2927
)
3028

3129
// ErrInvalidAlgorithmType represents an invalid algorithm error.
@@ -316,8 +314,7 @@ func InitSigningKey() error {
316314
case "HS384":
317315
fallthrough
318316
case "HS512":
319-
key, err = loadOrCreateSymmetricKey()
320-
317+
key, err = loadSymmetricKey()
321318
case "RS256":
322319
fallthrough
323320
case "RS384":
@@ -332,7 +329,6 @@ func InitSigningKey() error {
332329
fallthrough
333330
case "EdDSA":
334331
key, err = loadOrCreateAsymmetricKey()
335-
336332
default:
337333
return ErrInvalidAlgorithmType{setting.OAuth2.JWTSigningAlgorithm}
338334
}
@@ -351,22 +347,16 @@ func InitSigningKey() error {
351347
return nil
352348
}
353349

354-
// loadOrCreateSymmetricKey checks if the configured secret is valid.
355-
// If it is not valid a new secret is created and saved in the configuration file.
356-
func loadOrCreateSymmetricKey() (interface{}, error) {
350+
// loadSymmetricKey checks if the configured secret is valid.
351+
// If it is not valid, it will return an error.
352+
func loadSymmetricKey() (interface{}, error) {
357353
key := make([]byte, 32)
358354
n, err := base64.RawURLEncoding.Decode(key, []byte(setting.OAuth2.JWTSecretBase64))
359-
if err != nil || n != 32 {
360-
key, err = generate.NewJwtSecret()
361-
if err != nil {
362-
log.Fatal("error generating JWT secret: %v", err)
363-
return nil, err
364-
}
365-
366-
setting.CreateOrAppendToCustomConf("oauth2.JWT_SECRET", func(cfg *ini.File) {
367-
secretBase64 := base64.RawURLEncoding.EncodeToString(key)
368-
cfg.Section("oauth2").Key("JWT_SECRET").SetValue(secretBase64)
369-
})
355+
if err != nil {
356+
return nil, err
357+
}
358+
if n != 32 {
359+
return nil, fmt.Errorf("JWT secret must be 32 bytes long")
370360
}
371361

372362
return key, nil

0 commit comments

Comments
 (0)
Please sign in to comment.