add a specific permission to manage folders
creating/updating folders embedded in users is no longer supported. Fixes #1349 Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
e4be4048e3
commit
0413c0471c
21 changed files with 1346 additions and 3568 deletions
19
go.mod
19
go.mod
|
@ -23,9 +23,9 @@ require (
|
|||
github.com/coreos/go-oidc/v3 v3.6.0
|
||||
github.com/drakkan/webdav v0.0.0-20230227175313-32996838bcd8
|
||||
github.com/eikenb/pipeat v0.0.0-20210730190139-06b3e6902001
|
||||
github.com/fclairamb/ftpserverlib v0.21.0
|
||||
github.com/fclairamb/ftpserverlib v0.21.1-0.20230719102702-76e3b6785cda
|
||||
github.com/fclairamb/go-log v0.4.1
|
||||
github.com/go-acme/lego/v4 v4.12.3
|
||||
github.com/go-acme/lego/v4 v4.13.2
|
||||
github.com/go-chi/chi/v5 v5.0.10
|
||||
github.com/go-chi/jwtauth/v5 v5.1.1
|
||||
github.com/go-chi/render v1.0.3
|
||||
|
@ -66,21 +66,21 @@ require (
|
|||
github.com/wneessen/go-mail v0.4.0
|
||||
github.com/yl2chen/cidranger v1.0.3-0.20210928021809-d1cb2c52f37a
|
||||
go.etcd.io/bbolt v1.3.7
|
||||
go.uber.org/automaxprocs v1.5.2
|
||||
gocloud.dev v0.30.0
|
||||
go.uber.org/automaxprocs v1.5.3
|
||||
gocloud.dev v0.32.0
|
||||
golang.org/x/crypto v0.11.0
|
||||
golang.org/x/net v0.12.0
|
||||
golang.org/x/oauth2 v0.10.0
|
||||
golang.org/x/sys v0.10.0
|
||||
golang.org/x/term v0.10.0
|
||||
golang.org/x/time v0.3.0
|
||||
google.golang.org/api v0.131.0
|
||||
google.golang.org/api v0.132.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.110.6 // indirect
|
||||
cloud.google.com/go/compute v1.21.0 // indirect
|
||||
cloud.google.com/go/compute v1.22.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/iam v1.1.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect
|
||||
|
@ -161,9 +161,9 @@ require (
|
|||
golang.org/x/tools v0.11.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230720185612-659f7aaaa771 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230720185612-659f7aaaa771 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230720185612-659f7aaaa771 // indirect
|
||||
google.golang.org/grpc v1.56.2 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
|
@ -171,7 +171,6 @@ require (
|
|||
)
|
||||
|
||||
replace (
|
||||
github.com/fclairamb/ftpserverlib => github.com/drakkan/ftpserverlib v0.0.0-20230714144823-d8aff325a796
|
||||
github.com/jlaffaye/ftp => github.com/drakkan/ftp v0.0.0-20201114075148-9b9adce499a9
|
||||
github.com/robfig/cron/v3 => github.com/drakkan/cron/v3 v3.0.0-20230222140221-217a1e4d96c0
|
||||
golang.org/x/crypto => github.com/drakkan/crypto v0.0.0-20230614155948-29e7be6c0fab
|
||||
|
|
|
@ -1062,15 +1062,9 @@ func TestFileNotAllowedErrors(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRootDirVirtualFolder(t *testing.T) {
|
||||
u := getTestUser()
|
||||
u.QuotaFiles = 1000
|
||||
u.UploadDataTransfer = 1000
|
||||
u.DownloadDataTransfer = 5000
|
||||
mappedPath1 := filepath.Join(os.TempDir(), "mapped1")
|
||||
folderName1 := filepath.Base(mappedPath1)
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: filepath.Base(mappedPath1),
|
||||
MappedPath: mappedPath1,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
|
@ -1078,17 +1072,32 @@ func TestRootDirVirtualFolder(t *testing.T) {
|
|||
Passphrase: kms.NewPlainSecret("cryptsecret"),
|
||||
},
|
||||
},
|
||||
}
|
||||
mappedPath2 := filepath.Join(os.TempDir(), "mapped2")
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: filepath.Base(mappedPath2),
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
folder1, _, err := httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
folder2, _, err := httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
u := getTestUser()
|
||||
u.QuotaFiles = 1000
|
||||
u.UploadDataTransfer = 1000
|
||||
u.DownloadDataTransfer = 5000
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folder1.Name,
|
||||
},
|
||||
VirtualPath: "/",
|
||||
QuotaFiles: 1000,
|
||||
})
|
||||
mappedPath2 := filepath.Join(os.TempDir(), "mapped2")
|
||||
folderName2 := filepath.Base(mappedPath2)
|
||||
vdirPath2 := "/vmapped"
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
Name: folder2.Name,
|
||||
},
|
||||
VirtualPath: vdirPath2,
|
||||
QuotaFiles: -1,
|
||||
|
@ -1123,7 +1132,7 @@ func TestRootDirVirtualFolder(t *testing.T) {
|
|||
user, _, err := httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 0, user.UsedQuotaFiles)
|
||||
folder, _, err := httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
||||
folder, _, err := httpdtest.GetFolderByName(folder1.Name, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, folder.UsedQuotaFiles)
|
||||
|
||||
|
@ -1137,7 +1146,7 @@ func TestRootDirVirtualFolder(t *testing.T) {
|
|||
user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, user.UsedQuotaFiles)
|
||||
folder, _, err = httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
||||
folder, _, err = httpdtest.GetFolderByName(folder1.Name, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, folder.UsedQuotaFiles)
|
||||
|
||||
|
@ -1155,39 +1164,47 @@ func TestRootDirVirtualFolder(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = os.RemoveAll(user.GetHomeDir())
|
||||
assert.NoError(t, err)
|
||||
_, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName1}, http.StatusOK)
|
||||
_, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folder1.Name}, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
err = os.RemoveAll(mappedPath1)
|
||||
assert.NoError(t, err)
|
||||
_, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName2}, http.StatusOK)
|
||||
_, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folder2.Name}, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
err = os.RemoveAll(mappedPath2)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestTruncateQuotaLimits(t *testing.T) {
|
||||
mappedPath1 := filepath.Join(os.TempDir(), "mapped1")
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: filepath.Base(mappedPath1),
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
folder1, _, err := httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
mappedPath2 := filepath.Join(os.TempDir(), "mapped2")
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: filepath.Base(mappedPath2),
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
folder2, _, err := httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
u := getTestUser()
|
||||
u.QuotaSize = 20
|
||||
u.UploadDataTransfer = 1000
|
||||
u.DownloadDataTransfer = 5000
|
||||
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,
|
||||
Name: folder1.Name,
|
||||
},
|
||||
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,
|
||||
Name: folder2.Name,
|
||||
},
|
||||
VirtualPath: vdirPath2,
|
||||
QuotaFiles: -1,
|
||||
|
@ -1331,21 +1348,21 @@ func TestTruncateQuotaLimits(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
expectedQuotaFiles := 0
|
||||
expectedQuotaSize := int64(2)
|
||||
fold, _, err := httpdtest.GetFolderByName(folderName1, http.StatusOK)
|
||||
fold, _, err := httpdtest.GetFolderByName(folder1.Name, 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)
|
||||
fold, _, err = httpdtest.GetFolderByName(folder1.Name, 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)
|
||||
fold, _, err := httpdtest.GetFolderByName(folder1.Name, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(1), fold.UsedQuotaSize)
|
||||
assert.Equal(t, 1, fold.UsedQuotaFiles)
|
||||
|
@ -1360,14 +1377,14 @@ func TestTruncateQuotaLimits(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
expectedQuotaFiles := 0
|
||||
expectedQuotaSize := int64(3)
|
||||
fold, _, err := httpdtest.GetFolderByName(folderName2, http.StatusOK)
|
||||
fold, _, err := httpdtest.GetFolderByName(folder2.Name, 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)
|
||||
fold, _, err = httpdtest.GetFolderByName(folder2.Name, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expectedQuotaSize, fold.UsedQuotaSize)
|
||||
assert.Equal(t, expectedQuotaFiles, fold.UsedQuotaFiles)
|
||||
|
@ -1399,11 +1416,11 @@ func TestTruncateQuotaLimits(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = os.RemoveAll(localUser.GetHomeDir())
|
||||
assert.NoError(t, err)
|
||||
_, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName1}, http.StatusOK)
|
||||
_, err = httpdtest.RemoveFolder(folder1, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
err = os.RemoveAll(mappedPath1)
|
||||
assert.NoError(t, err)
|
||||
_, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName2}, http.StatusOK)
|
||||
_, err = httpdtest.RemoveFolder(folder2, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
err = os.RemoveAll(mappedPath2)
|
||||
assert.NoError(t, err)
|
||||
|
@ -1425,10 +1442,27 @@ func TestVirtualFoldersQuotaRenameOverwrite(t *testing.T) {
|
|||
mappedPath3 := filepath.Join(os.TempDir(), "vdir3")
|
||||
folderName3 := filepath.Base(mappedPath3)
|
||||
vdirPath3 := "/vdir3"
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f3 := vfs.BaseVirtualFolder{
|
||||
Name: folderName3,
|
||||
MappedPath: mappedPath3,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f3, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
QuotaFiles: 2,
|
||||
|
@ -1436,7 +1470,6 @@ func TestVirtualFoldersQuotaRenameOverwrite(t *testing.T) {
|
|||
})
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
MappedPath: mappedPath2,
|
||||
Name: folderName2,
|
||||
},
|
||||
VirtualPath: vdirPath2,
|
||||
|
@ -1446,7 +1479,6 @@ func TestVirtualFoldersQuotaRenameOverwrite(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName3,
|
||||
MappedPath: mappedPath3,
|
||||
},
|
||||
VirtualPath: vdirPath3,
|
||||
QuotaFiles: 2,
|
||||
|
@ -1611,10 +1643,21 @@ func TestVirtualFoldersQuotaValues(t *testing.T) {
|
|||
mappedPath2 := filepath.Join(os.TempDir(), "vdir2")
|
||||
vdirPath2 := "/vdir2"
|
||||
folderName2 := filepath.Base(mappedPath2)
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
// quota is included in the user's one
|
||||
|
@ -1624,7 +1667,6 @@ func TestVirtualFoldersQuotaValues(t *testing.T) {
|
|||
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
|
||||
|
@ -1701,10 +1743,21 @@ func TestQuotaRenameInsideSameVirtualFolder(t *testing.T) {
|
|||
mappedPath2 := filepath.Join(os.TempDir(), "vdir2")
|
||||
vdirPath2 := "/vdir2"
|
||||
folderName2 := filepath.Base(mappedPath2)
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
// quota is included in the user's one
|
||||
|
@ -1714,7 +1767,6 @@ func TestQuotaRenameInsideSameVirtualFolder(t *testing.T) {
|
|||
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
|
||||
|
@ -1881,10 +1933,21 @@ func TestQuotaRenameBetweenVirtualFolder(t *testing.T) {
|
|||
mappedPath2 := filepath.Join(os.TempDir(), "vdir2")
|
||||
folderName2 := filepath.Base(mappedPath2)
|
||||
vdirPath2 := "/vdir2"
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
// quota is included in the user's one
|
||||
|
@ -1894,7 +1957,6 @@ func TestQuotaRenameBetweenVirtualFolder(t *testing.T) {
|
|||
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
|
||||
|
@ -2077,10 +2139,21 @@ func TestQuotaRenameFromVirtualFolder(t *testing.T) {
|
|||
mappedPath2 := filepath.Join(os.TempDir(), "vdir2")
|
||||
folderName2 := filepath.Base(mappedPath2)
|
||||
vdirPath2 := "/vdir2"
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
// quota is included in the user's one
|
||||
|
@ -2090,7 +2163,6 @@ func TestQuotaRenameFromVirtualFolder(t *testing.T) {
|
|||
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
|
||||
|
@ -2276,10 +2348,21 @@ func TestQuotaRenameToVirtualFolder(t *testing.T) {
|
|||
mappedPath2 := filepath.Join(os.TempDir(), "vdir2")
|
||||
folderName2 := filepath.Base(mappedPath2)
|
||||
vdirPath2 := "/vdir2"
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
// quota is included in the user's one
|
||||
|
@ -2289,7 +2372,6 @@ func TestQuotaRenameToVirtualFolder(t *testing.T) {
|
|||
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
|
||||
|
@ -2568,10 +2650,21 @@ func TestVirtualFoldersLink(t *testing.T) {
|
|||
mappedPath2 := filepath.Join(os.TempDir(), "vdir2")
|
||||
folderName2 := filepath.Base(mappedPath2)
|
||||
vdirPath2 := "/vdir2"
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
// quota is included in the user's one
|
||||
|
@ -2581,7 +2674,6 @@ func TestVirtualFoldersLink(t *testing.T) {
|
|||
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
|
||||
|
@ -2687,10 +2779,7 @@ func TestCrossFolderRename(t *testing.T) {
|
|||
baseUser, resp, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
|
||||
u := getCryptFsUser()
|
||||
u.VirtualFolders = []vfs.VirtualFolder{
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folder1,
|
||||
MappedPath: filepath.Join(os.TempDir(), folder1),
|
||||
FsConfig: vfs.Filesystem{
|
||||
|
@ -2699,13 +2788,10 @@ func TestCrossFolderRename(t *testing.T) {
|
|||
Passphrase: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: path.Join("/", folder1),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folder2,
|
||||
MappedPath: filepath.Join(os.TempDir(), folder2),
|
||||
FsConfig: vfs.Filesystem{
|
||||
|
@ -2714,13 +2800,10 @@ func TestCrossFolderRename(t *testing.T) {
|
|||
Passphrase: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: path.Join("/", folder2),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f3 := vfs.BaseVirtualFolder{
|
||||
Name: folder3,
|
||||
MappedPath: filepath.Join(os.TempDir(), folder3),
|
||||
FsConfig: vfs.Filesystem{
|
||||
|
@ -2729,13 +2812,10 @@ func TestCrossFolderRename(t *testing.T) {
|
|||
Passphrase: kms.NewPlainSecret(defaultPassword + "mod"),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: path.Join("/", folder3),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f3, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f4 := vfs.BaseVirtualFolder{
|
||||
Name: folder4,
|
||||
MappedPath: filepath.Join(os.TempDir(), folder4),
|
||||
FsConfig: vfs.Filesystem{
|
||||
|
@ -2749,13 +2829,10 @@ func TestCrossFolderRename(t *testing.T) {
|
|||
Password: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: path.Join("/", folder4),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f4, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f5 := vfs.BaseVirtualFolder{
|
||||
Name: folder5,
|
||||
MappedPath: filepath.Join(os.TempDir(), folder5),
|
||||
FsConfig: vfs.Filesystem{
|
||||
|
@ -2769,13 +2846,10 @@ func TestCrossFolderRename(t *testing.T) {
|
|||
Password: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: path.Join("/", folder5),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f5, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f6 := vfs.BaseVirtualFolder{
|
||||
Name: folder6,
|
||||
MappedPath: filepath.Join(os.TempDir(), folder6),
|
||||
FsConfig: vfs.Filesystem{
|
||||
|
@ -2789,13 +2863,10 @@ func TestCrossFolderRename(t *testing.T) {
|
|||
Password: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: path.Join("/", folder6),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f6, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f7 := vfs.BaseVirtualFolder{
|
||||
Name: folder7,
|
||||
MappedPath: filepath.Join(os.TempDir(), folder7),
|
||||
FsConfig: vfs.Filesystem{
|
||||
|
@ -2809,6 +2880,63 @@ func TestCrossFolderRename(t *testing.T) {
|
|||
Password: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f7, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
u := getCryptFsUser()
|
||||
u.VirtualFolders = []vfs.VirtualFolder{
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folder1,
|
||||
},
|
||||
VirtualPath: path.Join("/", folder1),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folder2,
|
||||
},
|
||||
VirtualPath: path.Join("/", folder2),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folder3,
|
||||
},
|
||||
VirtualPath: path.Join("/", folder3),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folder4,
|
||||
},
|
||||
VirtualPath: path.Join("/", folder4),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folder5,
|
||||
},
|
||||
VirtualPath: path.Join("/", folder5),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folder6,
|
||||
},
|
||||
VirtualPath: path.Join("/", folder6),
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
},
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folder7,
|
||||
},
|
||||
VirtualPath: path.Join("/", folder7),
|
||||
QuotaSize: -1,
|
||||
|
@ -2889,10 +3017,15 @@ func TestDirs(t *testing.T) {
|
|||
mappedPath := filepath.Join(os.TempDir(), "vdir")
|
||||
folderName := filepath.Base(mappedPath)
|
||||
vdirPath := "/path/vdir"
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
})
|
||||
|
@ -4398,13 +4531,18 @@ func TestEventRulePreDelete(t *testing.T) {
|
|||
}
|
||||
rule1, _, err := httpdtest.AddEventRule(r1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: movePath,
|
||||
MappedPath: filepath.Join(os.TempDir(), movePath),
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
u := getTestUser()
|
||||
u.QuotaFiles = 1000
|
||||
u.VirtualFolders = []vfs.VirtualFolder{
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: movePath,
|
||||
MappedPath: filepath.Join(os.TempDir(), movePath),
|
||||
},
|
||||
VirtualPath: "/" + movePath,
|
||||
QuotaFiles: 1000,
|
||||
|
@ -5326,10 +5464,15 @@ func TestEventActionCompressQuotaFolder(t *testing.T) {
|
|||
mappedPath := filepath.Join(os.TempDir(), "virtualpath")
|
||||
folderName := filepath.Base(mappedPath)
|
||||
vdirPath := "/virtualpath"
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
QuotaSize: -1,
|
||||
|
@ -7092,10 +7235,15 @@ func TestGetQuotaError(t *testing.T) {
|
|||
mappedPath := filepath.Join(os.TempDir(), "vdir")
|
||||
folderName := filepath.Base(mappedPath)
|
||||
vdirPath := "/vpath"
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
QuotaSize: 0,
|
||||
|
@ -7559,15 +7707,13 @@ func TestSFTPLoopError(t *testing.T) {
|
|||
}
|
||||
err := smtpCfg.Initialize(configDir, true)
|
||||
require.NoError(t, err)
|
||||
|
||||
user1 := getTestUser()
|
||||
user2 := getTestUser()
|
||||
user1.Username += "1"
|
||||
user2.Username += "2"
|
||||
// user1 is a local account with a virtual SFTP folder to user2
|
||||
// user2 has user1 as SFTP fs
|
||||
user1.VirtualFolders = append(user1.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: "sftp",
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.SFTPFilesystemProvider,
|
||||
|
@ -7579,6 +7725,12 @@ func TestSFTPLoopError(t *testing.T) {
|
|||
Password: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
}
|
||||
folder, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user1.VirtualFolders = append(user1.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folder.Name,
|
||||
},
|
||||
VirtualPath: "/vdir",
|
||||
})
|
||||
|
@ -7683,7 +7835,7 @@ func TestSFTPLoopError(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = os.RemoveAll(user2.GetHomeDir())
|
||||
assert.NoError(t, err)
|
||||
_, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: "sftp"}, http.StatusOK)
|
||||
_, err = httpdtest.RemoveFolder(folder, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
|
||||
smtpCfg = smtp.Config{}
|
||||
|
@ -7703,6 +7855,20 @@ func TestNonLocalCrossRename(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderNameSFTP,
|
||||
},
|
||||
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,
|
||||
},
|
||||
VirtualPath: vdirCryptPath,
|
||||
})
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderNameSFTP,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.SFTPFilesystemProvider,
|
||||
SFTPConfig: vfs.SFTPFsConfig{
|
||||
|
@ -7713,14 +7879,10 @@ func TestNonLocalCrossRename(t *testing.T) {
|
|||
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{
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderNameCrypt,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
|
@ -7729,9 +7891,10 @@ func TestNonLocalCrossRename(t *testing.T) {
|
|||
},
|
||||
},
|
||||
MappedPath: mappedPathCrypt,
|
||||
},
|
||||
VirtualPath: vdirCryptPath,
|
||||
})
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
user, resp, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
conn, client, err := getSftpClient(user)
|
||||
|
@ -7813,7 +7976,6 @@ func TestNonLocalCrossRenameNonLocalBaseUser(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderNameLocal,
|
||||
MappedPath: mappedPathLocal,
|
||||
},
|
||||
VirtualPath: vdirLocalPath,
|
||||
})
|
||||
|
@ -7823,6 +7985,17 @@ func TestNonLocalCrossRenameNonLocalBaseUser(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderNameCrypt,
|
||||
},
|
||||
VirtualPath: vdirCryptPath,
|
||||
})
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderNameLocal,
|
||||
MappedPath: mappedPathLocal,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderNameCrypt,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
CryptConfig: vfs.CryptFsConfig{
|
||||
|
@ -7830,9 +8003,10 @@ func TestNonLocalCrossRenameNonLocalBaseUser(t *testing.T) {
|
|||
},
|
||||
},
|
||||
MappedPath: mappedPathCrypt,
|
||||
},
|
||||
VirtualPath: vdirCryptPath,
|
||||
})
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
user, resp, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
conn, client, err := getSftpClient(user)
|
||||
|
@ -8131,7 +8305,6 @@ func TestCrossFoldersCopy(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vpath1,
|
||||
QuotaSize: -1,
|
||||
|
@ -8143,7 +8316,6 @@ func TestCrossFoldersCopy(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
},
|
||||
VirtualPath: vpath2,
|
||||
QuotaSize: -1,
|
||||
|
@ -8155,13 +8327,6 @@ func TestCrossFoldersCopy(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName3,
|
||||
MappedPath: mappedPath3,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
CryptConfig: vfs.CryptFsConfig{
|
||||
Passphrase: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: vpath3,
|
||||
QuotaSize: -1,
|
||||
|
@ -8173,6 +8338,37 @@ func TestCrossFoldersCopy(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName4,
|
||||
},
|
||||
VirtualPath: vpath4,
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
})
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f3 := vfs.BaseVirtualFolder{
|
||||
Name: folderName3,
|
||||
MappedPath: mappedPath3,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
CryptConfig: vfs.CryptFsConfig{
|
||||
Passphrase: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f3, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f4 := vfs.BaseVirtualFolder{
|
||||
Name: folderName4,
|
||||
MappedPath: mappedPath4,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.SFTPFilesystemProvider,
|
||||
|
@ -8184,11 +8380,10 @@ func TestCrossFoldersCopy(t *testing.T) {
|
|||
Password: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: vpath4,
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
})
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f4, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
user, resp, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
conn, client, err := getSftpClient(user)
|
||||
|
|
|
@ -48,6 +48,10 @@ func TestTransfersCheckerDiskQuota(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
folder := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: filepath.Join(os.TempDir(), folderName),
|
||||
}
|
||||
user := dataprovider.User{
|
||||
BaseUser: sdk.BaseUser{
|
||||
Username: username,
|
||||
|
@ -63,7 +67,6 @@ func TestTransfersCheckerDiskQuota(t *testing.T) {
|
|||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: filepath.Join(os.TempDir(), folderName),
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
QuotaSize: 100,
|
||||
|
@ -80,6 +83,8 @@ func TestTransfersCheckerDiskQuota(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
group, err = dataprovider.GroupExists(groupName)
|
||||
assert.NoError(t, err)
|
||||
err = dataprovider.AddFolder(&folder, "", "", "")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(120), group.UserSettings.QuotaSize)
|
||||
err = dataprovider.AddUser(&user, "", "", "")
|
||||
assert.NoError(t, err)
|
||||
|
@ -601,6 +606,10 @@ func TestGetUsersForQuotaCheck(t *testing.T) {
|
|||
assert.Len(t, users, 0)
|
||||
|
||||
for i := 0; i < 40; i++ {
|
||||
folder := vfs.BaseVirtualFolder{
|
||||
Name: fmt.Sprintf("f%v", i),
|
||||
MappedPath: filepath.Join(os.TempDir(), fmt.Sprintf("f%v", i)),
|
||||
}
|
||||
user := dataprovider.User{
|
||||
BaseUser: sdk.BaseUser{
|
||||
Username: fmt.Sprintf("user%v", i),
|
||||
|
@ -615,14 +624,15 @@ func TestGetUsersForQuotaCheck(t *testing.T) {
|
|||
VirtualFolders: []vfs.VirtualFolder{
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: fmt.Sprintf("f%v", i),
|
||||
MappedPath: filepath.Join(os.TempDir(), fmt.Sprintf("f%v", i)),
|
||||
Name: folder.Name,
|
||||
},
|
||||
VirtualPath: "/vfolder",
|
||||
QuotaSize: 100,
|
||||
},
|
||||
},
|
||||
}
|
||||
err = dataprovider.AddFolder(&folder, "", "", "")
|
||||
assert.NoError(t, err)
|
||||
err = dataprovider.AddUser(&user, "", "", "")
|
||||
assert.NoError(t, err)
|
||||
err = dataprovider.UpdateVirtualFolderQuota(&vfs.BaseVirtualFolder{Name: fmt.Sprintf("f%v", i)}, 1, 50, false)
|
||||
|
|
|
@ -47,6 +47,7 @@ const (
|
|||
PermAdminViewServerStatus = "view_status"
|
||||
PermAdminManageAdmins = "manage_admins"
|
||||
PermAdminManageGroups = "manage_groups"
|
||||
PermAdminManageFolders = "manage_folders"
|
||||
PermAdminManageAPIKeys = "manage_apikeys"
|
||||
PermAdminQuotaScans = "quota_scans"
|
||||
PermAdminManageSystem = "manage_system"
|
||||
|
@ -71,11 +72,11 @@ const (
|
|||
|
||||
var (
|
||||
validAdminPerms = []string{PermAdminAny, PermAdminAddUsers, PermAdminChangeUsers, PermAdminDeleteUsers,
|
||||
PermAdminViewUsers, PermAdminManageGroups, PermAdminViewConnections, PermAdminCloseConnections,
|
||||
PermAdminViewServerStatus, PermAdminManageAdmins, PermAdminManageRoles, PermAdminManageEventRules,
|
||||
PermAdminManageAPIKeys, PermAdminQuotaScans, PermAdminManageSystem, PermAdminManageDefender,
|
||||
PermAdminViewDefender, PermAdminManageIPLists, PermAdminRetentionChecks, PermAdminMetadataChecks,
|
||||
PermAdminViewEvents}
|
||||
PermAdminViewUsers, PermAdminManageFolders, PermAdminManageGroups, PermAdminViewConnections,
|
||||
PermAdminCloseConnections, PermAdminViewServerStatus, PermAdminManageAdmins, PermAdminManageRoles,
|
||||
PermAdminManageEventRules, PermAdminManageAPIKeys, PermAdminQuotaScans, PermAdminManageSystem,
|
||||
PermAdminManageDefender, PermAdminViewDefender, PermAdminManageIPLists, PermAdminRetentionChecks,
|
||||
PermAdminMetadataChecks, PermAdminViewEvents}
|
||||
forbiddenPermsForRoleAdmins = []string{PermAdminAny, PermAdminManageAdmins, PermAdminManageSystem,
|
||||
PermAdminManageEventRules, PermAdminManageIPLists, PermAdminManageRoles}
|
||||
)
|
||||
|
|
|
@ -664,7 +664,7 @@ func (p *BoltProvider) addUser(user *User) error {
|
|||
return err
|
||||
}
|
||||
for idx := range user.VirtualFolders {
|
||||
err = p.addRelationToFolderMapping(&user.VirtualFolders[idx].BaseVirtualFolder, user, nil, foldersBucket)
|
||||
err = p.addRelationToFolderMapping(user.VirtualFolders[idx].Name, user, nil, foldersBucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1434,7 +1434,7 @@ func (p *BoltProvider) addGroup(group *Group) error {
|
|||
group.Users = nil
|
||||
group.Admins = nil
|
||||
for idx := range group.VirtualFolders {
|
||||
err = p.addRelationToFolderMapping(&group.VirtualFolders[idx].BaseVirtualFolder, nil, group, foldersBucket)
|
||||
err = p.addRelationToFolderMapping(group.VirtualFolders[idx].Name, nil, group, foldersBucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1476,7 +1476,7 @@ func (p *BoltProvider) updateGroup(group *Group) error {
|
|||
}
|
||||
}
|
||||
for idx := range group.VirtualFolders {
|
||||
err = p.addRelationToFolderMapping(&group.VirtualFolders[idx].BaseVirtualFolder, nil, group, foldersBucket)
|
||||
err = p.addRelationToFolderMapping(group.VirtualFolders[idx].Name, nil, group, foldersBucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -3427,7 +3427,7 @@ func (p *BoltProvider) removeRuleFromActionMapping(ruleName, actionName string,
|
|||
func (p *BoltProvider) addUserToGroupMapping(username, groupname string, bucket *bolt.Bucket) error {
|
||||
g := bucket.Get([]byte(groupname))
|
||||
if g == nil {
|
||||
return util.NewRecordNotFoundError(fmt.Sprintf("group %q does not exist", groupname))
|
||||
return util.NewGenericError(fmt.Sprintf("group %q does not exist", groupname))
|
||||
}
|
||||
var group Group
|
||||
err := json.Unmarshal(g, &group)
|
||||
|
@ -3539,43 +3539,33 @@ func (p *BoltProvider) removeGroupFromAdminMapping(groupName, adminName string,
|
|||
return bucket.Put([]byte(adminName), buf)
|
||||
}
|
||||
|
||||
func (p *BoltProvider) addRelationToFolderMapping(baseFolder *vfs.BaseVirtualFolder, user *User, group *Group, bucket *bolt.Bucket) error {
|
||||
f := bucket.Get([]byte(baseFolder.Name))
|
||||
func (p *BoltProvider) addRelationToFolderMapping(folderName string, user *User, group *Group, bucket *bolt.Bucket) error {
|
||||
f := bucket.Get([]byte(folderName))
|
||||
if f == nil {
|
||||
// folder does not exists, try to create
|
||||
baseFolder.LastQuotaUpdate = 0
|
||||
baseFolder.UsedQuotaFiles = 0
|
||||
baseFolder.UsedQuotaSize = 0
|
||||
if user != nil {
|
||||
baseFolder.Users = []string{user.Username}
|
||||
return util.NewGenericError(fmt.Sprintf("folder %q does not exist", folderName))
|
||||
}
|
||||
if group != nil {
|
||||
baseFolder.Groups = []string{group.Name}
|
||||
}
|
||||
return p.addFolderInternal(*baseFolder, bucket)
|
||||
}
|
||||
var oldFolder vfs.BaseVirtualFolder
|
||||
err := json.Unmarshal(f, &oldFolder)
|
||||
var folder vfs.BaseVirtualFolder
|
||||
err := json.Unmarshal(f, &folder)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
baseFolder.ID = oldFolder.ID
|
||||
baseFolder.LastQuotaUpdate = oldFolder.LastQuotaUpdate
|
||||
baseFolder.UsedQuotaFiles = oldFolder.UsedQuotaFiles
|
||||
baseFolder.UsedQuotaSize = oldFolder.UsedQuotaSize
|
||||
baseFolder.Users = oldFolder.Users
|
||||
baseFolder.Groups = oldFolder.Groups
|
||||
if user != nil && !util.Contains(baseFolder.Users, user.Username) {
|
||||
baseFolder.Users = append(baseFolder.Users, user.Username)
|
||||
updated := false
|
||||
if user != nil && !util.Contains(folder.Users, user.Username) {
|
||||
folder.Users = append(folder.Users, user.Username)
|
||||
updated = true
|
||||
}
|
||||
if group != nil && !util.Contains(baseFolder.Groups, group.Name) {
|
||||
baseFolder.Groups = append(baseFolder.Groups, group.Name)
|
||||
if group != nil && !util.Contains(folder.Groups, group.Name) {
|
||||
folder.Groups = append(folder.Groups, group.Name)
|
||||
updated = true
|
||||
}
|
||||
buf, err := json.Marshal(baseFolder)
|
||||
if !updated {
|
||||
return nil
|
||||
}
|
||||
buf, err := json.Marshal(folder)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return bucket.Put([]byte(baseFolder.Name), buf)
|
||||
return bucket.Put([]byte(folder.Name), buf)
|
||||
}
|
||||
|
||||
func (p *BoltProvider) removeRelationFromFolderMapping(folder vfs.VirtualFolder, username, groupname string,
|
||||
|
@ -3651,7 +3641,7 @@ func (p *BoltProvider) updateUserRelations(tx *bolt.Tx, user *User, oldUser User
|
|||
return err
|
||||
}
|
||||
for idx := range user.VirtualFolders {
|
||||
err = p.addRelationToFolderMapping(&user.VirtualFolders[idx].BaseVirtualFolder, user, nil, foldersBucket)
|
||||
err = p.addRelationToFolderMapping(user.VirtualFolders[idx].Name, user, nil, foldersBucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -2621,27 +2621,6 @@ func validateFolderQuotaLimits(folder vfs.VirtualFolder) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getVirtualFolderIfInvalid(folder *vfs.BaseVirtualFolder) *vfs.BaseVirtualFolder {
|
||||
if err := ValidateFolder(folder); err == nil {
|
||||
return folder
|
||||
}
|
||||
if folder.Name == "" {
|
||||
return folder
|
||||
}
|
||||
// we try to get the folder from the data provider if only the Name is populated
|
||||
// so if MappedPath or Provider are set just return
|
||||
if folder.MappedPath != "" {
|
||||
return folder
|
||||
}
|
||||
if folder.FsConfig.Provider != sdk.LocalFilesystemProvider {
|
||||
return folder
|
||||
}
|
||||
if f, err := GetFolderByName(folder.Name); err == nil {
|
||||
return &f
|
||||
}
|
||||
return folder
|
||||
}
|
||||
|
||||
func validateUserGroups(user *User) error {
|
||||
if len(user.Groups) == 0 {
|
||||
return nil
|
||||
|
@ -2682,12 +2661,11 @@ func validateAssociatedVirtualFolders(vfolders []vfs.VirtualFolder) ([]vfs.Virtu
|
|||
if err := validateFolderQuotaLimits(v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
folder := getVirtualFolderIfInvalid(&v.BaseVirtualFolder)
|
||||
if err := ValidateFolder(folder); err != nil {
|
||||
return nil, err
|
||||
if v.Name == "" {
|
||||
return nil, util.NewValidationError("folder name is mandatory")
|
||||
}
|
||||
if folderNames[folder.Name] {
|
||||
return nil, util.NewValidationError(fmt.Sprintf("the folder %q is duplicated", folder.Name))
|
||||
if folderNames[v.Name] {
|
||||
return nil, util.NewValidationError(fmt.Sprintf("the folder %q is duplicated", v.Name))
|
||||
}
|
||||
for _, vFolder := range virtualFolders {
|
||||
if util.IsDirOverlapped(vFolder.VirtualPath, cleanedVPath, false, "/") {
|
||||
|
@ -2696,12 +2674,14 @@ func validateAssociatedVirtualFolders(vfolders []vfs.VirtualFolder) ([]vfs.Virtu
|
|||
}
|
||||
}
|
||||
virtualFolders = append(virtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: *folder,
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: v.Name,
|
||||
},
|
||||
VirtualPath: cleanedVPath,
|
||||
QuotaSize: v.QuotaSize,
|
||||
QuotaFiles: v.QuotaFiles,
|
||||
})
|
||||
folderNames[folder.Name] = true
|
||||
folderNames[v.Name] = true
|
||||
}
|
||||
return virtualFolders, nil
|
||||
}
|
||||
|
|
|
@ -319,8 +319,6 @@ func (p *MemoryProvider) getUsedQuota(username string) (int, int64, int64, int64
|
|||
}
|
||||
|
||||
func (p *MemoryProvider) addUser(user *User) error {
|
||||
// we can query virtual folder while validating a user
|
||||
// so we have to check without holding the lock
|
||||
err := ValidateUser(user)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -361,16 +359,24 @@ func (p *MemoryProvider) addUser(user *User) error {
|
|||
}
|
||||
mappedGroups = append(mappedGroups, user.Groups[idx].Name)
|
||||
}
|
||||
user.VirtualFolders = p.joinUserVirtualFoldersFields(user)
|
||||
var mappedFolders []string
|
||||
for idx := range user.VirtualFolders {
|
||||
if err = p.addUserToFolderMapping(user.Username, user.VirtualFolders[idx].Name); err != nil {
|
||||
// try to remove folder mapping
|
||||
for _, f := range mappedFolders {
|
||||
p.removeRelationFromFolderMapping(f, user.Username, "")
|
||||
}
|
||||
return err
|
||||
}
|
||||
mappedFolders = append(mappedFolders, user.VirtualFolders[idx].Name)
|
||||
}
|
||||
p.dbHandle.users[user.Username] = user.getACopy()
|
||||
p.dbHandle.usernames = append(p.dbHandle.usernames, user.Username)
|
||||
sort.Strings(p.dbHandle.usernames)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *MemoryProvider) updateUser(user *User) error {
|
||||
// we can query virtual folder while validating a user
|
||||
// so we have to check without holding the lock
|
||||
func (p *MemoryProvider) updateUser(user *User) error { //nolint:gocyclo
|
||||
err := ValidateUser(user)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -413,7 +419,18 @@ func (p *MemoryProvider) updateUser(user *User) error {
|
|||
for _, oldFolder := range u.VirtualFolders {
|
||||
p.removeRelationFromFolderMapping(oldFolder.Name, u.Username, "")
|
||||
}
|
||||
user.VirtualFolders = p.joinUserVirtualFoldersFields(user)
|
||||
for idx := range user.VirtualFolders {
|
||||
if err = p.addUserToFolderMapping(user.Username, user.VirtualFolders[idx].Name); err != nil {
|
||||
// try to add old mapping
|
||||
for _, f := range u.VirtualFolders {
|
||||
if errRollback := p.addUserToFolderMapping(user.Username, f.Name); errRollback != nil {
|
||||
providerLog(logger.LevelError, "unable to rollback old folder mapping %q for user %q, error: %v",
|
||||
f.Name, user.Username, errRollback)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
user.LastQuotaUpdate = u.LastQuotaUpdate
|
||||
user.UsedQuotaSize = u.UsedQuotaSize
|
||||
user.UsedQuotaFiles = u.UsedQuotaFiles
|
||||
|
@ -1012,7 +1029,17 @@ func (p *MemoryProvider) addGroup(group *Group) error {
|
|||
group.UpdatedAt = util.GetTimeAsMsSinceEpoch(time.Now())
|
||||
group.Users = nil
|
||||
group.Admins = nil
|
||||
group.VirtualFolders = p.joinGroupVirtualFoldersFields(group)
|
||||
var mappedFolders []string
|
||||
for idx := range group.VirtualFolders {
|
||||
if err = p.addGroupToFolderMapping(group.Name, group.VirtualFolders[idx].Name); err != nil {
|
||||
// try to remove folder mapping
|
||||
for _, f := range mappedFolders {
|
||||
p.removeRelationFromFolderMapping(f, "", group.Name)
|
||||
}
|
||||
return err
|
||||
}
|
||||
mappedFolders = append(mappedFolders, group.VirtualFolders[idx].Name)
|
||||
}
|
||||
p.dbHandle.groups[group.Name] = group.getACopy()
|
||||
p.dbHandle.groupnames = append(p.dbHandle.groupnames, group.Name)
|
||||
sort.Strings(p.dbHandle.groupnames)
|
||||
|
@ -1035,7 +1062,18 @@ func (p *MemoryProvider) updateGroup(group *Group) error {
|
|||
for _, oldFolder := range g.VirtualFolders {
|
||||
p.removeRelationFromFolderMapping(oldFolder.Name, "", g.Name)
|
||||
}
|
||||
group.VirtualFolders = p.joinGroupVirtualFoldersFields(group)
|
||||
for idx := range group.VirtualFolders {
|
||||
if err = p.addGroupToFolderMapping(group.Name, group.VirtualFolders[idx].Name); err != nil {
|
||||
// try to add old mapping
|
||||
for _, f := range g.VirtualFolders {
|
||||
if errRollback := p.addGroupToFolderMapping(group.Name, f.Name); errRollback != nil {
|
||||
providerLog(logger.LevelError, "unable to rollback old folder mapping %q for group %q, error: %v",
|
||||
f.Name, group.Name, errRollback)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
group.CreatedAt = g.CreatedAt
|
||||
group.UpdatedAt = util.GetTimeAsMsSinceEpoch(time.Now())
|
||||
group.ID = g.ID
|
||||
|
@ -1105,19 +1143,6 @@ func (p *MemoryProvider) getUsedFolderQuota(name string) (int, int64, error) {
|
|||
return folder.UsedQuotaFiles, folder.UsedQuotaSize, err
|
||||
}
|
||||
|
||||
func (p *MemoryProvider) joinGroupVirtualFoldersFields(group *Group) []vfs.VirtualFolder {
|
||||
var folders []vfs.VirtualFolder
|
||||
for idx := range group.VirtualFolders {
|
||||
folder := &group.VirtualFolders[idx]
|
||||
f, err := p.addOrUpdateFolderInternal(&folder.BaseVirtualFolder, "", group.Name, 0, 0, 0)
|
||||
if err == nil {
|
||||
folder.BaseVirtualFolder = f
|
||||
folders = append(folders, *folder)
|
||||
}
|
||||
}
|
||||
return folders
|
||||
}
|
||||
|
||||
func (p *MemoryProvider) addVirtualFoldersToGroup(group *Group) {
|
||||
if len(group.VirtualFolders) > 0 {
|
||||
var folders []vfs.VirtualFolder
|
||||
|
@ -1317,17 +1342,28 @@ func (p *MemoryProvider) removeUserFromRole(username, role string) {
|
|||
p.dbHandle.roles[role] = r
|
||||
}
|
||||
|
||||
func (p *MemoryProvider) joinUserVirtualFoldersFields(user *User) []vfs.VirtualFolder {
|
||||
var folders []vfs.VirtualFolder
|
||||
for idx := range user.VirtualFolders {
|
||||
folder := &user.VirtualFolders[idx]
|
||||
f, err := p.addOrUpdateFolderInternal(&folder.BaseVirtualFolder, user.Username, "", 0, 0, 0)
|
||||
if err == nil {
|
||||
folder.BaseVirtualFolder = f
|
||||
folders = append(folders, *folder)
|
||||
func (p *MemoryProvider) addUserToFolderMapping(username, foldername string) error {
|
||||
f, err := p.folderExistsInternal(foldername)
|
||||
if err != nil {
|
||||
return util.NewGenericError(fmt.Sprintf("unable to get folder %q: %v", foldername, err))
|
||||
}
|
||||
if !util.Contains(f.Users, username) {
|
||||
f.Users = append(f.Users, username)
|
||||
p.dbHandle.vfolders[foldername] = f
|
||||
}
|
||||
return folders
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *MemoryProvider) addGroupToFolderMapping(name, foldername string) error {
|
||||
f, err := p.folderExistsInternal(foldername)
|
||||
if err != nil {
|
||||
return util.NewGenericError(fmt.Sprintf("unable to get folder %q: %v", foldername, err))
|
||||
}
|
||||
if !util.Contains(f.Groups, name) {
|
||||
f.Groups = append(f.Groups, name)
|
||||
p.dbHandle.vfolders[foldername] = f
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *MemoryProvider) addVirtualFoldersToUser(user *User) {
|
||||
|
@ -1348,7 +1384,9 @@ func (p *MemoryProvider) addVirtualFoldersToUser(user *User) {
|
|||
|
||||
func (p *MemoryProvider) removeRelationFromFolderMapping(folderName, username, groupname string) {
|
||||
folder, err := p.folderExistsInternal(folderName)
|
||||
if err == nil {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if username != "" {
|
||||
var usernames []string
|
||||
for _, user := range folder.Users {
|
||||
|
@ -1368,51 +1406,6 @@ func (p *MemoryProvider) removeRelationFromFolderMapping(folderName, username, g
|
|||
folder.Groups = groups
|
||||
}
|
||||
p.dbHandle.vfolders[folder.Name] = folder
|
||||
}
|
||||
}
|
||||
|
||||
func (p *MemoryProvider) updateFoldersMappingInternal(folder vfs.BaseVirtualFolder) {
|
||||
p.dbHandle.vfolders[folder.Name] = folder
|
||||
if !util.Contains(p.dbHandle.vfoldersNames, folder.Name) {
|
||||
p.dbHandle.vfoldersNames = append(p.dbHandle.vfoldersNames, folder.Name)
|
||||
sort.Strings(p.dbHandle.vfoldersNames)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *MemoryProvider) addOrUpdateFolderInternal(baseFolder *vfs.BaseVirtualFolder, username, groupname string,
|
||||
usedQuotaSize int64, usedQuotaFiles int, lastQuotaUpdate int64,
|
||||
) (vfs.BaseVirtualFolder, error) {
|
||||
folder, err := p.folderExistsInternal(baseFolder.Name)
|
||||
if err == nil {
|
||||
// exists
|
||||
folder.MappedPath = baseFolder.MappedPath
|
||||
folder.Description = baseFolder.Description
|
||||
folder.FsConfig = baseFolder.FsConfig.GetACopy()
|
||||
if username != "" && !util.Contains(folder.Users, username) {
|
||||
folder.Users = append(folder.Users, username)
|
||||
}
|
||||
if groupname != "" && !util.Contains(folder.Groups, groupname) {
|
||||
folder.Groups = append(folder.Groups, groupname)
|
||||
}
|
||||
p.updateFoldersMappingInternal(folder)
|
||||
return folder, nil
|
||||
}
|
||||
if errors.Is(err, util.ErrNotFound) {
|
||||
folder = baseFolder.GetACopy()
|
||||
folder.ID = p.getNextFolderID()
|
||||
folder.UsedQuotaSize = usedQuotaSize
|
||||
folder.UsedQuotaFiles = usedQuotaFiles
|
||||
folder.LastQuotaUpdate = lastQuotaUpdate
|
||||
if username != "" {
|
||||
folder.Users = []string{username}
|
||||
}
|
||||
if groupname != "" {
|
||||
folder.Groups = []string{groupname}
|
||||
}
|
||||
p.updateFoldersMappingInternal(folder)
|
||||
return folder, nil
|
||||
}
|
||||
return folder, err
|
||||
}
|
||||
|
||||
func (p *MemoryProvider) folderExistsInternal(name string) (vfs.BaseVirtualFolder, error) {
|
||||
|
|
|
@ -2302,19 +2302,6 @@ func sqlCommonGetFolderByName(ctx context.Context, name string, dbHandle sqlQuer
|
|||
return folders[0], nil
|
||||
}
|
||||
|
||||
func sqlCommonAddOrUpdateFolder(ctx context.Context, baseFolder *vfs.BaseVirtualFolder, usedQuotaSize int64,
|
||||
usedQuotaFiles int, lastQuotaUpdate int64, dbHandle sqlQuerier,
|
||||
) error {
|
||||
fsConfig, err := json.Marshal(baseFolder.FsConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
q := getUpsertFolderQuery()
|
||||
_, err = dbHandle.ExecContext(ctx, q, baseFolder.MappedPath, usedQuotaSize, usedQuotaFiles,
|
||||
lastQuotaUpdate, baseFolder.Name, baseFolder.Description, fsConfig)
|
||||
return err
|
||||
}
|
||||
|
||||
func sqlCommonAddFolder(folder *vfs.BaseVirtualFolder, dbHandle sqlQuerier) error {
|
||||
err := ValidateFolder(folder)
|
||||
if err != nil {
|
||||
|
@ -2518,10 +2505,6 @@ func generateGroupVirtualFoldersMapping(ctx context.Context, group *Group, dbHan
|
|||
}
|
||||
for idx := range group.VirtualFolders {
|
||||
vfolder := &group.VirtualFolders[idx]
|
||||
err = sqlCommonAddOrUpdateFolder(ctx, &vfolder.BaseVirtualFolder, 0, 0, 0, dbHandle)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = sqlCommonAddGroupFolderMapping(ctx, group, vfolder, dbHandle)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -2537,10 +2520,6 @@ func generateUserVirtualFoldersMapping(ctx context.Context, user *User, dbHandle
|
|||
}
|
||||
for idx := range user.VirtualFolders {
|
||||
vfolder := &user.VirtualFolders[idx]
|
||||
err := sqlCommonAddOrUpdateFolder(ctx, &vfolder.BaseVirtualFolder, 0, 0, 0, dbHandle)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = sqlCommonAddUserFolderMapping(ctx, user, vfolder, dbHandle)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -751,20 +751,6 @@ func getDeleteFolderQuery() string {
|
|||
return fmt.Sprintf(`DELETE FROM %s WHERE name = %s`, sqlTableFolders, sqlPlaceholders[0])
|
||||
}
|
||||
|
||||
func getUpsertFolderQuery() string {
|
||||
if config.Driver == MySQLDataProviderName {
|
||||
return fmt.Sprintf("INSERT INTO %s (`path`,`used_quota_size`,`used_quota_files`,`last_quota_update`,`name`,"+
|
||||
"`description`,`filesystem`) VALUES (%s,%s,%s,%s,%s,%s,%s) ON DUPLICATE KEY UPDATE "+
|
||||
"`path`=VALUES(`path`),`description`=VALUES(`description`),`filesystem`=VALUES(`filesystem`)",
|
||||
sqlTableFolders, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2], sqlPlaceholders[3], sqlPlaceholders[4],
|
||||
sqlPlaceholders[5], sqlPlaceholders[6])
|
||||
}
|
||||
return fmt.Sprintf(`INSERT INTO %s (path,used_quota_size,used_quota_files,last_quota_update,name,description,filesystem)
|
||||
VALUES (%s,%s,%s,%s,%s,%s,%s) ON CONFLICT (name) DO UPDATE SET path = EXCLUDED.path,description=EXCLUDED.description,
|
||||
filesystem=EXCLUDED.filesystem`, sqlTableFolders, sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2],
|
||||
sqlPlaceholders[3], sqlPlaceholders[4], sqlPlaceholders[5], sqlPlaceholders[6])
|
||||
}
|
||||
|
||||
func getClearUserGroupMappingQuery() string {
|
||||
return fmt.Sprintf(`DELETE FROM %s WHERE user_id = (SELECT id FROM %s WHERE username = %s)`, sqlTableUsersGroupsMapping,
|
||||
sqlTableUsers, sqlPlaceholders[0])
|
||||
|
|
|
@ -2684,16 +2684,21 @@ func TestUploadOverwriteVfolder(t *testing.T) {
|
|||
vdir := "/vdir"
|
||||
mappedPath := filepath.Join(os.TempDir(), "vdir")
|
||||
folderName := filepath.Base(mappedPath)
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
},
|
||||
VirtualPath: vdir,
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
})
|
||||
err := os.MkdirAll(mappedPath, os.ModePerm)
|
||||
err = os.MkdirAll(mappedPath, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
@ -2799,15 +2804,20 @@ func TestAllocateAvailable(t *testing.T) {
|
|||
u := getTestUser()
|
||||
mappedPath := filepath.Join(os.TempDir(), "vdir")
|
||||
folderName := filepath.Base(mappedPath)
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
},
|
||||
VirtualPath: "/vdir",
|
||||
QuotaSize: 110,
|
||||
})
|
||||
err := os.MkdirAll(mappedPath, os.ModePerm)
|
||||
err = os.MkdirAll(mappedPath, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
@ -3654,13 +3664,6 @@ func TestNestedVirtualFolders(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderNameCrypt,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
CryptConfig: vfs.CryptFsConfig{
|
||||
Passphrase: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
MappedPath: mappedPathCrypt,
|
||||
},
|
||||
VirtualPath: vdirCryptPath,
|
||||
})
|
||||
|
@ -3670,7 +3673,6 @@ func TestNestedVirtualFolders(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
})
|
||||
|
@ -3680,12 +3682,36 @@ func TestNestedVirtualFolders(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderNameNested,
|
||||
MappedPath: mappedPathNested,
|
||||
},
|
||||
VirtualPath: vdirNestedPath,
|
||||
QuotaFiles: -1,
|
||||
QuotaSize: -1,
|
||||
})
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderNameCrypt,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
CryptConfig: vfs.CryptFsConfig{
|
||||
Passphrase: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
MappedPath: mappedPathCrypt,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f3 := vfs.BaseVirtualFolder{
|
||||
Name: folderNameNested,
|
||||
MappedPath: mappedPathNested,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f3, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
sftpUser, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
client, err := getFTPClient(sftpUser, false, nil)
|
||||
|
|
|
@ -905,7 +905,6 @@ func TestGroupRelations(t *testing.T) {
|
|||
g1.VirtualFolders = append(g1.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: "/vdir1",
|
||||
})
|
||||
|
@ -914,7 +913,6 @@ func TestGroupRelations(t *testing.T) {
|
|||
g2.VirtualFolders = append(g2.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: "/vdir2",
|
||||
})
|
||||
|
@ -923,10 +921,17 @@ func TestGroupRelations(t *testing.T) {
|
|||
g3.VirtualFolders = append(g3.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: "/vdir3",
|
||||
})
|
||||
_, _, err = httpdtest.AddGroup(g1, http.StatusCreated)
|
||||
assert.Error(t, err, "adding a group with a missing folder must fail")
|
||||
_, _, err = httpdtest.AddFolder(vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
group1, resp, err := httpdtest.AddGroup(g1, http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
assert.Len(t, group1.VirtualFolders, 1)
|
||||
|
@ -1163,13 +1168,6 @@ func TestGroupSettingsOverride(t *testing.T) {
|
|||
g1.VirtualFolders = append(g1.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
FsConfig: vfs.Filesystem{
|
||||
OSConfig: sdk.OSFsConfig{
|
||||
ReadBufferSize: 3,
|
||||
WriteBufferSize: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: "/vdir1",
|
||||
})
|
||||
|
@ -1190,6 +1188,23 @@ func TestGroupSettingsOverride(t *testing.T) {
|
|||
g2.VirtualFolders = append(g2.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
},
|
||||
VirtualPath: "/vdir2",
|
||||
})
|
||||
g2.VirtualFolders = append(g2.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
},
|
||||
VirtualPath: "/vdir3",
|
||||
})
|
||||
g2.VirtualFolders = append(g2.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName3,
|
||||
},
|
||||
VirtualPath: "/vdir4",
|
||||
})
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
FsConfig: vfs.Filesystem{
|
||||
OSConfig: sdk.OSFsConfig{
|
||||
|
@ -1197,18 +1212,16 @@ func TestGroupSettingsOverride(t *testing.T) {
|
|||
WriteBufferSize: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: "/vdir2",
|
||||
})
|
||||
g2.VirtualFolders = append(g2.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
},
|
||||
VirtualPath: "/vdir3",
|
||||
})
|
||||
g2.VirtualFolders = append(g2.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f3 := vfs.BaseVirtualFolder{
|
||||
Name: folderName3,
|
||||
MappedPath: mappedPath3,
|
||||
FsConfig: vfs.Filesystem{
|
||||
|
@ -1217,9 +1230,10 @@ func TestGroupSettingsOverride(t *testing.T) {
|
|||
WriteBufferSize: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: "/vdir4",
|
||||
})
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f3, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
group1, resp, err := httpdtest.AddGroup(g1, http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
group2, resp, err := httpdtest.AddGroup(g2, http.StatusCreated)
|
||||
|
@ -1235,8 +1249,8 @@ func TestGroupSettingsOverride(t *testing.T) {
|
|||
Type: sdk.GroupTypeSecondary,
|
||||
},
|
||||
}
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user, resp, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
assert.Len(t, user.VirtualFolders, 0)
|
||||
assert.Len(t, user.Permissions, 1)
|
||||
|
||||
|
@ -2749,6 +2763,12 @@ func TestUserTimestamps(t *testing.T) {
|
|||
},
|
||||
VirtualPath: "/vdir",
|
||||
})
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
user, resp, err = httpdtest.UpdateUser(user, http.StatusOK, "")
|
||||
assert.NoError(t, err, string(resp))
|
||||
|
@ -4848,19 +4868,30 @@ func TestUpdateUser(t *testing.T) {
|
|||
user.VirtualFolders = append(user.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: "/vdir1",
|
||||
})
|
||||
user.VirtualFolders = append(user.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
},
|
||||
VirtualPath: "/vdir12/subdir",
|
||||
QuotaSize: 123,
|
||||
QuotaFiles: 2,
|
||||
})
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -5032,15 +5063,26 @@ func TestUserFolderMapping(t *testing.T) {
|
|||
u1.VirtualFolders = append(u1.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
UsedQuotaFiles: 2,
|
||||
UsedQuotaSize: 123,
|
||||
LastQuotaUpdate: 456,
|
||||
},
|
||||
VirtualPath: "/vdir",
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
})
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
UsedQuotaFiles: 2,
|
||||
UsedQuotaSize: 123,
|
||||
LastQuotaUpdate: 456,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user1, _, err := httpdtest.AddUser(u1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
// virtual folder must be auto created
|
||||
|
@ -5048,12 +5090,12 @@ func TestUserFolderMapping(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.Len(t, folder.Users, 1)
|
||||
assert.Contains(t, folder.Users, user1.Username)
|
||||
assert.Equal(t, 0, folder.UsedQuotaFiles)
|
||||
assert.Equal(t, int64(0), folder.UsedQuotaSize)
|
||||
assert.Equal(t, int64(0), folder.LastQuotaUpdate)
|
||||
assert.Equal(t, 0, user1.VirtualFolders[0].UsedQuotaFiles)
|
||||
assert.Equal(t, int64(0), user1.VirtualFolders[0].UsedQuotaSize)
|
||||
assert.Equal(t, int64(0), user1.VirtualFolders[0].LastQuotaUpdate)
|
||||
assert.Equal(t, 2, folder.UsedQuotaFiles)
|
||||
assert.Equal(t, int64(123), folder.UsedQuotaSize)
|
||||
assert.Equal(t, int64(456), folder.LastQuotaUpdate)
|
||||
assert.Equal(t, 2, user1.VirtualFolders[0].UsedQuotaFiles)
|
||||
assert.Equal(t, int64(123), user1.VirtualFolders[0].UsedQuotaSize)
|
||||
assert.Equal(t, int64(456), user1.VirtualFolders[0].LastQuotaUpdate)
|
||||
|
||||
u2 := getTestUser()
|
||||
u2.Username = defaultUsername + "2"
|
||||
|
@ -5180,6 +5222,11 @@ func TestUserS3Config(t *testing.T) {
|
|||
user.VirtualFolders = append(user.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
},
|
||||
VirtualPath: "/folderPath",
|
||||
})
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: filepath.Join(os.TempDir(), "folderName"),
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
|
@ -5187,9 +5234,9 @@ func TestUserS3Config(t *testing.T) {
|
|||
Passphrase: kms.NewPlainSecret("Crypted-Secret"),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: "/folderPath",
|
||||
})
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user, body, err := httpdtest.UpdateUser(user, http.StatusOK, "")
|
||||
assert.NoError(t, err, string(body))
|
||||
assert.Equal(t, sdkkms.SecretStatusSecretBox, user.FsConfig.S3Config.AccessSecret.GetStatus())
|
||||
|
@ -6097,227 +6144,6 @@ func TestStartQuotaScan(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestEmbeddedFolders(t *testing.T) {
|
||||
u := getTestUser()
|
||||
mappedPath := filepath.Join(os.TempDir(), "mapped_path")
|
||||
name := filepath.Base(mappedPath)
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: name,
|
||||
UsedQuotaFiles: 1000,
|
||||
UsedQuotaSize: 8192,
|
||||
LastQuotaUpdate: 123,
|
||||
},
|
||||
VirtualPath: "/vdir",
|
||||
QuotaSize: 4096,
|
||||
QuotaFiles: 1,
|
||||
})
|
||||
_, _, err := httpdtest.AddUser(u, http.StatusBadRequest)
|
||||
assert.NoError(t, err)
|
||||
u.VirtualFolders[0].MappedPath = mappedPath
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
// check that the folder was created
|
||||
folder, _, err := httpdtest.GetFolderByName(name, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, mappedPath, folder.MappedPath)
|
||||
assert.Equal(t, 0, folder.UsedQuotaFiles)
|
||||
assert.Equal(t, int64(0), folder.UsedQuotaSize)
|
||||
assert.Equal(t, int64(0), folder.LastQuotaUpdate)
|
||||
if assert.Len(t, user.VirtualFolders, 1) {
|
||||
assert.Equal(t, mappedPath, user.VirtualFolders[0].MappedPath)
|
||||
assert.Equal(t, u.VirtualFolders[0].VirtualPath, user.VirtualFolders[0].VirtualPath)
|
||||
assert.Equal(t, u.VirtualFolders[0].QuotaFiles, user.VirtualFolders[0].QuotaFiles)
|
||||
assert.Equal(t, u.VirtualFolders[0].QuotaSize, user.VirtualFolders[0].QuotaSize)
|
||||
}
|
||||
// if the folder already exists we can just reference it by name while adding/updating a user
|
||||
u.Username = u.Username + "1"
|
||||
u.VirtualFolders[0].MappedPath = ""
|
||||
user1, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.EqualError(t, err, "mapped path mismatch")
|
||||
if assert.Len(t, user1.VirtualFolders, 1) {
|
||||
assert.Equal(t, mappedPath, user1.VirtualFolders[0].MappedPath)
|
||||
assert.Equal(t, u.VirtualFolders[0].VirtualPath, user1.VirtualFolders[0].VirtualPath)
|
||||
assert.Equal(t, u.VirtualFolders[0].QuotaFiles, user1.VirtualFolders[0].QuotaFiles)
|
||||
assert.Equal(t, u.VirtualFolders[0].QuotaSize, user1.VirtualFolders[0].QuotaSize)
|
||||
}
|
||||
user1.VirtualFolders = u.VirtualFolders
|
||||
user1, _, err = httpdtest.UpdateUser(user1, http.StatusOK, "")
|
||||
assert.EqualError(t, err, "mapped path mismatch")
|
||||
if assert.Len(t, user1.VirtualFolders, 1) {
|
||||
assert.Equal(t, mappedPath, user1.VirtualFolders[0].MappedPath)
|
||||
assert.Equal(t, u.VirtualFolders[0].VirtualPath, user1.VirtualFolders[0].VirtualPath)
|
||||
assert.Equal(t, u.VirtualFolders[0].QuotaFiles, user1.VirtualFolders[0].QuotaFiles)
|
||||
assert.Equal(t, u.VirtualFolders[0].QuotaSize, user1.VirtualFolders[0].QuotaSize)
|
||||
}
|
||||
// now the virtual folder contains all the required paths
|
||||
user1, _, err = httpdtest.UpdateUser(user1, http.StatusOK, "")
|
||||
assert.NoError(t, err)
|
||||
if assert.Len(t, user1.VirtualFolders, 1) {
|
||||
assert.Equal(t, mappedPath, user1.VirtualFolders[0].MappedPath)
|
||||
assert.Equal(t, u.VirtualFolders[0].VirtualPath, user1.VirtualFolders[0].VirtualPath)
|
||||
assert.Equal(t, u.VirtualFolders[0].QuotaFiles, user1.VirtualFolders[0].QuotaFiles)
|
||||
assert.Equal(t, u.VirtualFolders[0].QuotaSize, user1.VirtualFolders[0].QuotaSize)
|
||||
}
|
||||
|
||||
_, err = httpdtest.RemoveUser(user, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
_, err = httpdtest.RemoveUser(user1, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: name}, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestEmbeddedFoldersUpdate(t *testing.T) {
|
||||
u := getTestUser()
|
||||
mappedPath := filepath.Join(os.TempDir(), "mapped_path")
|
||||
name := filepath.Base(mappedPath)
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: name,
|
||||
MappedPath: mappedPath,
|
||||
UsedQuotaFiles: 1000,
|
||||
UsedQuotaSize: 8192,
|
||||
LastQuotaUpdate: 123,
|
||||
},
|
||||
VirtualPath: "/vdir",
|
||||
QuotaSize: 4096,
|
||||
QuotaFiles: 1,
|
||||
})
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
folder, _, err := httpdtest.GetFolderByName(name, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, mappedPath, folder.MappedPath)
|
||||
assert.Equal(t, 0, folder.UsedQuotaFiles)
|
||||
assert.Equal(t, int64(0), folder.UsedQuotaSize)
|
||||
assert.Equal(t, int64(0), folder.LastQuotaUpdate)
|
||||
assert.Empty(t, folder.Description)
|
||||
assert.Equal(t, sdk.LocalFilesystemProvider, folder.FsConfig.Provider)
|
||||
assert.Len(t, folder.Users, 1)
|
||||
assert.Contains(t, folder.Users, user.Username)
|
||||
// update a field on the folder
|
||||
description := "updatedDesc"
|
||||
folder.MappedPath = mappedPath + "_update"
|
||||
folder.Description = description
|
||||
folder, _, err = httpdtest.UpdateFolder(folder, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, mappedPath+"_update", folder.MappedPath)
|
||||
assert.Equal(t, 0, folder.UsedQuotaFiles)
|
||||
assert.Equal(t, int64(0), folder.UsedQuotaSize)
|
||||
assert.Equal(t, int64(0), folder.LastQuotaUpdate)
|
||||
assert.Equal(t, description, folder.Description)
|
||||
assert.Equal(t, sdk.LocalFilesystemProvider, folder.FsConfig.Provider)
|
||||
// check that the user gets the changes
|
||||
user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
userFolder := user.VirtualFolders[0].BaseVirtualFolder
|
||||
assert.Equal(t, mappedPath+"_update", folder.MappedPath)
|
||||
assert.Equal(t, 0, userFolder.UsedQuotaFiles)
|
||||
assert.Equal(t, int64(0), userFolder.UsedQuotaSize)
|
||||
assert.Equal(t, int64(0), userFolder.LastQuotaUpdate)
|
||||
assert.Equal(t, description, userFolder.Description)
|
||||
assert.Equal(t, sdk.LocalFilesystemProvider, userFolder.FsConfig.Provider)
|
||||
// now update the folder embedding it inside the user
|
||||
user.VirtualFolders = []vfs.VirtualFolder{
|
||||
{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: name,
|
||||
MappedPath: "",
|
||||
UsedQuotaFiles: 1000,
|
||||
UsedQuotaSize: 8192,
|
||||
LastQuotaUpdate: 123,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.S3FilesystemProvider,
|
||||
S3Config: vfs.S3FsConfig{
|
||||
BaseS3FsConfig: sdk.BaseS3FsConfig{
|
||||
Bucket: "test",
|
||||
Region: "us-east-1",
|
||||
AccessKey: "akey",
|
||||
Endpoint: "http://127.0.1.1:9090",
|
||||
},
|
||||
AccessSecret: kms.NewPlainSecret("asecret"),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: "/vdir1",
|
||||
QuotaSize: 4096,
|
||||
QuotaFiles: 1,
|
||||
},
|
||||
}
|
||||
user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
|
||||
assert.NoError(t, err)
|
||||
userFolder = user.VirtualFolders[0].BaseVirtualFolder
|
||||
assert.Equal(t, 0, userFolder.UsedQuotaFiles)
|
||||
assert.Equal(t, int64(0), userFolder.UsedQuotaSize)
|
||||
assert.Equal(t, int64(0), userFolder.LastQuotaUpdate)
|
||||
assert.Empty(t, userFolder.Description)
|
||||
assert.Equal(t, sdk.S3FilesystemProvider, userFolder.FsConfig.Provider)
|
||||
assert.Equal(t, "test", userFolder.FsConfig.S3Config.Bucket)
|
||||
assert.Equal(t, "us-east-1", userFolder.FsConfig.S3Config.Region)
|
||||
assert.Equal(t, "http://127.0.1.1:9090", userFolder.FsConfig.S3Config.Endpoint)
|
||||
assert.Equal(t, sdkkms.SecretStatusSecretBox, userFolder.FsConfig.S3Config.AccessSecret.GetStatus())
|
||||
assert.NotEmpty(t, userFolder.FsConfig.S3Config.AccessSecret.GetPayload())
|
||||
assert.Empty(t, userFolder.FsConfig.S3Config.AccessSecret.GetKey())
|
||||
assert.Empty(t, userFolder.FsConfig.S3Config.AccessSecret.GetAdditionalData())
|
||||
// confirm the changes
|
||||
folder, _, err = httpdtest.GetFolderByName(name, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 0, folder.UsedQuotaFiles)
|
||||
assert.Equal(t, int64(0), folder.UsedQuotaSize)
|
||||
assert.Equal(t, int64(0), folder.LastQuotaUpdate)
|
||||
assert.Empty(t, folder.Description)
|
||||
assert.Equal(t, sdk.S3FilesystemProvider, folder.FsConfig.Provider)
|
||||
assert.Equal(t, "test", folder.FsConfig.S3Config.Bucket)
|
||||
assert.Equal(t, "us-east-1", folder.FsConfig.S3Config.Region)
|
||||
assert.Equal(t, "http://127.0.1.1:9090", folder.FsConfig.S3Config.Endpoint)
|
||||
assert.Equal(t, sdkkms.SecretStatusSecretBox, folder.FsConfig.S3Config.AccessSecret.GetStatus())
|
||||
assert.NotEmpty(t, folder.FsConfig.S3Config.AccessSecret.GetPayload())
|
||||
assert.Empty(t, folder.FsConfig.S3Config.AccessSecret.GetKey())
|
||||
assert.Empty(t, folder.FsConfig.S3Config.AccessSecret.GetAdditionalData())
|
||||
// now update folder usage limits and check that a folder update will not change them
|
||||
folder.UsedQuotaFiles = 100
|
||||
folder.UsedQuotaSize = 32768
|
||||
_, err = httpdtest.UpdateFolderQuotaUsage(folder, "reset", http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
folder, _, err = httpdtest.GetFolderByName(name, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 100, folder.UsedQuotaFiles)
|
||||
assert.Equal(t, int64(32768), folder.UsedQuotaSize)
|
||||
assert.Greater(t, folder.LastQuotaUpdate, int64(0))
|
||||
assert.Equal(t, sdk.S3FilesystemProvider, folder.FsConfig.Provider)
|
||||
assert.Equal(t, "test", folder.FsConfig.S3Config.Bucket)
|
||||
assert.Equal(t, "us-east-1", folder.FsConfig.S3Config.Region)
|
||||
assert.Equal(t, "http://127.0.1.1:9090", folder.FsConfig.S3Config.Endpoint)
|
||||
assert.Equal(t, sdkkms.SecretStatusSecretBox, folder.FsConfig.S3Config.AccessSecret.GetStatus())
|
||||
assert.NotEmpty(t, folder.FsConfig.S3Config.AccessSecret.GetPayload())
|
||||
assert.Empty(t, folder.FsConfig.S3Config.AccessSecret.GetKey())
|
||||
assert.Empty(t, folder.FsConfig.S3Config.AccessSecret.GetAdditionalData())
|
||||
|
||||
user.VirtualFolders[0].FsConfig.S3Config.AccessSecret = kms.NewPlainSecret("updated secret")
|
||||
user, resp, err := httpdtest.UpdateUser(user, http.StatusOK, "")
|
||||
assert.NoError(t, err, string(resp))
|
||||
userFolder = user.VirtualFolders[0].BaseVirtualFolder
|
||||
assert.Equal(t, 100, userFolder.UsedQuotaFiles)
|
||||
assert.Equal(t, int64(32768), userFolder.UsedQuotaSize)
|
||||
assert.Greater(t, userFolder.LastQuotaUpdate, int64(0))
|
||||
assert.Empty(t, userFolder.Description)
|
||||
assert.Equal(t, sdk.S3FilesystemProvider, userFolder.FsConfig.Provider)
|
||||
assert.Equal(t, "test", userFolder.FsConfig.S3Config.Bucket)
|
||||
assert.Equal(t, "us-east-1", userFolder.FsConfig.S3Config.Region)
|
||||
assert.Equal(t, "http://127.0.1.1:9090", userFolder.FsConfig.S3Config.Endpoint)
|
||||
assert.Equal(t, sdkkms.SecretStatusSecretBox, userFolder.FsConfig.S3Config.AccessSecret.GetStatus())
|
||||
assert.NotEmpty(t, userFolder.FsConfig.S3Config.AccessSecret.GetPayload())
|
||||
assert.Empty(t, userFolder.FsConfig.S3Config.AccessSecret.GetKey())
|
||||
assert.Empty(t, userFolder.FsConfig.S3Config.AccessSecret.GetAdditionalData())
|
||||
|
||||
_, err = httpdtest.RemoveUser(user, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
_, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: name}, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestUpdateFolderQuotaUsage(t *testing.T) {
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: "vdir",
|
||||
|
@ -7430,6 +7256,112 @@ func TestFolders(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestFolderRelations(t *testing.T) {
|
||||
mappedPath := filepath.Join(os.TempDir(), "mapped_path")
|
||||
name := filepath.Base(mappedPath)
|
||||
u := getTestUser()
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: name,
|
||||
},
|
||||
VirtualPath: "/mountu",
|
||||
})
|
||||
_, resp, err := httpdtest.AddUser(u, http.StatusInternalServerError)
|
||||
assert.NoError(t, err, string(resp))
|
||||
g := getTestGroup()
|
||||
g.VirtualFolders = append(g.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: name,
|
||||
},
|
||||
VirtualPath: "/mountg",
|
||||
})
|
||||
_, resp, err = httpdtest.AddGroup(g, http.StatusInternalServerError)
|
||||
assert.NoError(t, err, string(resp))
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: name,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
folder, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, folder.Users, 0)
|
||||
assert.Len(t, folder.Groups, 0)
|
||||
|
||||
user, resp, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
group, resp, err := httpdtest.AddGroup(g, http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
|
||||
folder, _, err = httpdtest.GetFolderByName(folder.Name, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, folder.Users, 1)
|
||||
assert.Len(t, folder.Groups, 1)
|
||||
|
||||
user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
if assert.Len(t, user.VirtualFolders, 1) {
|
||||
assert.Equal(t, mappedPath, user.VirtualFolders[0].MappedPath)
|
||||
}
|
||||
|
||||
group, _, err = httpdtest.GetGroupByName(group.Name, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
if assert.Len(t, group.VirtualFolders, 1) {
|
||||
assert.Equal(t, mappedPath, group.VirtualFolders[0].MappedPath)
|
||||
}
|
||||
// update the folder and check the modified field on user and group
|
||||
mappedPath = filepath.Join(os.TempDir(), "mapped_path")
|
||||
folder.MappedPath = mappedPath
|
||||
_, _, err = httpdtest.UpdateFolder(folder, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
if assert.Len(t, user.VirtualFolders, 1) {
|
||||
assert.Equal(t, mappedPath, user.VirtualFolders[0].MappedPath)
|
||||
}
|
||||
|
||||
group, _, err = httpdtest.GetGroupByName(group.Name, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
if assert.Len(t, group.VirtualFolders, 1) {
|
||||
assert.Equal(t, mappedPath, group.VirtualFolders[0].MappedPath)
|
||||
}
|
||||
|
||||
_, err = httpdtest.RemoveUser(user, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
_, err = httpdtest.RemoveGroup(group, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
folder, _, err = httpdtest.GetFolderByName(folder.Name, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, folder.Users, 0)
|
||||
assert.Len(t, folder.Groups, 0)
|
||||
|
||||
user, resp, err = httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
assert.Len(t, user.VirtualFolders, 1)
|
||||
group, resp, err = httpdtest.AddGroup(g, http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
assert.Len(t, group.VirtualFolders, 1)
|
||||
|
||||
folder, _, err = httpdtest.GetFolderByName(folder.Name, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, folder.Users, 1)
|
||||
assert.Len(t, folder.Groups, 1)
|
||||
|
||||
_, err = httpdtest.RemoveFolder(folder, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
|
||||
user, _, err = httpdtest.GetUserByUsername(user.Username, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, user.VirtualFolders, 0)
|
||||
|
||||
group, _, err = httpdtest.GetGroupByName(group.Name, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, group.VirtualFolders, 0)
|
||||
|
||||
_, err = httpdtest.RemoveUser(user, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
_, err = httpdtest.RemoveGroup(group, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestDumpdata(t *testing.T) {
|
||||
err := dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
|
@ -15550,9 +15482,7 @@ func TestWebGetFiles(t *testing.T) {
|
|||
|
||||
func TestRenameDifferentResource(t *testing.T) {
|
||||
folderName := "foldercryptfs"
|
||||
u := getTestUser()
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: filepath.Join(os.TempDir(), "folderName"),
|
||||
FsConfig: vfs.Filesystem{
|
||||
|
@ -15561,6 +15491,13 @@ func TestRenameDifferentResource(t *testing.T) {
|
|||
Passphrase: kms.NewPlainSecret("super secret"),
|
||||
},
|
||||
},
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
u := getTestUser()
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
},
|
||||
VirtualPath: "/folderPath",
|
||||
})
|
||||
|
@ -16142,6 +16079,13 @@ func TestBufferedWebFilesAPI(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
QuotaFiles: -1,
|
||||
QuotaSize: -1,
|
||||
})
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
|
@ -16153,11 +16097,10 @@ func TestBufferedWebFilesAPI(t *testing.T) {
|
|||
Passphrase: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
QuotaFiles: -1,
|
||||
QuotaSize: -1,
|
||||
})
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
webAPIToken, err := getJWTAPIUserTokenFromTestServer(defaultUsername, defaultPassword)
|
||||
|
@ -16697,12 +16640,18 @@ func TestWebAPIVFolder(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
},
|
||||
VirtualPath: vdir,
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
})
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -19102,7 +19051,7 @@ func TestWebAdminPermissions(t *testing.T) {
|
|||
resp, err = httpclient.GetHTTPClient().Do(req)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
assert.Equal(t, http.StatusForbidden, resp.StatusCode)
|
||||
|
||||
req, err = http.NewRequest(http.MethodGet, httpBaseURL+webStatusPath, nil)
|
||||
assert.NoError(t, err)
|
||||
|
@ -20072,18 +20021,10 @@ func TestUserTemplateWithFoldersMock(t *testing.T) {
|
|||
checkResponseCode(t, http.StatusForbidden, rr)
|
||||
require.Contains(t, rr.Body.String(), "unable to verify form token")
|
||||
|
||||
form.Set(csrfFormToken, csrfToken)
|
||||
b, contentType, _ = getMultipartFormData(form, "", "")
|
||||
req, _ = http.NewRequest(http.MethodPost, webTemplateUser, &b)
|
||||
setJWTCookieForReq(req, token)
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusBadRequest, rr)
|
||||
require.Contains(t, rr.Body.String(), "invalid folder mapped path")
|
||||
|
||||
folder, resp, err := httpdtest.AddFolder(folder, http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
|
||||
form.Set(csrfFormToken, csrfToken)
|
||||
b, contentType, _ = getMultipartFormData(form, "", "")
|
||||
req, _ = http.NewRequest(http.MethodPost, webTemplateUser, &b)
|
||||
setJWTCookieForReq(req, token)
|
||||
|
@ -20109,8 +20050,6 @@ func TestUserTemplateWithFoldersMock(t *testing.T) {
|
|||
assert.Equal(t, path.Join("/base", user2.Username), user2.Filters.StartDirectory)
|
||||
assert.Equal(t, 0, user2.Filters.DefaultSharesExpiration)
|
||||
assert.Equal(t, folder.Name, folder1.Name)
|
||||
assert.Equal(t, folder.MappedPath, folder1.MappedPath)
|
||||
assert.Equal(t, folder.Description, folder1.Description)
|
||||
assert.Len(t, user1.PublicKeys, 0)
|
||||
assert.Len(t, user2.PublicKeys, 1)
|
||||
assert.Len(t, user1.VirtualFolders, 1)
|
||||
|
|
|
@ -1297,11 +1297,11 @@ func (s *httpdServer) initializeRouter() {
|
|||
router.With(s.checkPerm(dataprovider.PermAdminChangeUsers)).Put(userPath+"/{username}", updateUser)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminDeleteUsers)).Delete(userPath+"/{username}", deleteUser)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminChangeUsers)).Put(userPath+"/{username}/2fa/disable", disableUser2FA)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminViewUsers)).Get(folderPath, getFolders)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminViewUsers)).Get(folderPath+"/{name}", getFolderByName)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminAddUsers)).Post(folderPath, addFolder)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminChangeUsers)).Put(folderPath+"/{name}", updateFolder)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminDeleteUsers)).Delete(folderPath+"/{name}", deleteFolder)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageFolders)).Get(folderPath, getFolders)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageFolders)).Get(folderPath+"/{name}", getFolderByName)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageFolders)).Post(folderPath, addFolder)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageFolders)).Put(folderPath+"/{name}", updateFolder)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageFolders)).Delete(folderPath+"/{name}", deleteFolder)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageGroups)).Get(groupPath, getGroups)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageGroups)).Get(groupPath+"/{name}", getGroupByName)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageGroups)).Post(groupPath, addGroup)
|
||||
|
@ -1652,11 +1652,11 @@ func (s *httpdServer) setupWebAdminRoutes() {
|
|||
Delete(webGroupPath+"/{name}", deleteGroup)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminViewConnections), s.refreshCookie).
|
||||
Get(webConnectionsPath, s.handleWebGetConnections)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminViewUsers), s.refreshCookie).
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageFolders), s.refreshCookie).
|
||||
Get(webFoldersPath, s.handleWebGetFolders)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminAddUsers), s.refreshCookie).
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageFolders), s.refreshCookie).
|
||||
Get(webFolderPath, s.handleWebAddFolderGet)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminAddUsers)).Post(webFolderPath, s.handleWebAddFolderPost)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageFolders)).Post(webFolderPath, s.handleWebAddFolderPost)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminViewServerStatus), s.refreshCookie).
|
||||
Get(webStatusPath, s.handleWebGetStatus)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageAdmins), s.refreshCookie).
|
||||
|
@ -1672,11 +1672,11 @@ func (s *httpdServer) setupWebAdminRoutes() {
|
|||
Delete(webAdminPath+"/{username}", deleteAdmin)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminCloseConnections), verifyCSRFHeader).
|
||||
Delete(webConnectionsPath+"/{connectionID}", handleCloseConnection)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminChangeUsers), s.refreshCookie).
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageFolders), s.refreshCookie).
|
||||
Get(webFolderPath+"/{name}", s.handleWebUpdateFolderGet)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminChangeUsers)).Post(webFolderPath+"/{name}",
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageFolders)).Post(webFolderPath+"/{name}",
|
||||
s.handleWebUpdateFolderPost)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminDeleteUsers), verifyCSRFHeader).
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageFolders), verifyCSRFHeader).
|
||||
Delete(webFolderPath+"/{name}", deleteFolder)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminQuotaScans), verifyCSRFHeader).
|
||||
Post(webScanVFolderPath+"/{name}", startFolderQuotaScan)
|
||||
|
|
|
@ -2105,8 +2105,8 @@ func compareVirtualFolders(expected []vfs.VirtualFolder, actual []vfs.VirtualFol
|
|||
found := false
|
||||
for _, v1 := range expected {
|
||||
if path.Clean(v.VirtualPath) == path.Clean(v1.VirtualPath) {
|
||||
if err := checkFolder(&v1.BaseVirtualFolder, &v.BaseVirtualFolder); err != nil {
|
||||
return err
|
||||
if dataprovider.ConvertName(v1.Name) != v.Name {
|
||||
return errors.New("virtual folder name mismatch")
|
||||
}
|
||||
if v.QuotaSize != v1.QuotaSize {
|
||||
return errors.New("vfolder quota size mismatch")
|
||||
|
|
|
@ -194,6 +194,11 @@ func TestHTTPFsVirtualFolder(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
})
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.HTTPFilesystemProvider,
|
||||
HTTPConfig: vfs.HTTPFsConfig{
|
||||
|
@ -204,9 +209,9 @@ func TestHTTPFsVirtualFolder(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
})
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
conn, client, err := getSftpClient(user, usePubKey)
|
||||
|
|
|
@ -3889,12 +3889,12 @@ func TestLoginExternalAuth(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
},
|
||||
VirtualPath: "/vpath",
|
||||
QuotaFiles: 1 + authScope,
|
||||
QuotaSize: 10 + int64(authScope),
|
||||
})
|
||||
|
||||
err := dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
err = config.LoadConfig(configDir, "")
|
||||
|
@ -3907,6 +3907,13 @@ func TestLoginExternalAuth(t *testing.T) {
|
|||
err = dataprovider.Initialize(providerConf, configDir, true)
|
||||
assert.NoError(t, err)
|
||||
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
conn, client, err := getSftpClient(u, usePubKey)
|
||||
if assert.NoError(t, err) {
|
||||
defer conn.Close()
|
||||
|
@ -5014,7 +5021,6 @@ func TestVirtualFolders(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
})
|
||||
|
@ -5022,6 +5028,12 @@ func TestVirtualFolders(t *testing.T) {
|
|||
u.Permissions[testDir1] = []string{dataprovider.PermCreateDirs, dataprovider.PermUpload, dataprovider.PermRename}
|
||||
u.Permissions[path.Join(testDir1, "subdir")] = []string{dataprovider.PermRename}
|
||||
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
conn, client, err := getSftpClient(user, usePubKey)
|
||||
|
@ -5122,7 +5134,6 @@ func TestVirtualFoldersQuotaLimit(t *testing.T) {
|
|||
u1.VirtualFolders = append(u1.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
QuotaFiles: -1,
|
||||
|
@ -5131,7 +5142,6 @@ func TestVirtualFoldersQuotaLimit(t *testing.T) {
|
|||
u1.VirtualFolders = append(u1.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
},
|
||||
VirtualPath: vdirPath2,
|
||||
QuotaFiles: 1,
|
||||
|
@ -5146,7 +5156,6 @@ func TestVirtualFoldersQuotaLimit(t *testing.T) {
|
|||
u2.VirtualFolders = append(u2.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
QuotaFiles: -1,
|
||||
|
@ -5155,7 +5164,6 @@ func TestVirtualFoldersQuotaLimit(t *testing.T) {
|
|||
u2.VirtualFolders = append(u2.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
},
|
||||
VirtualPath: vdirPath2,
|
||||
QuotaFiles: 0,
|
||||
|
@ -5167,6 +5175,18 @@ func TestVirtualFoldersQuotaLimit(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(mappedPath2, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
conn, client, err := getSftpClient(user, usePubKey)
|
||||
|
@ -5293,17 +5313,6 @@ func TestSFTPLoopVirtualFolders(t *testing.T) {
|
|||
user1.VirtualFolders = append(user1.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: sftpFloderName,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.SFTPFilesystemProvider,
|
||||
SFTPConfig: vfs.SFTPFsConfig{
|
||||
BaseSFTPFsConfig: sdk.BaseSFTPFsConfig{
|
||||
Endpoint: sftpServerAddr,
|
||||
Username: user2.Username,
|
||||
EqualityCheckMode: 1,
|
||||
},
|
||||
Password: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: "/vdir",
|
||||
})
|
||||
|
@ -5324,6 +5333,22 @@ func TestSFTPLoopVirtualFolders(t *testing.T) {
|
|||
},
|
||||
Password: kms.NewPlainSecret(defaultPassword),
|
||||
}
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: sftpFloderName,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.SFTPFilesystemProvider,
|
||||
SFTPConfig: vfs.SFTPFsConfig{
|
||||
BaseSFTPFsConfig: sdk.BaseSFTPFsConfig{
|
||||
Endpoint: sftpServerAddr,
|
||||
Username: user2.Username,
|
||||
EqualityCheckMode: 1,
|
||||
},
|
||||
Password: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
user1, resp, err := httpdtest.AddUser(user1, http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
|
@ -5405,13 +5430,6 @@ func TestNestedVirtualFolders(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderNameCrypt,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
CryptConfig: vfs.CryptFsConfig{
|
||||
Passphrase: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
MappedPath: mappedPathCrypt,
|
||||
},
|
||||
VirtualPath: vdirCryptPath,
|
||||
QuotaFiles: 100,
|
||||
|
@ -5422,7 +5440,6 @@ func TestNestedVirtualFolders(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
QuotaFiles: -1,
|
||||
|
@ -5434,12 +5451,35 @@ func TestNestedVirtualFolders(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderNameNested,
|
||||
MappedPath: mappedPathNested,
|
||||
},
|
||||
VirtualPath: vdirNestedPath,
|
||||
QuotaFiles: -1,
|
||||
QuotaSize: -1,
|
||||
})
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderNameCrypt,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
CryptConfig: vfs.CryptFsConfig{
|
||||
Passphrase: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
MappedPath: mappedPathCrypt,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f3 := vfs.BaseVirtualFolder{
|
||||
Name: folderNameNested,
|
||||
MappedPath: mappedPathNested,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f3, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user, resp, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
conn, client, err := getSftpClient(user, usePubKey)
|
||||
|
@ -5598,6 +5638,13 @@ func TestBufferedUser(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
QuotaFiles: -1,
|
||||
QuotaSize: -1,
|
||||
})
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
|
@ -5609,11 +5656,9 @@ func TestBufferedUser(t *testing.T) {
|
|||
Passphrase: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
QuotaFiles: -1,
|
||||
QuotaSize: -1,
|
||||
})
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
conn, client, err := getSftpClient(user, usePubKey)
|
||||
|
@ -5719,11 +5764,16 @@ func TestTruncateQuotaLimits(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
QuotaFiles: 10,
|
||||
})
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
localUser, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
u = getTestSFTPUser(usePubKey)
|
||||
|
@ -5933,7 +5983,6 @@ func TestVirtualFoldersQuotaRenameOverwrite(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
QuotaFiles: 2,
|
||||
|
@ -5941,7 +5990,6 @@ func TestVirtualFoldersQuotaRenameOverwrite(t *testing.T) {
|
|||
})
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
MappedPath: mappedPath2,
|
||||
Name: folderName2,
|
||||
},
|
||||
VirtualPath: vdirPath2,
|
||||
|
@ -5951,7 +5999,6 @@ func TestVirtualFoldersQuotaRenameOverwrite(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName3,
|
||||
MappedPath: mappedPath3,
|
||||
},
|
||||
VirtualPath: vdirPath3,
|
||||
QuotaFiles: 2,
|
||||
|
@ -5963,6 +6010,25 @@ func TestVirtualFoldersQuotaRenameOverwrite(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(mappedPath3, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f3 := vfs.BaseVirtualFolder{
|
||||
Name: folderName3,
|
||||
MappedPath: mappedPath3,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f3, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
conn, client, err := getSftpClient(user, usePubKey)
|
||||
|
@ -6071,7 +6137,6 @@ func TestVirtualFoldersQuotaValues(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
// quota is included in the user's one
|
||||
|
@ -6081,7 +6146,6 @@ func TestVirtualFoldersQuotaValues(t *testing.T) {
|
|||
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
|
||||
|
@ -6092,6 +6156,18 @@ func TestVirtualFoldersQuotaValues(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(mappedPath2, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
conn, client, err := getSftpClient(user, usePubKey)
|
||||
|
@ -6171,7 +6247,6 @@ func TestQuotaRenameInsideSameVirtualFolder(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
// quota is included in the user's one
|
||||
|
@ -6181,14 +6256,25 @@ func TestQuotaRenameInsideSameVirtualFolder(t *testing.T) {
|
|||
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,
|
||||
})
|
||||
err := os.MkdirAll(mappedPath1, os.ModePerm)
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(mappedPath1, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(mappedPath2, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
|
@ -6366,7 +6452,6 @@ func TestQuotaRenameBetweenVirtualFolder(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
// quota is included in the user's one
|
||||
|
@ -6376,7 +6461,6 @@ func TestQuotaRenameBetweenVirtualFolder(t *testing.T) {
|
|||
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
|
||||
|
@ -6387,6 +6471,18 @@ func TestQuotaRenameBetweenVirtualFolder(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(mappedPath2, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
conn, client, err := getSftpClient(user, usePubKey)
|
||||
|
@ -6578,7 +6674,6 @@ func TestQuotaRenameFromVirtualFolder(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
// quota is included in the user's one
|
||||
|
@ -6588,7 +6683,6 @@ func TestQuotaRenameFromVirtualFolder(t *testing.T) {
|
|||
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
|
||||
|
@ -6599,6 +6693,18 @@ func TestQuotaRenameFromVirtualFolder(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(mappedPath2, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
conn, client, err := getSftpClient(user, usePubKey)
|
||||
|
@ -6793,7 +6899,6 @@ func TestQuotaRenameToVirtualFolder(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
// quota is included in the user's one
|
||||
|
@ -6803,7 +6908,6 @@ func TestQuotaRenameToVirtualFolder(t *testing.T) {
|
|||
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
|
||||
|
@ -6814,6 +6918,18 @@ func TestQuotaRenameToVirtualFolder(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(mappedPath2, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
conn, client, err := getSftpClient(user, usePubKey)
|
||||
|
@ -7020,7 +7136,6 @@ func TestVirtualFoldersLink(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
// quota is included in the user's one
|
||||
|
@ -7030,7 +7145,6 @@ func TestVirtualFoldersLink(t *testing.T) {
|
|||
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
|
||||
|
@ -7041,6 +7155,18 @@ func TestVirtualFoldersLink(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(mappedPath2, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
conn, client, err := getSftpClient(user, usePubKey)
|
||||
|
@ -7169,7 +7295,6 @@ func TestVFolderQuotaSize(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
// quota is included in the user's one
|
||||
|
@ -7179,7 +7304,6 @@ func TestVFolderQuotaSize(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
},
|
||||
VirtualPath: vdirPath2,
|
||||
QuotaFiles: 1,
|
||||
|
@ -7192,6 +7316,19 @@ func TestVFolderQuotaSize(t *testing.T) {
|
|||
testFilePath := filepath.Join(homeBasePath, testFileName)
|
||||
err = createTestFile(testFilePath, testFileSize)
|
||||
assert.NoError(t, err)
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
conn, client, err := getSftpClient(user, usePubKey)
|
||||
|
@ -8895,7 +9032,6 @@ func TestSSHCopy(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
QuotaFiles: -1,
|
||||
|
@ -8904,7 +9040,6 @@ func TestSSHCopy(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
},
|
||||
VirtualPath: vdirPath2,
|
||||
QuotaFiles: 100,
|
||||
|
@ -8920,6 +9055,18 @@ func TestSSHCopy(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(mappedPath2, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
testDir := "adir"
|
||||
|
@ -9177,7 +9324,6 @@ func TestSSHCopyQuotaLimits(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
QuotaFiles: -1,
|
||||
|
@ -9186,7 +9332,6 @@ func TestSSHCopyQuotaLimits(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
},
|
||||
VirtualPath: vdirPath2,
|
||||
QuotaFiles: 3,
|
||||
|
@ -9202,6 +9347,18 @@ func TestSSHCopyQuotaLimits(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(mappedPath2, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
conn, client, err := getSftpClient(user, usePubKey)
|
||||
|
@ -9346,7 +9503,6 @@ func TestSSHRemove(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
QuotaFiles: -1,
|
||||
|
@ -9355,13 +9511,24 @@ func TestSSHRemove(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
},
|
||||
VirtualPath: vdirPath2,
|
||||
QuotaFiles: 100,
|
||||
QuotaSize: 0,
|
||||
})
|
||||
err := os.MkdirAll(mappedPath1, os.ModePerm)
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(mappedPath1, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(mappedPath2, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
|
@ -9486,7 +9653,6 @@ func TestSSHRemoveCryptFs(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
QuotaFiles: -1,
|
||||
|
@ -9495,6 +9661,19 @@ func TestSSHRemoveCryptFs(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
},
|
||||
VirtualPath: vdirPath2,
|
||||
QuotaFiles: 100,
|
||||
QuotaSize: 0,
|
||||
})
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
|
@ -9502,11 +9681,10 @@ func TestSSHRemoveCryptFs(t *testing.T) {
|
|||
Passphrase: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: vdirPath2,
|
||||
QuotaFiles: 100,
|
||||
QuotaSize: 0,
|
||||
})
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
conn, client, err := getSftpClient(user, usePubKey)
|
||||
|
@ -9659,12 +9837,17 @@ func TestGitIncludedVirtualFolders(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
},
|
||||
VirtualPath: "/" + repoName,
|
||||
QuotaFiles: -1,
|
||||
QuotaSize: -1,
|
||||
})
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -9732,13 +9915,18 @@ func TestGitQuotaVirtualFolders(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
},
|
||||
VirtualPath: "/" + repoName,
|
||||
QuotaFiles: 0,
|
||||
QuotaSize: 0,
|
||||
})
|
||||
err := os.MkdirAll(mappedPath, os.ModePerm)
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(mappedPath, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
@ -10210,11 +10398,16 @@ func TestSCPVirtualFolders(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
})
|
||||
err := os.MkdirAll(mappedPath, os.ModePerm)
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(mappedPath, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
@ -10266,6 +10459,21 @@ func TestSCPNestedFolders(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderNameSFTP,
|
||||
},
|
||||
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,
|
||||
},
|
||||
VirtualPath: vdirCryptPath,
|
||||
})
|
||||
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderNameSFTP,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.SFTPFilesystemProvider,
|
||||
SFTPConfig: vfs.SFTPFsConfig{
|
||||
|
@ -10276,14 +10484,10 @@ func TestSCPNestedFolders(t *testing.T) {
|
|||
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{
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderNameCrypt,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
|
@ -10292,9 +10496,9 @@ func TestSCPNestedFolders(t *testing.T) {
|
|||
},
|
||||
},
|
||||
MappedPath: mappedPathCrypt,
|
||||
},
|
||||
VirtualPath: vdirCryptPath,
|
||||
})
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
user, resp, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
|
@ -10399,7 +10603,6 @@ func TestSCPVirtualFoldersQuota(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
},
|
||||
VirtualPath: vdirPath1,
|
||||
QuotaFiles: -1,
|
||||
|
@ -10408,13 +10611,24 @@ func TestSCPVirtualFoldersQuota(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
},
|
||||
VirtualPath: vdirPath2,
|
||||
QuotaFiles: 0,
|
||||
QuotaSize: 0,
|
||||
})
|
||||
err := os.MkdirAll(mappedPath1, os.ModePerm)
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderName1,
|
||||
MappedPath: mappedPath1,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName2,
|
||||
MappedPath: mappedPath2,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(mappedPath1, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(mappedPath2, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
|
|
|
@ -17,7 +17,7 @@ package version
|
|||
|
||||
import "strings"
|
||||
|
||||
const version = "2.5.4-dev"
|
||||
const version = "2.5.99-dev"
|
||||
|
||||
var (
|
||||
commit = ""
|
||||
|
|
|
@ -1074,10 +1074,15 @@ func TestBasicUsersCache(t *testing.T) {
|
|||
_, ok = dataprovider.GetCachedWebDAVUser(username)
|
||||
assert.True(t, ok)
|
||||
folderName := "testFolder"
|
||||
f := &vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: filepath.Join(os.TempDir(), "mapped"),
|
||||
}
|
||||
err = dataprovider.AddFolder(f, "", "", "")
|
||||
assert.NoError(t, err)
|
||||
user.VirtualFolders = append(user.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: filepath.Join(os.TempDir(), "mapped"),
|
||||
},
|
||||
VirtualPath: "/vdir",
|
||||
})
|
||||
|
@ -1124,11 +1129,16 @@ func TestCachedUserWithFolders(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: filepath.Join(os.TempDir(), folderName),
|
||||
},
|
||||
VirtualPath: "/vpath",
|
||||
})
|
||||
err := dataprovider.AddUser(&u, "", "", "")
|
||||
f := &vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: filepath.Join(os.TempDir(), folderName),
|
||||
}
|
||||
err := dataprovider.AddFolder(f, "", "", "")
|
||||
assert.NoError(t, err)
|
||||
err = dataprovider.AddUser(&u, "", "", "")
|
||||
assert.NoError(t, err)
|
||||
user, err := dataprovider.UserExists(u.Username, "")
|
||||
assert.NoError(t, err)
|
||||
|
|
|
@ -733,6 +733,13 @@ func TestBufferedUser(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
QuotaFiles: -1,
|
||||
QuotaSize: -1,
|
||||
})
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
|
@ -744,11 +751,9 @@ func TestBufferedUser(t *testing.T) {
|
|||
Passphrase: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
QuotaFiles: -1,
|
||||
QuotaSize: -1,
|
||||
})
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -2535,16 +2540,21 @@ func TestUploadOverwriteVfolder(t *testing.T) {
|
|||
vdir := "/vdir"
|
||||
mappedPath := filepath.Join(os.TempDir(), "mappedDir")
|
||||
folderName := filepath.Base(mappedPath)
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
},
|
||||
VirtualPath: vdir,
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
})
|
||||
err := os.MkdirAll(mappedPath, os.ModePerm)
|
||||
err = os.MkdirAll(mappedPath, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
@ -2602,12 +2612,17 @@ func TestOsErrors(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
},
|
||||
VirtualPath: vdir,
|
||||
QuotaSize: -1,
|
||||
QuotaFiles: -1,
|
||||
})
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
user, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
client := getWebDavClient(user, false, nil)
|
||||
|
@ -3052,19 +3067,10 @@ func TestSFTPLoopVirtualFolders(t *testing.T) {
|
|||
user2.Username += "2"
|
||||
// user1 is a local account with a virtual SFTP folder to user2
|
||||
// user2 has user1 as SFTP fs
|
||||
folderName := "sftp"
|
||||
user1.VirtualFolders = append(user1.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: "sftp",
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.SFTPFilesystemProvider,
|
||||
SFTPConfig: vfs.SFTPFsConfig{
|
||||
BaseSFTPFsConfig: sdk.BaseSFTPFsConfig{
|
||||
Endpoint: sftpServerAddr,
|
||||
Username: user2.Username,
|
||||
},
|
||||
Password: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
Name: folderName,
|
||||
},
|
||||
VirtualPath: "/vdir",
|
||||
})
|
||||
|
@ -3076,6 +3082,21 @@ func TestSFTPLoopVirtualFolders(t *testing.T) {
|
|||
},
|
||||
Password: kms.NewPlainSecret(defaultPassword),
|
||||
}
|
||||
f := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.SFTPFilesystemProvider,
|
||||
SFTPConfig: vfs.SFTPFsConfig{
|
||||
BaseSFTPFsConfig: sdk.BaseSFTPFsConfig{
|
||||
Endpoint: sftpServerAddr,
|
||||
Username: user2.Username,
|
||||
},
|
||||
Password: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
}
|
||||
_, _, err := httpdtest.AddFolder(f, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
user1, resp, err := httpdtest.AddUser(user1, http.StatusCreated)
|
||||
assert.NoError(t, err, string(resp))
|
||||
|
@ -3112,7 +3133,7 @@ func TestSFTPLoopVirtualFolders(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
err = os.RemoveAll(user2.GetHomeDir())
|
||||
assert.NoError(t, err)
|
||||
_, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: "sftp"}, http.StatusOK)
|
||||
_, err = httpdtest.RemoveFolder(vfs.BaseVirtualFolder{Name: folderName}, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
|
@ -3127,13 +3148,6 @@ func TestNestedVirtualFolders(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderNameCrypt,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
CryptConfig: vfs.CryptFsConfig{
|
||||
Passphrase: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
MappedPath: mappedPathCrypt,
|
||||
},
|
||||
VirtualPath: vdirCryptPath,
|
||||
})
|
||||
|
@ -3143,7 +3157,6 @@ func TestNestedVirtualFolders(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
},
|
||||
VirtualPath: vdirPath,
|
||||
})
|
||||
|
@ -3153,12 +3166,35 @@ func TestNestedVirtualFolders(t *testing.T) {
|
|||
u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
Name: folderNameNested,
|
||||
MappedPath: mappedPathNested,
|
||||
},
|
||||
VirtualPath: vdirNestedPath,
|
||||
QuotaFiles: -1,
|
||||
QuotaSize: -1,
|
||||
})
|
||||
f1 := vfs.BaseVirtualFolder{
|
||||
Name: folderNameCrypt,
|
||||
FsConfig: vfs.Filesystem{
|
||||
Provider: sdk.CryptedFilesystemProvider,
|
||||
CryptConfig: vfs.CryptFsConfig{
|
||||
Passphrase: kms.NewPlainSecret(defaultPassword),
|
||||
},
|
||||
},
|
||||
MappedPath: mappedPathCrypt,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f2 := vfs.BaseVirtualFolder{
|
||||
Name: folderName,
|
||||
MappedPath: mappedPath,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f2, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
f3 := vfs.BaseVirtualFolder{
|
||||
Name: folderNameNested,
|
||||
MappedPath: mappedPathNested,
|
||||
}
|
||||
_, _, err = httpdtest.AddFolder(f3, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
sftpUser, _, err := httpdtest.AddUser(u, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ info:
|
|||
SFTPGo supports groups to simplify the administration of multiple accounts by letting you assign settings once to a group, instead of multiple times to each individual user.
|
||||
The SFTPGo WebClient allows end users to change their credentials, browse and manage their files in the browser and setup two-factor authentication which works with Authy, Google Authenticator and other compatible apps.
|
||||
From the WebClient each authorized user can also create HTTP/S links to externally share files and folders securely, by setting limits to the number of downloads/uploads, protecting the share with a password, limiting access by source IP address, setting an automatic expiration date.
|
||||
version: 2.5.4-dev
|
||||
version: 2.5.99-dev
|
||||
contact:
|
||||
name: API support
|
||||
url: 'https://github.com/drakkan/sftpgo'
|
||||
|
@ -4993,6 +4993,7 @@ components:
|
|||
- close_conns
|
||||
- view_status
|
||||
- manage_admins
|
||||
- manage_folders
|
||||
- manage_groups
|
||||
- manage_apikeys
|
||||
- quota_scans
|
||||
|
@ -5016,6 +5017,7 @@ components:
|
|||
* `close_conns` - close active connections is allowed
|
||||
* `view_status` - view the server status is allowed
|
||||
* `manage_admins` - manage other admins is allowed
|
||||
* `manage_folders` - manage folders is allowed
|
||||
* `manage_groups` - manage groups is allowed
|
||||
* `manage_apikeys` - manage API keys is allowed
|
||||
* `quota_scans` - view and start quota scans is allowed
|
||||
|
@ -5919,7 +5921,7 @@ components:
|
|||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/VirtualFolder'
|
||||
description: mapping between virtual SFTPGo paths and virtual folders. If one or more of the specified folders are not inside the dataprovider they will be automatically created. You have to create the folder on the filesystem yourself
|
||||
description: mapping between virtual SFTPGo paths and virtual folders
|
||||
uid:
|
||||
type: integer
|
||||
format: int32
|
||||
|
|
|
@ -83,7 +83,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||
</li>
|
||||
{{end}}
|
||||
|
||||
{{ if .LoggedAdmin.HasPermission "view_users"}}
|
||||
{{ if .LoggedAdmin.HasPermission "manage_folders"}}
|
||||
<li class="nav-item {{if eq .CurrentURL .FoldersURL}}active{{end}}">
|
||||
<a class="nav-link" href="{{.FoldersURL}}">
|
||||
<i class="fas fa-folder"></i>
|
||||
|
|
Loading…
Reference in a new issue