142 lines
3.6 KiB
Go
142 lines
3.6 KiB
Go
package S3
|
||
|
||
import (
|
||
"fmt"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/aws/aws-sdk-go/aws"
|
||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||
"github.com/aws/aws-sdk-go/aws/session"
|
||
"github.com/aws/aws-sdk-go/service/s3"
|
||
)
|
||
|
||
func DeleteFromS3(imageURL string) error {
|
||
const op = "s3.DeleteFromS3"
|
||
|
||
parts := strings.SplitN(strings.TrimPrefix(imageURL, "https://s3.regru.cloud/"), "/", 2)
|
||
if len(parts) != 2 {
|
||
return fmt.Errorf("%s: invalid S3 URL format", op)
|
||
}
|
||
bucket := parts[0]
|
||
key := parts[1]
|
||
|
||
sess := session.Must(session.NewSession(&aws.Config{
|
||
Region: aws.String("ru-central1"),
|
||
Endpoint: aws.String("https://s3.regru.cloud"),
|
||
S3ForcePathStyle: aws.Bool(true),
|
||
Credentials: credentials.NewStaticCredentials(
|
||
"TJ946G2S1Z5FEI3I7DQQ",
|
||
"C2H2aITHRDpek8H921yhnrINZwDoADsjW3F6HURl",
|
||
"",
|
||
),
|
||
}))
|
||
|
||
svc := s3.New(sess)
|
||
|
||
_, err := svc.DeleteObject(&s3.DeleteObjectInput{
|
||
Bucket: aws.String(bucket),
|
||
Key: aws.String(key),
|
||
})
|
||
if err != nil {
|
||
return fmt.Errorf("%s: failed to delete object from S3: %w", op, err)
|
||
}
|
||
|
||
err = svc.WaitUntilObjectNotExists(&s3.HeadObjectInput{
|
||
Bucket: aws.String(bucket),
|
||
Key: aws.String(key),
|
||
})
|
||
if err != nil {
|
||
return fmt.Errorf("%s: failed to wait for object deletion: %w", op, err)
|
||
}
|
||
|
||
return nil
|
||
}
|
||
func GeneratePresignedUploadURL(userID int, filename string) (string, string, error) {
|
||
const op = "s3.GeneratePresignedUploadURL"
|
||
|
||
sess := session.Must(session.NewSession(&aws.Config{
|
||
Region: aws.String("ru-central1"),
|
||
Endpoint: aws.String("https://s3.regru.cloud"),
|
||
Credentials: credentials.NewStaticCredentials(
|
||
"TJ946G2S1Z5FEI3I7DQQ",
|
||
"C2H2aITHRDpek8H921yhnrINZwDoADsjW3F6HURl",
|
||
"",
|
||
),
|
||
}))
|
||
|
||
svc := s3.New(sess)
|
||
|
||
// Генерируем уникальный ключ с userID для безопасности
|
||
uniqueKey := fmt.Sprintf("temp/%d/%d_%s", userID, time.Now().UnixNano(), filename)
|
||
|
||
req, _ := svc.PutObjectRequest(&s3.PutObjectInput{
|
||
Bucket: aws.String("tailly"),
|
||
Key: aws.String(uniqueKey),
|
||
ContentLength: aws.Int64(10 * 1024 * 1024), // Макс 10MB
|
||
})
|
||
|
||
// URL действителен 15 минут
|
||
url, err := req.Presign(15 * time.Minute)
|
||
if err != nil {
|
||
return "", "", fmt.Errorf("%s: failed to generate presigned URL: %w", op, err)
|
||
}
|
||
|
||
return url, uniqueKey, nil
|
||
}
|
||
|
||
func MoveFile(sourceKey, destinationKey string) error {
|
||
const op = "s3.MoveFile"
|
||
|
||
sess := session.Must(session.NewSession(&aws.Config{
|
||
Region: aws.String("ru-central1"),
|
||
Endpoint: aws.String("https://s3.regru.cloud"),
|
||
Credentials: credentials.NewStaticCredentials(
|
||
"TJ946G2S1Z5FEI3I7DQQ",
|
||
"C2H2aITHRDpek8H921yhnrINZwDoADsjW3F6HURl",
|
||
"",
|
||
),
|
||
}))
|
||
|
||
svc := s3.New(sess)
|
||
|
||
// Копируем файл
|
||
_, err := svc.CopyObject(&s3.CopyObjectInput{
|
||
Bucket: aws.String("tailly"),
|
||
CopySource: aws.String(fmt.Sprintf("tailly/%s", sourceKey)),
|
||
Key: aws.String(destinationKey),
|
||
})
|
||
if err != nil {
|
||
return fmt.Errorf("%s: failed to copy file: %w", op, err)
|
||
}
|
||
|
||
// Удаляем исходный файл
|
||
return DeleteTempFile(sourceKey)
|
||
}
|
||
|
||
func DeleteTempFile(key string) error {
|
||
const op = "s3.DeleteTempFile"
|
||
|
||
sess := session.Must(session.NewSession(&aws.Config{
|
||
Region: aws.String("ru-central1"),
|
||
Endpoint: aws.String("https://s3.regru.cloud"),
|
||
Credentials: credentials.NewStaticCredentials(
|
||
"TJ946G2S1Z5FEI3I7DQQ",
|
||
"C2H2aITHRDpek8H921yhnrINZwDoADsjW3F6HURl",
|
||
"",
|
||
),
|
||
}))
|
||
|
||
svc := s3.New(sess)
|
||
|
||
_, err := svc.DeleteObject(&s3.DeleteObjectInput{
|
||
Bucket: aws.String("tailly"),
|
||
Key: aws.String(key),
|
||
})
|
||
if err != nil {
|
||
return fmt.Errorf("%s: failed to delete temp file: %w", op, err)
|
||
}
|
||
|
||
return nil
|
||
}
|