fix: align WebDAV overwrite authorization

This commit is contained in:
OpenClaw Agent
2026-09-21 22:12:44 +08:00
parent 024c887d96
commit 003244059f
+24 -14
View File
@@ -1061,12 +1061,13 @@ func (f *webdavStorageFS) Copy(ctx context.Context, name, dest string, opts *web
if sameOrDescendantPath(src, dst) {
return false, webdav.NewHTTPError(http.StatusConflict, fmt.Errorf("destination is inside source"))
}
if opts != nil && opts.NoOverwrite {
if _, err := f.store.Stat(dst); err == nil {
return false, webdav.NewHTTPError(http.StatusPreconditionFailed, fmt.Errorf("destination exists"))
} else if !os.IsNotExist(err) {
return false, err
}
_, dstErr := f.store.Stat(dst)
dstExists := dstErr == nil
if dstErr != nil && !os.IsNotExist(dstErr) {
return false, dstErr
}
if opts != nil && opts.NoOverwrite && dstExists {
return false, webdav.NewHTTPError(http.StatusPreconditionFailed, fmt.Errorf("destination exists"))
}
if m, ok := f.store.(storage.Multi); ok {
srcRoot, _, srcOK := m.FindRoot(src)
@@ -1094,7 +1095,7 @@ func (f *webdavStorageFS) Copy(ctx context.Context, name, dest string, opts *web
}
_ = created
}
return true, nil
return !dstExists, nil
}
in, err := f.store.Open(src)
if err != nil {
@@ -1114,7 +1115,7 @@ func (f *webdavStorageFS) Copy(ctx context.Context, name, dest string, opts *web
if closeErr != nil {
return false, closeErr
}
return true, nil
return !dstExists, nil
}
func (f *webdavStorageFS) Move(ctx context.Context, name, dest string, opts *webdav.MoveOptions) (bool, error) {
@@ -1129,12 +1130,12 @@ func (f *webdavStorageFS) Move(ctx context.Context, name, dest string, opts *web
if sameOrDescendantPath(src, dst) {
return false, webdav.NewHTTPError(http.StatusConflict, fmt.Errorf("destination is inside source"))
}
if opts == nil || opts.NoOverwrite {
if _, err := f.store.Stat(dst); err == nil {
return false, webdav.NewHTTPError(http.StatusPreconditionFailed, fmt.Errorf("destination exists"))
} else if !os.IsNotExist(err) {
return false, err
}
if _, err := f.store.Stat(dst); err == nil {
// CHFS v4 MOVE does not overwrite an existing destination, even when
// Overwrite is omitted/T and the caller has delete permission.
return false, webdav.NewHTTPError(http.StatusPreconditionFailed, fmt.Errorf("destination exists"))
} else if !os.IsNotExist(err) {
return false, err
}
if m, ok := f.store.(storage.Multi); ok {
srcRoot, _, srcOK := m.FindRoot(src)
@@ -1370,6 +1371,15 @@ func (f *webdavAuthFS) Create(ctx context.Context, name string, body io.ReadClos
if err := f.allow(parent, auth.Write); err != nil {
return nil, false, err
}
// CHFS permits PUT to overwrite an existing file only when the target
// itself is writable. A writable parent alone is enough for creation.
if _, err := f.inner.Stat(ctx, name); err == nil {
if err := f.allow(name, auth.Write); err != nil {
return nil, false, err
}
} else if !os.IsNotExist(err) {
return nil, false, err
}
return f.inner.Create(ctx, name, body, opts)
}
func (f *webdavAuthFS) RemoveAll(ctx context.Context, name string, opts *webdav.RemoveAllOptions) error {