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:
Nicola Murino
2022-08-15 21:39:04 +02:00
parent c86db09cd8
commit ced4206c5f
18 changed files with 558 additions and 70 deletions

View File

@@ -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")