mirror of
https://github.com/rjNemo/rentease.git
synced 2026-06-06 02:36:49 +00:00
101 lines
2.4 KiB
Go
101 lines
2.4 KiB
Go
package storage
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/minio/minio-go/v7"
|
|
"github.com/minio/minio-go/v7/pkg/credentials"
|
|
|
|
"github.com/rjNemo/rentease/internal/config"
|
|
"github.com/rjNemo/rentease/internal/service/booking"
|
|
)
|
|
|
|
type MinioInvoiceStorage struct {
|
|
bucket string
|
|
client *minio.Client
|
|
}
|
|
|
|
func NewMinioInvoiceStorage(cfg *config.Config) (*MinioInvoiceStorage, error) {
|
|
if cfg.MinIOEndpoint == "" && cfg.MinIOAccessKey == "" && cfg.MinIOSecretKey == "" && cfg.MinIOBucket == "" {
|
|
return nil, nil
|
|
}
|
|
|
|
switch {
|
|
case cfg.MinIOEndpoint == "":
|
|
return nil, fmt.Errorf("minio endpoint is required")
|
|
case cfg.MinIOAccessKey == "":
|
|
return nil, fmt.Errorf("minio access key is required")
|
|
case cfg.MinIOSecretKey == "":
|
|
return nil, fmt.Errorf("minio secret key is required")
|
|
case cfg.MinIOBucket == "":
|
|
return nil, fmt.Errorf("minio bucket is required")
|
|
}
|
|
|
|
client, err := minio.New(cfg.MinIOEndpoint, &minio.Options{
|
|
Creds: credentials.NewStaticV4(cfg.MinIOAccessKey, cfg.MinIOSecretKey, ""),
|
|
Secure: cfg.MinIOUseSSL,
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("create minio client: %w", err)
|
|
}
|
|
|
|
return &MinioInvoiceStorage{
|
|
bucket: cfg.MinIOBucket,
|
|
client: client,
|
|
}, nil
|
|
}
|
|
|
|
func (s *MinioInvoiceStorage) StoreInvoice(
|
|
ctx context.Context,
|
|
objectKey string,
|
|
file booking.GeneratedFile,
|
|
shareURLTTL time.Duration,
|
|
) (*booking.StoredInvoiceFile, error) {
|
|
if err := s.ensureBucket(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
_, err := s.client.PutObject(
|
|
ctx,
|
|
s.bucket,
|
|
objectKey,
|
|
bytes.NewReader(file.Data),
|
|
int64(len(file.Data)),
|
|
minio.PutObjectOptions{
|
|
ContentType: file.ContentType,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("upload object %q: %w", objectKey, err)
|
|
}
|
|
|
|
shareURL, err := s.client.PresignedGetObject(ctx, s.bucket, objectKey, shareURLTTL, nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("presign object %q: %w", objectKey, err)
|
|
}
|
|
|
|
return &booking.StoredInvoiceFile{
|
|
ObjectKey: objectKey,
|
|
ShareURL: shareURL.String(),
|
|
ShareURLExpiresAt: time.Now().UTC().Add(shareURLTTL),
|
|
}, nil
|
|
}
|
|
|
|
func (s *MinioInvoiceStorage) ensureBucket(ctx context.Context) error {
|
|
exists, err := s.client.BucketExists(ctx, s.bucket)
|
|
if err != nil {
|
|
return fmt.Errorf("check bucket %q: %w", s.bucket, err)
|
|
}
|
|
if exists {
|
|
return nil
|
|
}
|
|
|
|
if err := s.client.MakeBucket(ctx, s.bucket, minio.MakeBucketOptions{}); err != nil {
|
|
return fmt.Errorf("create bucket %q: %w", s.bucket, err)
|
|
}
|
|
|
|
return nil
|
|
}
|