mirror of
https://github.com/hacdias/webdav.git
synced 2026-10-19 16:15:39 +00:00
fix: correctly read user permissions and rules from env
This commit is contained in:
+26
-5
@@ -142,15 +142,33 @@ func ParseConfig(filename string, flags *pflag.FlagSet) (*Config, error) {
|
||||
return nil, fmt.Errorf("invalid config: user %q: %w", cfg.Users[i].Username, err)
|
||||
}
|
||||
|
||||
if !v.IsSet(fmt.Sprintf("Users.%d.Permissions", i)) {
|
||||
// Viper does not apply environment variables to fields of slice elements
|
||||
// when unmarshaling, so explicitly set values are read back with Get.
|
||||
userPermissionsKey := fmt.Sprintf("Users.%d.Permissions", i)
|
||||
if isExplicitlySet(v, flags, userPermissionsKey) {
|
||||
permissions := Permissions{}
|
||||
err := permissions.UnmarshalText([]byte(v.GetString(userPermissionsKey)))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid config: user %q: %w", cfg.Users[i].Username, err)
|
||||
}
|
||||
cfg.Users[i].Permissions = permissions
|
||||
} else {
|
||||
cfg.Users[i].Permissions = cfg.Permissions
|
||||
}
|
||||
|
||||
if !v.IsSet(fmt.Sprintf("Users.%d.RulesBehavior", i)) {
|
||||
userRulesBehaviorKey := fmt.Sprintf("Users.%d.RulesBehavior", i)
|
||||
if isExplicitlySet(v, flags, userRulesBehaviorKey) {
|
||||
cfg.Users[i].RulesBehavior = RulesBehavior(v.GetString(userRulesBehaviorKey))
|
||||
} else {
|
||||
cfg.Users[i].RulesBehavior = cfg.RulesBehavior
|
||||
}
|
||||
|
||||
if v.IsSet(fmt.Sprintf("Users.%d.Rules", i)) {
|
||||
userRulesKey := fmt.Sprintf("Users.%d.Rules", i)
|
||||
if os.Getenv(envKey(userRulesKey)) != "" {
|
||||
return nil, fmt.Errorf("invalid config: user %q: rules cannot be set via environment variables", cfg.Users[i].Username)
|
||||
}
|
||||
|
||||
if isExplicitlySet(v, flags, userRulesKey) {
|
||||
switch cfg.Users[i].RulesBehavior {
|
||||
case RulesOverwrite:
|
||||
// Do nothing
|
||||
@@ -208,11 +226,14 @@ func isExplicitlySet(v *viper.Viper, flags *pflag.FlagSet, key string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
envKey := "WD_" + strings.ToUpper(strings.ReplaceAll(key, ".", "_"))
|
||||
value, ok := os.LookupEnv(envKey)
|
||||
value, ok := os.LookupEnv(envKey(key))
|
||||
return ok && value != ""
|
||||
}
|
||||
|
||||
func envKey(key string) string {
|
||||
return "WD_" + strings.ToUpper(strings.ReplaceAll(key, ".", "_"))
|
||||
}
|
||||
|
||||
func (c *Config) Validate() error {
|
||||
var err error
|
||||
|
||||
|
||||
@@ -387,6 +387,130 @@ users:
|
||||
require.Equal(t, DirectoryMounts{{Name: filepath.Base(userMulti), Path: userMulti}}, cfg.Users[2].Directories)
|
||||
}
|
||||
|
||||
func TestConfigUserEnvOverrides(t *testing.T) {
|
||||
t.Setenv("WD_USERS_0_PERMISSIONS", "R")
|
||||
t.Setenv("WD_USERS_1_PERMISSIONS", "none")
|
||||
t.Setenv("WD_USERS_1_RULESBEHAVIOR", "overwrite")
|
||||
|
||||
cfg := writeAndParseConfig(t, `
|
||||
directory: /
|
||||
permissions: CRUD
|
||||
rulesBehavior: append
|
||||
rules:
|
||||
- path: /secret
|
||||
permissions: none
|
||||
users:
|
||||
- username: inherited
|
||||
password: inherited
|
||||
- username: own
|
||||
password: own
|
||||
permissions: CRUD
|
||||
rules:
|
||||
- path: /mine`, ".yml")
|
||||
require.NoError(t, cfg.Validate())
|
||||
|
||||
require.Equal(t, Permissions{Read: true}, cfg.Users[0].Permissions)
|
||||
require.Equal(t, RulesAppend, cfg.Users[0].RulesBehavior)
|
||||
require.Len(t, cfg.Users[0].Rules, 1)
|
||||
require.Equal(t, "/secret", cfg.Users[0].Rules[0].Path)
|
||||
|
||||
require.Equal(t, Permissions{}, cfg.Users[1].Permissions)
|
||||
require.Equal(t, RulesOverwrite, cfg.Users[1].RulesBehavior)
|
||||
require.Len(t, cfg.Users[1].Rules, 1)
|
||||
require.Equal(t, "/mine", cfg.Users[1].Rules[0].Path)
|
||||
}
|
||||
|
||||
func TestConfigUserRulesEnvRejected(t *testing.T) {
|
||||
t.Setenv("WD_USERS_0_RULES", "placeholder")
|
||||
|
||||
writeAndParseConfigWithError(t, `
|
||||
directory: /
|
||||
rules:
|
||||
- path: /secret
|
||||
permissions: none
|
||||
users:
|
||||
- username: foo
|
||||
password: bar`, ".yml", "rules cannot be set via environment variables")
|
||||
}
|
||||
|
||||
func TestConfigUserEnvPermissionsNone(t *testing.T) {
|
||||
t.Setenv("WD_USERS_0_PERMISSIONS", "none")
|
||||
|
||||
cfg := writeAndParseConfig(t, `
|
||||
directory: /
|
||||
permissions: CRUD
|
||||
rules:
|
||||
- path: /secret
|
||||
permissions: none
|
||||
users:
|
||||
- username: foo
|
||||
password: bar`, ".yml")
|
||||
require.NoError(t, cfg.Validate())
|
||||
|
||||
require.Equal(t, Permissions{}, cfg.Users[0].Permissions)
|
||||
require.Len(t, cfg.Users[0].Rules, 1)
|
||||
require.Equal(t, "/secret", cfg.Users[0].Rules[0].Path)
|
||||
}
|
||||
|
||||
func TestConfigUserEnvEmptyInherits(t *testing.T) {
|
||||
t.Setenv("WD_USERS_0_PERMISSIONS", "")
|
||||
t.Setenv("WD_USERS_0_RULESBEHAVIOR", "")
|
||||
t.Setenv("WD_USERS_0_RULES", "")
|
||||
|
||||
cfg := writeAndParseConfig(t, `
|
||||
directory: /
|
||||
permissions: CRUD
|
||||
rulesBehavior: append
|
||||
rules:
|
||||
- path: /secret
|
||||
permissions: none
|
||||
users:
|
||||
- username: foo
|
||||
password: bar`, ".yml")
|
||||
require.NoError(t, cfg.Validate())
|
||||
|
||||
require.Equal(t, cfg.Permissions, cfg.Users[0].Permissions)
|
||||
require.Equal(t, RulesAppend, cfg.Users[0].RulesBehavior)
|
||||
require.Len(t, cfg.Users[0].Rules, 1)
|
||||
require.Equal(t, "/secret", cfg.Users[0].Rules[0].Path)
|
||||
}
|
||||
|
||||
func TestConfigUserFileOverrides(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cfg := writeAndParseConfig(t, `
|
||||
directory: /
|
||||
permissions: CRUD
|
||||
rulesBehavior: append
|
||||
rules:
|
||||
- path: /secret
|
||||
permissions: none
|
||||
users:
|
||||
- username: none
|
||||
password: none
|
||||
permissions: none
|
||||
- username: overwrite
|
||||
password: overwrite
|
||||
rulesBehavior: overwrite
|
||||
rules:
|
||||
- path: /mine
|
||||
- username: empty
|
||||
password: empty
|
||||
rules:`, ".yml")
|
||||
require.NoError(t, cfg.Validate())
|
||||
|
||||
require.Equal(t, Permissions{}, cfg.Users[0].Permissions)
|
||||
require.Len(t, cfg.Users[0].Rules, 1)
|
||||
|
||||
require.Equal(t, RulesOverwrite, cfg.Users[1].RulesBehavior)
|
||||
require.Len(t, cfg.Users[1].Rules, 1)
|
||||
require.Equal(t, "/mine", cfg.Users[1].Rules[0].Path)
|
||||
|
||||
require.Equal(t, cfg.Permissions, cfg.Users[2].Permissions)
|
||||
require.Len(t, cfg.Users[2].Rules, 1)
|
||||
require.Equal(t, "/secret", cfg.Users[2].Rules[0].Path)
|
||||
}
|
||||
|
||||
func TestConfigKeys(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user