55 "context"
66 "encoding/json"
77 "errors"
8+ "fmt"
89 "io"
910 "math"
1011 "net/http"
@@ -128,11 +129,17 @@ func (d *Driver) toResourceInfo(fi *kwlib.FileInfo, spaceID, spaceRootPath strin
128129 return ri
129130}
130131
131- // Capabilities declares kiteworks read-only: every write method rejects with
132- // NotSupported. The zero value is the declaration, so any capability added later
133- // stays false here without an edit.
132+ // Capabilities omits Trash, Sharing and ArbitraryMetadata: those methods still
133+ // reject with NotSupported.
134134func (d * Driver ) Capabilities (_ context.Context ) storage.Capabilities {
135- return storage.Capabilities {}
135+ return storage.Capabilities {
136+ Upload : true ,
137+ CreateContainer : true ,
138+ Delete : true ,
139+ Move : true ,
140+ Versioning : true ,
141+ Locking : true ,
142+ }
136143}
137144
138145// --- Read methods ---
@@ -474,7 +481,7 @@ func (d *Driver) Delete(ctx context.Context, ref *provider.Reference) (*storage.
474481 err = c .DeleteFolder (nodeID )
475482 if err != nil {
476483 var ce * kwlib.ClientError
477- if ! errors .As (err , & ce ) || ( ce .StatusCode != http .StatusNotFound && ce . StatusCode != http . StatusForbidden ) {
484+ if ! errors .As (err , & ce ) || ce .StatusCode != http .StatusNotFound {
478485 return nil , err
479486 }
480487 if err = c .DeleteFile (nodeID ); err != nil {
@@ -505,21 +512,44 @@ func (d *Driver) rawNodeInfo(ctx context.Context, nodeID string) (*kwlib.FileInf
505512 return c .GetFileByID (nodeID )
506513}
507514
515+ func moveNode (c * kwlib.APIClient , fi * kwlib.FileInfo , parentID string ) error {
516+ if fi .IsDir () {
517+ return c .MoveFolder (fi .ID , parentID )
518+ }
519+ _ , err := c .Move (fi , & kwlib.FileInfo {ID : parentID }, false )
520+ return err
521+ }
522+
523+ func renameNode (c * kwlib.APIClient , fi * kwlib.FileInfo , name string ) error {
524+ if fi .IsDir () {
525+ _ , err := c .RenameFolder (fi , name )
526+ return err
527+ }
528+ _ , err := c .RenameFile (fi , name , false )
529+ return err
530+ }
531+
508532func (d * Driver ) Move (ctx context.Context , src , dst * provider.Reference ) (* storage.MoveResult , error ) {
533+ dstName := path .Base (dst .GetPath ())
534+ if dstName == "" || dstName == "." || dstName == "/" {
535+ return nil , errtypes .BadRequest ("kiteworks: Move requires a destination name" )
536+ }
537+
509538 srcNodeID , _ , err := d .resolveRef (ctx , src )
510539 if err != nil {
511540 return nil , err
512541 }
513542
514- dstParentRef := & provider.Reference {
543+ dstParentID , _ , err := d . resolveRef ( ctx , & provider.Reference {
515544 ResourceId : dst .GetResourceId (),
516545 Path : path .Dir (dst .GetPath ()),
517- }
518- dstParentID , _ , err := d .resolveRef (ctx , dstParentRef )
546+ })
519547 if err != nil {
520548 return nil , err
521549 }
522- dstName := path .Base (dst .GetPath ())
550+ if dstParentID == srcNodeID {
551+ return nil , errtypes .BadRequest ("kiteworks: cannot move a resource into itself" )
552+ }
523553
524554 srcFI , err := d .rawNodeInfo (ctx , srcNodeID )
525555 if err != nil {
@@ -531,28 +561,25 @@ func (d *Driver) Move(ctx context.Context, src, dst *provider.Reference) (*stora
531561 srcParentID = * srcFI .ParentID
532562 }
533563
564+ // KW has no combined move+rename. Rename first: it is the undoable step, and
565+ // the new name cannot collide in a parent the node has not left yet.
534566 c := d .client (ctx )
535- if srcParentID != dstParentID {
536- if srcFI .IsDir () {
537- if err = c .MoveFolder (srcNodeID , dstParentID ); err != nil {
538- return nil , err
539- }
540- } else {
541- if _ , err = c .Move (srcFI , & kwlib.FileInfo {ID : dstParentID }, false ); err != nil {
542- return nil , err
543- }
567+ renamed := dstName != srcFI .Name
568+ if renamed {
569+ if err := renameNode (c , srcFI , dstName ); err != nil {
570+ return nil , err
544571 }
545572 }
546573
547- if dstName != srcFI .Name {
548- if srcFI .IsDir () {
549- if _ , err = c .RenameFolder (srcFI , dstName ); err != nil {
550- return nil , err
551- }
552- } else {
553- if _ , err = c .RenameFile (srcFI , dstName , false ); err != nil {
554- return nil , err
574+ if srcParentID != dstParentID {
575+ if err := moveNode (c , srcFI , dstParentID ); err != nil {
576+ if renamed {
577+ if rbErr := renameNode (c , srcFI , srcFI .Name ); rbErr != nil {
578+ d .log .Error ().Err (rbErr ).Str ("nodeID" , srcNodeID ).Msg ("could not restore the original name after a failed move" )
579+ return nil , fmt .Errorf ("kiteworks: move failed and %q is left renamed to %q: %w" , srcFI .Name , dstName , err )
580+ }
555581 }
582+ return nil , err
556583 }
557584 }
558585
0 commit comments