This commit is contained in:
parent
d71d79dfcc
commit
8e247cdb0d
@ -45,21 +45,21 @@ func NewPostService(postRepo repository.PostRepository) PostService {
|
||||
return &postService{postRepo: postRepo}
|
||||
}
|
||||
|
||||
func (s *postService) CreateWithS3Upload(ctx context.Context, authorID int, title, s3TempKey string) (*domain.Post, error) {
|
||||
func (s *postService) CreateWithS3Upload(ctx context.Context, authorID int, title, s3Key string) (*domain.Post, error) {
|
||||
const op = "service/postService.CreateWithS3Upload"
|
||||
|
||||
// Валидация
|
||||
if s3TempKey == "" {
|
||||
return nil, errors.New("S3 temp key cannot be empty")
|
||||
if s3Key == "" {
|
||||
return nil, errors.New("S3 key cannot be empty")
|
||||
}
|
||||
|
||||
// Проверяем что ключ принадлежит пользователю (дополнительная валидация)
|
||||
if !isValidUserTempKey(authorID, s3TempKey) {
|
||||
return nil, errors.New("invalid temp key for user")
|
||||
// Проверяем что ключ принадлежит пользователю и находится в правильной папке
|
||||
if !isValidUserPostKey(authorID, s3Key) {
|
||||
return nil, errors.New("invalid S3 key for user")
|
||||
}
|
||||
|
||||
// Генерируем временный URL для модерации
|
||||
tempURL := fmt.Sprintf("https://s3.regru.cloud/tailly/%s", s3TempKey)
|
||||
// Формируем URL для модерации
|
||||
imageURL := fmt.Sprintf("https://s3.regru.cloud/tailly/%s", s3Key)
|
||||
|
||||
// Модерация изображения по URL
|
||||
modClient, err := moderation.NewModerationClient("tailly_censor:50051")
|
||||
@ -68,29 +68,19 @@ func (s *postService) CreateWithS3Upload(ctx context.Context, authorID int, titl
|
||||
}
|
||||
defer modClient.Close()
|
||||
|
||||
allowed, err := modClient.CheckImageURL(ctx, tempURL)
|
||||
allowed, err := modClient.CheckImageURL(ctx, imageURL)
|
||||
if err != nil {
|
||||
// Удаляем временный файл при ошибке модерации
|
||||
S3.DeleteTempFile(s3TempKey)
|
||||
// Удаляем файл при ошибке модерации
|
||||
S3.DeleteFromS3(imageURL)
|
||||
return nil, fmt.Errorf("%s: image moderation failed: %w", op, err)
|
||||
}
|
||||
if !allowed {
|
||||
// Удаляем временный файл если не прошло модерацию
|
||||
S3.DeleteTempFile(s3TempKey)
|
||||
// Удаляем файл если не прошло модерацию
|
||||
S3.DeleteFromS3(imageURL)
|
||||
return nil, errors.New("image rejected by moderation service")
|
||||
}
|
||||
|
||||
// Перемещаем файл из временной папки в постоянную
|
||||
permanentKey := fmt.Sprintf("posts/%d/%d_%s", authorID, time.Now().UnixNano(), getFilenameFromKey(s3TempKey))
|
||||
|
||||
err = S3.MoveFile(s3TempKey, permanentKey)
|
||||
if err != nil {
|
||||
S3.DeleteTempFile(s3TempKey) // Удаляем временный файл при ошибке
|
||||
return nil, fmt.Errorf("%s: failed to move file to permanent location: %w", op, err)
|
||||
}
|
||||
|
||||
imageURL := fmt.Sprintf("https://s3.regru.cloud/tailly/%s", permanentKey)
|
||||
|
||||
// Создаем пост с уже готовым URL
|
||||
post := &domain.Post{
|
||||
Title: title,
|
||||
Content: imageURL,
|
||||
@ -101,22 +91,18 @@ func (s *postService) CreateWithS3Upload(ctx context.Context, authorID int, titl
|
||||
|
||||
if err := s.postRepo.Create(ctx, post); err != nil {
|
||||
// Если не удалось сохранить пост, удаляем файл из S3
|
||||
S3.DeleteTempFile(permanentKey)
|
||||
S3.DeleteFromS3(imageURL)
|
||||
return nil, fmt.Errorf("%s: failed to save post: %w", op, err)
|
||||
}
|
||||
|
||||
return post, nil
|
||||
}
|
||||
|
||||
func isValidUserTempKey(userID int, key string) bool {
|
||||
// Проверяем что ключ принадлежит пользователю
|
||||
// Формат: temp/{userID}/{timestamp}_{filename}
|
||||
return strings.Contains(key, fmt.Sprintf("temp/%d/", userID))
|
||||
}
|
||||
|
||||
func getFilenameFromKey(key string) string {
|
||||
parts := strings.Split(key, "/")
|
||||
return parts[len(parts)-1]
|
||||
// Новая функция проверки ключа
|
||||
func isValidUserPostKey(userID int, key string) bool {
|
||||
// Проверяем что ключ принадлежит пользователю и находится в папке posts
|
||||
// Формат: posts/{userID}/{timestamp}_{filename}
|
||||
return strings.HasPrefix(key, fmt.Sprintf("posts/%d/", userID))
|
||||
}
|
||||
|
||||
// Создание нового поста
|
||||
|
||||
44
pkg/S3/s3.go
44
pkg/S3/s3.go
@ -87,7 +87,8 @@ func GeneratePresignedUploadURL(userID int, filename string) (string, string, er
|
||||
return "", "", fmt.Errorf("%s: failed to create S3 client: %w", op, err)
|
||||
}
|
||||
|
||||
uniqueKey := fmt.Sprintf("temp/%d/%d_%s", userID, time.Now().UnixNano(), filename)
|
||||
// Генерируем ключ сразу в конечной папке с уникальным именем
|
||||
uniqueKey := fmt.Sprintf("posts/%d/%d_%s", userID, time.Now().UnixNano(), filename)
|
||||
|
||||
presignClient := s3.NewPresignClient(client)
|
||||
|
||||
@ -105,44 +106,3 @@ func GeneratePresignedUploadURL(userID int, filename string) (string, string, er
|
||||
|
||||
return result.URL, uniqueKey, nil
|
||||
}
|
||||
|
||||
func MoveFile(sourceKey, destinationKey string) error {
|
||||
const op = "s3.MoveFile"
|
||||
|
||||
client, err := getS3Client()
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: failed to create S3 client: %w", op, err)
|
||||
}
|
||||
|
||||
// Копируем файл
|
||||
_, err = client.CopyObject(context.TODO(), &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"
|
||||
|
||||
client, err := getS3Client()
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: failed to create S3 client: %w", op, err)
|
||||
}
|
||||
|
||||
_, err = client.DeleteObject(context.TODO(), &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
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user