From be30cd17813098278a185cb738446c04866c2dca Mon Sep 17 00:00:00 2001 From: Abhishek Shroff Date: Sun, 20 Oct 2024 11:48:18 +0530 Subject: [PATCH] [server][core][fs] simplify and document targetByPathOrUuid --- server/internal/core/fs/copy_move.go | 85 ++++++++++++++++------------ server/internal/core/fs/errors.go | 1 + 2 files changed, 50 insertions(+), 36 deletions(-) diff --git a/server/internal/core/fs/copy_move.go b/server/internal/core/fs/copy_move.go index 48031876..8b475f6e 100644 --- a/server/internal/core/fs/copy_move.go +++ b/server/internal/core/fs/copy_move.go @@ -165,48 +165,61 @@ func (f filesystem) Copy(src Resource, target string, id uuid.UUID, recursive, o return } +// targetByPathOrUuid splits a target path or uuid into its constituent components +// `pathOrUuid` can be of the following formats: +// 1. absolute path beginning with '/' +// 2. uuid+name separated by ':' +// For the latter, if either uuid or name is not provided then it is filled in from `src` func (f filesystem) targetByPathOrUuid(src Resource, pathOrUuid string) (Resource, string, error) { - if pathOrUuid[0] == '/' { - path := strings.TrimRight(pathOrUuid, "/") - if dest, err := f.ResourceByPath(path); err == nil { - return dest, src.Name, nil - } else { - index := strings.LastIndex(path, "/") - name := path[index+1:] - path = path[0:index] - if parent, err := f.ResourceByPath(path); err != nil { - if errors.Is(err, ErrResourceNotFound) { - err = ErrParentNotFound - } - return Resource{}, "", err - } else if checkNameInvalid(name) { - return Resource{}, "", ErrResourceNameInvalid - } else { - return parent, name, nil - } - } - } - index := strings.Index(pathOrUuid, "/") + index := strings.Index(pathOrUuid, ":") if index == -1 { - return src, pathOrUuid, nil - } - if id, err := uuid.Parse(pathOrUuid[0:index]); err != nil { - return Resource{}, "", err - } else if parent, err := f.ResourceByID(id); err != nil { - if errors.Is(err, ErrResourceNotFound) { - err = ErrParentNotFound + if pathOrUuid[0] != '/' { + return Resource{}, "", ErrResourcePathInvalid } - return Resource{}, "", err - } else { - name := pathOrUuid[index+1:] - if name == "" { - name = src.Name - } - if checkNameInvalid(name) { + path := strings.TrimRight(pathOrUuid, "/") + // if dest, err := f.ResourceByPath(path); err == nil { + // return dest, src.Name, nil + // } else { + index := strings.LastIndex(path, "/") + name := path[index+1:] + path = path[0:index] + if parent, err := f.ResourceByPath(path); err != nil { + if errors.Is(err, ErrResourceNotFound) { + err = ErrParentNotFound + } + return Resource{}, "", err + } else if checkNameInvalid(name) { return Resource{}, "", ErrResourceNameInvalid + } else { + return parent, name, nil } - return parent, name, nil + // } } + var parent Resource + if index == 0 { + parent = src + } else { + if id, err := uuid.Parse(pathOrUuid[0:index]); err != nil { + return Resource{}, "", err + } else if res, err := f.ResourceByID(id); err != nil { + if errors.Is(err, ErrResourceNotFound) { + err = ErrParentNotFound + } + return Resource{}, "", err + } else { + parent = res + } + + } + + name := pathOrUuid[index+1:] + if name == "" { + name = src.Name + } else if checkNameInvalid(name) { + return Resource{}, "", ErrResourceNameInvalid + } + + return parent, name, nil } func (f filesystem) copyContents(k, v uuid.UUID) (int64, error) { diff --git a/server/internal/core/fs/errors.go b/server/internal/core/fs/errors.go index f668ffea..71668700 100644 --- a/server/internal/core/fs/errors.go +++ b/server/internal/core/fs/errors.go @@ -12,6 +12,7 @@ var ( ErrResourceNotCollection = errors.NewError(http.StatusMethodNotAllowed, "resource_not_collection", "cannot add member to non-collection resource") ErrResourceCollection = errors.NewError(http.StatusMethodNotAllowed, "resource_collection", "cannot write to collection resource") ErrResourceIDConflict = errors.NewError(http.StatusConflict, "resource_id_conflict", "resource id already exists") + ErrResourcePathInvalid = errors.NewError(http.StatusBadRequest, "resource_path_invalid", "invalid path") ErrResourceNameInvalid = errors.NewError(http.StatusBadRequest, "resource_name_invalid", "invalid name") ErrResourceNameConflict = errors.NewError(http.StatusPreconditionFailed, "resource_name_conflict", "resource name already exists") ErrResourceMoveTargetSubdirectory = errors.NewError(http.StatusConflict, "move_target_subdirectory", "cannot move resource to its own subdirectory")