diff --git a/go.mod b/go.mod
index 93fbd50d..94c9ca26 100644
--- a/go.mod
+++ b/go.mod
@@ -53,7 +53,7 @@ require (
github.com/rs/cors v1.9.0
github.com/rs/xid v1.5.0
github.com/rs/zerolog v1.29.1
- github.com/sftpgo/sdk v0.1.4
+ github.com/sftpgo/sdk v0.1.5-0.20230524172149-afb96ebee860
github.com/shirou/gopsutil/v3 v3.23.4
github.com/spf13/afero v1.9.5
github.com/spf13/cobra v1.7.0
diff --git a/go.sum b/go.sum
index d8ad4216..320461d7 100644
--- a/go.sum
+++ b/go.sum
@@ -1842,8 +1842,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
github.com/secsy/goftp v0.0.0-20200609142545-aa2de14babf4 h1:PT+ElG/UUFMfqy5HrxJxNzj3QBOf7dZwupeVC+mG1Lo=
-github.com/sftpgo/sdk v0.1.4 h1:TyNzpG7o8PuOgAQ1AvpFNJ93quR/90r+9FYyElTKqfw=
-github.com/sftpgo/sdk v0.1.4/go.mod h1:TjeoMWS0JEXt9RukJveTnaiHj4+MVLtUiDC+mY++Odk=
+github.com/sftpgo/sdk v0.1.5-0.20230524172149-afb96ebee860 h1:adaUl1JO/4bPhQuhSH7bQJ2o+2CW6Ry7R2w2SltS/PE=
+github.com/sftpgo/sdk v0.1.5-0.20230524172149-afb96ebee860/go.mod h1:TjeoMWS0JEXt9RukJveTnaiHj4+MVLtUiDC+mY++Odk=
github.com/shirou/gopsutil/v3 v3.23.4 h1:hZwmDxZs7Ewt75DV81r4pFMqbq+di2cbt9FsQBqLD2o=
github.com/shirou/gopsutil/v3 v3.23.4/go.mod h1:ZcGxyfzAMRevhUR2+cfhXDH6gQdFYE/t8j1nsU4mPI8=
github.com/shoenig/go-m1cpu v0.1.5/go.mod h1:Wwvst4LR89UxjeFtLRMrpgRiyY4xPsejnVZym39dbAQ=
diff --git a/internal/common/connection_test.go b/internal/common/connection_test.go
index d680f3ce..dd5fd32d 100644
--- a/internal/common/connection_test.go
+++ b/internal/common/connection_test.go
@@ -16,6 +16,7 @@ package common
import (
"errors"
+ "fmt"
"os"
"path"
"path/filepath"
@@ -645,3 +646,160 @@ func TestFsFileCopier(t *testing.T) {
_, ok = fs.(vfs.FsFileCopier)
assert.True(t, ok)
}
+
+func TestFilterListDirs(t *testing.T) {
+ filters := dataprovider.UserFilters{
+ BaseUserFilters: sdk.BaseUserFilters{
+ FilePatterns: []sdk.PatternsFilter{
+ {
+ Path: "/dir1",
+ DenyPolicy: sdk.DenyPolicyDefault,
+ AllowedPatterns: []string{"*.jpg"},
+ },
+ {
+ Path: "/dir2",
+ DenyPolicy: sdk.DenyPolicyHide,
+ AllowedPatterns: []string{"*.jpg"},
+ },
+ },
+ },
+ }
+ virtualFolders := []vfs.VirtualFolder{
+ {
+ VirtualPath: "/dir1/vdir1",
+ },
+ {
+ VirtualPath: "/dir1/vdir2",
+ },
+ {
+ VirtualPath: "/dir1/vdir3",
+ },
+ {
+ VirtualPath: "/dir2/vdir1",
+ },
+ {
+ VirtualPath: "/dir2/vdir2",
+ },
+ {
+ VirtualPath: "/dir2/vdir3.jpg",
+ },
+ }
+ user := dataprovider.User{
+ Filters: filters,
+ VirtualFolders: virtualFolders,
+ }
+
+ dirContents := []os.FileInfo{
+ vfs.NewFileInfo("file1.txt", false, 123, time.Now(), false),
+ vfs.NewFileInfo("file1.jpg", false, 123, time.Now(), false),
+ }
+
+ filtered := user.FilterListDir(dirContents, "/dir1")
+ assert.Len(t, filtered, 5)
+
+ filtered = user.FilterListDir(dirContents, "/dir2")
+ assert.Len(t, filtered, 2)
+
+ dirContents = []os.FileInfo{
+ vfs.NewFileInfo("file1.txt", false, 123, time.Now(), false),
+ vfs.NewFileInfo("vdir3.jpg", false, 123, time.Now(), false),
+ }
+
+ filtered = user.FilterListDir(dirContents, "/dir1")
+ assert.Len(t, filtered, 5)
+
+ dirContents = []os.FileInfo{
+ vfs.NewFileInfo("file1.txt", false, 123, time.Now(), false),
+ vfs.NewFileInfo("vdir3.jpg", false, 123, time.Now(), false),
+ }
+
+ filtered = user.FilterListDir(dirContents, "/dir2")
+ if assert.Len(t, filtered, 1) {
+ assert.True(t, filtered[0].IsDir())
+ }
+
+ user.VirtualFolders = nil
+ dirContents = []os.FileInfo{
+ vfs.NewFileInfo("file1.txt", false, 123, time.Now(), false),
+ vfs.NewFileInfo("vdir3.jpg", false, 123, time.Now(), false),
+ }
+ filtered = user.FilterListDir(dirContents, "/dir1")
+ assert.Len(t, filtered, 2)
+
+ dirContents = []os.FileInfo{
+ vfs.NewFileInfo("file1.txt", false, 123, time.Now(), false),
+ vfs.NewFileInfo("vdir3.jpg", false, 123, time.Now(), false),
+ }
+ filtered = user.FilterListDir(dirContents, "/dir2")
+ if assert.Len(t, filtered, 1) {
+ assert.False(t, filtered[0].IsDir())
+ }
+
+ dirContents = []os.FileInfo{
+ vfs.NewFileInfo("file1.jpg", false, 123, time.Now(), false),
+ vfs.NewFileInfo("file1.txt", false, 123, time.Now(), false),
+ vfs.NewFileInfo("file2.txt", false, 123, time.Now(), false),
+ vfs.NewFileInfo("vdir3.jpg", false, 123, time.Now(), false),
+ }
+ filtered = user.FilterListDir(dirContents, "/dir2")
+ if assert.Len(t, filtered, 2) {
+ assert.False(t, filtered[0].IsDir())
+ assert.False(t, filtered[1].IsDir())
+ }
+
+ user.VirtualFolders = virtualFolders
+ user.Filters = filters
+ filtered = user.FilterListDir(nil, "/dir1")
+ assert.Len(t, filtered, 3)
+ filtered = user.FilterListDir(nil, "/dir2")
+ assert.Len(t, filtered, 1)
+
+ dirContents = []os.FileInfo{
+ vfs.NewFileInfo("file1.jPg", false, 123, time.Now(), false),
+ vfs.NewFileInfo("file1.txt", false, 123, time.Now(), false),
+ vfs.NewFileInfo("file2.txt", false, 123, time.Now(), false),
+ vfs.NewFileInfo("vdir3.jpg", false, 456, time.Now(), false),
+ }
+ filtered = user.FilterListDir(dirContents, "/dir2")
+ assert.Len(t, filtered, 2)
+
+ user = dataprovider.User{
+ Filters: dataprovider.UserFilters{
+ BaseUserFilters: sdk.BaseUserFilters{
+ FilePatterns: []sdk.PatternsFilter{
+ {
+ Path: "/dir3",
+ AllowedPatterns: []string{"ic35"},
+ DeniedPatterns: []string{"*"},
+ DenyPolicy: sdk.DenyPolicyHide,
+ },
+ },
+ },
+ },
+ }
+ dirContents = []os.FileInfo{
+ vfs.NewFileInfo("file1.jpg", false, 123, time.Now(), false),
+ vfs.NewFileInfo("file1.txt", false, 123, time.Now(), false),
+ vfs.NewFileInfo("file2.txt", false, 123, time.Now(), false),
+ vfs.NewFileInfo("vdir3.jpg", false, 456, time.Now(), false),
+ }
+ filtered = user.FilterListDir(dirContents, "/dir3")
+ assert.Len(t, filtered, 0)
+
+ dirContents = nil
+ for i := 0; i < 100; i++ {
+ dirContents = append(dirContents, vfs.NewFileInfo(fmt.Sprintf("ic%02d", i), i%2 == 0, int64(i), time.Now(), false))
+ }
+ dirContents = append(dirContents, vfs.NewFileInfo("ic350", false, 123, time.Now(), false))
+ dirContents = append(dirContents, vfs.NewFileInfo(".ic35", false, 123, time.Now(), false))
+ dirContents = append(dirContents, vfs.NewFileInfo("ic35.", false, 123, time.Now(), false))
+ dirContents = append(dirContents, vfs.NewFileInfo("*ic35", false, 123, time.Now(), false))
+ dirContents = append(dirContents, vfs.NewFileInfo("ic35*", false, 123, time.Now(), false))
+ dirContents = append(dirContents, vfs.NewFileInfo("ic35.*", false, 123, time.Now(), false))
+ dirContents = append(dirContents, vfs.NewFileInfo("file.jpg", false, 123, time.Now(), false))
+
+ filtered = user.FilterListDir(dirContents, "/dir3")
+ if assert.Len(t, filtered, 1) {
+ assert.Equal(t, "ic35", filtered[0].Name())
+ }
+}
diff --git a/openapi/openapi.yaml b/openapi/openapi.yaml
index 571fdd87..7e52eca1 100644
--- a/openapi/openapi.yaml
+++ b/openapi/openapi.yaml
@@ -5403,7 +5403,7 @@ components:
type: array
items:
type: string
- description: 'list of, case insensitive, allowed shell like patterns.'
+ description: 'list of, case insensitive, allowed shell like patterns. Allowed patterns are evaluated before the denied ones'
example:
- '*.jpg'
- a*b?.png
@@ -5411,7 +5411,7 @@ components:
type: array
items:
type: string
- description: 'list of, case insensitive, denied shell like patterns. Denied patterns are evaluated before the allowed ones'
+ description: 'list of, case insensitive, denied shell like patterns'
example:
- '*.zip'
deny_policy:
diff --git a/templates/webadmin/group.html b/templates/webadmin/group.html
index f8d02425..1f8afc81 100644
--- a/templates/webadmin/group.html
+++ b/templates/webadmin/group.html
@@ -222,7 +222,7 @@ along with this program. If not, see
Denied entries are visible in directory listing by default, you can hide them by setting the "Hidden" policy, but please be aware that this may cause performance issues for large directories
+Match is case insensitive, set you patterns as lowercase. Denied entries are visible in directory listing by default, you can hide them by setting the "Hidden" policy, but please be aware that this may cause performance issues for large directories
Denied entries are visible in directory listing by default, you can hide them by setting the "Hidden" policy, but please be aware that this may cause performance issues for large directories
+Match is case insensitive, set you patterns as lowercase. Denied entries are visible in directory listing by default, you can hide them by setting the "Hidden" policy, but please be aware that this may cause performance issues for large directories