mirror of
https://github.com/drakkan/sftpgo.git
synced 2025-12-06 22:30:56 +03:00
allow cross folder renaming if the underlying resource is the same
this was only allowed for the local filesystem before this change Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
@@ -55,6 +55,7 @@ import (
|
||||
"github.com/drakkan/sftpgo/v2/internal/kms"
|
||||
"github.com/drakkan/sftpgo/v2/internal/logger"
|
||||
"github.com/drakkan/sftpgo/v2/internal/mfa"
|
||||
"github.com/drakkan/sftpgo/v2/internal/sftpd"
|
||||
"github.com/drakkan/sftpgo/v2/internal/smtp"
|
||||
"github.com/drakkan/sftpgo/v2/internal/util"
|
||||
"github.com/drakkan/sftpgo/v2/internal/vfs"
|
||||
@@ -132,6 +133,9 @@ func TestMain(m *testing.M) {
|
||||
|
||||
sftpdConf := config.GetSFTPDConfig()
|
||||
sftpdConf.Bindings[0].Port = 4022
|
||||
sftpdConf.Bindings = append(sftpdConf.Bindings, sftpd.Binding{
|
||||
Port: 4024,
|
||||
})
|
||||
sftpdConf.KeyboardInteractiveAuthentication = true
|
||||
|
||||
httpdConf := config.GetHTTPDConfig()
|
||||
@@ -2309,6 +2313,216 @@ func TestVirtualFoldersLink(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestCrossFolderRename(t *testing.T) {
|
||||
folder1 := "folder1"
|
||||
folder2 := "folder2"
|
||||
folder3 := "folder3"
|
||||
folder4 := "folder4"
|
||||
folder5 := "folder5"
|
||||
folder6 := "folder6"
|
||||
folder7 := "folder7"
|
||||
|
||||
baseUser, resp, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
|
||||
u := getCryptFsUser()
|
||||
u.Username += "_crypt"
|
||||
u.VirtualFolders = []vfs.VirtualFolder{
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folder1,
|
||||
MappedPath: filepath.Join(os.TempDir(), folder1),
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
CryptConfig: vfs.CryptFsConfig{
|
||||
Passphrase: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: path.Join("/", folder1),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folder2,
|
||||
MappedPath: filepath.Join(os.TempDir(), folder2),
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
CryptConfig: vfs.CryptFsConfig{
|
||||
Passphrase: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: path.Join("/", folder2),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folder3,
|
||||
MappedPath: filepath.Join(os.TempDir(), folder3),
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
CryptConfig: vfs.CryptFsConfig{
|
||||
Passphrase: kms.NewPlainSecret(defaultPassword + "mod"),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: path.Join("/", folder3),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folder4,
|
||||
MappedPath: filepath.Join(os.TempDir(), folder4),
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.SFTPFilesystemProvider,
|
||||
SFTPConfig: vfs.SFTPFsConfig{
|
||||
BaseSFTPFsConfig: sdk.BaseSFTPFsConfig{
|
||||
Endpoint: sftpServerAddr,
|
||||
Username: baseUser.Username,
|
||||
Prefix: path.Join("/", folder4),
|
||||
},
|
||||
Password: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: path.Join("/", folder4),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folder5,
|
||||
MappedPath: filepath.Join(os.TempDir(), folder5),
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.SFTPFilesystemProvider,
|
||||
SFTPConfig: vfs.SFTPFsConfig{
|
||||
BaseSFTPFsConfig: sdk.BaseSFTPFsConfig{
|
||||
Endpoint: sftpServerAddr,
|
||||
Username: baseUser.Username,
|
||||
Prefix: path.Join("/", folder5),
|
||||
},
|
||||
Password: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: path.Join("/", folder5),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folder6,
|
||||
MappedPath: filepath.Join(os.TempDir(), folder6),
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.SFTPFilesystemProvider,
|
||||
SFTPConfig: vfs.SFTPFsConfig{
|
||||
BaseSFTPFsConfig: sdk.BaseSFTPFsConfig{
|
||||
Endpoint: "127.0.0.1:4024",
|
||||
Username: baseUser.Username,
|
||||
Prefix: path.Join("/", folder6),
|
||||
},
|
||||
Password: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: path.Join("/", folder6),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folder7,
|
||||
MappedPath: filepath.Join(os.TempDir(), folder7),
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.SFTPFilesystemProvider,
|
||||
SFTPConfig: vfs.SFTPFsConfig{
|
||||
BaseSFTPFsConfig: sdk.BaseSFTPFsConfig{
|
||||
Endpoint: sftpServerAddr,
|
||||
Username: baseUser.Username,
|
||||
Prefix: path.Join("/", folder4),
|
||||
},
|
||||
Password: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: path.Join("/", folder7),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
}
|
||||
|
||||
user, resp, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
conn, client, err := getSftpClient(user)
|
||||
if assert.NoError(t, err) {
|
||||
defer conn.Close()
|
||||
defer client.Close()
|
||||
|
||||
subDir := "testSubDir"
|
||||
err = client.Mkdir(subDir)
|
||||
assert.NoError(t, err)
|
||||
err = writeSFTPFile(path.Join(subDir, "afile.bin"), 64, client)
|
||||
assert.NoError(t, err)
|
||||
err = client.Rename(subDir, path.Join("/", folder1, subDir))
|
||||
assert.NoError(t, err)
|
||||
_, err = client.Stat(path.Join("/", folder1, subDir))
|
||||
assert.NoError(t, err)
|
||||
_, err = client.Stat(path.Join("/", folder1, subDir, "afile.bin"))
|
||||
assert.NoError(t, err)
|
||||
err = client.Rename(path.Join("/", folder1, subDir), path.Join("/", folder2, subDir))
|
||||
assert.NoError(t, err)
|
||||
_, err = client.Stat(path.Join("/", folder2, subDir))
|
||||
assert.NoError(t, err)
|
||||
_, err = client.Stat(path.Join("/", folder2, subDir, "afile.bin"))
|
||||
assert.NoError(t, err)
|
||||
err = client.Rename(path.Join("/", folder2, subDir), path.Join("/", folder3, subDir))
|
||||
assert.ErrorIs(t, err, os.ErrPermission)
|
||||
err = writeSFTPFile(path.Join("/", folder3, "file.bin"), 64, client)
|
||||
assert.NoError(t, err)
|
||||
err = client.Rename(path.Join("/", folder3, "file.bin"), "/renamed.bin")
|
||||
assert.ErrorIs(t, err, os.ErrPermission)
|
||||
err = client.Rename(path.Join("/", folder3, "file.bin"), path.Join("/", folder2, "/renamed.bin"))
|
||||
assert.ErrorIs(t, err, os.ErrPermission)
|
||||
err = client.Rename(path.Join("/", folder3, "file.bin"), path.Join("/", folder3, "/renamed.bin"))
|
||||
assert.NoError(t, err)
|
||||
err = writeSFTPFile("/afile.bin", 64, client)
|
||||
assert.NoError(t, err)
|
||||
err = client.Rename("afile.bin", path.Join("/", folder4, "afile_renamed.bin"))
|
||||
assert.ErrorIs(t, err, os.ErrPermission)
|
||||
err = writeSFTPFile(path.Join("/", folder4, "afile.bin"), 64, client)
|
||||
assert.NoError(t, err)
|
||||
err = client.Rename(path.Join("/", folder4, "afile.bin"), path.Join("/", folder5, "afile_renamed.bin"))
|
||||
assert.NoError(t, err)
|
||||
err = client.Rename(path.Join("/", folder5, "afile_renamed.bin"), path.Join("/", folder6, "afile_renamed.bin"))
|
||||
assert.ErrorIs(t, err, os.ErrPermission)
|
||||
err = writeSFTPFile(path.Join("/", folder4, "afile.bin"), 64, client)
|
||||
assert.NoError(t, err)
|
||||
_, err = client.Stat(path.Join("/", folder7, "afile.bin"))
|
||||
assert.NoError(t, err)
|
||||
err = client.Rename(path.Join("/", folder4, "afile.bin"), path.Join("/", folder7, "afile.bin"))
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
_, err = httpdtest.RemoveUser(user, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
err = os.RemoveAll(user.GetHomeDir())
|
||||
assert.NoError(t, err)
|
||||
_, err = httpdtest.RemoveUser(baseUser, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
err = os.RemoveAll(baseUser.GetHomeDir())
|
||||
assert.NoError(t, err)
|
||||
for _, folderName := range []string{folder1, folder2, folder3, folder4, folder5, folder6, folder7} {
|
||||
_, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName}, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
err = os.RemoveAll(filepath.Join(os.TempDir(), folderName))
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDirs(t *testing.T) {
|
||||
u := getTestUser()
|
||||
mappedPath := filepath.Join(os.TempDir(), "vdir")
|
||||
|
||||
Reference in New Issue
Block a user