From 932bb54e26a1f44c8b13a5ac2dad19fe618b9e2f Mon Sep 17 00:00:00 2001 From: Christian Richter Date: Thu, 1 Feb 2024 12:20:39 +0100 Subject: [PATCH 1/7] 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) From 98f91a4d39b1bf1f08ff7606c98f3bd954447f24 Mon Sep 17 00:00:00 2001 From: Christian Richter Date: Thu, 1 Feb 2024 13:29:42 +0100 Subject: [PATCH 2/7] Fix nil pointer 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 --- .../http/services/owncloud/ocdav/context.go | 18 +++++++++++++ internal/http/services/owncloud/ocdav/dav.go | 4 +-- .../services/owncloud/ocdav/errors/error.go | 2 ++ .../services/owncloud/ocdav/publicfile.go | 25 +++++++++++++------ internal/http/services/owncloud/ocdav/tus.go | 6 ++--- 5 files changed, 41 insertions(+), 14 deletions(-) create mode 100644 internal/http/services/owncloud/ocdav/context.go diff --git a/internal/http/services/owncloud/ocdav/context.go b/internal/http/services/owncloud/ocdav/context.go new file mode 100644 index 0000000000..ed48e6c323 --- /dev/null +++ b/internal/http/services/owncloud/ocdav/context.go @@ -0,0 +1,18 @@ +package ocdav + +import ( + "context" + + cs3storage "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" +) + +type tokenStatInfoKey struct{} + +func ContextWithTokenStatInfo(ctx context.Context, info *cs3storage.ResourceInfo) context.Context { + return context.WithValue(ctx, tokenStatInfoKey{}, info) +} + +func TokenStatInfoFromContext(ctx context.Context) (*cs3storage.ResourceInfo, bool) { + v, ok := ctx.Value(tokenStatInfoKey{}).(*cs3storage.ResourceInfo) + return v, ok +} diff --git a/internal/http/services/owncloud/ocdav/dav.go b/internal/http/services/owncloud/ocdav/dav.go index f3e71586e2..db26d729bd 100644 --- a/internal/http/services/owncloud/ocdav/dav.go +++ b/internal/http/services/owncloud/ocdav/dav.go @@ -44,8 +44,6 @@ const ( _trashbinPath = "trash-bin" ) -type tokenStatInfoKey struct{} - // DavHandler routes to the different sub handlers type DavHandler struct { AvatarsHandler *AvatarsHandler @@ -318,7 +316,7 @@ 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) + ctx := ContextWithTokenStatInfo(ctx, sRes.Info) r = r.WithContext(ctx) if sRes.Info.Type != provider.ResourceType_RESOURCE_TYPE_CONTAINER { h.PublicFileHandler.Handler(s).ServeHTTP(w, r) diff --git a/internal/http/services/owncloud/ocdav/errors/error.go b/internal/http/services/owncloud/ocdav/errors/error.go index b573dd20ad..78df1d1983 100644 --- a/internal/http/services/owncloud/ocdav/errors/error.go +++ b/internal/http/services/owncloud/ocdav/errors/error.go @@ -159,6 +159,8 @@ var ( ErrNoSuchLock = errors.New("webdav: no such lock") // ErrNotImplemented is returned when hitting not implemented code paths ErrNotImplemented = errors.New("webdav: not implemented") + // ErrTokenNotFound is returned when a token is not found + ErrTokenStatInfoMissing = errors.New("webdav: token stat info missing") ) // HandleErrorStatus checks the status code, logs a Debug or Error level message diff --git a/internal/http/services/owncloud/ocdav/publicfile.go b/internal/http/services/owncloud/ocdav/publicfile.go index 31c92616b2..91bfe5f1b4 100644 --- a/internal/http/services/owncloud/ocdav/publicfile.go +++ b/internal/http/services/owncloud/ocdav/publicfile.go @@ -26,7 +26,7 @@ import ( provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" - "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/errors" + ocdaverrors "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/errors" "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/net" "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/propfind" "github.com/cs3org/reva/v2/pkg/appctx" @@ -96,7 +96,16 @@ func (s *svc) handlePropfindOnToken(w http.ResponseWriter, r *http.Request, ns s ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "token_propfind") defer span.End() - tokenStatInfo := ctx.Value(tokenStatInfoKey{}).(*provider.ResourceInfo) + tokenStatInfo, ok := TokenStatInfoFromContext(ctx) + if !ok { + span.RecordError(ocdaverrors.ErrTokenStatInfoMissing) + span.SetStatus(codes.Error, ocdaverrors.ErrTokenStatInfoMissing.Error()) + span.SetAttributes(semconv.HTTPStatusCodeKey.Int(http.StatusInternalServerError)) + w.WriteHeader(http.StatusInternalServerError) + b, err := ocdaverrors.Marshal(http.StatusInternalServerError, ocdaverrors.ErrTokenStatInfoMissing.Error(), "") + ocdaverrors.HandleWebdavError(appctx.GetLogger(ctx), w, b, err) + return + } sublog := appctx.GetLogger(ctx).With().Interface("tokenStatInfo", tokenStatInfo).Logger() sublog.Debug().Msg("handlePropfindOnToken") @@ -109,20 +118,20 @@ func (s *svc) handlePropfindOnToken(w http.ResponseWriter, r *http.Request, ns s sublog.Debug().Str("depth", dh).Msg(err.Error()) w.WriteHeader(http.StatusBadRequest) m := fmt.Sprintf("Invalid Depth header value: %v", dh) - b, err := errors.Marshal(http.StatusBadRequest, m, "") - errors.HandleWebdavError(&sublog, w, b, err) + b, err := ocdaverrors.Marshal(http.StatusBadRequest, m, "") + ocdaverrors.HandleWebdavError(&sublog, w, b, err) return } if depth == net.DepthInfinity && !s.c.AllowPropfindDepthInfinitiy { - span.RecordError(errors.ErrInvalidDepth) + span.RecordError(ocdaverrors.ErrInvalidDepth) span.SetStatus(codes.Error, "DEPTH: infinity is not supported") span.SetAttributes(semconv.HTTPStatusCodeKey.Int(http.StatusBadRequest)) - sublog.Debug().Str("depth", dh).Msg(errors.ErrInvalidDepth.Error()) + sublog.Debug().Str("depth", dh).Msg(ocdaverrors.ErrInvalidDepth.Error()) w.WriteHeader(http.StatusBadRequest) m := fmt.Sprintf("Invalid Depth header value: %v", dh) - b, err := errors.Marshal(http.StatusBadRequest, m, "") - errors.HandleWebdavError(&sublog, w, b, err) + b, err := ocdaverrors.Marshal(http.StatusBadRequest, m, "") + ocdaverrors.HandleWebdavError(&sublog, w, b, err) return } diff --git a/internal/http/services/owncloud/ocdav/tus.go b/internal/http/services/owncloud/ocdav/tus.go index 6e2397eac7..95ba36aa84 100644 --- a/internal/http/services/owncloud/ocdav/tus.go +++ b/internal/http/services/owncloud/ocdav/tus.go @@ -117,11 +117,11 @@ func (s *svc) handleTusPost(ctx context.Context, w http.ResponseWriter, r *http. return } - var isSecretFileDrop bool // Test if the target is a secret filedrop - tokenStatInfo := r.Context().Value(tokenStatInfoKey{}).(*provider.ResourceInfo) + var isSecretFileDrop bool + tokenStatInfo, ok := TokenStatInfoFromContext(ctx) // 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 { + if ok && tokenStatInfo.GetPermissionSet().CreateContainer && !tokenStatInfo.GetPermissionSet().ListContainer { isSecretFileDrop = true } From 149e0743dbd2fd3692d1b5cd70c09ed14d79a829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Thu, 1 Feb 2024 16:23:11 +0100 Subject: [PATCH 3/7] extract FindName and use it for PUT and TUS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- .../http/services/owncloud/ocdav/filedrop.go | 47 +++++++++++++++++++ internal/http/services/owncloud/ocdav/put.go | 41 ++++++++++++++++ internal/http/services/owncloud/ocdav/tus.go | 35 +++----------- 3 files changed, 95 insertions(+), 28 deletions(-) create mode 100644 internal/http/services/owncloud/ocdav/filedrop.go diff --git a/internal/http/services/owncloud/ocdav/filedrop.go b/internal/http/services/owncloud/ocdav/filedrop.go new file mode 100644 index 0000000000..db0aee50fa --- /dev/null +++ b/internal/http/services/owncloud/ocdav/filedrop.go @@ -0,0 +1,47 @@ +package ocdav + +import ( + "context" + "errors" + "path/filepath" + "strconv" + "strings" + + gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" + rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" + provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" +) + +// FindName returns the next filename available when the current +func FindName(ctx context.Context, client gatewayv1beta1.GatewayAPIClient, name string, parentid *provider.ResourceId) (string, *rpc.Status, error) { + lReq := &provider.ListContainerRequest{ + Ref: &provider.Reference{ + ResourceId: parentid, + }, + } + lRes, err := client.ListContainer(ctx, lReq) + if err != nil { + return "", nil, err + } + if lRes.Status.Code != rpc.Code_CODE_OK { + return "", lRes.Status, nil + } + // 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(name) + fileName := strings.TrimSuffix(name, 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 { + return fileName + " (" + strconv.Itoa(i) + ")" + ext, nil, nil + } + } + return "", nil, errors.New("could not determine new filename") +} diff --git a/internal/http/services/owncloud/ocdav/put.go b/internal/http/services/owncloud/ocdav/put.go index 485629a3f4..5add5740dc 100644 --- a/internal/http/services/owncloud/ocdav/put.go +++ b/internal/http/services/owncloud/ocdav/put.go @@ -155,6 +155,47 @@ func (s *svc) handlePut(ctx context.Context, w http.ResponseWriter, r *http.Requ w.WriteHeader(http.StatusInternalServerError) return } + + // Test if the target is a secret filedrop + tokenStatInfo, ok := TokenStatInfoFromContext(ctx) + // We assume that when the uploader can create containers, but is not allowed to list them, it is a secret file drop + if ok && tokenStatInfo.GetPermissionSet().CreateContainer && !tokenStatInfo.GetPermissionSet().ListContainer { + // TODO we can skip this stat if the tokenStatInfo is the direct parent + sReq := &provider.StatRequest{ + Ref: ref, + } + sRes, err := client.Stat(ctx, sReq) + if err != nil { + log.Error().Err(err).Msg("error sending grpc stat request") + w.WriteHeader(http.StatusInternalServerError) + return + } + + // We also need to continue if we are not allowed to stat a resource. We may not have stat permission. That still means it exists and we need to find a new filename. + switch sRes.Status.Code { + case rpc.Code_CODE_OK, rpc.Code_CODE_PERMISSION_DENIED: + // find next filename + newName, status, err := FindName(ctx, client, filepath.Base(ref.Path), sRes.GetInfo().GetParentId()) + if err != nil { + log.Error().Err(err).Msg("error sending grpc stat request") + w.WriteHeader(http.StatusInternalServerError) + return + } + if status.Code != rpc.Code_CODE_OK { + log.Error().Interface("status", status).Msg("error listing file") + errors.HandleErrorStatus(&log, w, status) + return + } + ref.Path = utils.MakeRelativePath(filepath.Join(filepath.Dir(ref.GetPath()), newName)) + case rpc.Code_CODE_NOT_FOUND: + // just continue with normal upload + default: + log.Error().Interface("status", sRes.Status).Msg("error stating file") + errors.HandleErrorStatus(&log, w, sRes.Status) + return + } + } + opaque := &typespb.Opaque{} if mtime := r.Header.Get(net.HeaderOCMtime); mtime != "" { utils.AppendPlainToOpaque(opaque, net.HeaderOCMtime, mtime) diff --git a/internal/http/services/owncloud/ocdav/tus.go b/internal/http/services/owncloud/ocdav/tus.go index 95ba36aa84..d85c8ce92b 100644 --- a/internal/http/services/owncloud/ocdav/tus.go +++ b/internal/http/services/owncloud/ocdav/tus.go @@ -169,41 +169,20 @@ func (s *svc) handleTusPost(ctx context.Context, w http.ResponseWriter, r *http. } } if isSecretFileDrop { - lReq := &provider.ListContainerRequest{ - Ref: &provider.Reference{ - ResourceId: sRes.GetInfo().GetParentId(), - }, - } - lRes, err := client.ListContainer(ctx, lReq) + // find next filename + newName, status, err := FindName(ctx, client, filepath.Base(ref.Path), sRes.GetInfo().GetParentId()) 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) + if status.Code != rpc.Code_CODE_OK { + log.Error().Interface("status", status).Msg("error listing file") + errors.HandleErrorStatus(&log, w, 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 - } - } + ref.Path = utils.MakeRelativePath(filepath.Join(filepath.Dir(ref.GetPath()), newName)) + sRes.GetInfo().Name = newName } } From f0c6295fdae4a3c97e6e1cae3a9206d7a11d507c Mon Sep 17 00:00:00 2001 From: Christian Richter Date: Thu, 1 Feb 2024 16:32:31 +0100 Subject: [PATCH 4/7] Fix nil-pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jörn Friedrich Dreyer Signed-off-by: Christian Richter --- internal/http/services/owncloud/ocdav/filedrop.go | 2 +- internal/http/services/owncloud/ocdav/tus.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/http/services/owncloud/ocdav/filedrop.go b/internal/http/services/owncloud/ocdav/filedrop.go index db0aee50fa..53cb41799f 100644 --- a/internal/http/services/owncloud/ocdav/filedrop.go +++ b/internal/http/services/owncloud/ocdav/filedrop.go @@ -40,7 +40,7 @@ func FindName(ctx context.Context, client gatewayv1beta1.GatewayAPIClient, name // 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 { - return fileName + " (" + strconv.Itoa(i) + ")" + ext, nil, nil + return fileName + " (" + strconv.Itoa(i) + ")" + ext, lRes.GetStatus(), nil } } return "", nil, errors.New("could not determine new filename") diff --git a/internal/http/services/owncloud/ocdav/tus.go b/internal/http/services/owncloud/ocdav/tus.go index d85c8ce92b..bd5831d4eb 100644 --- a/internal/http/services/owncloud/ocdav/tus.go +++ b/internal/http/services/owncloud/ocdav/tus.go @@ -176,12 +176,12 @@ func (s *svc) handleTusPost(ctx context.Context, w http.ResponseWriter, r *http. w.WriteHeader(http.StatusInternalServerError) return } - if status.Code != rpc.Code_CODE_OK { + if status.GetCode() != rpc.Code_CODE_OK { log.Error().Interface("status", status).Msg("error listing file") errors.HandleErrorStatus(&log, w, status) return } - ref.Path = utils.MakeRelativePath(filepath.Join(filepath.Dir(ref.GetPath()), newName)) + ref.Path = filepath.Join(filepath.Dir(ref.GetPath()), newName) sRes.GetInfo().Name = newName } } From b7969841168b2c6ca84a32688a5e97395db68061 Mon Sep 17 00:00:00 2001 From: Christian Richter Date: Fri, 2 Feb 2024 09:46:05 +0100 Subject: [PATCH 5/7] add missing comments Signed-off-by: Christian Richter --- internal/http/services/owncloud/ocdav/context.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/http/services/owncloud/ocdav/context.go b/internal/http/services/owncloud/ocdav/context.go index ed48e6c323..7c0a6d443f 100644 --- a/internal/http/services/owncloud/ocdav/context.go +++ b/internal/http/services/owncloud/ocdav/context.go @@ -8,10 +8,12 @@ import ( type tokenStatInfoKey struct{} +// ContextWithTokenStatInfo adds the token stat info to the context func ContextWithTokenStatInfo(ctx context.Context, info *cs3storage.ResourceInfo) context.Context { return context.WithValue(ctx, tokenStatInfoKey{}, info) } +// TokenStatInfoFromContext returns the token stat info from the context func TokenStatInfoFromContext(ctx context.Context) (*cs3storage.ResourceInfo, bool) { v, ok := ctx.Value(tokenStatInfoKey{}).(*cs3storage.ResourceInfo) return v, ok From b961119ee40009b439d737f3e47ce0cc2b97965c Mon Sep 17 00:00:00 2001 From: Christian Richter Date: Fri, 2 Feb 2024 09:49:06 +0100 Subject: [PATCH 6/7] remove expected failure Signed-off-by: Christian Richter --- tests/acceptance/expected-failures-on-OCIS-storage.md | 9 +++++++-- tests/acceptance/expected-failures-on-S3NG-storage.md | 3 +-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/acceptance/expected-failures-on-OCIS-storage.md b/tests/acceptance/expected-failures-on-OCIS-storage.md index 558d886411..86273b45a9 100644 --- a/tests/acceptance/expected-failures-on-OCIS-storage.md +++ b/tests/acceptance/expected-failures-on-OCIS-storage.md @@ -75,8 +75,13 @@ Synchronization features like etag propagation, setting mtime and locking files #### [Upload-only shares must not overwrite but create a separate file](https://github.com/owncloud/ocis/issues/1267) -- [coreApiSharePublicLink2/uploadToPublicLinkShare.feature:13](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiSharePublicLink2/uploadToPublicLinkShare.feature#L13) -- [coreApiSharePublicLink2/uploadToPublicLinkShare.feature:121](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiSharePublicLink2/uploadToPublicLinkShare.feature#L121) +- [coreApiSharePublicLink3/uploadToPublicLinkShare.feature:13](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiSharePublicLink3/uploadToPublicLinkShare.feature#L13) + +#### [Set quota over settings](https://github.com/owncloud/ocis/issues/1290) +_requires a [CS3 user provisioning api that can update the quota for a user](https://github.com/cs3org/cs3apis/pull/95#issuecomment-772780683)_ + +- [coreApiSharePublicLink3/uploadToPublicLinkShare.feature:91](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiSharePublicLink3/uploadToPublicLinkShare.feature#L91) +- [coreApiSharePublicLink3/uploadToPublicLinkShare.feature:101](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiSharePublicLink3/uploadToPublicLinkShare.feature#L101) #### [oc:privatelink property not returned in webdav responses](https://github.com/owncloud/product/issues/262) - [coreApiWebdavProperties/getFileProperties.feature:295](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavProperties/getFileProperties.feature#L295) diff --git a/tests/acceptance/expected-failures-on-S3NG-storage.md b/tests/acceptance/expected-failures-on-S3NG-storage.md index aff004bf11..6005f52a46 100644 --- a/tests/acceptance/expected-failures-on-S3NG-storage.md +++ b/tests/acceptance/expected-failures-on-S3NG-storage.md @@ -74,8 +74,7 @@ Synchronization features like etag propagation, setting mtime and locking files #### [Upload-only shares must not overwrite but create a separate file](https://github.com/owncloud/ocis/issues/1267) -- [coreApiSharePublicLink2/uploadToPublicLinkShare.feature:13](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiSharePublicLink2/uploadToPublicLinkShare.feature#L13) -- [coreApiSharePublicLink2/uploadToPublicLinkShare.feature:121](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiSharePublicLink2/uploadToPublicLinkShare.feature#L121) +- [coreApiSharePublicLink3/uploadToPublicLinkShare.feature:13](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiSharePublicLink3/uploadToPublicLinkShare.feature#L13) #### [Set quota over settings](https://github.com/owncloud/ocis/issues/1290) _requires a [CS3 user provisioning api that can update the quota for a user](https://github.com/cs3org/cs3apis/pull/95#issuecomment-772780683)_ From 3a034feeb22f1f24a0041650f8a44489e561cdd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Fri, 2 Feb 2024 12:37:57 +0100 Subject: [PATCH 7/7] update expected failures --- tests/acceptance/expected-failures-on-OCIS-storage.md | 8 +------- tests/acceptance/expected-failures-on-S3NG-storage.md | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/tests/acceptance/expected-failures-on-OCIS-storage.md b/tests/acceptance/expected-failures-on-OCIS-storage.md index 86273b45a9..77200ddea4 100644 --- a/tests/acceptance/expected-failures-on-OCIS-storage.md +++ b/tests/acceptance/expected-failures-on-OCIS-storage.md @@ -75,13 +75,7 @@ Synchronization features like etag propagation, setting mtime and locking files #### [Upload-only shares must not overwrite but create a separate file](https://github.com/owncloud/ocis/issues/1267) -- [coreApiSharePublicLink3/uploadToPublicLinkShare.feature:13](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiSharePublicLink3/uploadToPublicLinkShare.feature#L13) - -#### [Set quota over settings](https://github.com/owncloud/ocis/issues/1290) -_requires a [CS3 user provisioning api that can update the quota for a user](https://github.com/cs3org/cs3apis/pull/95#issuecomment-772780683)_ - -- [coreApiSharePublicLink3/uploadToPublicLinkShare.feature:91](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiSharePublicLink3/uploadToPublicLinkShare.feature#L91) -- [coreApiSharePublicLink3/uploadToPublicLinkShare.feature:101](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiSharePublicLink3/uploadToPublicLinkShare.feature#L101) +- [coreApiSharePublicLink2/uploadToPublicLinkShare.feature:13](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiSharePublicLink2/uploadToPublicLinkShare.feature#L13) #### [oc:privatelink property not returned in webdav responses](https://github.com/owncloud/product/issues/262) - [coreApiWebdavProperties/getFileProperties.feature:295](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavProperties/getFileProperties.feature#L295) diff --git a/tests/acceptance/expected-failures-on-S3NG-storage.md b/tests/acceptance/expected-failures-on-S3NG-storage.md index 6005f52a46..84326adb30 100644 --- a/tests/acceptance/expected-failures-on-S3NG-storage.md +++ b/tests/acceptance/expected-failures-on-S3NG-storage.md @@ -74,7 +74,7 @@ Synchronization features like etag propagation, setting mtime and locking files #### [Upload-only shares must not overwrite but create a separate file](https://github.com/owncloud/ocis/issues/1267) -- [coreApiSharePublicLink3/uploadToPublicLinkShare.feature:13](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiSharePublicLink3/uploadToPublicLinkShare.feature#L13) +- [coreApiSharePublicLink2/uploadToPublicLinkShare.feature:13](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiSharePublicLink2/uploadToPublicLinkShare.feature#L13) #### [Set quota over settings](https://github.com/owncloud/ocis/issues/1290) _requires a [CS3 user provisioning api that can update the quota for a user](https://github.com/cs3org/cs3apis/pull/95#issuecomment-772780683)_