mirror of
https://codeberg.org/shroff/phylum.git
synced 2026-01-06 03:31:02 -06:00
[server] resource bind conflict resolution for copy and move
This commit is contained in:
@@ -4,12 +4,13 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"github.com/shroff/phylum/server/internal/api/auth"
|
||||
"github.com/shroff/phylum/server/internal/core/fs"
|
||||
)
|
||||
|
||||
type cpParams struct {
|
||||
ID uuid.UUID `json:"id" binding:"required"`
|
||||
Target string `json:"target"`
|
||||
Overwrite bool `json:"overwrite"`
|
||||
ID uuid.UUID `json:"id" binding:"required"`
|
||||
Target string `json:"target"`
|
||||
Conflict fs.ResourceBindConflictResolution `json:"conflict"`
|
||||
}
|
||||
|
||||
func handleCpRequest(c *gin.Context) {
|
||||
@@ -30,7 +31,7 @@ func handleCpRequest(c *gin.Context) {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if r, _, err := r.Copy(params.Target, params.ID, true, params.Overwrite); err != nil {
|
||||
if r, _, err := r.Copy(params.Target, params.ID, true, params.Conflict); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
c.JSON(200, ResponseFromResourceInfo(r.Info))
|
||||
|
||||
@@ -4,11 +4,12 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"github.com/shroff/phylum/server/internal/api/auth"
|
||||
"github.com/shroff/phylum/server/internal/core/fs"
|
||||
)
|
||||
|
||||
type mvParams struct {
|
||||
Target string `json:"target"`
|
||||
Overwrite bool `json:"overwrite"`
|
||||
Target string `json:"target"`
|
||||
Conflict fs.ResourceBindConflictResolution `json:"conflict"`
|
||||
}
|
||||
|
||||
func handleMvRequest(c *gin.Context) {
|
||||
@@ -29,7 +30,7 @@ func handleMvRequest(c *gin.Context) {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if r, _, err := r.Move(params.Target, params.Overwrite); err != nil {
|
||||
if r, _, err := r.Move(params.Target, params.Conflict); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
c.JSON(200, ResponseFromResourceInfo(r.Info))
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/shroff/phylum/server/internal/core/errors"
|
||||
"github.com/shroff/phylum/server/internal/core/fs"
|
||||
)
|
||||
|
||||
func (h *Handler) handleCopyMove(_ http.ResponseWriter, r *http.Request) (status int, err error) {
|
||||
@@ -83,14 +84,18 @@ func (h *Handler) handleCopyMove(_ http.ResponseWriter, r *http.Request) (status
|
||||
// moveFiles moves files and/or directories from src to dst.
|
||||
//
|
||||
// See section 9.9.4 for when various HTTP status codes apply.
|
||||
func moveFiles(fs FileSystem, srcPath, dstPath string, overwrite bool) (status int, err error) {
|
||||
if src, err := fs.ResourceByPath(srcPath); err != nil {
|
||||
func moveFiles(f FileSystem, srcPath, dstPath string, overwrite bool) (status int, err error) {
|
||||
if src, err := f.ResourceByPath(srcPath); err != nil {
|
||||
if e, ok := err.(*errors.Error); ok {
|
||||
return e.Status, e
|
||||
}
|
||||
return http.StatusInternalServerError, err
|
||||
} else {
|
||||
if _, deleted, err := src.Move(dstPath, overwrite); err != nil {
|
||||
var conflictResolution fs.ResourceBindConflictResolution = fs.ResourceBindConflictResolutionNone
|
||||
if overwrite {
|
||||
conflictResolution = fs.ResourceBindConflictResolutionOverwrite
|
||||
}
|
||||
if _, deleted, err := src.Move(dstPath, conflictResolution); err != nil {
|
||||
if e, ok := err.(*errors.Error); ok {
|
||||
return e.Status, e
|
||||
}
|
||||
@@ -108,15 +113,19 @@ func moveFiles(fs FileSystem, srcPath, dstPath string, overwrite bool) (status i
|
||||
// copyFiles copies files and/or directories from src to dst.
|
||||
//
|
||||
// See section 9.8.5 for when various HTTP status codes apply.
|
||||
func copyFiles(fs FileSystem, srcPath, dstPath string, overwrite bool, depth int) (status int, err error) {
|
||||
if src, err := fs.ResourceByPath(srcPath); err != nil {
|
||||
func copyFiles(f FileSystem, srcPath, dstPath string, overwrite bool, depth int) (status int, err error) {
|
||||
if src, err := f.ResourceByPath(srcPath); err != nil {
|
||||
if e, ok := err.(*errors.Error); ok {
|
||||
return e.Status, e
|
||||
}
|
||||
return http.StatusInternalServerError, err
|
||||
} else {
|
||||
id, _ := uuid.NewV7()
|
||||
if _, deleted, err := src.Copy(dstPath, id, depth != 0, overwrite); err != nil {
|
||||
var conflictResolution fs.ResourceBindConflictResolution = fs.ResourceBindConflictResolutionNone
|
||||
if overwrite {
|
||||
conflictResolution = fs.ResourceBindConflictResolutionOverwrite
|
||||
}
|
||||
if _, deleted, err := src.Copy(dstPath, id, depth != 0, conflictResolution); err != nil {
|
||||
if e, ok := err.(*errors.Error); ok {
|
||||
return e.Status, e
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/shroff/phylum/server/internal/command/common"
|
||||
"github.com/shroff/phylum/server/internal/core/fs"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -32,7 +33,11 @@ func setupCpCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
id, _ := uuid.NewV7()
|
||||
if _, _, err := src.Copy(args[1], id, true, force); err != nil {
|
||||
var conflictResolution fs.ResourceBindConflictResolution = fs.ResourceBindConflictResolutionNone
|
||||
if force {
|
||||
conflictResolution = fs.ResourceBindConflictResolutionOverwrite
|
||||
}
|
||||
if _, _, err := src.Copy(args[1], id, true, conflictResolution); err != nil {
|
||||
fmt.Println("cannot copy'" + srcPathOrUUID + "' to '" + args[1] + "': " + err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/shroff/phylum/server/internal/command/common"
|
||||
"github.com/shroff/phylum/server/internal/core/fs"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -24,7 +25,11 @@ func setupMvCommand() *cobra.Command {
|
||||
|
||||
force, _ := cmd.Flags().GetBool("force")
|
||||
|
||||
if _, _, err := src.Move(args[1], force); err != nil {
|
||||
var conflictResolution fs.ResourceBindConflictResolution = fs.ResourceBindConflictResolutionNone
|
||||
if force {
|
||||
conflictResolution = fs.ResourceBindConflictResolutionOverwrite
|
||||
}
|
||||
if _, _, err := src.Move(args[1], conflictResolution); err != nil {
|
||||
fmt.Println("cannot move'" + srcPathOrUUID + "' to '" + args[1] + "': " + err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,15 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func (r Resource) Move(target string, overwrite bool) (Resource, bool, error) {
|
||||
type ResourceBindConflictResolution int32
|
||||
|
||||
const (
|
||||
ResourceBindConflictResolutionNone = 0
|
||||
ResourceBindConflictResolutionOverwrite = 1
|
||||
ResourceBindConflictResolutionRename = 2
|
||||
)
|
||||
|
||||
func (r Resource) Move(target string, conflictResolution ResourceBindConflictResolution) (Resource, bool, error) {
|
||||
if r.ParentID() == nil {
|
||||
return Resource{}, false, ErrInsufficientPermissions
|
||||
}
|
||||
@@ -51,7 +59,7 @@ func (r Resource) Move(target string, overwrite bool) (Resource, bool, error) {
|
||||
var deleted = false
|
||||
return r, deleted, r.f.db.WithTx(r.f.ctx, func(dbh *db.DbHandler) error {
|
||||
f := r.f.withDb(dbh)
|
||||
if overwrite {
|
||||
if conflictResolution == ResourceBindConflictResolutionOverwrite {
|
||||
if _, err := destParent.DeleteChildRecursive(destName, false); err == nil {
|
||||
deleted = true
|
||||
} else if !errors.Is(err, ErrResourceNotFound) {
|
||||
@@ -71,7 +79,7 @@ func (r Resource) Move(target string, overwrite bool) (Resource, bool, error) {
|
||||
})
|
||||
}
|
||||
|
||||
func (r Resource) Copy(target string, id uuid.UUID, recursive, overwrite bool) (Resource, bool, error) {
|
||||
func (r Resource) Copy(target string, id uuid.UUID, recursive bool, conflictResolution ResourceBindConflictResolution) (Resource, bool, error) {
|
||||
// Check source directory permissions
|
||||
if !r.hasPermission(PermissionRead) {
|
||||
return Resource{}, false, ErrInsufficientPermissions
|
||||
@@ -143,7 +151,7 @@ func (r Resource) Copy(target string, id uuid.UUID, recursive, overwrite bool) (
|
||||
var deleted = false
|
||||
err = r.f.db.WithTx(r.f.ctx, func(dbh *db.DbHandler) error {
|
||||
f := r.f.withDb(dbh)
|
||||
if overwrite {
|
||||
if conflictResolution == ResourceBindConflictResolutionOverwrite {
|
||||
if _, err := destParent.DeleteChildRecursive(destName, false); err == nil {
|
||||
deleted = true
|
||||
} else if !errors.Is(err, ErrResourceNotFound) {
|
||||
|
||||
Reference in New Issue
Block a user