From f4f0554ce7ee767e72ee61772e7e84fc262cf2e4 Mon Sep 17 00:00:00 2001 From: Christian Richter Date: Thu, 1 Feb 2024 12:20:39 +0100 Subject: [PATCH] Add filename incrementor for secret filedrops. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jörn Dreyer Signed-off-by: Christian Richter --- .../fileincrementor-for-secret-file-drops.md | 7 +++ internal/http/services/owncloud/ocdav/dav.go | 4 +- internal/http/services/owncloud/ocdav/tus.go | 47 +++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 changelog/unreleased/fileincrementor-for-secret-file-drops.md diff --git a/changelog/unreleased/fileincrementor-for-secret-file-drops.md b/changelog/unreleased/fileincrementor-for-secret-file-drops.md new file mode 100644 index 0000000000..13dca6ef11 --- /dev/null +++ b/changelog/unreleased/fileincrementor-for-secret-file-drops.md @@ -0,0 +1,7 @@ +Enhancement: Add filename incrementor for secret filedrops + +We have added a function that appends a number to the filename if the file already exists in a secret filedrop. +This is useful if you want to upload a file with the same name multiple times. + +https://github.com/cs3org/reva/pull/4491 +https://github.com/owncloud/ocis/issues/8291 \ No newline at end of file diff --git a/internal/http/services/owncloud/ocdav/dav.go b/internal/http/services/owncloud/ocdav/dav.go index 93e12da1de..f3e71586e2 100644 --- a/internal/http/services/owncloud/ocdav/dav.go +++ b/internal/http/services/owncloud/ocdav/dav.go @@ -318,9 +318,9 @@ func (h *DavHandler) Handler(s *svc) http.Handler { } log.Debug().Interface("statInfo", sRes.Info).Msg("Stat info from public link token path") + ctx := context.WithValue(ctx, tokenStatInfoKey{}, sRes.Info) + r = r.WithContext(ctx) if sRes.Info.Type != provider.ResourceType_RESOURCE_TYPE_CONTAINER { - ctx := context.WithValue(ctx, tokenStatInfoKey{}, sRes.Info) - r = r.WithContext(ctx) h.PublicFileHandler.Handler(s).ServeHTTP(w, r) } else { h.PublicFolderHandler.Handler(s).ServeHTTP(w, r) diff --git a/internal/http/services/owncloud/ocdav/tus.go b/internal/http/services/owncloud/ocdav/tus.go index c32f4022a6..6e2397eac7 100644 --- a/internal/http/services/owncloud/ocdav/tus.go +++ b/internal/http/services/owncloud/ocdav/tus.go @@ -24,6 +24,7 @@ import ( "io" "net/http" "path" + "path/filepath" "strconv" "strings" "time" @@ -115,6 +116,15 @@ func (s *svc) handleTusPost(ctx context.Context, w http.ResponseWriter, r *http. w.WriteHeader(http.StatusPreconditionFailed) return } + + var isSecretFileDrop bool + // Test if the target is a secret filedrop + tokenStatInfo := r.Context().Value(tokenStatInfoKey{}).(*provider.ResourceInfo) + // We assume that when the uploader can create containers, but is not allowed to list them, it is a secret file drop + if tokenStatInfo.GetPermissionSet().CreateContainer && !tokenStatInfo.GetPermissionSet().ListContainer { + isSecretFileDrop = true + } + // r.Header.Get(net.HeaderOCChecksum) // TODO must be SHA1, ADLER32 or MD5 ... in capital letters???? // curl -X PUT https://demo.owncloud.com/remote.php/webdav/testcs.bin -u demo:demo -d '123' -v -H 'OC-Checksum: SHA1:40bd001563085fc35165329ea1ff5c5ecbdbbeef' @@ -158,6 +168,43 @@ func (s *svc) handleTusPost(ctx context.Context, w http.ResponseWriter, r *http. return } } + if isSecretFileDrop { + lReq := &provider.ListContainerRequest{ + Ref: &provider.Reference{ + ResourceId: sRes.GetInfo().GetParentId(), + }, + } + lRes, err := client.ListContainer(ctx, lReq) + if err != nil { + log.Error().Err(err).Msg("error sending grpc stat request") + w.WriteHeader(http.StatusInternalServerError) + return + } + if lRes.Status.Code != rpc.Code_CODE_OK { + log.Debug().Err(err).Msg("error listing container") + errors.HandleErrorStatus(&log, w, lRes.Status) + return + } + // iterate over the listing to determine next suffix + var itemMap = make(map[string]struct{}) + for _, fi := range lRes.Infos { + itemMap[fi.GetName()] = struct{}{} + } + ext := filepath.Ext(sRes.GetInfo().GetName()) + fileName := strings.TrimSuffix(sRes.GetInfo().GetName(), ext) + if strings.HasSuffix(fileName, ".tar") { + fileName = strings.TrimSuffix(fileName, ".tar") + ext = filepath.Ext(fileName) + "." + ext + } + // starts with two because "normal" humans begin counting with 1 and we say the existing file is the first one + for i := 2; i < len(itemMap)+3; i++ { + if _, ok := itemMap[fileName+" ("+strconv.Itoa(i)+")"+ext]; !ok { + sRes.GetInfo().Name = fileName + " (" + strconv.Itoa(i) + ")" + ext + ref.Path = filepath.Join(filepath.Dir(ref.GetPath()), sRes.GetInfo().GetName()) + break + } + } + } } uploadLength, err := strconv.ParseInt(r.Header.Get(net.HeaderUploadLength), 10, 64)