mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Storage: fix filestorage.Wrapper
PathFiltering and non-recursive folder listing (#46469)
* fix pathFilters in wrapper - apply rootPath changes before filtering * fix non-recursive folder listing
This commit is contained in:
parent
ed924b3d0c
commit
5881127319
@ -310,7 +310,24 @@ func (c cdkBlobStorage) listFolderPaths(ctx context.Context, parentFolderPath st
|
|||||||
|
|
||||||
if options.IsAllowed(obj.Key) {
|
if options.IsAllowed(obj.Key) {
|
||||||
if obj.IsDir && !recursive && options.IsAllowed(obj.Key) {
|
if obj.IsDir && !recursive && options.IsAllowed(obj.Key) {
|
||||||
foundPaths = append(foundPaths, strings.TrimSuffix(obj.Key, Delimiter))
|
var nestedDirPath string
|
||||||
|
dirMPath := obj.Key + directoryMarker
|
||||||
|
attributes, err := c.bucket.Attributes(ctx, dirMPath)
|
||||||
|
if err != nil {
|
||||||
|
c.log.Error("Failed while retrieving attributes", "path", obj.Key, "err", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if attributes != nil && attributes.Metadata != nil {
|
||||||
|
if path, ok := attributes.Metadata[originalPathAttributeKey]; ok {
|
||||||
|
nestedDirPath = getParentFolderPath(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if nestedDirPath != "" {
|
||||||
|
foundPaths = append(foundPaths, nestedDirPath)
|
||||||
|
} else {
|
||||||
|
foundPaths = append(foundPaths, strings.TrimSuffix(obj.Key, Delimiter))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if dirPath == "" && !obj.IsDir {
|
if dirPath == "" && !obj.IsDir {
|
||||||
|
@ -318,6 +318,8 @@ func (s dbFileStorage) ListFiles(ctx context.Context, folderPath string, paging
|
|||||||
|
|
||||||
func (s dbFileStorage) ListFolders(ctx context.Context, parentFolderPath string, options *ListOptions) ([]FileMetadata, error) {
|
func (s dbFileStorage) ListFolders(ctx context.Context, parentFolderPath string, options *ListOptions) ([]FileMetadata, error) {
|
||||||
folders := make([]FileMetadata, 0)
|
folders := make([]FileMetadata, 0)
|
||||||
|
|
||||||
|
parentFolderPath = strings.TrimSuffix(parentFolderPath, Delimiter)
|
||||||
err := s.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
err := s.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||||
var foundPaths []string
|
var foundPaths []string
|
||||||
|
|
||||||
@ -327,7 +329,7 @@ func (s dbFileStorage) ListFolders(ctx context.Context, parentFolderPath string,
|
|||||||
if options.Recursive {
|
if options.Recursive {
|
||||||
sess.Where("LOWER(parent_folder_path) > ?", strings.ToLower(parentFolderPath))
|
sess.Where("LOWER(parent_folder_path) > ?", strings.ToLower(parentFolderPath))
|
||||||
} else {
|
} else {
|
||||||
sess.Where("LOWER(parent_folder_path) = ?", strings.ToLower(parentFolderPath))
|
sess.Where("LOWER(parent_folder_path) LIKE ? AND LOWER(parent_folder_path) NOT LIKE ?", strings.ToLower(parentFolderPath)+Delimiter+"%", strings.ToLower(parentFolderPath)+Delimiter+"%"+Delimiter+"%")
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.PathFilters.isDenyAll() {
|
if options.PathFilters.isDenyAll() {
|
||||||
|
@ -419,6 +419,53 @@ func TestFsStorage(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "listing folders non recursively",
|
||||||
|
steps: []interface{}{
|
||||||
|
cmdUpsert{
|
||||||
|
cmd: UpsertFileCommand{
|
||||||
|
Path: "/folder1/folder2/file.jpg",
|
||||||
|
Contents: &[]byte{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
cmdUpsert{
|
||||||
|
cmd: UpsertFileCommand{
|
||||||
|
Path: "/folder1/file-inner.jpg",
|
||||||
|
Contents: &[]byte{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
cmdUpsert{
|
||||||
|
cmd: UpsertFileCommand{
|
||||||
|
Path: "/folderX/folderZ/file.txt",
|
||||||
|
Contents: &[]byte{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
cmdUpsert{
|
||||||
|
cmd: UpsertFileCommand{
|
||||||
|
Path: "/folderA/folderB/file.txt",
|
||||||
|
Contents: &[]byte{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
queryListFolders{
|
||||||
|
input: queryListFoldersInput{path: "/folder1", options: &ListOptions{Recursive: false}},
|
||||||
|
checks: [][]interface{}{
|
||||||
|
checks(fPath("/folder1/folder2")),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
queryListFolders{
|
||||||
|
input: queryListFoldersInput{path: "/folderZ", options: &ListOptions{Recursive: false}},
|
||||||
|
checks: [][]interface{}{},
|
||||||
|
},
|
||||||
|
queryListFolders{
|
||||||
|
input: queryListFoldersInput{path: "/", options: &ListOptions{Recursive: false}},
|
||||||
|
checks: [][]interface{}{
|
||||||
|
checks(fPath("/folder1")),
|
||||||
|
checks(fPath("/folderA")),
|
||||||
|
checks(fPath("/folderX")),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,11 +197,12 @@ func (b wrapper) Get(ctx context.Context, path string) (*File, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !b.pathFilters.IsAllowed(path) {
|
rootedPath := b.addRoot(path)
|
||||||
|
if !b.pathFilters.IsAllowed(rootedPath) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := b.wrapped.Get(ctx, b.addRoot(path))
|
file, err := b.wrapped.Get(ctx, rootedPath)
|
||||||
if file != nil {
|
if file != nil {
|
||||||
file.FullPath = b.removeRoot(file.FullPath)
|
file.FullPath = b.removeRoot(file.FullPath)
|
||||||
}
|
}
|
||||||
@ -212,11 +213,12 @@ func (b wrapper) Delete(ctx context.Context, path string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !b.pathFilters.IsAllowed(path) {
|
rootedPath := b.addRoot(path)
|
||||||
|
if !b.pathFilters.IsAllowed(rootedPath) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.wrapped.Delete(ctx, b.addRoot(path))
|
return b.wrapped.Delete(ctx, rootedPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func detectContentType(path string, originalGuess string) string {
|
func detectContentType(path string, originalGuess string) string {
|
||||||
@ -235,7 +237,8 @@ func (b wrapper) Upsert(ctx context.Context, file *UpsertFileCommand) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !b.pathFilters.IsAllowed(file.Path) {
|
rootedPath := b.addRoot(file.Path)
|
||||||
|
if !b.pathFilters.IsAllowed(rootedPath) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,7 +253,7 @@ func (b wrapper) Upsert(ctx context.Context, file *UpsertFileCommand) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return b.wrapped.Upsert(ctx, &UpsertFileCommand{
|
return b.wrapped.Upsert(ctx, &UpsertFileCommand{
|
||||||
Path: b.addRoot(file.Path),
|
Path: rootedPath,
|
||||||
MimeType: file.MimeType,
|
MimeType: file.MimeType,
|
||||||
Contents: file.Contents,
|
Contents: file.Contents,
|
||||||
Properties: file.Properties,
|
Properties: file.Properties,
|
||||||
@ -362,11 +365,12 @@ func (b wrapper) CreateFolder(ctx context.Context, path string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !b.pathFilters.IsAllowed(path) {
|
rootedPath := b.addRoot(path)
|
||||||
|
if !b.pathFilters.IsAllowed(rootedPath) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.wrapped.CreateFolder(ctx, b.addRoot(path))
|
return b.wrapped.CreateFolder(ctx, rootedPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b wrapper) DeleteFolder(ctx context.Context, path string) error {
|
func (b wrapper) DeleteFolder(ctx context.Context, path string) error {
|
||||||
@ -374,7 +378,8 @@ func (b wrapper) DeleteFolder(ctx context.Context, path string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !b.pathFilters.IsAllowed(path) {
|
rootedPath := b.addRoot(path)
|
||||||
|
if !b.pathFilters.IsAllowed(rootedPath) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,7 +392,7 @@ func (b wrapper) DeleteFolder(ctx context.Context, path string) error {
|
|||||||
return fmt.Errorf("folder %s is not empty - cant remove it", path)
|
return fmt.Errorf("folder %s is not empty - cant remove it", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.wrapped.DeleteFolder(ctx, b.addRoot(path))
|
return b.wrapped.DeleteFolder(ctx, rootedPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b wrapper) isFolderEmpty(ctx context.Context, path string) (bool, error) {
|
func (b wrapper) isFolderEmpty(ctx context.Context, path string) (bool, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user