config: fix for slices with default values

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
Nicola Murino 2022-10-14 16:45:20 +02:00
parent 13ee236884
commit 07b3f2f4d6
No known key found for this signature in database
GPG key ID: 935D2952DEC4EECF
5 changed files with 135 additions and 18 deletions

12
go.mod
View file

@ -66,10 +66,10 @@ require (
go.etcd.io/bbolt v1.3.6
go.uber.org/automaxprocs v1.5.1
gocloud.dev v0.27.0
golang.org/x/crypto v0.0.0-20221010152910-d6f0a8c073c2
golang.org/x/net v0.0.0-20221004154528-8021a29435af
golang.org/x/crypto v0.0.0-20221012134737-56aed061732a
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b
golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1
golang.org/x/sys v0.0.0-20221010170243-090e33056c14
golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af
google.golang.org/api v0.98.0
gopkg.in/natefinch/lumberjack.v2 v2.0.0
@ -159,7 +159,7 @@ require (
golang.org/x/tools v0.1.12 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e // indirect
google.golang.org/genproto v0.0.0-20221013201013-33fc6f83cba4 // indirect
google.golang.org/grpc v1.50.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
@ -171,6 +171,6 @@ require (
replace (
github.com/jlaffaye/ftp => github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9
github.com/pkg/sftp => github.com/drakkan/sftp v0.0.0-20220930161944-e8c89afc13a7
golang.org/x/crypto => github.com/drakkan/crypto v0.0.0-20221011170652-7c454d6a47a0
golang.org/x/net => github.com/drakkan/net v0.0.0-20221011170324-793589996ca2
golang.org/x/crypto => github.com/drakkan/crypto v0.0.0-20221014140914-137f4b1d754c
golang.org/x/net => github.com/drakkan/net v0.0.0-20221014140113-499335f62da1
)

16
go.sum
View file

@ -535,12 +535,12 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/drakkan/crypto v0.0.0-20221011170652-7c454d6a47a0 h1:H8T0AOkrwrWacTEY8nP1PDQ+kUMeTQbCu8OY+x0/mXY=
github.com/drakkan/crypto v0.0.0-20221011170652-7c454d6a47a0/go.mod h1:SiM6ypd8Xu1xldObYtbDztuUU7xUzMnUULfphXFZmro=
github.com/drakkan/crypto v0.0.0-20221014140914-137f4b1d754c h1:McuxdVQM/jDDxZHZrtQySRNKaAqevQQcicZKisIAJ7Y=
github.com/drakkan/crypto v0.0.0-20221014140914-137f4b1d754c/go.mod h1:SiM6ypd8Xu1xldObYtbDztuUU7xUzMnUULfphXFZmro=
github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9 h1:LPH1dEblAOO/LoG7yHPMtBLXhQmjaga91/DDjWk9jWA=
github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9/go.mod h1:2lmrmq866uF2tnje75wQHzmPXhmSWUt7Gyx2vgK1RCU=
github.com/drakkan/net v0.0.0-20221011170324-793589996ca2 h1:nFZmCADOhW2YZ51/IKcODGsJsg3cX1VGVgjFDQYuVKs=
github.com/drakkan/net v0.0.0-20221011170324-793589996ca2/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
github.com/drakkan/net v0.0.0-20221014140113-499335f62da1 h1:v/AU5W67QpUA+kOOqxRosCTuvtzh9XYN8UAV448XaO0=
github.com/drakkan/net v0.0.0-20221014140113-499335f62da1/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
github.com/drakkan/sftp v0.0.0-20220930161944-e8c89afc13a7 h1:Hj7AAfZ5yt9QuCxSQDllRygmL33xJ2sZLOmcyyOAdYU=
github.com/drakkan/sftp v0.0.0-20220930161944-e8c89afc13a7/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
@ -1918,8 +1918,8 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20221010170243-090e33056c14 h1:k5II8e6QD8mITdi+okbbmR/cIyEbeXLBhy5Ha4nevyc=
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43 h1:OK7RB6t2WQX54srQQYSXMW8dF5C6/8+oA/s5QBmmto4=
golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@ -2209,8 +2209,8 @@ google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljW
google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220802133213-ce4fa296bf78/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc=
google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e h1:halCgTFuLWDRD61piiNSxPsARANGD3Xl16hPrLgLiIg=
google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U=
google.golang.org/genproto v0.0.0-20221013201013-33fc6f83cba4 h1:nZ28yoLJWNLTcERW43BN+JDsNQOdiZOFB9Dly/IUrjw=
google.golang.org/genproto v0.0.0-20221013201013-33fc6f83cba4/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=

View file

@ -427,7 +427,7 @@ func Init() {
},
},
MFAConfig: mfa.Config{
TOTP: nil,
TOTP: []mfa.TOTPConfig{defaultTOTP},
},
TelemetryConfig: telemetry.Conf{
BindPort: 0,
@ -659,6 +659,40 @@ func readEnvFiles(configDir string) {
}
}
func checkOverrideDefaultSettings() {
// for slices we need to set the defaults to nil if the key is set in the config file,
// otherwise the values are merged and not replaced as expected
rateLimiters := viper.Get("common.rate_limiters")
if val, ok := rateLimiters.([]any); ok {
if len(val) > 0 {
if rl, ok := val[0].(map[string]any); ok {
if _, ok := rl["protocols"]; ok {
globalConf.Common.RateLimitersConfig[0].Protocols = nil
}
}
}
}
httpdBindings := viper.Get("httpd.bindings")
if val, ok := httpdBindings.([]any); ok {
if len(val) > 0 {
if binding, ok := val[0].(map[string]any); ok {
if val, ok := binding["oidc"]; ok {
if oidc, ok := val.(map[string]any); ok {
if _, ok := oidc["scopes"]; ok {
globalConf.HTTPDConfig.Bindings[0].OIDC.Scopes = nil
}
}
}
}
}
}
if util.Contains(viper.AllKeys(), "mfa.totp") {
globalConf.MFAConfig.TOTP = nil
}
}
// LoadConfig loads the configuration
// configDir will be added to the configuration search paths.
// The search path contains by default the current directory and on linux it contains
@ -682,8 +716,8 @@ func LoadConfig(configDir, configFile string) error {
logger.Warn(logSender, "", "error loading configuration file: %v", err)
logger.WarnToConsole("error loading configuration file: %v", err)
}
globalConf.MFAConfig.TOTP = []mfa.TOTPConfig{defaultTOTP}
}
checkOverrideDefaultSettings()
err = viper.Unmarshal(&globalConf)
if err != nil {
logger.Warn(logSender, "", "error parsing configuration file: %v", err)

View file

@ -84,9 +84,13 @@ func TestLoadConfigFileNotFound(t *testing.T) {
viper.SetConfigName("configfile")
err := config.LoadConfig(os.TempDir(), "")
assert.NoError(t, err)
require.NoError(t, err)
mfaConf := config.GetMFAConfig()
assert.Len(t, mfaConf.TOTP, 1)
require.Len(t, mfaConf.TOTP, 1)
require.Len(t, config.GetCommonConfig().RateLimitersConfig, 1)
require.Len(t, config.GetCommonConfig().RateLimitersConfig[0].Protocols, 4)
require.Len(t, config.GetHTTPDConfig().Bindings, 1)
require.Len(t, config.GetHTTPDConfig().Bindings[0].OIDC.Scopes, 3)
}
func TestReadEnvFiles(t *testing.T) {
@ -489,6 +493,81 @@ func TestDisabledMFAConfig(t *testing.T) {
assert.NoError(t, err)
}
func TestOverrideSliceValues(t *testing.T) {
reset()
confName := tempConfigName + ".json"
configFilePath := filepath.Join(configDir, confName)
c := make(map[string]any)
c["common"] = common.Configuration{
RateLimitersConfig: []common.RateLimiterConfig{
{
Type: 1,
Protocols: []string{"HTTP"},
},
},
}
jsonConf, err := json.Marshal(c)
assert.NoError(t, err)
err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
assert.NoError(t, err)
err = config.LoadConfig(configDir, confName)
assert.NoError(t, err)
require.Len(t, config.GetCommonConfig().RateLimitersConfig, 1)
require.Equal(t, []string{"HTTP"}, config.GetCommonConfig().RateLimitersConfig[0].Protocols)
reset()
// empty ratelimiters, default value should be used
c["common"] = common.Configuration{}
jsonConf, err = json.Marshal(c)
assert.NoError(t, err)
err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
assert.NoError(t, err)
err = config.LoadConfig(configDir, confName)
assert.NoError(t, err)
require.Len(t, config.GetCommonConfig().RateLimitersConfig, 1)
rl := config.GetCommonConfig().RateLimitersConfig[0]
require.Equal(t, []string{"SSH", "FTP", "DAV", "HTTP"}, rl.Protocols)
require.Equal(t, int64(1000), rl.Period)
reset()
c = make(map[string]any)
c["httpd"] = httpd.Conf{
Bindings: []httpd.Binding{
{
OIDC: httpd.OIDC{
Scopes: []string{"scope1"},
},
},
},
}
jsonConf, err = json.Marshal(c)
assert.NoError(t, err)
err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
assert.NoError(t, err)
err = config.LoadConfig(configDir, confName)
assert.NoError(t, err)
require.Len(t, config.GetHTTPDConfig().Bindings, 1)
require.Equal(t, []string{"scope1"}, config.GetHTTPDConfig().Bindings[0].OIDC.Scopes)
reset()
c = make(map[string]any)
c["httpd"] = httpd.Conf{
Bindings: []httpd.Binding{},
}
jsonConf, err = json.Marshal(c)
assert.NoError(t, err)
err = os.WriteFile(configFilePath, jsonConf, os.ModePerm)
assert.NoError(t, err)
err = config.LoadConfig(configDir, confName)
assert.NoError(t, err)
require.Len(t, config.GetHTTPDConfig().Bindings, 1)
require.Equal(t, []string{"openid", "profile", "email"}, config.GetHTTPDConfig().Bindings[0].OIDC.Scopes)
}
func TestFTPDOverridesFromEnv(t *testing.T) {
reset()

View file

@ -21,6 +21,10 @@ Configuration file location:
C:\ProgramData\SFTPGo\sftpgo.json
Directory to create environment variable files to set configuration options:
C:\ProgramData\SFTPGo\env.d
Getting started guide:
https://github.com/drakkan/sftpgo/blob/main/docs/howto/getting-started.md