[server] Fix invalid resource moves

This commit is contained in:
Abhishek Shroff
2024-10-01 13:03:55 +05:30
parent cfe26bc336
commit d6747dbbd0
3 changed files with 25 additions and 7 deletions

View File

@@ -22,6 +22,7 @@ var (
errResourceNotDirectory = errors.New(http.StatusMethodNotAllowed, "resource_not_directory", "Resource Not Directory")
errInvalidParams = errors.New(http.StatusBadRequest, "invalid_parameters", "Invalid Request Parameters")
errResourceNameConflict = errors.New(http.StatusConflict, "name_conflict", "Resource Name Conflict")
errMoveTargetSubdirectory = errors.New(http.StatusBadRequest, "move_target_subdirectory", "Move Target Subdirectory")
)
type resourceResponse struct {
@@ -209,13 +210,16 @@ func handleResourceMoveRoute(c *gin.Context) {
panic(err)
}
if r, err := fs.UpdateNameParent(r, params.Name, params.ParentID); err != nil {
if r, err := fs.Move(r, params.Name, params.ParentID); err != nil {
if errors.Is(err, core.ErrInsufficientPermissions) {
panic(errInsufficientPermissions)
}
if errors.Is(err, core.ErrResourceNameConflict) {
panic(errResourceNameConflict)
}
if errors.Is(err, core.ErrMoveTargetSubdirectory) {
panic(errMoveTargetSubdirectory)
}
panic(err)
} else {
c.JSON(200, responseFromResource(r))

View File

@@ -21,12 +21,11 @@ var (
ErrInsufficientPermissions = errors.New("insufficient permissions")
ErrCannotGrantOwnerPermission = errors.New("cannot grant owner permission")
ErrResourceNotCollection = errors.New("cannot add member to non-collection resource")
ErrCannotReparentRootResource = errors.New("cannot reparent root resource")
ErrCannotReparentToRoot = errors.New("cannot reparent resource to root")
ErrIDNotSpecified = errors.New("resource id not specified")
ErrNameInvalid = errors.New("name invalid")
ErrResourceNameConflict = errors.New("name conflict")
ErrResourceIDConflict = errors.New("id conflict")
ErrMoveTargetSubdirectory = errors.New("move target subdirectory")
)
type FileSystem interface {
@@ -40,7 +39,7 @@ type FileSystem interface {
ReadDir(r Resource) ([]Resource, error)
CreateMemberResource(r Resource, id uuid.UUID, name string, dir bool) (Resource, error)
DeleteRecursive(r Resource, hardDelete bool) (uuid.UUIDs, error)
UpdateNameParent(r Resource, name string, parent *uuid.UUID) (Resource, error)
Move(r Resource, name string, parent *uuid.UUID) (Resource, error)
UpdatePermissions(r Resource, username string, permission Permission) error
}
@@ -192,7 +191,7 @@ func (f filesystem) CreateMemberResource(r Resource, id uuid.UUID, name string,
if id == uuid.Nil {
return nil, ErrIDNotSpecified
}
if name == "" {
if name == "" || checkNameInvalid(name) {
return nil, ErrNameInvalid
}
var result db.Resource
@@ -283,17 +282,21 @@ func (f filesystem) UpdateName(r Resource, name string) (Resource, error) {
}
}
func (f filesystem) UpdateNameParent(r Resource, name string, parent *uuid.UUID) (Resource, error) {
func (f filesystem) Move(r Resource, name string, parent *uuid.UUID) (Resource, error) {
if r.ParentID() == nil {
return nil, ErrInsufficientPermissions
}
if name == r.Name() {
name = ""
}
if checkNameInvalid(name) {
return nil, ErrNameInvalid
}
if parent == r.ParentID() {
parent = nil
}
// Check source directory permissions
oldParent, err := f.ResourceByID(*r.ParentID())
if err != nil {
return nil, err
@@ -302,6 +305,7 @@ func (f filesystem) UpdateNameParent(r Resource, name string, parent *uuid.UUID)
return nil, ErrInsufficientPermissions
}
// Check target directory permissions (if applicable)
if parent != nil {
newParent, err := f.ResourceByID(*parent)
if err != nil {
@@ -310,6 +314,10 @@ func (f filesystem) UpdateNameParent(r Resource, name string, parent *uuid.UUID)
if newParent.UserPermission() < PermissionReadWrite {
return nil, ErrInsufficientPermissions
}
if res, err := f.db.ResourceByID(f.ctx, db.ResourceByIDParams{Root: r.ID(), ResourceID: *parent, Username: f.username}); err != nil || res.Found {
return nil, ErrMoveTargetSubdirectory
}
}
if r, err := f.db.UpdateResourceNameParent(f.ctx, db.UpdateResourceNameParentParams{ID: r.ID(), Name: name, Parent: parent}); err != nil {
if strings.Contains(err.Error(), "unique_member_resource_name") {
@@ -346,3 +354,9 @@ func (f filesystem) UpdatePermissions(r Resource, username string, permission Pe
Permission: permission,
})
}
func checkNameInvalid(s string) bool {
return strings.ContainsFunc(s, func(r rune) bool {
return r == 0 || r == '/'
})
}

View File

@@ -147,7 +147,7 @@ func (a adapter) Rename(ctx context.Context, oldName, newName string) error {
}
parentID := parent.ID()
if _, err = a.fs.UpdateNameParent(src, newName, &parentID); err != nil {
if _, err = a.fs.Move(src, newName, &parentID); err != nil {
return err
}
return nil