feat: Allow file and directory creation modes to be configured

The defaults remain the same as before.
For now, the config options are global instead of per-user.
Note also that the BoltDB creation maintains the old default mode of 0640
since it's not really a user-facing filesystem manipulation.
Fixes #5316, #5200
This commit is contained in:
Vincent Lee
2025-07-20 18:21:52 -07:00
committed by Henrique Dias
parent 5b7ea9f95a
commit 21ad653b7e
12 changed files with 73 additions and 41 deletions

View File

@@ -2,29 +2,28 @@ package fileutils
import (
"io"
"io/fs"
"os"
"path"
"path/filepath"
"github.com/spf13/afero"
"github.com/filebrowser/filebrowser/v2/files"
)
// MoveFile moves file from src to dst.
// By default the rename filesystem system call is used. If src and dst point to different volumes
// the file copy is used as a fallback
func MoveFile(fs afero.Fs, src, dst string) error {
if fs.Rename(src, dst) == nil {
func MoveFile(afs afero.Fs, src, dst string, fileMode, dirMode fs.FileMode) error {
if afs.Rename(src, dst) == nil {
return nil
}
// fallback
err := Copy(fs, src, dst)
err := Copy(afs, src, dst, fileMode, dirMode)
if err != nil {
_ = fs.Remove(dst)
_ = afs.Remove(dst)
return err
}
if err := fs.RemoveAll(src); err != nil {
if err := afs.RemoveAll(src); err != nil {
return err
}
return nil
@@ -32,9 +31,9 @@ func MoveFile(fs afero.Fs, src, dst string) error {
// CopyFile copies a file from source to dest and returns
// an error if any.
func CopyFile(fs afero.Fs, source, dest string) error {
func CopyFile(afs afero.Fs, source, dest string, fileMode, dirMode fs.FileMode) error {
// Open the source file.
src, err := fs.Open(source)
src, err := afs.Open(source)
if err != nil {
return err
}
@@ -42,13 +41,13 @@ func CopyFile(fs afero.Fs, source, dest string) error {
// Makes the directory needed to create the dst
// file.
err = fs.MkdirAll(filepath.Dir(dest), files.PermDir)
err = afs.MkdirAll(filepath.Dir(dest), dirMode)
if err != nil {
return err
}
// Create the destination file.
dst, err := fs.OpenFile(dest, os.O_RDWR|os.O_CREATE|os.O_TRUNC, files.PermFile)
dst, err := afs.OpenFile(dest, os.O_RDWR|os.O_CREATE|os.O_TRUNC, fileMode)
if err != nil {
return err
}
@@ -61,11 +60,11 @@ func CopyFile(fs afero.Fs, source, dest string) error {
}
// Copy the mode
info, err := fs.Stat(source)
info, err := afs.Stat(source)
if err != nil {
return err
}
err = fs.Chmod(dest, info.Mode())
err = afs.Chmod(dest, info.Mode())
if err != nil {
return err
}