fix(versioner): fix perms of created folders (fixes #9626) (#10105)

As suggested in the linked issue, I've updated the versioner code to use
the permissions of the corresponding directory in the synced folder,
when creating the folder in the versions directory

### Testing
- Some tests are included with the PR. Happy to add more if you think
there are some edge-cases that we're missing.
- I've tested manually on linux to confirm the permissions of the
created directories.
- I haven't tested on Windows or OSX (I don't have access to these OS)
This commit is contained in:
Ashish Bhate
2025-05-24 07:35:32 +02:00
committed by GitHub
parent beda37f28b
commit 1a131a56f2
2 changed files with 147 additions and 3 deletions
+100
View File
@@ -13,6 +13,7 @@ import (
"testing"
"time"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/config"
)
@@ -156,3 +157,102 @@ func TestPathTildes(t *testing.T) {
t.Fatalf("found versioned file %q, want one that begins with %q", got, testPath)
}
}
func TestArchiveFoldersCreationPermission(t *testing.T) {
if build.IsWindows {
t.Skip("Skipping on Windows")
return
}
dir := t.TempDir()
versionsDir := t.TempDir()
cfg := config.FolderConfiguration{
FilesystemType: config.FilesystemTypeBasic,
Path: dir,
Versioning: config.VersioningConfiguration{
FSPath: versionsDir,
FSType: config.FilesystemTypeBasic,
Params: map[string]string{
"keep": "2",
},
},
}
vfs := cfg.Filesystem(nil)
v := newSimple(cfg)
// Create two folders and set their permissions
folder1Path := filepath.Join(dir, "folder1")
folder1Perms := os.FileMode(0o777)
folder1VersionsPath := filepath.Join(versionsDir, "folder1")
err := os.Mkdir(folder1Path, folder1Perms)
if err != nil {
t.Fatal(err)
}
// chmod incase umask changes the create permissions
err = os.Chmod(folder1Path, folder1Perms)
if err != nil {
t.Fatal(err)
}
folder2Path := filepath.Join(folder1Path, "földer2")
folder2VersionsPath := filepath.Join(folder1VersionsPath, "földer2")
folder2Perms := os.FileMode(0o744)
err = os.Mkdir(folder2Path, folder2Perms)
if err != nil {
t.Fatal(err)
}
// chmod incase umask changes the create permissions
err = os.Chmod(folder2Path, folder2Perms)
if err != nil {
t.Fatal(err)
}
// create a file
filePath := filepath.Join("folder1", "földer2", "testFile")
f, err := vfs.Create(filePath)
if err != nil {
t.Fatal(err)
}
f.Close()
if err := v.Archive(filePath); err != nil {
t.Error(err)
}
// check permissions of the created version folders
folder1VersionsInfo, err := os.Stat(folder1VersionsPath)
if err != nil {
t.Fatal(err)
}
if folder1VersionsInfo.Mode().Perm() != folder1Perms {
t.Errorf("folder1 permissions %v, want %v", folder1VersionsInfo.Mode(), folder1Perms)
}
folder2VersionsInfo, err := os.Stat(folder2VersionsPath)
if err != nil {
t.Fatal(err)
}
if folder2VersionsInfo.Mode().Perm() != folder2Perms {
t.Errorf("földer2 permissions %v, want %v", folder2VersionsInfo.Mode(), folder2Perms)
}
// Archive again to test that archiving doesn't fail if the versioned folders already exist
if err := v.Archive(filePath); err != nil {
t.Error(err)
}
folder1VersionsInfo, err = os.Stat(folder1VersionsPath)
if err != nil {
t.Fatal(err)
}
if folder1VersionsInfo.Mode().Perm() != folder1Perms {
t.Errorf("folder1 permissions %v, want %v", folder1VersionsInfo.Mode(), folder1Perms)
}
folder2VersionsInfo, err = os.Stat(folder2VersionsPath)
if err != nil {
t.Fatal(err)
}
if folder2VersionsInfo.Mode().Perm() != folder2Perms {
t.Errorf("földer2 permissions %v, want %v", folder2VersionsInfo.Mode(), folder2Perms)
}
}