From ea3b1c9b211f5766dfaba1ff007b3f09d71e97b8 Mon Sep 17 00:00:00 2001 From: Gianmaria Del Monte Date: Thu, 4 Nov 2021 10:55:48 +0100 Subject: [PATCH 1/4] Specify a list of allowed folders/files to be archived --- internal/http/services/archiver/handler.go | 76 ++++++++++++++++++---- 1 file changed, 62 insertions(+), 14 deletions(-) diff --git a/internal/http/services/archiver/handler.go b/internal/http/services/archiver/handler.go index 2a836f5156..5f72eb5604 100644 --- a/internal/http/services/archiver/handler.go +++ b/internal/http/services/archiver/handler.go @@ -31,6 +31,8 @@ import ( rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + "regexp" + "github.com/cs3org/reva/internal/http/services/archiver/manager" "github.com/cs3org/reva/pkg/errtypes" "github.com/cs3org/reva/pkg/rgrpc/todo/pool" @@ -52,17 +54,20 @@ type svc struct { log *zerolog.Logger walker walker.Walker downloader downloader.Downloader + + allowedFolders []*regexp.Regexp } // Config holds the config options that need to be passed down to all ocdav handlers type Config struct { - Prefix string `mapstructure:"prefix"` - GatewaySvc string `mapstructure:"gatewaysvc"` - Timeout int64 `mapstructure:"timeout"` - Insecure bool `mapstructure:"insecure"` - Name string `mapstructure:"name"` - MaxNumFiles int64 `mapstructure:"max_num_files"` - MaxSize int64 `mapstructure:"max_size"` + Prefix string `mapstructure:"prefix"` + GatewaySvc string `mapstructure:"gatewaysvc"` + Timeout int64 `mapstructure:"timeout"` + Insecure bool `mapstructure:"insecure"` + Name string `mapstructure:"name"` + MaxNumFiles int64 `mapstructure:"max_num_files"` + MaxSize int64 `mapstructure:"max_size"` + AllowedFolders []string `mapstructure:"allowed_folders"` } func init() { @@ -84,12 +89,23 @@ func New(conf map[string]interface{}, log *zerolog.Logger) (global.Service, erro return nil, err } + // compile all the regex for filtering folders + allowedFolderRegex := make([]*regexp.Regexp, 0, len(c.AllowedFolders)) + for _, s := range c.AllowedFolders { + regex, err := regexp.Compile(s) + if err != nil { + return nil, err + } + allowedFolderRegex = append(allowedFolderRegex, regex) + } + return &svc{ - config: c, - gtwClient: gtw, - downloader: downloader.NewDownloader(gtw, rhttp.Insecure(c.Insecure), rhttp.Timeout(time.Duration(c.Timeout*int64(time.Second)))), - walker: walker.NewWalker(gtw), - log: log, + config: c, + gtwClient: gtw, + downloader: downloader.NewDownloader(gtw, rhttp.Insecure(c.Insecure), rhttp.Timeout(time.Duration(c.Timeout*int64(time.Second)))), + walker: walker.NewWalker(gtw), + log: log, + allowedFolders: allowedFolderRegex, }, nil } @@ -110,7 +126,7 @@ func (s *svc) getFiles(ctx context.Context, files, ids []string) ([]string, erro return nil, errtypes.BadRequest("file and id lists are both empty") } - f := []string{} + f := make([]string, 0, len(files)+len(ids)) for _, id := range ids { // id is base64 encoded and after decoding has the form : @@ -142,7 +158,39 @@ func (s *svc) getFiles(ctx context.Context, files, ids []string) ([]string, erro } - return append(f, files...), nil + total := append(f, files...) + + // check if all the folders are allowed to be archived + err := s.allAllowed(total) + if err != nil { + return nil, err + } + + return total, nil +} + +// return true if path match with at least with one allowed folder regex +func (s *svc) isPathAllowed(path string) bool { + for _, reg := range s.allowedFolders { + if reg.MatchString(path) { + return true + } + } + return false +} + +// return nil if all the paths in the slide match with at least one allowed folder regex +func (s *svc) allAllowed(paths []string) error { + if len(s.allowedFolders) == 0 { + return nil + } + + for _, f := range paths { + if !s.isPathAllowed(f) { + return errtypes.BadRequest(fmt.Sprintf("resource at %s not allowed to be archived", f)) + } + } + return nil } func (s *svc) Handler() http.Handler { From 2bdfac9d8ea85221375e2b98e279b32f7d7846bc Mon Sep 17 00:00:00 2001 From: Gianmaria Del Monte Date: Thu, 4 Nov 2021 11:54:18 +0100 Subject: [PATCH 2/4] Add error message in the body of http response in case of error --- internal/http/services/archiver/handler.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/http/services/archiver/handler.go b/internal/http/services/archiver/handler.go index 5f72eb5604..2e20909e63 100644 --- a/internal/http/services/archiver/handler.go +++ b/internal/http/services/archiver/handler.go @@ -212,6 +212,7 @@ func (s *svc) Handler() http.Handler { if err != nil { s.log.Error().Msg(err.Error()) rw.WriteHeader(http.StatusBadRequest) + rw.Write([]byte(err.Error())) return } @@ -222,6 +223,7 @@ func (s *svc) Handler() http.Handler { if err != nil { s.log.Error().Msg(err.Error()) rw.WriteHeader(http.StatusInternalServerError) + rw.Write([]byte(err.Error())) return } From 099f579b8c56de5eadfb4d3670a7021868f23bb2 Mon Sep 17 00:00:00 2001 From: Gianmaria Del Monte Date: Thu, 4 Nov 2021 12:04:54 +0100 Subject: [PATCH 3/4] Add changelog --- changelog/unreleased/select-folders-to-be-archived.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 changelog/unreleased/select-folders-to-be-archived.md diff --git a/changelog/unreleased/select-folders-to-be-archived.md b/changelog/unreleased/select-folders-to-be-archived.md new file mode 100644 index 0000000000..9812acb1d6 --- /dev/null +++ b/changelog/unreleased/select-folders-to-be-archived.md @@ -0,0 +1,6 @@ +Enhancement: Specify a list of allowed folders/files to be archived + +Adds a configuration to the archiver service in order to specify +a list of folders (as regex) that can be archived. + +https://github.com/cs3org/reva/pull/2235 \ No newline at end of file From 8da98f4a179dc13bf8ecc0e7f181e9177f2bf906 Mon Sep 17 00:00:00 2001 From: Gianmaria Del Monte Date: Thu, 4 Nov 2021 13:17:18 +0100 Subject: [PATCH 4/4] Fix linter --- internal/http/services/archiver/handler.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/http/services/archiver/handler.go b/internal/http/services/archiver/handler.go index 2e20909e63..3d5106e8ec 100644 --- a/internal/http/services/archiver/handler.go +++ b/internal/http/services/archiver/handler.go @@ -212,7 +212,7 @@ func (s *svc) Handler() http.Handler { if err != nil { s.log.Error().Msg(err.Error()) rw.WriteHeader(http.StatusBadRequest) - rw.Write([]byte(err.Error())) + _, _ = rw.Write([]byte(err.Error())) return } @@ -223,7 +223,7 @@ func (s *svc) Handler() http.Handler { if err != nil { s.log.Error().Msg(err.Error()) rw.WriteHeader(http.StatusInternalServerError) - rw.Write([]byte(err.Error())) + _, _ = rw.Write([]byte(err.Error())) return }