[server] Hook up resource bind conflict resolution

This commit is contained in:
Abhishek Shroff
2024-12-25 22:18:45 +05:30
parent ce53844d68
commit 5bd7ac964f
10 changed files with 29 additions and 20 deletions

View File

@@ -4,11 +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 mkdirParams struct {
Name string `json:"name" binding:"required"`
ParentID uuid.UUID `json:"parent_id" binding:"required"`
Name string `json:"name" binding:"required"`
ParentID uuid.UUID `json:"parent_id" binding:"required"`
Conflict fs.ResourceBindConflictResolution `json:"conflict"`
}
func handleMkdirRequest(c *gin.Context) {
@@ -29,7 +31,7 @@ func handleMkdirRequest(c *gin.Context) {
panic(err)
}
r, err := parent.CreateMemberResource(params.Name, resourceID, true)
r, err := parent.CreateMemberResource(params.Name, resourceID, true, params.Conflict)
if err != nil {
panic(err)
}

View File

@@ -3,6 +3,7 @@ package fs
import (
"io"
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
@@ -21,6 +22,10 @@ func handleUploadRequest(c *gin.Context) {
if err != nil || name == "" {
panic(errInvalidParams)
}
conflict, err := strconv.Atoi(c.Request.FormValue("conflict"))
if err != nil || name == "" {
panic(errInvalidParams)
}
// TODO: Calculate and verify sha sum
// c.Request.FormValue("sha256sum")
@@ -31,7 +36,7 @@ func handleUploadRequest(c *gin.Context) {
return err
}
res, err := parent.CreateMemberResource(name, resourceID, false)
res, err := parent.CreateMemberResource(name, resourceID, false, fs.ResourceBindConflictResolution(conflict))
if err != nil {
return err
}

View File

@@ -93,7 +93,7 @@ func moveFiles(f FileSystem, srcPath, dstPath string, overwrite bool) (status in
} else {
var conflictResolution fs.ResourceBindConflictResolution = fs.ResourceBindConflictResolutionNone
if overwrite {
conflictResolution = fs.ResourceBindConflictResolutionOverwrite
conflictResolution = fs.ResourceBindConflictResolutionDelete
}
if _, deleted, err := src.Move(dstPath, conflictResolution); err != nil {
if e, ok := err.(*errors.Error); ok {

View File

@@ -36,7 +36,7 @@ type Handler struct {
// of host operating system convention.
type FileSystem interface {
ResourceByPath(name string) (fs.Resource, error)
CreateResourceByPath(name string, dir, recursive bool) (fs.Resource, error)
CreateResourceByPath(name string, dir, recursive bool, conflictResolution fs.ResourceBindConflictResolution) (fs.Resource, error)
}
func (h *Handler) stripPrefix(p string) (string, int, error) {
@@ -259,7 +259,7 @@ func (h *Handler) handlePut(w http.ResponseWriter, r *http.Request) (status int,
res, err := h.FileSystem.ResourceByPath(reqPath)
if errors.Is(err, fs.ErrResourceNotFound) {
res, err = h.FileSystem.CreateResourceByPath(reqPath, false, false)
res, err = h.FileSystem.CreateResourceByPath(reqPath, false, false, fs.ResourceBindConflictResolutionOverwrite)
if err != nil {
if errors.Is(err, fs.ErrParentNotFound) {
return http.StatusConflict, err
@@ -304,7 +304,7 @@ func (h *Handler) handleMkcol(_ http.ResponseWriter, r *http.Request) (status in
if r.ContentLength > 0 {
return http.StatusUnsupportedMediaType, nil
}
if _, err := h.FileSystem.CreateResourceByPath(reqPath, true, false); err != nil {
if _, err := h.FileSystem.CreateResourceByPath(reqPath, true, false, fs.ResourceBindConflictResolutionNone); err != nil {
if errors.Is(err, fs.ErrParentNotFound) {
return http.StatusConflict, err
}
@@ -381,7 +381,7 @@ func (h *Handler) handleLock(w http.ResponseWriter, r *http.Request) (retStatus
// Create the resource if it didn't previously exist.
if _, err := h.FileSystem.ResourceByPath(reqPath); err != nil {
_, err = h.FileSystem.CreateResourceByPath(reqPath, false, false)
_, err = h.FileSystem.CreateResourceByPath(reqPath, false, false, fs.ResourceBindConflictResolutionNone)
if err != nil {
if errors.Is(err, fs.ErrParentNotFound) {
return http.StatusConflict, err

View File

@@ -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"
)
@@ -23,7 +24,7 @@ func setupMkdirCommand() *cobra.Command {
} else {
recursive = b
}
if _, err := f.CreateResourceByPath(path, true, recursive); err != nil {
if _, err := f.CreateResourceByPath(path, true, recursive, fs.ResourceBindConflictResolutionNone); err != nil {
fmt.Println("could not create directory: " + err.Error())
os.Exit(1)
}

View File

@@ -27,7 +27,7 @@ func setupMvCommand() *cobra.Command {
var conflictResolution fs.ResourceBindConflictResolution = fs.ResourceBindConflictResolutionNone
if force {
conflictResolution = fs.ResourceBindConflictResolutionOverwrite
conflictResolution = fs.ResourceBindConflictResolutionDelete
}
if _, _, err := src.Move(args[1], conflictResolution); err != nil {
fmt.Println("cannot move'" + srcPathOrUUID + "' to '" + args[1] + "': " + err.Error())

View File

@@ -103,7 +103,7 @@ func setupUserAddCommand() *cobra.Command {
if homePath != "" {
rootFS = rootFS.WithDb(db)
home, err := rootFS.CreateResourceByPath(homePath, true, true)
home, err := rootFS.CreateResourceByPath(homePath, true, true, fs.ResourceBindConflictResolutionNone)
if err != nil {
return err
}

View File

@@ -13,9 +13,10 @@ import (
type ResourceBindConflictResolution int32
const (
ResourceBindConflictResolutionNone = 0
ResourceBindConflictResolutionOverwrite = 1
ResourceBindConflictResolutionRename = 2
ResourceBindConflictResolutionNone = 0 // Throw Error
ResourceBindConflictResolutionRename = 1 // Auto rename with suffix
ResourceBindConflictResolutionOverwrite = 2 // Try to preserve props, delete only if type mismatch (dir vs regular)
ResourceBindConflictResolutionDelete = 3 // Delete existing resource first
)
func (r Resource) Move(target string, conflictResolution ResourceBindConflictResolution) (Resource, bool, error) {

View File

@@ -9,7 +9,7 @@ import (
"github.com/shroff/phylum/server/internal/core/db"
)
func (f filesystem) CreateResourceByPath(path string, dir, recursive bool) (Resource, error) {
func (f filesystem) CreateResourceByPath(path string, dir, recursive bool, conflictResolution ResourceBindConflictResolution) (Resource, error) {
path = strings.TrimRight(path, "/")
index := strings.LastIndex(path, "/")
name := path[index+1:]
@@ -19,7 +19,7 @@ func (f filesystem) CreateResourceByPath(path string, dir, recursive bool) (Reso
if errors.Is(err, ErrResourceNotFound) {
if recursive {
// TODO: this is very inefficient, but used only directly from the command line
parent, err = f.CreateResourceByPath(parentPath, true, true)
parent, err = f.CreateResourceByPath(parentPath, true, true, conflictResolution)
} else {
err = ErrParentNotFound
}
@@ -28,10 +28,10 @@ func (f filesystem) CreateResourceByPath(path string, dir, recursive bool) (Reso
return Resource{}, err
}
}
return parent.CreateMemberResource(name, uuid.Nil, dir)
return parent.CreateMemberResource(name, uuid.Nil, dir, conflictResolution)
}
func (r Resource) CreateMemberResource(name string, id uuid.UUID, dir bool) (Resource, error) {
func (r Resource) CreateMemberResource(name string, id uuid.UUID, dir bool, conflictResolution ResourceBindConflictResolution) (Resource, error) {
if !r.Dir() {
return Resource{}, ErrResourceNotCollection
}

View File

@@ -17,7 +17,7 @@ type FileSystem interface {
RunInTx(fn func(FileSystem) error) error
// create.go
CreateResourceByPath(path string, dir, recursive bool) (Resource, error)
CreateResourceByPath(path string, dir, recursive bool, conflictResolution ResourceBindConflictResolution) (Resource, error)
// find.go
ResourceByID(id uuid.UUID) (Resource, error)