|
@@ -0,0 +1,2415 @@
|
|
|
+package common_test
|
|
|
+
|
|
|
+import (
|
|
|
+ "bytes"
|
|
|
+ "crypto/rand"
|
|
|
+ "fmt"
|
|
|
+ "io"
|
|
|
+ "math"
|
|
|
+ "net"
|
|
|
+ "net/http"
|
|
|
+ "os"
|
|
|
+ "path"
|
|
|
+ "path/filepath"
|
|
|
+ "runtime"
|
|
|
+ "testing"
|
|
|
+ "time"
|
|
|
+
|
|
|
+ _ "github.com/go-sql-driver/mysql"
|
|
|
+ _ "github.com/lib/pq"
|
|
|
+ _ "github.com/mattn/go-sqlite3"
|
|
|
+ "github.com/pkg/sftp"
|
|
|
+ "github.com/stretchr/testify/assert"
|
|
|
+ "github.com/stretchr/testify/require"
|
|
|
+ "golang.org/x/crypto/ssh"
|
|
|
+
|
|
|
+ "github.com/rs/zerolog"
|
|
|
+
|
|
|
+ "github.com/drakkan/sftpgo/common"
|
|
|
+ "github.com/drakkan/sftpgo/config"
|
|
|
+ "github.com/drakkan/sftpgo/dataprovider"
|
|
|
+ "github.com/drakkan/sftpgo/httpclient"
|
|
|
+ "github.com/drakkan/sftpgo/httpdtest"
|
|
|
+ "github.com/drakkan/sftpgo/kms"
|
|
|
+ "github.com/drakkan/sftpgo/logger"
|
|
|
+ "github.com/drakkan/sftpgo/vfs"
|
|
|
+)
|
|
|
+
|
|
|
+const (
|
|
|
+ configDir = ".."
|
|
|
+ httpAddr = "127.0.0.1:9999"
|
|
|
+ httpProxyAddr = "127.0.0.1:7777"
|
|
|
+ sftpServerAddr = "127.0.0.1:4022"
|
|
|
+ defaultUsername = "test_common_sftp"
|
|
|
+ defaultPassword = "test_password"
|
|
|
+ defaultSFTPUsername = "test_common_sftpfs_user"
|
|
|
+ osWindows = "windows"
|
|
|
+ testFileName = "test_file_common_sftp.dat"
|
|
|
+ testDir = "test_dir_common"
|
|
|
+)
|
|
|
+
|
|
|
+var (
|
|
|
+ allPerms = []string{dataprovider.PermAny}
|
|
|
+ homeBasePath string
|
|
|
+ testFileContent = []byte("test data")
|
|
|
+)
|
|
|
+
|
|
|
+func TestMain(m *testing.M) {
|
|
|
+ homeBasePath = os.TempDir()
|
|
|
+ logFilePath := filepath.Join(configDir, "common_test.log")
|
|
|
+ logger.InitLogger(logFilePath, 5, 1, 28, false, zerolog.DebugLevel)
|
|
|
+
|
|
|
+ err := config.LoadConfig(configDir, "")
|
|
|
+ if err != nil {
|
|
|
+ logger.ErrorToConsole("error loading configuration: %v", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+ providerConf := config.GetProviderConf()
|
|
|
+ logger.InfoToConsole("Starting COMMON tests, provider: %v", providerConf.Driver)
|
|
|
+
|
|
|
+ err = common.Initialize(config.GetCommonConfig())
|
|
|
+ if err != nil {
|
|
|
+ logger.WarnToConsole("error initializing common: %v", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+
|
|
|
+ err = dataprovider.Initialize(providerConf, configDir, true)
|
|
|
+ if err != nil {
|
|
|
+ logger.ErrorToConsole("error initializing data provider: %v", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+
|
|
|
+ httpConfig := config.GetHTTPConfig()
|
|
|
+ httpConfig.Timeout = 5
|
|
|
+ httpConfig.RetryMax = 0
|
|
|
+ httpConfig.Initialize(configDir) //nolint:errcheck
|
|
|
+ kmsConfig := config.GetKMSConfig()
|
|
|
+ err = kmsConfig.Initialize()
|
|
|
+ if err != nil {
|
|
|
+ logger.ErrorToConsole("error initializing kms: %v", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+
|
|
|
+ sftpdConf := config.GetSFTPDConfig()
|
|
|
+ sftpdConf.Bindings[0].Port = 4022
|
|
|
+
|
|
|
+ httpdConf := config.GetHTTPDConfig()
|
|
|
+ httpdConf.Bindings[0].Port = 4080
|
|
|
+ httpdtest.SetBaseURL("http://127.0.0.1:4080")
|
|
|
+
|
|
|
+ go func() {
|
|
|
+ if err := sftpdConf.Initialize(configDir); err != nil {
|
|
|
+ logger.ErrorToConsole("could not start SFTP server: %v", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
+ go func() {
|
|
|
+ if err := httpdConf.Initialize(configDir); err != nil {
|
|
|
+ logger.ErrorToConsole("could not start HTTP server: %v", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
+ go func() {
|
|
|
+ // start a test HTTP server to receive action notifications
|
|
|
+ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
|
+ fmt.Fprintf(w, "OK\n")
|
|
|
+ })
|
|
|
+ http.HandleFunc("/404", func(w http.ResponseWriter, r *http.Request) {
|
|
|
+ w.WriteHeader(http.StatusNotFound)
|
|
|
+ fmt.Fprintf(w, "Not found\n")
|
|
|
+ })
|
|
|
+ if err := http.ListenAndServe(httpAddr, nil); err != nil {
|
|
|
+ logger.ErrorToConsole("could not start HTTP notification server: %v", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
+ go func() {
|
|
|
+ common.Config.ProxyProtocol = 2
|
|
|
+ listener, err := net.Listen("tcp", httpProxyAddr)
|
|
|
+ if err != nil {
|
|
|
+ logger.ErrorToConsole("error creating listener for proxy protocol server: %v", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+ proxyListener, err := common.Config.GetProxyListener(listener)
|
|
|
+ if err != nil {
|
|
|
+ logger.ErrorToConsole("error creating proxy protocol listener: %v", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+ common.Config.ProxyProtocol = 0
|
|
|
+
|
|
|
+ s := &http.Server{}
|
|
|
+ if err := s.Serve(proxyListener); err != nil {
|
|
|
+ logger.ErrorToConsole("could not start HTTP proxy protocol server: %v", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
+ waitTCPListening(httpAddr)
|
|
|
+ waitTCPListening(httpProxyAddr)
|
|
|
+
|
|
|
+ waitTCPListening(sftpdConf.Bindings[0].GetAddress())
|
|
|
+ waitTCPListening(httpdConf.Bindings[0].GetAddress())
|
|
|
+
|
|
|
+ exitCode := m.Run()
|
|
|
+ os.Remove(logFilePath)
|
|
|
+ os.Exit(exitCode)
|
|
|
+}
|
|
|
+
|
|
|
+func TestBaseConnection(t *testing.T) {
|
|
|
+ u := getTestUser()
|
|
|
+ user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ assert.NoError(t, checkBasicSFTP(client))
|
|
|
+ _, err = client.ReadDir(testDir)
|
|
|
+ assert.ErrorIs(t, err, os.ErrNotExist)
|
|
|
+ err = client.RemoveDirectory(testDir)
|
|
|
+ assert.ErrorIs(t, err, os.ErrNotExist)
|
|
|
+ err = client.Mkdir(testDir)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Mkdir(testDir)
|
|
|
+ assert.Error(t, err)
|
|
|
+ info, err := client.Stat(testDir)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ assert.True(t, info.IsDir())
|
|
|
+ }
|
|
|
+ err = client.RemoveDirectory(testDir)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Remove(testFileName)
|
|
|
+ assert.ErrorIs(t, err, os.ErrNotExist)
|
|
|
+ f, err := client.Create(testFileName)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = f.Write(testFileContent)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = f.Close()
|
|
|
+ assert.NoError(t, err)
|
|
|
+ linkName := testFileName + ".link"
|
|
|
+ err = client.Symlink(testFileName, linkName)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Symlink(testFileName, testFileName)
|
|
|
+ assert.Error(t, err)
|
|
|
+ info, err = client.Stat(testFileName)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ assert.Equal(t, int64(len(testFileContent)), info.Size())
|
|
|
+ assert.False(t, info.IsDir())
|
|
|
+ }
|
|
|
+ info, err = client.Lstat(linkName)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ assert.NotEqual(t, int64(7), info.Size())
|
|
|
+ assert.True(t, info.Mode()&os.ModeSymlink != 0)
|
|
|
+ assert.False(t, info.IsDir())
|
|
|
+ }
|
|
|
+ err = client.RemoveDirectory(linkName)
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), "Failure")
|
|
|
+ }
|
|
|
+ err = client.Remove(testFileName)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Remove(linkName)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(testFileName, "test")
|
|
|
+ assert.ErrorIs(t, err, os.ErrNotExist)
|
|
|
+ f, err = client.Create(testFileName)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = f.Close()
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(testFileName, testFileName+"1")
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Remove(testFileName + "1")
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.RemoveDirectory("missing")
|
|
|
+ assert.Error(t, err)
|
|
|
+ }
|
|
|
+
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestSetStat(t *testing.T) {
|
|
|
+ u := getTestUser()
|
|
|
+ user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ f, err := client.Create(testFileName)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = f.Write(testFileContent)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = f.Close()
|
|
|
+ assert.NoError(t, err)
|
|
|
+ acmodTime := time.Now().Add(36 * time.Hour)
|
|
|
+ err = client.Chtimes(testFileName, acmodTime, acmodTime)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ newFi, err := client.Lstat(testFileName)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ diff := math.Abs(newFi.ModTime().Sub(acmodTime).Seconds())
|
|
|
+ assert.LessOrEqual(t, diff, float64(1))
|
|
|
+ if runtime.GOOS != osWindows {
|
|
|
+ err = client.Chown(testFileName, os.Getuid(), os.Getgid())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ }
|
|
|
+ newPerm := os.FileMode(0666)
|
|
|
+ err = client.Chmod(testFileName, newPerm)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ newFi, err = client.Lstat(testFileName)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ assert.Equal(t, newPerm, newFi.Mode().Perm())
|
|
|
+ }
|
|
|
+ err = client.Truncate(testFileName, 2)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ info, err := client.Stat(testFileName)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ assert.Equal(t, int64(2), info.Size())
|
|
|
+ }
|
|
|
+ err = client.Remove(testFileName)
|
|
|
+ assert.NoError(t, err)
|
|
|
+
|
|
|
+ err = client.Truncate(testFileName, 0)
|
|
|
+ assert.ErrorIs(t, err, os.ErrNotExist)
|
|
|
+ err = client.Chtimes(testFileName, acmodTime, acmodTime)
|
|
|
+ assert.ErrorIs(t, err, os.ErrNotExist)
|
|
|
+ if runtime.GOOS != osWindows {
|
|
|
+ err = client.Chown(testFileName, os.Getuid(), os.Getgid())
|
|
|
+ assert.ErrorIs(t, err, os.ErrNotExist)
|
|
|
+ }
|
|
|
+ err = client.Chmod(testFileName, newPerm)
|
|
|
+ assert.ErrorIs(t, err, os.ErrNotExist)
|
|
|
+ }
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestPermissionErrors(t *testing.T) {
|
|
|
+ user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ u := getTestSFTPUser()
|
|
|
+ subDir := "/sub"
|
|
|
+ u.Permissions[subDir] = nil
|
|
|
+ sftpUser, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ err = client.MkdirAll(path.Join(subDir, subDir))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ f, err := client.Create(path.Join(subDir, subDir, testFileName))
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ _, err = f.Write(testFileContent)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = f.Close()
|
|
|
+ assert.NoError(t, err)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ client, err = getSftpClient(sftpUser)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ assert.NoError(t, checkBasicSFTP(client))
|
|
|
+ _, err = client.ReadDir(subDir)
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Mkdir(path.Join(subDir, subDir))
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.RemoveDirectory(path.Join(subDir, subDir))
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Symlink("test", path.Join(subDir, subDir))
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Chmod(path.Join(subDir, subDir), os.ModePerm)
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Chown(path.Join(subDir, subDir), os.Getuid(), os.Getgid())
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Chtimes(path.Join(subDir, subDir), time.Now(), time.Now())
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Truncate(path.Join(subDir, subDir), 0)
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Remove(path.Join(subDir, subDir, testFileName))
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ }
|
|
|
+ _, err = httpdtest.RemoveUser(sftpUser, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestFileNotAllowedErrors(t *testing.T) {
|
|
|
+ deniedDir := "/denied"
|
|
|
+ u := getTestUser()
|
|
|
+ u.Filters.FilePatterns = []dataprovider.PatternsFilter{
|
|
|
+ {
|
|
|
+ Path: deniedDir,
|
|
|
+ DeniedPatterns: []string{"*.txt"},
|
|
|
+ },
|
|
|
+ }
|
|
|
+ user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ testFile := filepath.Join(u.GetHomeDir(), deniedDir, "file.txt")
|
|
|
+ err = os.MkdirAll(filepath.Join(u.GetHomeDir(), deniedDir), os.ModePerm)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.WriteFile(testFile, testFileContent, os.ModePerm)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Remove(path.Join(deniedDir, "file.txt"))
|
|
|
+ // the sftp client will try to remove the path as directory after receiving
|
|
|
+ // a permission denied error, so we get a generic failure here
|
|
|
+ assert.Error(t, err)
|
|
|
+ err = client.Rename(path.Join(deniedDir, "file.txt"), path.Join(deniedDir, "file1.txt"))
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ }
|
|
|
+
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestTruncateQuotaLimits(t *testing.T) {
|
|
|
+ u := getTestUser()
|
|
|
+ u.QuotaSize = 20
|
|
|
+ mappedPath1 := filepath.Join(os.TempDir(), "mapped1")
|
|
|
+ folderName1 := filepath.Base(mappedPath1)
|
|
|
+ vdirPath1 := "/vmapped1"
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName1,
|
|
|
+ MappedPath: mappedPath1,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath1,
|
|
|
+ QuotaFiles: 10,
|
|
|
+ })
|
|
|
+ mappedPath2 := filepath.Join(os.TempDir(), "mapped2")
|
|
|
+ folderName2 := filepath.Base(mappedPath2)
|
|
|
+ vdirPath2 := "/vmapped2"
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName2,
|
|
|
+ MappedPath: mappedPath2,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath2,
|
|
|
+ QuotaFiles: -1,
|
|
|
+ QuotaSize: -1,
|
|
|
+ })
|
|
|
+ localUser, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ u = getTestSFTPUser()
|
|
|
+ u.QuotaSize = 20
|
|
|
+ sftpUser, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ for _, user := range []dataprovider.User{localUser, sftpUser} {
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ f, err := client.OpenFile(testFileName, os.O_WRONLY)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ n, err := f.Write(testFileContent)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, len(testFileContent), n)
|
|
|
+ err = f.Truncate(2)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ expectedQuotaFiles := 0
|
|
|
+ expectedQuotaSize := int64(2)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, expectedQuotaFiles, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, expectedQuotaSize, user.UsedQuotaSize)
|
|
|
+ _, err = f.Seek(expectedQuotaSize, io.SeekStart)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ n, err = f.Write(testFileContent)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, len(testFileContent), n)
|
|
|
+ err = f.Truncate(5)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ expectedQuotaSize = int64(5)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, expectedQuotaFiles, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, expectedQuotaSize, user.UsedQuotaSize)
|
|
|
+ _, err = f.Seek(expectedQuotaSize, io.SeekStart)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ n, err = f.Write(testFileContent)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, len(testFileContent), n)
|
|
|
+ err = f.Close()
|
|
|
+ assert.NoError(t, err)
|
|
|
+ expectedQuotaFiles = 1
|
|
|
+ expectedQuotaSize = int64(5) + int64(len(testFileContent))
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, expectedQuotaFiles, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, expectedQuotaSize, user.UsedQuotaSize)
|
|
|
+ }
|
|
|
+ // now truncate by path
|
|
|
+ err = client.Truncate(testFileName, 5)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 1, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, int64(5), user.UsedQuotaSize)
|
|
|
+ // now open an existing file without truncate it, quota should not change
|
|
|
+ f, err = client.OpenFile(testFileName, os.O_WRONLY)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ err = f.Close()
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 1, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, int64(5), user.UsedQuotaSize)
|
|
|
+ }
|
|
|
+ // open the file truncating it
|
|
|
+ f, err = client.OpenFile(testFileName, os.O_WRONLY|os.O_TRUNC)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ err = f.Close()
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 1, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, int64(0), user.UsedQuotaSize)
|
|
|
+ }
|
|
|
+ // now test max write size
|
|
|
+ f, err = client.OpenFile(testFileName, os.O_WRONLY)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ n, err := f.Write(testFileContent)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, len(testFileContent), n)
|
|
|
+ err = f.Truncate(11)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 1, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, int64(11), user.UsedQuotaSize)
|
|
|
+ _, err = f.Seek(int64(11), io.SeekStart)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ n, err = f.Write(testFileContent)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, len(testFileContent), n)
|
|
|
+ err = f.Truncate(5)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 1, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, int64(5), user.UsedQuotaSize)
|
|
|
+ _, err = f.Seek(int64(5), io.SeekStart)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ n, err = f.Write(testFileContent)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, len(testFileContent), n)
|
|
|
+ err = f.Truncate(12)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 1, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, int64(12), user.UsedQuotaSize)
|
|
|
+ _, err = f.Seek(int64(12), io.SeekStart)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = f.Write(testFileContent)
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), common.ErrQuotaExceeded.Error())
|
|
|
+ }
|
|
|
+ err = f.Close()
|
|
|
+ assert.Error(t, err)
|
|
|
+ // the file is deleted
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 0, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, int64(0), user.UsedQuotaSize)
|
|
|
+ }
|
|
|
+
|
|
|
+ if user.Username == defaultUsername {
|
|
|
+ // basic test inside a virtual folder
|
|
|
+ vfileName1 := path.Join(vdirPath1, testFileName)
|
|
|
+ f, err = client.OpenFile(vfileName1, os.O_WRONLY)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ n, err := f.Write(testFileContent)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, len(testFileContent), n)
|
|
|
+ err = f.Truncate(2)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ expectedQuotaFiles := 0
|
|
|
+ expectedQuotaSize := int64(2)
|
|
|
+ fold, _, err := httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, expectedQuotaSize, fold.UsedQuotaSize)
|
|
|
+ assert.Equal(t, expectedQuotaFiles, fold.UsedQuotaFiles)
|
|
|
+ err = f.Close()
|
|
|
+ assert.NoError(t, err)
|
|
|
+ expectedQuotaFiles = 1
|
|
|
+ fold, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, expectedQuotaSize, fold.UsedQuotaSize)
|
|
|
+ assert.Equal(t, expectedQuotaFiles, fold.UsedQuotaFiles)
|
|
|
+ }
|
|
|
+ err = client.Truncate(vfileName1, 1)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ fold, _, err := httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, int64(1), fold.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, fold.UsedQuotaFiles)
|
|
|
+ // now test on vdirPath2, the folder quota is included in the user's quota
|
|
|
+ vfileName2 := path.Join(vdirPath2, testFileName)
|
|
|
+ f, err = client.OpenFile(vfileName2, os.O_WRONLY)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ n, err := f.Write(testFileContent)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, len(testFileContent), n)
|
|
|
+ err = f.Truncate(3)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ expectedQuotaFiles := 0
|
|
|
+ expectedQuotaSize := int64(3)
|
|
|
+ fold, _, err := httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, expectedQuotaSize, fold.UsedQuotaSize)
|
|
|
+ assert.Equal(t, expectedQuotaFiles, fold.UsedQuotaFiles)
|
|
|
+ err = f.Close()
|
|
|
+ assert.NoError(t, err)
|
|
|
+ expectedQuotaFiles = 1
|
|
|
+ fold, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, expectedQuotaSize, fold.UsedQuotaSize)
|
|
|
+ assert.Equal(t, expectedQuotaFiles, fold.UsedQuotaFiles)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, expectedQuotaFiles, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, expectedQuotaSize, user.UsedQuotaSize)
|
|
|
+ }
|
|
|
+
|
|
|
+ // cleanup
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user.UsedQuotaFiles = 0
|
|
|
+ user.UsedQuotaSize = 0
|
|
|
+ _, err = httpdtest.UpdateQuotaUsage(user, "reset", http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user.QuotaSize = 0
|
|
|
+ _, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
|
|
|
+ assert.NoError(t, err)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ _, err = httpdtest.RemoveUser(sftpUser, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveUser(localUser, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(localUser.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName1}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath1)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName2}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath2)
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestVirtualFoldersQuotaRenameOverwrite(t *testing.T) {
|
|
|
+ testFileSize := int64(131072)
|
|
|
+ testFileSize1 := int64(65537)
|
|
|
+ testFileName1 := "test_file1.dat" //nolint:goconst
|
|
|
+ u := getTestUser()
|
|
|
+ u.QuotaFiles = 0
|
|
|
+ u.QuotaSize = 0
|
|
|
+ mappedPath1 := filepath.Join(os.TempDir(), "vdir1")
|
|
|
+ folderName1 := filepath.Base(mappedPath1)
|
|
|
+ vdirPath1 := "/vdir1" //nolint:goconst
|
|
|
+ mappedPath2 := filepath.Join(os.TempDir(), "vdir2")
|
|
|
+ folderName2 := filepath.Base(mappedPath2)
|
|
|
+ vdirPath2 := "/vdir2" //nolint:goconst
|
|
|
+ mappedPath3 := filepath.Join(os.TempDir(), "vdir3")
|
|
|
+ folderName3 := filepath.Base(mappedPath3)
|
|
|
+ vdirPath3 := "/vdir3"
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName1,
|
|
|
+ MappedPath: mappedPath1,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath1,
|
|
|
+ QuotaFiles: 2,
|
|
|
+ QuotaSize: 0,
|
|
|
+ })
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ MappedPath: mappedPath2,
|
|
|
+ Name: folderName2,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath2,
|
|
|
+ QuotaFiles: 0,
|
|
|
+ QuotaSize: testFileSize + testFileSize1 + 1,
|
|
|
+ })
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName3,
|
|
|
+ MappedPath: mappedPath3,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath3,
|
|
|
+ QuotaFiles: 2,
|
|
|
+ QuotaSize: testFileSize * 2,
|
|
|
+ })
|
|
|
+ user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath1, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath2, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath1, testFileName1), testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath2, testFileName1), testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(testFileName, testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(testFileName1, testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath3, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath3, testFileName+"1"), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(testFileName, path.Join(vdirPath1, testFileName+".rename"))
|
|
|
+ assert.Error(t, err)
|
|
|
+ // we overwrite an existing file and we have unlimited size
|
|
|
+ err = client.Rename(testFileName, path.Join(vdirPath1, testFileName))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ // we have no space and we try to overwrite a bigger file with a smaller one, this should succeed
|
|
|
+ err = client.Rename(testFileName1, path.Join(vdirPath2, testFileName))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath2, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(testFileName, testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ // we have no space and we try to overwrite a smaller file with a bigger one, this should fail
|
|
|
+ err = client.Rename(testFileName, path.Join(vdirPath2, testFileName1))
|
|
|
+ assert.Error(t, err)
|
|
|
+ fi, err := client.Stat(path.Join(vdirPath1, testFileName1))
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ assert.Equal(t, testFileSize1, fi.Size())
|
|
|
+ }
|
|
|
+ // we are overquota inside vdir3 size 2/2 and size 262144/262144
|
|
|
+ err = client.Rename(path.Join(vdirPath1, testFileName1), path.Join(vdirPath3, testFileName1+".rename"))
|
|
|
+ assert.Error(t, err)
|
|
|
+ // we overwrite an existing file and we have enough size
|
|
|
+ err = client.Rename(path.Join(vdirPath1, testFileName1), path.Join(vdirPath3, testFileName))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ testFileName2 := "test_file2.dat"
|
|
|
+ err = writeSFTPFile(testFileName2, testFileSize+testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ // we overwrite an existing file and we haven't enough size
|
|
|
+ err = client.Rename(testFileName2, path.Join(vdirPath3, testFileName))
|
|
|
+ assert.Error(t, err)
|
|
|
+ // now remove a file from vdir3, create a dir with 2 files and try to rename it in vdir3
|
|
|
+ // this will fail since the rename will result in 3 files inside vdir3 and quota limits only
|
|
|
+ // allow 2 total files there
|
|
|
+ err = client.Remove(path.Join(vdirPath3, testFileName+"1"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ aDir := "a dir"
|
|
|
+ err = client.Mkdir(aDir)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(aDir, testFileName1), testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(aDir, testFileName1+"1"), testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(aDir, path.Join(vdirPath3, aDir))
|
|
|
+ assert.Error(t, err)
|
|
|
+ }
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName1}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName2}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName3}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath1)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath2)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath3)
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestQuotaRenameOverwrite(t *testing.T) {
|
|
|
+ u := getTestUser()
|
|
|
+ u.QuotaFiles = 100
|
|
|
+ user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ testFileSize := int64(131072)
|
|
|
+ testFileSize1 := int64(65537)
|
|
|
+ testFileName1 := "test_file1.dat"
|
|
|
+ err = writeSFTPFile(testFileName, testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(testFileName1, testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 2, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, user.UsedQuotaSize)
|
|
|
+ err = client.Rename(testFileName, testFileName1)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 1, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize, user.UsedQuotaSize)
|
|
|
+ err = client.Remove(testFileName1)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(testFileName, testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(testFileName1, testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(testFileName1, testFileName)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 1, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize1, user.UsedQuotaSize)
|
|
|
+ }
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestVirtualFoldersQuotaValues(t *testing.T) {
|
|
|
+ u := getTestUser()
|
|
|
+ u.QuotaFiles = 100
|
|
|
+ mappedPath1 := filepath.Join(os.TempDir(), "vdir1")
|
|
|
+ vdirPath1 := "/vdir1"
|
|
|
+ folderName1 := filepath.Base(mappedPath1)
|
|
|
+ mappedPath2 := filepath.Join(os.TempDir(), "vdir2")
|
|
|
+ vdirPath2 := "/vdir2"
|
|
|
+ folderName2 := filepath.Base(mappedPath2)
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName1,
|
|
|
+ MappedPath: mappedPath1,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath1,
|
|
|
+ // quota is included in the user's one
|
|
|
+ QuotaFiles: -1,
|
|
|
+ QuotaSize: -1,
|
|
|
+ })
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName2,
|
|
|
+ MappedPath: mappedPath2,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath2,
|
|
|
+ // quota is unlimited and excluded from user's one
|
|
|
+ QuotaFiles: 0,
|
|
|
+ QuotaSize: 0,
|
|
|
+ })
|
|
|
+ user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ testFileSize := int64(131072)
|
|
|
+ err = writeSFTPFile(testFileName, testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ // we copy the same file two times to test quota update on file overwrite
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath1, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath1, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath2, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath2, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ expectedQuotaFiles := 2
|
|
|
+ expectedQuotaSize := testFileSize * 2
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, expectedQuotaFiles, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, expectedQuotaSize, user.UsedQuotaSize)
|
|
|
+ f, _, err := httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+
|
|
|
+ err = client.Remove(path.Join(vdirPath1, testFileName))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Remove(path.Join(vdirPath2, testFileName))
|
|
|
+ assert.NoError(t, err)
|
|
|
+
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, int64(0), f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 0, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, int64(0), f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 0, f.UsedQuotaFiles)
|
|
|
+ }
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName1}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName2}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath1)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath2)
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestQuotaRenameInsideSameVirtualFolder(t *testing.T) {
|
|
|
+ u := getTestUser()
|
|
|
+ u.QuotaFiles = 100
|
|
|
+ mappedPath1 := filepath.Join(os.TempDir(), "vdir1")
|
|
|
+ vdirPath1 := "/vdir1"
|
|
|
+ folderName1 := filepath.Base(mappedPath1)
|
|
|
+ mappedPath2 := filepath.Join(os.TempDir(), "vdir2")
|
|
|
+ vdirPath2 := "/vdir2"
|
|
|
+ folderName2 := filepath.Base(mappedPath2)
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName1,
|
|
|
+ MappedPath: mappedPath1,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath1,
|
|
|
+ // quota is included in the user's one
|
|
|
+ QuotaFiles: -1,
|
|
|
+ QuotaSize: -1,
|
|
|
+ })
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName2,
|
|
|
+ MappedPath: mappedPath2,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath2,
|
|
|
+ // quota is unlimited and excluded from user's one
|
|
|
+ QuotaFiles: 0,
|
|
|
+ QuotaSize: 0,
|
|
|
+ })
|
|
|
+ user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ testFileName1 := "test_file1.dat"
|
|
|
+ testFileSize := int64(131072)
|
|
|
+ testFileSize1 := int64(65535)
|
|
|
+ dir1 := "dir1" //nolint:goconst
|
|
|
+ dir2 := "dir2" //nolint:goconst
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Mkdir(path.Join(vdirPath1, dir1))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Mkdir(path.Join(vdirPath1, dir2))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Mkdir(path.Join(vdirPath2, dir1))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Mkdir(path.Join(vdirPath2, dir2))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath1, dir1, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath1, dir2, testFileName1), testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath2, dir1, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath2, dir2, testFileName1), testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 2, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, user.UsedQuotaSize)
|
|
|
+ f, _, err := httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 2, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 2, f.UsedQuotaFiles)
|
|
|
+ // initial files:
|
|
|
+ // - vdir1/dir1/testFileName
|
|
|
+ // - vdir1/dir2/testFileName1
|
|
|
+ // - vdir2/dir1/testFileName
|
|
|
+ // - vdir2/dir2/testFileName1
|
|
|
+ //
|
|
|
+ // rename a file inside vdir1 it is included inside user quota, so we have:
|
|
|
+ // - vdir1/dir1/testFileName.rename
|
|
|
+ // - vdir1/dir2/testFileName1
|
|
|
+ // - vdir2/dir1/testFileName
|
|
|
+ // - vdir2/dir2/testFileName1
|
|
|
+ err = client.Rename(path.Join(vdirPath1, dir1, testFileName), path.Join(vdirPath1, dir1, testFileName+".rename"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 2, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 2, f.UsedQuotaFiles)
|
|
|
+ // rename a file inside vdir2, it isn't included inside user quota, so we have:
|
|
|
+ // - vdir1/dir1/testFileName.rename
|
|
|
+ // - vdir1/dir2/testFileName1
|
|
|
+ // - vdir2/dir1/testFileName.rename
|
|
|
+ // - vdir2/dir2/testFileName1
|
|
|
+ err = client.Rename(path.Join(vdirPath2, dir1, testFileName), path.Join(vdirPath2, dir1, testFileName+".rename"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 2, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 2, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 2, f.UsedQuotaFiles)
|
|
|
+ // rename a file inside vdir2 overwriting an existing, we now have:
|
|
|
+ // - vdir1/dir1/testFileName.rename
|
|
|
+ // - vdir1/dir2/testFileName1
|
|
|
+ // - vdir2/dir1/testFileName.rename (initial testFileName1)
|
|
|
+ err = client.Rename(path.Join(vdirPath2, dir2, testFileName1), path.Join(vdirPath2, dir1, testFileName+".rename"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 2, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 2, f.UsedQuotaFiles)
|
|
|
+ // rename a file inside vdir1 overwriting an existing, we now have:
|
|
|
+ // - vdir1/dir1/testFileName.rename (initial testFileName1)
|
|
|
+ // - vdir2/dir1/testFileName.rename (initial testFileName1)
|
|
|
+ err = client.Rename(path.Join(vdirPath1, dir2, testFileName1), path.Join(vdirPath1, dir1, testFileName+".rename"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 1, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize1, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ // rename a directory inside the same virtual folder, quota should not change
|
|
|
+ err = client.RemoveDirectory(path.Join(vdirPath1, dir2))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.RemoveDirectory(path.Join(vdirPath2, dir2))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(path.Join(vdirPath1, dir1), path.Join(vdirPath1, dir2))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(path.Join(vdirPath2, dir1), path.Join(vdirPath2, dir2))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 1, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize1, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ }
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName1}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName2}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath1)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath2)
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestQuotaRenameBetweenVirtualFolder(t *testing.T) {
|
|
|
+ u := getTestUser()
|
|
|
+ u.QuotaFiles = 100
|
|
|
+ mappedPath1 := filepath.Join(os.TempDir(), "vdir1")
|
|
|
+ folderName1 := filepath.Base(mappedPath1)
|
|
|
+ vdirPath1 := "/vdir1"
|
|
|
+ mappedPath2 := filepath.Join(os.TempDir(), "vdir2")
|
|
|
+ folderName2 := filepath.Base(mappedPath2)
|
|
|
+ vdirPath2 := "/vdir2"
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName1,
|
|
|
+ MappedPath: mappedPath1,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath1,
|
|
|
+ // quota is included in the user's one
|
|
|
+ QuotaFiles: -1,
|
|
|
+ QuotaSize: -1,
|
|
|
+ })
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName2,
|
|
|
+ MappedPath: mappedPath2,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath2,
|
|
|
+ // quota is unlimited and excluded from user's one
|
|
|
+ QuotaFiles: 0,
|
|
|
+ QuotaSize: 0,
|
|
|
+ })
|
|
|
+ user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ testFileName1 := "test_file1.dat"
|
|
|
+ testFileSize := int64(131072)
|
|
|
+ testFileSize1 := int64(65535)
|
|
|
+ dir1 := "dir1"
|
|
|
+ dir2 := "dir2"
|
|
|
+ err = client.Mkdir(path.Join(vdirPath1, dir1))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Mkdir(path.Join(vdirPath1, dir2))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Mkdir(path.Join(vdirPath2, dir1))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Mkdir(path.Join(vdirPath2, dir2))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath1, dir1, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath1, dir2, testFileName1), testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath2, dir1, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath2, dir2, testFileName1), testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ // initial files:
|
|
|
+ // - vdir1/dir1/testFileName
|
|
|
+ // - vdir1/dir2/testFileName1
|
|
|
+ // - vdir2/dir1/testFileName
|
|
|
+ // - vdir2/dir2/testFileName1
|
|
|
+ //
|
|
|
+ // rename a file from vdir1 to vdir2, vdir1 is included inside user quota, so we have:
|
|
|
+ // - vdir1/dir1/testFileName
|
|
|
+ // - vdir2/dir1/testFileName
|
|
|
+ // - vdir2/dir2/testFileName1
|
|
|
+ // - vdir2/dir1/testFileName1.rename
|
|
|
+ err = client.Rename(path.Join(vdirPath1, dir2, testFileName1), path.Join(vdirPath2, dir1, testFileName1+".rename"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 1, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize, user.UsedQuotaSize)
|
|
|
+ f, _, err := httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1+testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 3, f.UsedQuotaFiles)
|
|
|
+ // rename a file from vdir2 to vdir1, vdir2 is not included inside user quota, so we have:
|
|
|
+ // - vdir1/dir1/testFileName
|
|
|
+ // - vdir1/dir2/testFileName.rename
|
|
|
+ // - vdir2/dir2/testFileName1
|
|
|
+ // - vdir2/dir1/testFileName1.rename
|
|
|
+ err = client.Rename(path.Join(vdirPath2, dir1, testFileName), path.Join(vdirPath1, dir2, testFileName+".rename"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 2, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize*2, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize*2, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 2, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize1*2, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 2, f.UsedQuotaFiles)
|
|
|
+ // rename a file from vdir1 to vdir2 overwriting an existing file, vdir1 is included inside user quota, so we have:
|
|
|
+ // - vdir1/dir2/testFileName.rename
|
|
|
+ // - vdir2/dir2/testFileName1 (is the initial testFileName)
|
|
|
+ // - vdir2/dir1/testFileName1.rename
|
|
|
+ err = client.Rename(path.Join(vdirPath1, dir1, testFileName), path.Join(vdirPath2, dir2, testFileName1))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 1, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize1+testFileSize, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 2, f.UsedQuotaFiles)
|
|
|
+ // rename a file from vdir2 to vdir1 overwriting an existing file, vdir2 is not included inside user quota, so we have:
|
|
|
+ // - vdir1/dir2/testFileName.rename (is the initial testFileName1)
|
|
|
+ // - vdir2/dir2/testFileName1 (is the initial testFileName)
|
|
|
+ err = client.Rename(path.Join(vdirPath2, dir1, testFileName1+".rename"), path.Join(vdirPath1, dir2, testFileName+".rename"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 1, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize1, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath1, dir2, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath2, dir2, testFileName), testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath2, dir2, testFileName+"1.dupl"), testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.RemoveDirectory(path.Join(vdirPath1, dir1))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.RemoveDirectory(path.Join(vdirPath2, dir1))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ // - vdir1/dir2/testFileName.rename (initial testFileName1)
|
|
|
+ // - vdir1/dir2/testFileName
|
|
|
+ // - vdir2/dir2/testFileName1 (initial testFileName)
|
|
|
+ // - vdir2/dir2/testFileName (initial testFileName1)
|
|
|
+ // - vdir2/dir2/testFileName1.dupl
|
|
|
+ // rename directories between the two virtual folders
|
|
|
+ err = client.Rename(path.Join(vdirPath2, dir2), path.Join(vdirPath1, dir1))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 5, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize1*3+testFileSize*2, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize1*3+testFileSize*2, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 5, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, int64(0), f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 0, f.UsedQuotaFiles)
|
|
|
+ // now move on vpath2
|
|
|
+ err = client.Rename(path.Join(vdirPath1, dir2), path.Join(vdirPath2, dir1))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 3, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize1*2+testFileSize, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize1*2+testFileSize, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 3, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 2, f.UsedQuotaFiles)
|
|
|
+ }
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName1}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName2}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath1)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath2)
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestQuotaRenameFromVirtualFolder(t *testing.T) {
|
|
|
+ u := getTestUser()
|
|
|
+ u.QuotaFiles = 100
|
|
|
+ mappedPath1 := filepath.Join(os.TempDir(), "vdir1")
|
|
|
+ folderName1 := filepath.Base(mappedPath1)
|
|
|
+ vdirPath1 := "/vdir1"
|
|
|
+ mappedPath2 := filepath.Join(os.TempDir(), "vdir2")
|
|
|
+ folderName2 := filepath.Base(mappedPath2)
|
|
|
+ vdirPath2 := "/vdir2"
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName1,
|
|
|
+ MappedPath: mappedPath1,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath1,
|
|
|
+ // quota is included in the user's one
|
|
|
+ QuotaFiles: -1,
|
|
|
+ QuotaSize: -1,
|
|
|
+ })
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName2,
|
|
|
+ MappedPath: mappedPath2,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath2,
|
|
|
+ // quota is unlimited and excluded from user's one
|
|
|
+ QuotaFiles: 0,
|
|
|
+ QuotaSize: 0,
|
|
|
+ })
|
|
|
+ user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ testFileName1 := "test_file1.dat"
|
|
|
+ testFileSize := int64(131072)
|
|
|
+ testFileSize1 := int64(65535)
|
|
|
+ dir1 := "dir1"
|
|
|
+ dir2 := "dir2"
|
|
|
+ err = client.Mkdir(path.Join(vdirPath1, dir1))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Mkdir(path.Join(vdirPath1, dir2))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Mkdir(path.Join(vdirPath2, dir1))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Mkdir(path.Join(vdirPath2, dir2))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath1, dir1, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath1, dir2, testFileName1), testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath2, dir1, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath2, dir2, testFileName1), testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ // initial files:
|
|
|
+ // - vdir1/dir1/testFileName
|
|
|
+ // - vdir1/dir2/testFileName1
|
|
|
+ // - vdir2/dir1/testFileName
|
|
|
+ // - vdir2/dir2/testFileName1
|
|
|
+ //
|
|
|
+ // rename a file from vdir1 to the user home dir, vdir1 is included in user quota so we have:
|
|
|
+ // - testFileName
|
|
|
+ // - vdir1/dir2/testFileName1
|
|
|
+ // - vdir2/dir1/testFileName
|
|
|
+ // - vdir2/dir2/testFileName1
|
|
|
+ err = client.Rename(path.Join(vdirPath1, dir1, testFileName), path.Join(testFileName))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 2, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, user.UsedQuotaSize)
|
|
|
+ f, _, err := httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 2, f.UsedQuotaFiles)
|
|
|
+ // rename a file from vdir2 to the user home dir, vdir2 is not included in user quota so we have:
|
|
|
+ // - testFileName
|
|
|
+ // - testFileName1
|
|
|
+ // - vdir1/dir2/testFileName1
|
|
|
+ // - vdir2/dir1/testFileName
|
|
|
+ err = client.Rename(path.Join(vdirPath2, dir2, testFileName1), path.Join(testFileName1))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 3, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1+testFileSize1, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ // rename a file from vdir1 to the user home dir overwriting an existing file, vdir1 is included in user quota so we have:
|
|
|
+ // - testFileName (initial testFileName1)
|
|
|
+ // - testFileName1
|
|
|
+ // - vdir2/dir1/testFileName
|
|
|
+ err = client.Rename(path.Join(vdirPath1, dir2, testFileName1), path.Join(testFileName))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 2, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize1+testFileSize1, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, int64(0), f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 0, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ // rename a file from vdir2 to the user home dir overwriting an existing file, vdir2 is not included in user quota so we have:
|
|
|
+ // - testFileName (initial testFileName1)
|
|
|
+ // - testFileName1 (initial testFileName)
|
|
|
+ err = client.Rename(path.Join(vdirPath2, dir1, testFileName), path.Join(testFileName1))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 2, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, int64(0), f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 0, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, int64(0), f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 0, f.UsedQuotaFiles)
|
|
|
+ // dir rename
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath1, dir1, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath1, dir1, testFileName1), testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath2, dir1, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath2, dir1, testFileName1), testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ // - testFileName (initial testFileName1)
|
|
|
+ // - testFileName1 (initial testFileName)
|
|
|
+ // - vdir1/dir1/testFileName
|
|
|
+ // - vdir1/dir1/testFileName1
|
|
|
+ // - dir1/testFileName
|
|
|
+ // - dir1/testFileName1
|
|
|
+ err = client.Rename(path.Join(vdirPath2, dir1), dir1)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 6, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize*3+testFileSize1*3, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 2, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, int64(0), f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 0, f.UsedQuotaFiles)
|
|
|
+ // - testFileName (initial testFileName1)
|
|
|
+ // - testFileName1 (initial testFileName)
|
|
|
+ // - dir2/testFileName
|
|
|
+ // - dir2/testFileName1
|
|
|
+ // - dir1/testFileName
|
|
|
+ // - dir1/testFileName1
|
|
|
+ err = client.Rename(path.Join(vdirPath1, dir1), dir2)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 6, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize*3+testFileSize1*3, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, int64(0), f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 0, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, int64(0), f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 0, f.UsedQuotaFiles)
|
|
|
+ }
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName1}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName2}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath1)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath2)
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestQuotaRenameToVirtualFolder(t *testing.T) {
|
|
|
+ u := getTestUser()
|
|
|
+ u.QuotaFiles = 100
|
|
|
+ mappedPath1 := filepath.Join(os.TempDir(), "vdir1")
|
|
|
+ folderName1 := filepath.Base(mappedPath1)
|
|
|
+ vdirPath1 := "/vdir1"
|
|
|
+ mappedPath2 := filepath.Join(os.TempDir(), "vdir2")
|
|
|
+ folderName2 := filepath.Base(mappedPath2)
|
|
|
+ vdirPath2 := "/vdir2"
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName1,
|
|
|
+ MappedPath: mappedPath1,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath1,
|
|
|
+ // quota is included in the user's one
|
|
|
+ QuotaFiles: -1,
|
|
|
+ QuotaSize: -1,
|
|
|
+ })
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName2,
|
|
|
+ MappedPath: mappedPath2,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath2,
|
|
|
+ // quota is unlimited and excluded from user's one
|
|
|
+ QuotaFiles: 0,
|
|
|
+ QuotaSize: 0,
|
|
|
+ })
|
|
|
+ u.Permissions[vdirPath1] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermUpload,
|
|
|
+ dataprovider.PermOverwrite, dataprovider.PermDelete, dataprovider.PermCreateSymlinks, dataprovider.PermCreateDirs}
|
|
|
+ user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ testFileName1 := "test_file1.dat"
|
|
|
+ testFileSize := int64(131072)
|
|
|
+ testFileSize1 := int64(65535)
|
|
|
+ dir1 := "dir1"
|
|
|
+ dir2 := "dir2"
|
|
|
+ err = client.Mkdir(path.Join(vdirPath1, dir1))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Mkdir(path.Join(vdirPath1, dir2))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Mkdir(path.Join(vdirPath2, dir1))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Mkdir(path.Join(vdirPath2, dir2))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(testFileName, testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(testFileName1, testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ // initial files:
|
|
|
+ // - testFileName
|
|
|
+ // - testFileName1
|
|
|
+ //
|
|
|
+ // rename a file from user home dir to vdir1, vdir1 is included in user quota so we have:
|
|
|
+ // - testFileName
|
|
|
+ // - /vdir1/dir1/testFileName1
|
|
|
+ err = client.Rename(testFileName1, path.Join(vdirPath1, dir1, testFileName1))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 2, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, user.UsedQuotaSize)
|
|
|
+ f, _, err := httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ // rename a file from user home dir to vdir2, vdir2 is not included in user quota so we have:
|
|
|
+ // - /vdir2/dir1/testFileName
|
|
|
+ // - /vdir1/dir1/testFileName1
|
|
|
+ err = client.Rename(testFileName, path.Join(vdirPath2, dir1, testFileName))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 1, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize1, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ // upload two new files to the user home dir so we have:
|
|
|
+ // - testFileName
|
|
|
+ // - testFileName1
|
|
|
+ // - /vdir1/dir1/testFileName1
|
|
|
+ // - /vdir2/dir1/testFileName
|
|
|
+ err = writeSFTPFile(testFileName, testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(testFileName1, testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 3, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1+testFileSize1, user.UsedQuotaSize)
|
|
|
+ // rename a file from user home dir to vdir1 overwriting an existing file, vdir1 is included in user quota so we have:
|
|
|
+ // - testFileName1
|
|
|
+ // - /vdir1/dir1/testFileName1 (initial testFileName)
|
|
|
+ // - /vdir2/dir1/testFileName
|
|
|
+ err = client.Rename(testFileName, path.Join(vdirPath1, dir1, testFileName1))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 2, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize+testFileSize1, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ // rename a file from user home dir to vdir2 overwriting an existing file, vdir2 is not included in user quota so we have:
|
|
|
+ // - /vdir1/dir1/testFileName1 (initial testFileName)
|
|
|
+ // - /vdir2/dir1/testFileName (initial testFileName1)
|
|
|
+ err = client.Rename(testFileName1, path.Join(vdirPath2, dir1, testFileName))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 1, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+
|
|
|
+ err = client.Mkdir(dir1)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(dir1, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(dir1, testFileName1), testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ // - /dir1/testFileName
|
|
|
+ // - /dir1/testFileName1
|
|
|
+ // - /vdir1/dir1/testFileName1 (initial testFileName)
|
|
|
+ // - /vdir2/dir1/testFileName (initial testFileName1)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 3, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize*2+testFileSize1, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ // - /vdir1/adir/testFileName
|
|
|
+ // - /vdir1/adir/testFileName1
|
|
|
+ // - /vdir1/dir1/testFileName1 (initial testFileName)
|
|
|
+ // - /vdir2/dir1/testFileName (initial testFileName1)
|
|
|
+ err = client.Rename(dir1, path.Join(vdirPath1, "adir"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 3, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize*2+testFileSize1, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize*2+testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 3, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 1, f.UsedQuotaFiles)
|
|
|
+ err = client.Mkdir(dir1)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(dir1, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(dir1, testFileName1), testFileSize1, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ // - /vdir1/adir/testFileName
|
|
|
+ // - /vdir1/adir/testFileName1
|
|
|
+ // - /vdir1/dir1/testFileName1 (initial testFileName)
|
|
|
+ // - /vdir2/dir1/testFileName (initial testFileName1)
|
|
|
+ // - /vdir2/adir/testFileName
|
|
|
+ // - /vdir2/adir/testFileName1
|
|
|
+ err = client.Rename(dir1, path.Join(vdirPath2, "adir"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, 3, user.UsedQuotaFiles)
|
|
|
+ assert.Equal(t, testFileSize*2+testFileSize1, user.UsedQuotaSize)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize*2+testFileSize1, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 3, f.UsedQuotaFiles)
|
|
|
+ f, _, err = httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ assert.Equal(t, testFileSize1*2+testFileSize, f.UsedQuotaSize)
|
|
|
+ assert.Equal(t, 3, f.UsedQuotaFiles)
|
|
|
+ }
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName1}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName2}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath1)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath2)
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestVirtualFoldersLink(t *testing.T) {
|
|
|
+ u := getTestUser()
|
|
|
+ mappedPath1 := filepath.Join(os.TempDir(), "vdir1")
|
|
|
+ folderName1 := filepath.Base(mappedPath1)
|
|
|
+ vdirPath1 := "/vdir1"
|
|
|
+ mappedPath2 := filepath.Join(os.TempDir(), "vdir2")
|
|
|
+ folderName2 := filepath.Base(mappedPath2)
|
|
|
+ vdirPath2 := "/vdir2"
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName1,
|
|
|
+ MappedPath: mappedPath1,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath1,
|
|
|
+ // quota is included in the user's one
|
|
|
+ QuotaFiles: -1,
|
|
|
+ QuotaSize: -1,
|
|
|
+ })
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName2,
|
|
|
+ MappedPath: mappedPath2,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath2,
|
|
|
+ // quota is unlimited and excluded from user's one
|
|
|
+ QuotaFiles: 0,
|
|
|
+ QuotaSize: 0,
|
|
|
+ })
|
|
|
+ user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ testFileSize := int64(131072)
|
|
|
+ testDir := "adir"
|
|
|
+ err = writeSFTPFile(testFileName, testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath1, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirPath2, testFileName), testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Mkdir(path.Join(vdirPath1, testDir))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Mkdir(path.Join(vdirPath2, testDir))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Symlink(testFileName, testFileName+".link")
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Symlink(path.Join(vdirPath1, testFileName), path.Join(vdirPath1, testFileName+".link"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Symlink(path.Join(vdirPath1, testFileName), path.Join(vdirPath1, testDir, testFileName+".link"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Symlink(path.Join(vdirPath2, testFileName), path.Join(vdirPath2, testFileName+".link"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Symlink(path.Join(vdirPath2, testFileName), path.Join(vdirPath2, testDir, testFileName+".link"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Symlink(testFileName, path.Join(vdirPath1, testFileName+".link1"))
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), "Operation Unsupported")
|
|
|
+ }
|
|
|
+ err = client.Symlink(testFileName, path.Join(vdirPath1, testDir, testFileName+".link1"))
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), "Operation Unsupported")
|
|
|
+ }
|
|
|
+ err = client.Symlink(testFileName, path.Join(vdirPath2, testFileName+".link1"))
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), "Operation Unsupported")
|
|
|
+ }
|
|
|
+ err = client.Symlink(testFileName, path.Join(vdirPath2, testDir, testFileName+".link1"))
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), "Operation Unsupported")
|
|
|
+ }
|
|
|
+ err = client.Symlink(path.Join(vdirPath1, testFileName), testFileName+".link1")
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), "Operation Unsupported")
|
|
|
+ }
|
|
|
+ err = client.Symlink(path.Join(vdirPath2, testFileName), testFileName+".link1")
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), "Operation Unsupported")
|
|
|
+ }
|
|
|
+ err = client.Symlink(path.Join(vdirPath1, testFileName), path.Join(vdirPath2, testDir, testFileName+".link1"))
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), "Operation Unsupported")
|
|
|
+ }
|
|
|
+ err = client.Symlink(path.Join(vdirPath2, testFileName), path.Join(vdirPath1, testFileName+".link1"))
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), "Operation Unsupported")
|
|
|
+ }
|
|
|
+ err = client.Symlink("/", "/roolink")
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Symlink(testFileName, "/")
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Symlink(testFileName, vdirPath1)
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), "Operation Unsupported")
|
|
|
+ }
|
|
|
+ err = client.Symlink(vdirPath1, testFileName+".link2")
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), "Operation Unsupported")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName1}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName2}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath1)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath2)
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestDirs(t *testing.T) {
|
|
|
+ u := getTestUser()
|
|
|
+ mappedPath := filepath.Join(os.TempDir(), "vdir")
|
|
|
+ folderName := filepath.Base(mappedPath)
|
|
|
+ vdirPath := "/path/vdir"
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName,
|
|
|
+ MappedPath: mappedPath,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath,
|
|
|
+ })
|
|
|
+ u.Permissions["/subdir"] = []string{dataprovider.PermDownload, dataprovider.PermUpload,
|
|
|
+ dataprovider.PermDelete, dataprovider.PermCreateDirs, dataprovider.PermRename, dataprovider.PermListItems}
|
|
|
+
|
|
|
+ user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ info, err := client.ReadDir("/")
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ assert.Len(t, info, 1)
|
|
|
+ assert.Equal(t, "path", info[0].Name())
|
|
|
+ }
|
|
|
+ fi, err := client.Stat(path.Dir(vdirPath))
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ assert.True(t, fi.IsDir())
|
|
|
+ }
|
|
|
+ err = client.RemoveDirectory("/")
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.RemoveDirectory(vdirPath)
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.RemoveDirectory(path.Dir(vdirPath))
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), "Operation Unsupported")
|
|
|
+ }
|
|
|
+ err = client.Mkdir(vdirPath)
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Mkdir("adir")
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename("/adir", path.Dir(vdirPath))
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), "Operation Unsupported")
|
|
|
+ }
|
|
|
+ err = client.MkdirAll("/subdir/adir")
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename("adir", "subdir/adir")
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), "Operation Unsupported")
|
|
|
+ }
|
|
|
+ err = writeSFTPFile("/subdir/afile.bin", 64, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile("/afile.bin", 32, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename("afile.bin", "subdir/afile.bin")
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Rename("afile.bin", "subdir/afile1.bin")
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(path.Dir(vdirPath), "renamed_vdir")
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), "Operation Unsupported")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath)
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestCryptFsStat(t *testing.T) {
|
|
|
+ user, _, err := httpdtest.AddUser(getCryptFsUser(), http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ testFileSize := int64(4096)
|
|
|
+ err = writeSFTPFile(testFileName, testFileSize, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ info, err := client.Stat(testFileName)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ assert.Equal(t, testFileSize, info.Size())
|
|
|
+ }
|
|
|
+ info, err = os.Stat(filepath.Join(user.HomeDir, testFileName))
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ assert.Greater(t, info.Size(), testFileSize)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestFsPermissionErrors(t *testing.T) {
|
|
|
+ if runtime.GOOS == osWindows {
|
|
|
+ t.Skip("this test is not available on Windows")
|
|
|
+ }
|
|
|
+ user, _, err := httpdtest.AddUser(getCryptFsUser(), http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ testDir := "tDir"
|
|
|
+ err = client.Mkdir(testDir)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.Chmod(user.GetHomeDir(), 0111)
|
|
|
+ assert.NoError(t, err)
|
|
|
+
|
|
|
+ err = client.RemoveDirectory(testDir)
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Rename(testDir, testDir+"1")
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+
|
|
|
+ err = os.Chmod(user.GetHomeDir(), os.ModePerm)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ }
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestResolvePathError(t *testing.T) {
|
|
|
+ u := getTestUser()
|
|
|
+ u.HomeDir = "relative_path"
|
|
|
+ conn := common.NewBaseConnection("", common.ProtocolFTP, u)
|
|
|
+ testPath := "apath"
|
|
|
+ _, err := conn.ListDir(testPath)
|
|
|
+ assert.Error(t, err)
|
|
|
+ err = conn.CreateDir(testPath)
|
|
|
+ assert.Error(t, err)
|
|
|
+ err = conn.RemoveDir(testPath)
|
|
|
+ assert.Error(t, err)
|
|
|
+ err = conn.Rename(testPath, testPath+"1")
|
|
|
+ assert.Error(t, err)
|
|
|
+ err = conn.CreateSymlink(testPath, testPath+".sym")
|
|
|
+ assert.Error(t, err)
|
|
|
+ _, err = conn.DoStat(testPath, 0)
|
|
|
+ assert.Error(t, err)
|
|
|
+ err = conn.SetStat(testPath, &common.StatAttributes{
|
|
|
+ Atime: time.Now(),
|
|
|
+ Mtime: time.Now(),
|
|
|
+ })
|
|
|
+ assert.Error(t, err)
|
|
|
+
|
|
|
+ u = getTestUser()
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ MappedPath: "relative_mapped_path",
|
|
|
+ },
|
|
|
+ VirtualPath: "/vpath",
|
|
|
+ })
|
|
|
+ err = os.MkdirAll(u.HomeDir, os.ModePerm)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ conn.User = u
|
|
|
+ err = conn.Rename(testPath, "/vpath/subpath")
|
|
|
+ assert.Error(t, err)
|
|
|
+
|
|
|
+ outHomePath := filepath.Join(os.TempDir(), testFileName)
|
|
|
+ err = os.WriteFile(outHomePath, testFileContent, os.ModePerm)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.Symlink(outHomePath, filepath.Join(u.HomeDir, testFileName+".link"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.WriteFile(filepath.Join(u.HomeDir, testFileName), testFileContent, os.ModePerm)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = conn.CreateSymlink(testFileName, testFileName+".link")
|
|
|
+ assert.Error(t, err)
|
|
|
+
|
|
|
+ err = os.RemoveAll(u.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.Remove(outHomePath)
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestQuotaTrackDisabled(t *testing.T) {
|
|
|
+ err := dataprovider.Close()
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = config.LoadConfig(configDir, "")
|
|
|
+ assert.NoError(t, err)
|
|
|
+ providerConf := config.GetProviderConf()
|
|
|
+ providerConf.TrackQuota = 0
|
|
|
+ err = dataprovider.Initialize(providerConf, configDir, true)
|
|
|
+ assert.NoError(t, err)
|
|
|
+
|
|
|
+ user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ err = writeSFTPFile(testFileName, 32, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(testFileName, testFileName+"1")
|
|
|
+ assert.NoError(t, err)
|
|
|
+ }
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+
|
|
|
+ err = dataprovider.Close()
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = config.LoadConfig(configDir, "")
|
|
|
+ assert.NoError(t, err)
|
|
|
+ providerConf = config.GetProviderConf()
|
|
|
+ err = dataprovider.Initialize(providerConf, configDir, true)
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestGetQuotaError(t *testing.T) {
|
|
|
+ u := getTestUser()
|
|
|
+ mappedPath := filepath.Join(os.TempDir(), "vdir")
|
|
|
+ folderName := filepath.Base(mappedPath)
|
|
|
+ vdirPath := "/vpath"
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderName,
|
|
|
+ MappedPath: mappedPath,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirPath,
|
|
|
+ QuotaSize: 0,
|
|
|
+ QuotaFiles: 10,
|
|
|
+ })
|
|
|
+ user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ err = writeSFTPFile(testFileName, 32, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+
|
|
|
+ err = dataprovider.Close()
|
|
|
+ assert.NoError(t, err)
|
|
|
+
|
|
|
+ err = client.Rename(testFileName, path.Join(vdirPath, testFileName))
|
|
|
+ assert.Error(t, err)
|
|
|
+
|
|
|
+ err = config.LoadConfig(configDir, "")
|
|
|
+ assert.NoError(t, err)
|
|
|
+ providerConf := config.GetProviderConf()
|
|
|
+ err = dataprovider.Initialize(providerConf, configDir, true)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ }
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPath)
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestRenameDir(t *testing.T) {
|
|
|
+ u := getTestUser()
|
|
|
+ testDir := "/dir-to-rename"
|
|
|
+ u.Permissions[testDir] = []string{dataprovider.PermListItems, dataprovider.PermUpload}
|
|
|
+ user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ err = client.Mkdir(testDir)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(testDir, testFileName), 32, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(testDir, testDir+"_rename")
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ }
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestRenameSymlink(t *testing.T) {
|
|
|
+ u := getTestUser()
|
|
|
+ testDir := "/dir-no-create-links"
|
|
|
+ otherDir := "otherdir"
|
|
|
+ u.Permissions[testDir] = []string{dataprovider.PermListItems, dataprovider.PermUpload, dataprovider.PermDelete,
|
|
|
+ dataprovider.PermCreateDirs}
|
|
|
+ user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ err = client.Mkdir(otherDir)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Symlink(otherDir, otherDir+".link")
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(otherDir+".link", path.Join(testDir, "symlink"))
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Rename(otherDir+".link", "allowed_link")
|
|
|
+ assert.NoError(t, err)
|
|
|
+ }
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestNonLocalCrossRename(t *testing.T) {
|
|
|
+ baseUser, resp, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
|
|
|
+ assert.NoError(t, err, string(resp))
|
|
|
+ u := getTestUser()
|
|
|
+ u.HomeDir += "_folders"
|
|
|
+ u.Username += "_folders"
|
|
|
+ mappedPathSFTP := filepath.Join(os.TempDir(), "sftp")
|
|
|
+ folderNameSFTP := filepath.Base(mappedPathSFTP)
|
|
|
+ vdirSFTPPath := "/vdir/sftp"
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderNameSFTP,
|
|
|
+ FsConfig: vfs.Filesystem{
|
|
|
+ Provider: vfs.SFTPFilesystemProvider,
|
|
|
+ SFTPConfig: vfs.SFTPFsConfig{
|
|
|
+ Endpoint: sftpServerAddr,
|
|
|
+ Username: baseUser.Username,
|
|
|
+ Password: kms.NewPlainSecret(defaultPassword),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ VirtualPath: vdirSFTPPath,
|
|
|
+ })
|
|
|
+ mappedPathCrypt := filepath.Join(os.TempDir(), "crypt")
|
|
|
+ folderNameCrypt := filepath.Base(mappedPathCrypt)
|
|
|
+ vdirCryptPath := "/vdir/crypt"
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderNameCrypt,
|
|
|
+ FsConfig: vfs.Filesystem{
|
|
|
+ Provider: vfs.CryptedFilesystemProvider,
|
|
|
+ CryptConfig: vfs.CryptFsConfig{
|
|
|
+ Passphrase: kms.NewPlainSecret(defaultPassword),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ MappedPath: mappedPathCrypt,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirCryptPath,
|
|
|
+ })
|
|
|
+ user, resp, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err, string(resp))
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ assert.NoError(t, checkBasicSFTP(client))
|
|
|
+ err = writeSFTPFile(testFileName, 4096, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirSFTPPath, testFileName), 8192, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirCryptPath, testFileName), 16384, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(path.Join(vdirSFTPPath, testFileName), path.Join(vdirCryptPath, testFileName+".rename"))
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Rename(path.Join(vdirCryptPath, testFileName), path.Join(vdirSFTPPath, testFileName+".rename"))
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Rename(testFileName, path.Join(vdirCryptPath, testFileName+".rename"))
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Rename(testFileName, path.Join(vdirSFTPPath, testFileName+".rename"))
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Rename(path.Join(vdirSFTPPath, testFileName), testFileName+".rename")
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Rename(path.Join(vdirCryptPath, testFileName), testFileName+".rename")
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ // rename on local fs or on the same folder must work
|
|
|
+ err = client.Rename(testFileName, testFileName+".rename")
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(path.Join(vdirSFTPPath, testFileName), path.Join(vdirSFTPPath, testFileName+"_rename"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(path.Join(vdirCryptPath, testFileName), path.Join(vdirCryptPath, testFileName+"_rename"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ // renaming a virtual folder is not allowed
|
|
|
+ err = client.Rename(vdirSFTPPath, vdirSFTPPath+"_rename")
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Rename(vdirCryptPath, vdirCryptPath+"_rename")
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Rename(vdirCryptPath, path.Join(vdirCryptPath, "rename"))
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Mkdir(path.Join(vdirCryptPath, "subcryptdir"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(path.Join(vdirCryptPath, "subcryptdir"), vdirCryptPath)
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ // renaming root folder is not allowed
|
|
|
+ err = client.Rename("/", "new_name")
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ // renaming a path to a virtual folder is not allowed
|
|
|
+ err = client.Rename("/vdir", "new_vdir")
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), "Operation Unsupported")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderNameCrypt}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderNameSFTP}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveUser(baseUser, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(baseUser.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPathCrypt)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPathSFTP)
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestNonLocalCrossRenameNonLocalBaseUser(t *testing.T) {
|
|
|
+ baseUser, resp, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
|
|
|
+ assert.NoError(t, err, string(resp))
|
|
|
+ u := getTestSFTPUser()
|
|
|
+ mappedPathLocal := filepath.Join(os.TempDir(), "local")
|
|
|
+ folderNameLocal := filepath.Base(mappedPathLocal)
|
|
|
+ vdirLocalPath := "/vdir/local"
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderNameLocal,
|
|
|
+ MappedPath: mappedPathLocal,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirLocalPath,
|
|
|
+ })
|
|
|
+ mappedPathCrypt := filepath.Join(os.TempDir(), "crypt")
|
|
|
+ folderNameCrypt := filepath.Base(mappedPathCrypt)
|
|
|
+ vdirCryptPath := "/vdir/crypt"
|
|
|
+ u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
|
|
+ BaseVirtualFolder: vfs.BaseVirtualFolder{
|
|
|
+ Name: folderNameCrypt,
|
|
|
+ FsConfig: vfs.Filesystem{
|
|
|
+ Provider: vfs.CryptedFilesystemProvider,
|
|
|
+ CryptConfig: vfs.CryptFsConfig{
|
|
|
+ Passphrase: kms.NewPlainSecret(defaultPassword),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ MappedPath: mappedPathCrypt,
|
|
|
+ },
|
|
|
+ VirtualPath: vdirCryptPath,
|
|
|
+ })
|
|
|
+ user, resp, err := httpdtest.AddUser(u, http.StatusCreated)
|
|
|
+ assert.NoError(t, err, string(resp))
|
|
|
+ client, err := getSftpClient(user)
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer client.Close()
|
|
|
+ assert.NoError(t, checkBasicSFTP(client))
|
|
|
+ err = writeSFTPFile(testFileName, 4096, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirLocalPath, testFileName), 8192, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = writeSFTPFile(path.Join(vdirCryptPath, testFileName), 16384, client)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(path.Join(vdirLocalPath, testFileName), path.Join(vdirCryptPath, testFileName+".rename"))
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Rename(path.Join(vdirCryptPath, testFileName), path.Join(vdirLocalPath, testFileName+".rename"))
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Rename(testFileName, path.Join(vdirCryptPath, testFileName+".rename"))
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Rename(testFileName, path.Join(vdirLocalPath, testFileName+".rename"))
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Rename(path.Join(vdirLocalPath, testFileName), testFileName+".rename")
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Rename(path.Join(vdirCryptPath, testFileName), testFileName+".rename")
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ // rename on local fs or on the same folder must work
|
|
|
+ err = client.Rename(testFileName, testFileName+".rename")
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(path.Join(vdirLocalPath, testFileName), path.Join(vdirLocalPath, testFileName+"_rename"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = client.Rename(path.Join(vdirCryptPath, testFileName), path.Join(vdirCryptPath, testFileName+"_rename"))
|
|
|
+ assert.NoError(t, err)
|
|
|
+ // renaming a virtual folder is not allowed
|
|
|
+ err = client.Rename(vdirLocalPath, vdirLocalPath+"_rename")
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ err = client.Rename(vdirCryptPath, vdirCryptPath+"_rename")
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ // renaming root folder is not allowed
|
|
|
+ err = client.Rename("/", "new_name")
|
|
|
+ assert.ErrorIs(t, err, os.ErrPermission)
|
|
|
+ // renaming a path to a virtual folder is not allowed
|
|
|
+ err = client.Rename("/vdir", "new_vdir")
|
|
|
+ if assert.Error(t, err) {
|
|
|
+ assert.Contains(t, err.Error(), "Operation Unsupported")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ _, err = httpdtest.RemoveUser(user, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderNameCrypt}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderNameLocal}, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ _, err = httpdtest.RemoveUser(baseUser, http.StatusOK)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(user.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(baseUser.GetHomeDir())
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPathCrypt)
|
|
|
+ assert.NoError(t, err)
|
|
|
+ err = os.RemoveAll(mappedPathLocal)
|
|
|
+ assert.NoError(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func TestProxyProtocol(t *testing.T) {
|
|
|
+ httpClient := httpclient.GetHTTPClient()
|
|
|
+ resp, err := httpClient.Get(fmt.Sprintf("http://%v", httpProxyAddr))
|
|
|
+ if assert.NoError(t, err) {
|
|
|
+ defer resp.Body.Close()
|
|
|
+ assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func TestSetProtocol(t *testing.T) {
|
|
|
+ conn := common.NewBaseConnection("id", "sshd_exec", dataprovider.User{HomeDir: os.TempDir()})
|
|
|
+ conn.SetProtocol(common.ProtocolSCP)
|
|
|
+ require.Equal(t, "SCP_id", conn.GetID())
|
|
|
+}
|
|
|
+
|
|
|
+func TestGetFsError(t *testing.T) {
|
|
|
+ u := getTestUser()
|
|
|
+ u.FsConfig.Provider = vfs.GCSFilesystemProvider
|
|
|
+ u.FsConfig.GCSConfig.Bucket = "test"
|
|
|
+ u.FsConfig.GCSConfig.Credentials = kms.NewPlainSecret("invalid JSON for credentials")
|
|
|
+ conn := common.NewBaseConnection("", common.ProtocolFTP, u)
|
|
|
+ _, _, err := conn.GetFsAndResolvedPath("/vpath")
|
|
|
+ assert.Error(t, err)
|
|
|
+}
|
|
|
+
|
|
|
+func waitTCPListening(address string) {
|
|
|
+ for {
|
|
|
+ conn, err := net.Dial("tcp", address)
|
|
|
+ if err != nil {
|
|
|
+ logger.WarnToConsole("tcp server %v not listening: %v", address, err)
|
|
|
+ time.Sleep(100 * time.Millisecond)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ logger.InfoToConsole("tcp server %v now listening", address)
|
|
|
+ conn.Close()
|
|
|
+ break
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func checkBasicSFTP(client *sftp.Client) error {
|
|
|
+ _, err := client.Getwd()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ _, err = client.ReadDir(".")
|
|
|
+ return err
|
|
|
+}
|
|
|
+
|
|
|
+func getSftpClient(user dataprovider.User) (*sftp.Client, error) {
|
|
|
+ var sftpClient *sftp.Client
|
|
|
+ config := &ssh.ClientConfig{
|
|
|
+ User: user.Username,
|
|
|
+ HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
|
|
+ return nil
|
|
|
+ },
|
|
|
+ }
|
|
|
+ if user.Password != "" {
|
|
|
+ config.Auth = []ssh.AuthMethod{ssh.Password(user.Password)}
|
|
|
+ } else {
|
|
|
+ config.Auth = []ssh.AuthMethod{ssh.Password(defaultPassword)}
|
|
|
+ }
|
|
|
+
|
|
|
+ conn, err := ssh.Dial("tcp", sftpServerAddr, config)
|
|
|
+ if err != nil {
|
|
|
+ return sftpClient, err
|
|
|
+ }
|
|
|
+ sftpClient, err = sftp.NewClient(conn)
|
|
|
+ return sftpClient, err
|
|
|
+}
|
|
|
+
|
|
|
+func getTestUser() dataprovider.User {
|
|
|
+ user := dataprovider.User{
|
|
|
+ Username: defaultUsername,
|
|
|
+ Password: defaultPassword,
|
|
|
+ HomeDir: filepath.Join(homeBasePath, defaultUsername),
|
|
|
+ Status: 1,
|
|
|
+ ExpirationDate: 0,
|
|
|
+ }
|
|
|
+ user.Permissions = make(map[string][]string)
|
|
|
+ user.Permissions["/"] = allPerms
|
|
|
+ return user
|
|
|
+}
|
|
|
+
|
|
|
+func getTestSFTPUser() dataprovider.User {
|
|
|
+ u := getTestUser()
|
|
|
+ u.Username = defaultSFTPUsername
|
|
|
+ u.FsConfig.Provider = vfs.SFTPFilesystemProvider
|
|
|
+ u.FsConfig.SFTPConfig.Endpoint = sftpServerAddr
|
|
|
+ u.FsConfig.SFTPConfig.Username = defaultUsername
|
|
|
+ u.FsConfig.SFTPConfig.Password = kms.NewPlainSecret(defaultPassword)
|
|
|
+ return u
|
|
|
+}
|
|
|
+
|
|
|
+func getCryptFsUser() dataprovider.User {
|
|
|
+ u := getTestUser()
|
|
|
+ u.FsConfig.Provider = vfs.CryptedFilesystemProvider
|
|
|
+ u.FsConfig.CryptConfig.Passphrase = kms.NewPlainSecret(defaultPassword)
|
|
|
+ return u
|
|
|
+}
|
|
|
+
|
|
|
+func writeSFTPFile(name string, size int64, client *sftp.Client) error {
|
|
|
+ content := make([]byte, size)
|
|
|
+ _, err := rand.Read(content)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ f, err := client.Create(name)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ _, err = io.Copy(f, bytes.NewBuffer(content))
|
|
|
+ if err != nil {
|
|
|
+ f.Close()
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ err = f.Close()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ info, err := client.Stat(name)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if info.Size() != size {
|
|
|
+ return fmt.Errorf("file size mismatch, wanted %v, actual %v", size, info.Size())
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|