Skip to content

Commit

Permalink
fix restore for nested spaces
Browse files Browse the repository at this point in the history
There can be nested spaces e.g. the 'Shares Jail' inside a users space
  • Loading branch information
David Christofas committed Mar 11, 2022
1 parent d192df5 commit 9b0a703
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 14 deletions.
8 changes: 6 additions & 2 deletions internal/http/services/owncloud/ocdav/spaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/cs3org/reva/v2/pkg/appctx"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/rhttp/router"
"github.com/cs3org/reva/v2/pkg/utils"
)

// SpacesHandler handles trashbin requests
Expand Down Expand Up @@ -184,9 +185,12 @@ func (h *SpacesHandler) handleSpacesTrashbin(w http.ResponseWriter, r *http.Requ
w.WriteHeader(http.StatusBadRequest)
return
}

log.Debug().Str("key", key).Str("path", r.URL.Path).Str("dst", dst).Msg("spaces restore")
trashbinHandler.restore(w, r, s, ref, dst, key, r.URL.Path)

dstRef := ref
dstRef.Path = utils.MakeRelativePath(dst)

trashbinHandler.restore(w, r, s, ref, dstRef, key, r.URL.Path)
case http.MethodDelete:
trashbinHandler.delete(w, r, s, ref, key, r.URL.Path)
default:
Expand Down
34 changes: 22 additions & 12 deletions internal/http/services/owncloud/ocdav/trashbin.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,22 @@ func (h *TrashbinHandler) Handler(s *svc) http.Handler {
return
}

p := path.Join(ns, dst)
// The destination can be in another space. E.g. the 'Shares Jail'.
space, rpcstatus, err := spacelookup.LookUpStorageSpaceForPath(ctx, client, p)
if err != nil {
log.Error().Err(err).Str("path", p).Msg("failed to look up destination storage space")
w.WriteHeader(http.StatusInternalServerError)
return
}
if rpcstatus.Code != rpc.Code_CODE_OK {
errors.HandleErrorStatus(log, w, rpcstatus)
return
}
dstRef := spacelookup.MakeRelativeReference(space, p, false)

log.Debug().Str("key", key).Str("dst", dst).Msg("restore")
h.restore(w, r, s, ref, dst, key, r.URL.Path)
h.restore(w, r, s, ref, dstRef, key, r.URL.Path)
case http.MethodDelete:
h.delete(w, r, s, ref, key, r.URL.Path)
default:
Expand Down Expand Up @@ -438,7 +452,7 @@ func (h *TrashbinHandler) itemToPropResponse(ctx context.Context, s *svc, refBas
return &response, nil
}

func (h *TrashbinHandler) restore(w http.ResponseWriter, r *http.Request, s *svc, ref *provider.Reference, dst, key, itemPath string) {
func (h *TrashbinHandler) restore(w http.ResponseWriter, r *http.Request, s *svc, ref, dst *provider.Reference, key, itemPath string) {
ctx, span := rtrace.Provider.Tracer("trash-bin").Start(r.Context(), "restore")
defer span.End()

Expand All @@ -459,10 +473,7 @@ func (h *TrashbinHandler) restore(w http.ResponseWriter, r *http.Request, s *svc
return
}

dstRef := ref
dstRef.Path = utils.MakeRelativePath(dst)

dstStatReq := &provider.StatRequest{Ref: dstRef}
dstStatReq := &provider.StatRequest{Ref: dst}
dstStatRes, err := client.Stat(ctx, dstStatReq)
if err != nil {
sublog.Error().Err(err).Msg("error sending grpc stat request")
Expand All @@ -477,9 +488,8 @@ func (h *TrashbinHandler) restore(w http.ResponseWriter, r *http.Request, s *svc

// Restoring to a non-existent location is not supported by the WebDAV spec. The following block ensures the target
// restore location exists, and if it doesn't returns a conflict error code.
if dstStatRes.Status.Code == rpc.Code_CODE_NOT_FOUND && isNested(dst) {
parentRef := ref
parentRef.Path = utils.MakeRelativePath(path.Dir(dst))
if dstStatRes.Status.Code == rpc.Code_CODE_NOT_FOUND && isNested(dst.Path) {
parentRef := &provider.Reference{ResourceId: dst.ResourceId, Path: utils.MakeRelativePath(path.Dir(dst.Path))}
parentStatReq := &provider.StatRequest{Ref: parentRef}

parentStatResponse, err := client.Stat(ctx, parentStatReq)
Expand Down Expand Up @@ -512,7 +522,7 @@ func (h *TrashbinHandler) restore(w http.ResponseWriter, r *http.Request, s *svc
return
}
// delete existing tree
delReq := &provider.DeleteRequest{Ref: dstRef}
delReq := &provider.DeleteRequest{Ref: dst}
delRes, err := client.Delete(ctx, delReq)
if err != nil {
sublog.Error().Err(err).Msg("error sending grpc delete request")
Expand All @@ -529,7 +539,7 @@ func (h *TrashbinHandler) restore(w http.ResponseWriter, r *http.Request, s *svc
req := &provider.RestoreRecycleItemRequest{
Ref: ref,
Key: path.Join(key, itemPath),
RestoreRef: dstRef,
RestoreRef: dst,
}

res, err := client.RestoreRecycleItem(ctx, req)
Expand Down Expand Up @@ -621,5 +631,5 @@ func (h *TrashbinHandler) delete(w http.ResponseWriter, r *http.Request, s *svc,

func isNested(p string) bool {
dir, _ := path.Split(p)
return dir != "/"
return dir != "/" && dir != "./"
}

0 comments on commit 9b0a703

Please sign in to comment.