feat(storage): add S3 backend support and advanced upload limits
- Introduce S3-compatible storage backend support using minio-go. - Add configuration options for local storage limits, box limits, and rate limiting. - Implement storage backend selection (local vs S3) for anonymous and registered users. - Add an `/admin/storage` management interface. - Update documentation and environment examples with the new configuration variables.
This commit is contained in:
@@ -2,6 +2,7 @@ package services
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"log/slog"
|
||||
"mime/multipart"
|
||||
@@ -93,6 +94,64 @@ func TestUserActiveStorageUsedIgnoresExpiredBoxes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLocalStorageBackendAndLegacyFallback(t *testing.T) {
|
||||
service := newTestUploadService(t)
|
||||
result := createTestBox(t, service, "file.txt", "hello")
|
||||
box := getTestBox(t, service, result.BoxID)
|
||||
if service.BoxStorageBackendID(box) != StorageBackendLocal {
|
||||
t.Fatalf("BoxStorageBackendID = %q", service.BoxStorageBackendID(box))
|
||||
}
|
||||
if box.Files[0].ObjectKey == "" {
|
||||
t.Fatalf("new file did not store object key")
|
||||
}
|
||||
object, err := service.OpenFileObject(testContext(), box, box.Files[0])
|
||||
if err != nil {
|
||||
t.Fatalf("OpenFileObject returned error: %v", err)
|
||||
}
|
||||
data, err := io.ReadAll(object.Body)
|
||||
object.Body.Close()
|
||||
if err != nil {
|
||||
t.Fatalf("ReadAll returned error: %v", err)
|
||||
}
|
||||
if string(data) != "hello" {
|
||||
t.Fatalf("object body = %q", string(data))
|
||||
}
|
||||
|
||||
box.StorageBackendID = ""
|
||||
box.Files[0].ObjectKey = ""
|
||||
object, err = service.OpenFileObject(testContext(), box, box.Files[0])
|
||||
if err != nil {
|
||||
t.Fatalf("legacy OpenFileObject returned error: %v", err)
|
||||
}
|
||||
object.Body.Close()
|
||||
}
|
||||
|
||||
func TestContaboStorageConfigAllowsDisplayNamesWithSpaces(t *testing.T) {
|
||||
service := newTestUploadService(t)
|
||||
cfg, err := service.Storage().CreateS3Backend(StorageBackendConfig{
|
||||
Provider: StorageProviderContabo,
|
||||
Name: "Contabo main",
|
||||
Endpoint: "https://eu2.contabostorage.com",
|
||||
Region: "EU",
|
||||
Bucket: "My Main Bucket",
|
||||
AccessKey: "access",
|
||||
SecretKey: "secret",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("CreateS3Backend returned error: %v", err)
|
||||
}
|
||||
if cfg.Provider != StorageProviderContabo || !cfg.UseSSL || !cfg.PathStyle {
|
||||
t.Fatalf("contabo config was not normalized: %+v", cfg)
|
||||
}
|
||||
if cfg.Bucket != "My Main Bucket" {
|
||||
t.Fatalf("bucket = %q", cfg.Bucket)
|
||||
}
|
||||
}
|
||||
|
||||
func testContext() context.Context {
|
||||
return context.Background()
|
||||
}
|
||||
|
||||
func newTestUploadService(t *testing.T) *UploadService {
|
||||
t.Helper()
|
||||
service, err := NewUploadService(1024*1024, t.TempDir(), "http://example.test", slog.New(slog.NewTextHandler(io.Discard, nil)))
|
||||
|
||||
Reference in New Issue
Block a user