mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
[MM-57034]: Check for s3 object is File or Directory (#26837)
* check for path when number of object is one * add test and updated condition to check for path * updated test and removed string trim * using exported method --------- Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
parent
b86ba51efd
commit
075e0df5df
@ -8,6 +8,7 @@ import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"io"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@ -641,6 +642,7 @@ func (b *S3FileBackend) listDirectory(path string, recursion bool) ([]string, er
|
||||
var paths []string
|
||||
ctx, cancel := context.WithTimeout(context.Background(), b.timeout)
|
||||
defer cancel()
|
||||
var count int
|
||||
for object := range b.client.ListObjects(ctx, b.bucket, opts) {
|
||||
if object.Err != nil {
|
||||
return nil, errors.Wrapf(object.Err, "unable to list the directory %s", path)
|
||||
@ -652,6 +654,12 @@ func (b *S3FileBackend) listDirectory(path string, recursion bool) ([]string, er
|
||||
if trimmed != "" {
|
||||
paths = append(paths, trimmed)
|
||||
}
|
||||
count++
|
||||
}
|
||||
// Check if only one item was returned and it matches the path prefix
|
||||
if count == 1 && len(paths) > 0 && strings.TrimRight(path, "/") == paths[0] {
|
||||
// Return a fs.PathError to maintain consistency
|
||||
return nil, &fs.PathError{Op: "readdir", Path: path, Err: fs.ErrNotExist}
|
||||
}
|
||||
|
||||
return paths, nil
|
||||
|
@ -4,12 +4,14 @@
|
||||
package filestore
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"net/http/httptest"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
@ -20,6 +22,7 @@ import (
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
s3 "github.com/minio/minio-go/v7"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@ -320,3 +323,59 @@ func (fc fauxCloser) Close() error {
|
||||
fc.s3WithCancel.cancel()
|
||||
return fc.closeErr
|
||||
}
|
||||
|
||||
func TestListDirectory(t *testing.T) {
|
||||
s3Host := os.Getenv("CI_MINIO_HOST")
|
||||
if s3Host == "" {
|
||||
s3Host = "localhost"
|
||||
}
|
||||
|
||||
s3Port := os.Getenv("CI_MINIO_PORT")
|
||||
if s3Port == "" {
|
||||
s3Port = "9000"
|
||||
}
|
||||
|
||||
s3Endpoint := fmt.Sprintf("%s:%s", s3Host, s3Port)
|
||||
|
||||
cfg := FileBackendSettings{
|
||||
DriverName: driverS3,
|
||||
AmazonS3AccessKeyId: "minioaccesskey",
|
||||
AmazonS3SecretAccessKey: "miniosecretkey",
|
||||
AmazonS3Bucket: "mattermost-test-1",
|
||||
AmazonS3Region: "",
|
||||
AmazonS3Endpoint: s3Endpoint,
|
||||
AmazonS3PathPrefix: "",
|
||||
AmazonS3SSL: false,
|
||||
AmazonS3SSE: false,
|
||||
AmazonS3RequestTimeoutMilliseconds: 5000,
|
||||
}
|
||||
|
||||
fileBackend, err := NewS3FileBackend(cfg)
|
||||
require.NoError(t, err)
|
||||
|
||||
found, err := fileBackend.client.BucketExists(context.Background(), cfg.AmazonS3Bucket)
|
||||
require.NoError(t, err)
|
||||
|
||||
if !found {
|
||||
err = fileBackend.MakeBucket()
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
fileBackend.pathPrefix = "19700101/"
|
||||
require.NoError(t, err)
|
||||
b := []byte("test")
|
||||
|
||||
path1 := "19700101/" + randomString() + ".txt"
|
||||
_, err = fileBackend.WriteFile(bytes.NewReader(b), path1)
|
||||
require.NoError(t, err, "Failed to write file1 to S3")
|
||||
|
||||
_, err = fileBackend.ListDirectory("")
|
||||
var pErr *fs.PathError
|
||||
assert.True(t, errors.As(err, &pErr), "error is not of type fs.PathError")
|
||||
|
||||
err = fileBackend.RemoveFile(path1)
|
||||
require.NoError(t, err, "Failed to remove file1 from S3")
|
||||
|
||||
err = fileBackend.RemoveDirectory("19700101")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user