diff --git a/filesystem.go b/filesystem.go index cec9633..447b7ef 100644 --- a/filesystem.go +++ b/filesystem.go @@ -16,12 +16,13 @@ const writeFlag = os.O_RDWR | os.O_CREATE | os.O_TRUNC // WriteOnlyOnceFileSystem is a file write only wrapper for a webdav.FileSystem type WriteOnlyOnceFileSystem struct { - fs webdav.FileSystem + Filters []Filter + fs webdav.FileSystem } // NewWriteOnlyOnceFileSystem returns a new WriteOnlyOnceFileSystem wrapping a webdav.FileSystem func NewWriteOnlyOnceFileSystem(fs webdav.FileSystem) *WriteOnlyOnceFileSystem { - return &WriteOnlyOnceFileSystem{fs} + return &WriteOnlyOnceFileSystem{fs: fs} } // Mkdir is not permitted @@ -38,6 +39,12 @@ func (fs *WriteOnlyOnceFileSystem) OpenFile(ctx context.Context, name string, fl return nil, ErrWonly } } + for _, filter := range fs.Filters { + err = filter.Filter(name) + if err != nil { + return nil, err + } + } f, err := fs.fs.OpenFile(ctx, name, flag, perm) if err != nil { return nil, err @@ -45,8 +52,15 @@ func (fs *WriteOnlyOnceFileSystem) OpenFile(ctx context.Context, name string, fl return &File{f}, nil } -// RemoveAll is not permitted +// RemoveAll only permits deleting empty files func (fs *WriteOnlyOnceFileSystem) RemoveAll(ctx context.Context, name string) error { + fi, err := fs.fs.Stat(ctx, name) + if err != nil { + return err + } + if fi.Mode().IsRegular() && fi.Size() == 0 { + return fs.fs.RemoveAll(ctx, name) + } return ErrWonly } diff --git a/filter.go b/filter.go new file mode 100644 index 0000000..7c6d442 --- /dev/null +++ b/filter.go @@ -0,0 +1,44 @@ +// Copyright (C) 2019 Marius Schellenberger + +package authdav + +import ( + "errors" + "path/filepath" + "strings" +) + +type Matcher func(path string) bool + +type Filter interface { + Filter(path string) error +} + +var ErrMacOSFilter = errors.New("authdav: MacOS filter: access denied") + +type MacOSFilter struct { + match []Matcher +} + +func NewMacOSFilter() *MacOSFilter { + return &MacOSFilter{ + match: []Matcher{ + func(p string) { + return p == ".DS_Store" + }, + func(p string) { + return strings.HasPrefix(p, "._") + }, + }, + } +} + +func (f *MacOSFilter) Filter(path string) error { + _, f := filepath.Split(path) + for _, m := range f.match { + if m(f) { + return ErrMacOSFilter + } + } + return nil +} diff --git a/go.mod b/go.mod index ac73fd3..02cb02c 100644 --- a/go.mod +++ b/go.mod @@ -1 +1,5 @@ module git.giftfish.de/ston1th/authdav + +go 1.12 + +require golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..dc1e52d --- /dev/null +++ b/go.sum @@ -0,0 +1,5 @@ +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=