diff --git a/internal/http/services/owncloud/ocdav/context.go b/internal/http/services/owncloud/ocdav/context.go new file mode 100644 index 00000000000..18c8a48965f --- /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 f3e71586e22..db26d729bd9 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 b573dd20adc..78df1d19835 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 31c92616b2b..91bfe5f1b4f 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 6e2397eac73..41d7bd84d04 100644 --- a/internal/http/services/owncloud/ocdav/tus.go +++ b/internal/http/services/owncloud/ocdav/tus.go @@ -119,10 +119,12 @@ func (s *svc) handleTusPost(ctx context.Context, w http.ResponseWriter, r *http. 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 + tokenStatInfo, ok := TokenStatInfoFromContext(ctx) + if ok { + // 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)