mirror of
https://github.com/drakkan/sftpgo.git
synced 2024-11-24 16:40:26 +00:00
config: fix for slices with default values
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
13ee236884
commit
07b3f2f4d6
5 changed files with 135 additions and 18 deletions
12
go.mod
12
go.mod
|
@ -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
16
go.sum
|
@ -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=
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue