From 4ed6b340c3d38a2a746590c73fcbb0c165705fc9 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 23 Jul 2024 07:56:24 +0200 Subject: [PATCH] feat!: simplified rule with regex instead of boolean BREAKING CHANGE: the "regex" field in the rule is now a regular expression instead of a boolean. --- README.md | 3 +-- go.mod | 1 + go.sum | 2 ++ lib/config.go | 7 ++++++- lib/config_test.go | 12 +++++------- lib/permissions.go | 19 ++++++------------- 6 files changed, 21 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 2a84c77..f24d810 100644 --- a/README.md +++ b/README.md @@ -108,8 +108,7 @@ users: modify: true # With this rule, the user CAN modify all files ending with .js. It uses # a regular expression. - - path: "^*.js$" - regex: true + - regex: "^.+\.js$" modify: true # CORS configuration diff --git a/go.mod b/go.mod index 1048ae2..9723c03 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/hacdias/webdav/v4 go 1.22 require ( + github.com/go-viper/mapstructure/v2 v2.0.0 github.com/rs/cors v1.11.0 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 diff --git a/go.sum b/go.sum index 3b7682a..b562a43 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/go-viper/mapstructure/v2 v2.0.0 h1:dhn8MZ1gZ0mzeodTG3jt5Vj/o87xZKuNAprG2mQfMfc= +github.com/go-viper/mapstructure/v2 v2.0.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= diff --git a/lib/config.go b/lib/config.go index 67f9ec0..93e7c3e 100644 --- a/lib/config.go +++ b/lib/config.go @@ -6,6 +6,7 @@ import ( "path/filepath" "strings" + "github.com/go-viper/mapstructure/v2" "github.com/spf13/pflag" "github.com/spf13/viper" ) @@ -101,7 +102,11 @@ func ParseConfig(filename string, flags *pflag.FlagSet) (*Config, error) { } cfg := &Config{} - err = v.Unmarshal(cfg) + err = v.Unmarshal(cfg, viper.DecodeHook(mapstructure.ComposeDecodeHookFunc( + mapstructure.StringToTimeDurationHookFunc(), + mapstructure.StringToSliceHookFunc(","), + mapstructure.TextUnmarshallerHookFunc(), + ))) if err != nil { return nil, err } diff --git a/lib/config_test.go b/lib/config_test.go index a16394d..21291fc 100644 --- a/lib/config_test.go +++ b/lib/config_test.go @@ -176,11 +176,9 @@ auth: false scope: / modify: true rules: - - path: '^.+\.js$' - regex: true + - regex: '^.+\.js$' modify: true - path: /public/access/ - regex: false modify: true` cfg := writeAndParseConfig(t, content, ".yaml") @@ -189,12 +187,12 @@ rules: require.Len(t, cfg.Rules, 2) require.Empty(t, cfg.Rules[0].Path) - require.NotNil(t, cfg.Rules[0].Regexp) - require.True(t, cfg.Rules[0].Regexp.MatchString("/my/path/to/file.js")) - require.False(t, cfg.Rules[0].Regexp.MatchString("/my/path/to/file.ts")) + require.NotNil(t, cfg.Rules[0].Regex) + require.True(t, cfg.Rules[0].Regex.MatchString("/my/path/to/file.js")) + require.False(t, cfg.Rules[0].Regex.MatchString("/my/path/to/file.ts")) require.NotEmpty(t, cfg.Rules[1].Path) - require.Nil(t, cfg.Rules[1].Regexp) + require.Nil(t, cfg.Rules[1].Regex) } func TestConfigEnv(t *testing.T) { diff --git a/lib/permissions.go b/lib/permissions.go index ddf66d9..849fcf0 100644 --- a/lib/permissions.go +++ b/lib/permissions.go @@ -1,6 +1,7 @@ package lib import ( + "errors" "fmt" "net/http" "regexp" @@ -15,23 +16,15 @@ var readMethods = []string{ } type Rule struct { - Regex bool Allow bool Modify bool Path string - // TODO: remove Regex and replace by this. It encodes - Regexp *regexp.Regexp `mapstructure:"-"` + Regex *regexp.Regexp } func (r *Rule) Validate() error { - if r.Regex { - rp, err := regexp.Compile(r.Path) - if err != nil { - return fmt.Errorf("invalid rule: %w", err) - } - r.Regexp = rp - r.Path = "" - r.Regex = false + if r.Regex != nil && r.Path != "" { + return errors.New("invalid rule: cannot define both regex and path") } return nil @@ -39,8 +32,8 @@ func (r *Rule) Validate() error { // Matches checks if [Rule] matches the given path. func (r *Rule) Matches(path string) bool { - if r.Regexp != nil { - return r.Regexp.MatchString(path) + if r.Regex != nil { + return r.Regex.MatchString(path) } return strings.HasPrefix(path, r.Path)