Initial commit: Open sourcing all of the Maple Open Technologies code.
This commit is contained in:
commit
755d54a99d
2010 changed files with 448675 additions and 0 deletions
|
|
@ -0,0 +1,62 @@
|
|||
// monorepo/cloud/backend/internal/maplefile/usecase/fileobjectstorage/delete_encrypted_data.go
|
||||
package fileobjectstorage
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
|
||||
dom_file "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/file"
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
|
||||
)
|
||||
|
||||
type DeleteEncryptedDataUseCase interface {
|
||||
Execute(storagePath string) error
|
||||
}
|
||||
|
||||
type deleteEncryptedDataUseCaseImpl struct {
|
||||
config *config.Configuration
|
||||
logger *zap.Logger
|
||||
repo dom_file.FileObjectStorageRepository
|
||||
}
|
||||
|
||||
func NewDeleteEncryptedDataUseCase(
|
||||
config *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) DeleteEncryptedDataUseCase {
|
||||
logger = logger.Named("DeleteEncryptedDataUseCase")
|
||||
return &deleteEncryptedDataUseCaseImpl{config, logger, repo}
|
||||
}
|
||||
|
||||
func (uc *deleteEncryptedDataUseCaseImpl) Execute(storagePath string) error {
|
||||
//
|
||||
// STEP 1: Validation.
|
||||
//
|
||||
|
||||
e := make(map[string]string)
|
||||
if storagePath == "" {
|
||||
e["storage_path"] = "Storage path is required"
|
||||
}
|
||||
if len(e) != 0 {
|
||||
uc.logger.Warn("Failed validating delete encrypted data",
|
||||
zap.Any("error", e))
|
||||
return httperror.NewForBadRequest(&e)
|
||||
}
|
||||
|
||||
//
|
||||
// STEP 2: Delete encrypted data.
|
||||
//
|
||||
|
||||
err := uc.repo.DeleteEncryptedData(storagePath)
|
||||
if err != nil {
|
||||
uc.logger.Error("Failed to delete encrypted data",
|
||||
zap.String("storage_path", storagePath),
|
||||
zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
uc.logger.Info("Successfully deleted encrypted data",
|
||||
zap.String("storage_path", storagePath))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
// monorepo/cloud/backend/internal/maplefile/usecase/fileobjectstorage/delete_multiple_encrypted_data.go
|
||||
package fileobjectstorage
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
|
||||
dom_file "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/file"
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
|
||||
)
|
||||
|
||||
type DeleteMultipleEncryptedDataUseCase interface {
|
||||
Execute(storagePaths []string) error
|
||||
}
|
||||
|
||||
type deleteMultipleEncryptedDataUseCaseImpl struct {
|
||||
config *config.Configuration
|
||||
logger *zap.Logger
|
||||
repo dom_file.FileObjectStorageRepository
|
||||
}
|
||||
|
||||
func NewDeleteMultipleEncryptedDataUseCase(
|
||||
config *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) DeleteMultipleEncryptedDataUseCase {
|
||||
logger = logger.Named("DeleteMultipleEncryptedDataUseCase")
|
||||
return &deleteMultipleEncryptedDataUseCaseImpl{config, logger, repo}
|
||||
}
|
||||
|
||||
func (uc *deleteMultipleEncryptedDataUseCaseImpl) Execute(storagePaths []string) error {
|
||||
//
|
||||
// STEP 1: Validation.
|
||||
//
|
||||
|
||||
e := make(map[string]string)
|
||||
if storagePaths == nil || len(storagePaths) == 0 {
|
||||
e["storage_paths"] = "Storage paths are required"
|
||||
} else {
|
||||
for i, path := range storagePaths {
|
||||
if path == "" {
|
||||
e[fmt.Sprintf("storage_paths[%d]", i)] = "Storage path is required"
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(e) != 0 {
|
||||
uc.logger.Warn("Failed validating delete multiple encrypted data",
|
||||
zap.Any("error", e))
|
||||
return httperror.NewForBadRequest(&e)
|
||||
}
|
||||
|
||||
//
|
||||
// STEP 2: Delete encrypted data files.
|
||||
//
|
||||
|
||||
var errors []error
|
||||
successCount := 0
|
||||
|
||||
for _, storagePath := range storagePaths {
|
||||
err := uc.repo.DeleteEncryptedData(storagePath)
|
||||
if err != nil {
|
||||
uc.logger.Error("Failed to delete encrypted data",
|
||||
zap.String("storage_path", storagePath),
|
||||
zap.Error(err))
|
||||
errors = append(errors, fmt.Errorf("failed to delete %s: %w", storagePath, err))
|
||||
} else {
|
||||
successCount++
|
||||
uc.logger.Debug("Successfully deleted encrypted data",
|
||||
zap.String("storage_path", storagePath))
|
||||
}
|
||||
}
|
||||
|
||||
// Log summary
|
||||
uc.logger.Info("Completed bulk delete operation",
|
||||
zap.Int("total_requested", len(storagePaths)),
|
||||
zap.Int("successful_deletions", successCount),
|
||||
zap.Int("failed_deletions", len(errors)))
|
||||
|
||||
// If all operations failed, return the first error
|
||||
if len(errors) == len(storagePaths) {
|
||||
return errors[0]
|
||||
}
|
||||
|
||||
// If some operations failed, log but don't return error (partial success)
|
||||
if len(errors) > 0 {
|
||||
uc.logger.Warn("Some delete operations failed",
|
||||
zap.Int("failed_count", len(errors)))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
// monorepo/cloud/backend/internal/maplefile/usecase/fileobjectstorage/get_encrypted_data.go
|
||||
package fileobjectstorage
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
|
||||
dom_file "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/file"
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
|
||||
)
|
||||
|
||||
type GetEncryptedDataUseCase interface {
|
||||
Execute(storagePath string) ([]byte, error)
|
||||
}
|
||||
|
||||
type getEncryptedDataUseCaseImpl struct {
|
||||
config *config.Configuration
|
||||
logger *zap.Logger
|
||||
repo dom_file.FileObjectStorageRepository
|
||||
}
|
||||
|
||||
func NewGetEncryptedDataUseCase(
|
||||
config *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) GetEncryptedDataUseCase {
|
||||
logger = logger.Named("GetEncryptedDataUseCase")
|
||||
return &getEncryptedDataUseCaseImpl{config, logger, repo}
|
||||
}
|
||||
|
||||
func (uc *getEncryptedDataUseCaseImpl) Execute(storagePath string) ([]byte, error) {
|
||||
//
|
||||
// STEP 1: Validation.
|
||||
//
|
||||
|
||||
e := make(map[string]string)
|
||||
if storagePath == "" {
|
||||
e["storage_path"] = "Storage path is required"
|
||||
}
|
||||
if len(e) != 0 {
|
||||
uc.logger.Warn("Failed validating get encrypted data",
|
||||
zap.Any("error", e))
|
||||
return nil, httperror.NewForBadRequest(&e)
|
||||
}
|
||||
|
||||
//
|
||||
// STEP 2: Get encrypted data.
|
||||
//
|
||||
|
||||
data, err := uc.repo.GetEncryptedData(storagePath)
|
||||
if err != nil {
|
||||
uc.logger.Error("Failed to get encrypted data",
|
||||
zap.String("storage_path", storagePath),
|
||||
zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
uc.logger.Debug("Successfully retrieved encrypted data",
|
||||
zap.String("storage_path", storagePath),
|
||||
zap.Int("data_size", len(data)))
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
// monorepo/cloud/backend/internal/maplefile/usecase/fileobjectstorage/get_object_size.go
|
||||
package fileobjectstorage
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
|
||||
dom_file "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/file"
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
|
||||
)
|
||||
|
||||
type GetObjectSizeUseCase interface {
|
||||
Execute(storagePath string) (int64, error)
|
||||
}
|
||||
|
||||
type getObjectSizeUseCaseImpl struct {
|
||||
config *config.Configuration
|
||||
logger *zap.Logger
|
||||
repo dom_file.FileObjectStorageRepository
|
||||
}
|
||||
|
||||
func NewGetObjectSizeUseCase(
|
||||
config *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) GetObjectSizeUseCase {
|
||||
logger = logger.Named("GetObjectSizeUseCase")
|
||||
return &getObjectSizeUseCaseImpl{config, logger, repo}
|
||||
}
|
||||
|
||||
func (uc *getObjectSizeUseCaseImpl) Execute(storagePath string) (int64, error) {
|
||||
//
|
||||
// STEP 1: Validation.
|
||||
//
|
||||
|
||||
e := make(map[string]string)
|
||||
if storagePath == "" {
|
||||
e["storage_path"] = "Storage path is required"
|
||||
}
|
||||
if len(e) != 0 {
|
||||
uc.logger.Warn("Failed validating get object size",
|
||||
zap.Any("error", e))
|
||||
return 0, httperror.NewForBadRequest(&e)
|
||||
}
|
||||
|
||||
//
|
||||
// STEP 2: Get object size.
|
||||
//
|
||||
|
||||
size, err := uc.repo.GetObjectSize(storagePath)
|
||||
if err != nil {
|
||||
uc.logger.Error("Failed to get object size",
|
||||
zap.String("storage_path", storagePath),
|
||||
zap.Error(err))
|
||||
return 0, err
|
||||
}
|
||||
|
||||
uc.logger.Debug("Retrieved object size",
|
||||
zap.String("storage_path", storagePath),
|
||||
zap.Int64("size", size))
|
||||
|
||||
return size, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
// monorepo/cloud/backend/internal/maplefile/usecase/fileobjectstorage/presigned_download_url.go
|
||||
package fileobjectstorage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
|
||||
dom_file "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/file"
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
|
||||
)
|
||||
|
||||
type GeneratePresignedDownloadURLUseCase interface {
|
||||
Execute(ctx context.Context, storagePath string, duration time.Duration) (string, error)
|
||||
}
|
||||
|
||||
type generatePresignedDownloadURLUseCaseImpl struct {
|
||||
config *config.Configuration
|
||||
logger *zap.Logger
|
||||
repo dom_file.FileObjectStorageRepository
|
||||
}
|
||||
|
||||
func NewGeneratePresignedDownloadURLUseCase(
|
||||
config *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) GeneratePresignedDownloadURLUseCase {
|
||||
logger = logger.Named("GeneratePresignedDownloadURLUseCase")
|
||||
return &generatePresignedDownloadURLUseCaseImpl{config, logger, repo}
|
||||
}
|
||||
|
||||
func (uc *generatePresignedDownloadURLUseCaseImpl) Execute(ctx context.Context, storagePath string, duration time.Duration) (string, error) {
|
||||
//
|
||||
// STEP 1: Validation.
|
||||
//
|
||||
|
||||
e := make(map[string]string)
|
||||
if storagePath == "" {
|
||||
e["storage_path"] = "Storage path is required"
|
||||
}
|
||||
if duration <= 0 {
|
||||
e["duration"] = "Duration must be greater than 0"
|
||||
}
|
||||
// Set reasonable limits for presigned URL duration
|
||||
maxDuration := 24 * time.Hour // 24 hours max
|
||||
if duration > maxDuration {
|
||||
e["duration"] = "Duration cannot exceed 24 hours"
|
||||
}
|
||||
if len(e) != 0 {
|
||||
uc.logger.Warn("Failed validating generate presigned download URL",
|
||||
zap.Any("error", e))
|
||||
return "", httperror.NewForBadRequest(&e)
|
||||
}
|
||||
|
||||
//
|
||||
// STEP 2: Generate and get presigned download URL.
|
||||
//
|
||||
|
||||
url, err := uc.repo.GeneratePresignedDownloadURL(storagePath, duration)
|
||||
if err != nil {
|
||||
uc.logger.Error("Failed to generate presigned download URL",
|
||||
zap.String("storage_path", storagePath),
|
||||
zap.Duration("duration", duration),
|
||||
zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return url, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
// monorepo/cloud/backend/internal/maplefile/usecase/fileobjectstorage/presigned_upload_url.go
|
||||
package fileobjectstorage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
|
||||
dom_file "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/file"
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
|
||||
)
|
||||
|
||||
type GeneratePresignedUploadURLUseCase interface {
|
||||
Execute(ctx context.Context, storagePath string, duration time.Duration) (string, error)
|
||||
}
|
||||
|
||||
type generatePresignedUploadURLUseCaseImpl struct {
|
||||
config *config.Configuration
|
||||
logger *zap.Logger
|
||||
repo dom_file.FileObjectStorageRepository
|
||||
}
|
||||
|
||||
func NewGeneratePresignedUploadURLUseCase(
|
||||
config *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) GeneratePresignedUploadURLUseCase {
|
||||
logger = logger.Named("GeneratePresignedUploadURLUseCase")
|
||||
return &generatePresignedUploadURLUseCaseImpl{config, logger, repo}
|
||||
}
|
||||
|
||||
func (uc *generatePresignedUploadURLUseCaseImpl) Execute(ctx context.Context, storagePath string, duration time.Duration) (string, error) {
|
||||
//
|
||||
// STEP 1: Validation.
|
||||
//
|
||||
|
||||
e := make(map[string]string)
|
||||
if storagePath == "" {
|
||||
e["storage_path"] = "Storage path is required"
|
||||
}
|
||||
if duration <= 0 {
|
||||
e["duration"] = "Duration must be greater than 0"
|
||||
}
|
||||
// Set reasonable limits for presigned URL duration
|
||||
maxDuration := 24 * time.Hour // 24 hours max
|
||||
if duration > maxDuration {
|
||||
e["duration"] = "Duration cannot exceed 24 hours"
|
||||
}
|
||||
if len(e) != 0 {
|
||||
uc.logger.Warn("Failed validating generate presigned upload URL",
|
||||
zap.Any("error", e))
|
||||
return "", httperror.NewForBadRequest(&e)
|
||||
}
|
||||
|
||||
//
|
||||
// STEP 2: Generate and get presigned upload URL.
|
||||
//
|
||||
|
||||
url, err := uc.repo.GeneratePresignedUploadURL(storagePath, duration)
|
||||
if err != nil {
|
||||
uc.logger.Error("Failed to generate presigned upload URL",
|
||||
zap.String("storage_path", storagePath),
|
||||
zap.Duration("duration", duration),
|
||||
zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return url, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
package fileobjectstorage
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
|
||||
dom_file "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/file"
|
||||
)
|
||||
|
||||
// Wire providers for file object storage use cases
|
||||
|
||||
func ProvideStoreEncryptedDataUseCase(
|
||||
cfg *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) StoreEncryptedDataUseCase {
|
||||
return NewStoreEncryptedDataUseCase(cfg, logger, repo)
|
||||
}
|
||||
|
||||
func ProvideGetEncryptedDataUseCase(
|
||||
cfg *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) GetEncryptedDataUseCase {
|
||||
return NewGetEncryptedDataUseCase(cfg, logger, repo)
|
||||
}
|
||||
|
||||
func ProvideDeleteEncryptedDataUseCase(
|
||||
cfg *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) DeleteEncryptedDataUseCase {
|
||||
return NewDeleteEncryptedDataUseCase(cfg, logger, repo)
|
||||
}
|
||||
|
||||
func ProvideStoreMultipleEncryptedDataUseCase(
|
||||
cfg *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) StoreMultipleEncryptedDataUseCase {
|
||||
return NewStoreMultipleEncryptedDataUseCase(cfg, logger, repo)
|
||||
}
|
||||
|
||||
func ProvideDeleteMultipleEncryptedDataUseCase(
|
||||
cfg *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) DeleteMultipleEncryptedDataUseCase {
|
||||
return NewDeleteMultipleEncryptedDataUseCase(cfg, logger, repo)
|
||||
}
|
||||
|
||||
func ProvideVerifyObjectExistsUseCase(
|
||||
cfg *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) VerifyObjectExistsUseCase {
|
||||
return NewVerifyObjectExistsUseCase(cfg, logger, repo)
|
||||
}
|
||||
|
||||
func ProvideGeneratePresignedUploadURLUseCase(
|
||||
cfg *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) GeneratePresignedUploadURLUseCase {
|
||||
return NewGeneratePresignedUploadURLUseCase(cfg, logger, repo)
|
||||
}
|
||||
|
||||
func ProvideGetObjectSizeUseCase(
|
||||
cfg *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) GetObjectSizeUseCase {
|
||||
return NewGetObjectSizeUseCase(cfg, logger, repo)
|
||||
}
|
||||
|
||||
func ProvideGeneratePresignedDownloadURLUseCase(
|
||||
cfg *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) GeneratePresignedDownloadURLUseCase {
|
||||
return NewGeneratePresignedDownloadURLUseCase(cfg, logger, repo)
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
// monorepo/cloud/backend/internal/maplefile/usecase/fileobjectstorage/store_encrypted_data.go
|
||||
package fileobjectstorage
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
|
||||
dom_file "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/file"
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
|
||||
)
|
||||
|
||||
type StoreEncryptedDataUseCase interface {
|
||||
Execute(ownerID string, fileID string, encryptedData []byte) (string, error)
|
||||
}
|
||||
|
||||
type storeEncryptedDataUseCaseImpl struct {
|
||||
config *config.Configuration
|
||||
logger *zap.Logger
|
||||
repo dom_file.FileObjectStorageRepository
|
||||
}
|
||||
|
||||
func NewStoreEncryptedDataUseCase(
|
||||
config *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) StoreEncryptedDataUseCase {
|
||||
logger = logger.Named("StoreEncryptedDataUseCase")
|
||||
return &storeEncryptedDataUseCaseImpl{config, logger, repo}
|
||||
}
|
||||
|
||||
func (uc *storeEncryptedDataUseCaseImpl) Execute(ownerID string, fileID string, encryptedData []byte) (string, error) {
|
||||
//
|
||||
// STEP 1: Validation.
|
||||
//
|
||||
|
||||
e := make(map[string]string)
|
||||
if ownerID == "" {
|
||||
e["owner_id"] = "Owner ID is required"
|
||||
}
|
||||
if fileID == "" {
|
||||
e["file_id"] = "File ID is required"
|
||||
}
|
||||
if encryptedData == nil || len(encryptedData) == 0 {
|
||||
e["encrypted_data"] = "Encrypted data is required"
|
||||
}
|
||||
if len(e) != 0 {
|
||||
uc.logger.Warn("Failed validating store encrypted data",
|
||||
zap.Any("error", e))
|
||||
return "", httperror.NewForBadRequest(&e)
|
||||
}
|
||||
|
||||
//
|
||||
// STEP 2: Store encrypted data.
|
||||
//
|
||||
|
||||
storagePath, err := uc.repo.StoreEncryptedData(ownerID, fileID, encryptedData)
|
||||
if err != nil {
|
||||
uc.logger.Error("Failed to store encrypted data",
|
||||
zap.String("owner_id", ownerID),
|
||||
zap.String("file_id", fileID),
|
||||
zap.Int("data_size", len(encryptedData)),
|
||||
zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
uc.logger.Info("Successfully stored encrypted data",
|
||||
zap.String("owner_id", ownerID),
|
||||
zap.String("file_id", fileID),
|
||||
zap.String("storage_path", storagePath),
|
||||
zap.Int("data_size", len(encryptedData)))
|
||||
|
||||
return storagePath, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
// monorepo/cloud/backend/internal/maplefile/usecase/fileobjectstorage/store_multiple_encrypted_data.go
|
||||
package fileobjectstorage
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
|
||||
dom_file "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/file"
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
|
||||
)
|
||||
|
||||
// EncryptedDataItem represents a single item to be stored
|
||||
type EncryptedDataItem struct {
|
||||
OwnerID string `json:"owner_id"`
|
||||
FileID string `json:"file_id"`
|
||||
EncryptedData []byte `json:"encrypted_data"`
|
||||
}
|
||||
|
||||
// StorageResult represents the result of storing a single item
|
||||
type StorageResult struct {
|
||||
FileID string `json:"file_id"`
|
||||
StoragePath string `json:"storage_path,omitempty"`
|
||||
Error error `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
type StoreMultipleEncryptedDataUseCase interface {
|
||||
Execute(items []EncryptedDataItem) ([]StorageResult, error)
|
||||
}
|
||||
|
||||
type storeMultipleEncryptedDataUseCaseImpl struct {
|
||||
config *config.Configuration
|
||||
logger *zap.Logger
|
||||
repo dom_file.FileObjectStorageRepository
|
||||
}
|
||||
|
||||
func NewStoreMultipleEncryptedDataUseCase(
|
||||
config *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) StoreMultipleEncryptedDataUseCase {
|
||||
logger = logger.Named("StoreMultipleEncryptedDataUseCase")
|
||||
return &storeMultipleEncryptedDataUseCaseImpl{config, logger, repo}
|
||||
}
|
||||
|
||||
func (uc *storeMultipleEncryptedDataUseCaseImpl) Execute(items []EncryptedDataItem) ([]StorageResult, error) {
|
||||
//
|
||||
// STEP 1: Validation.
|
||||
//
|
||||
|
||||
e := make(map[string]string)
|
||||
if items == nil || len(items) == 0 {
|
||||
e["items"] = "Items are required"
|
||||
} else {
|
||||
for i, item := range items {
|
||||
if item.OwnerID == "" {
|
||||
e[fmt.Sprintf("items[%d].owner_id", i)] = "Owner ID is required"
|
||||
}
|
||||
if item.FileID == "" {
|
||||
e[fmt.Sprintf("items[%d].file_id", i)] = "File ID is required"
|
||||
}
|
||||
if item.EncryptedData == nil || len(item.EncryptedData) == 0 {
|
||||
e[fmt.Sprintf("items[%d].encrypted_data", i)] = "Encrypted data is required"
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(e) != 0 {
|
||||
uc.logger.Warn("Failed validating store multiple encrypted data",
|
||||
zap.Any("error", e))
|
||||
return nil, httperror.NewForBadRequest(&e)
|
||||
}
|
||||
|
||||
//
|
||||
// STEP 2: Store encrypted data files.
|
||||
//
|
||||
|
||||
results := make([]StorageResult, len(items))
|
||||
successCount := 0
|
||||
|
||||
for i, item := range items {
|
||||
storagePath, err := uc.repo.StoreEncryptedData(item.OwnerID, item.FileID, item.EncryptedData)
|
||||
|
||||
results[i] = StorageResult{
|
||||
FileID: item.FileID,
|
||||
StoragePath: storagePath,
|
||||
Error: err,
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
uc.logger.Error("Failed to store encrypted data",
|
||||
zap.String("owner_id", item.OwnerID),
|
||||
zap.String("file_id", item.FileID),
|
||||
zap.Int("data_size", len(item.EncryptedData)),
|
||||
zap.Error(err))
|
||||
} else {
|
||||
successCount++
|
||||
uc.logger.Debug("Successfully stored encrypted data",
|
||||
zap.String("owner_id", item.OwnerID),
|
||||
zap.String("file_id", item.FileID),
|
||||
zap.String("storage_path", storagePath),
|
||||
zap.Int("data_size", len(item.EncryptedData)))
|
||||
}
|
||||
}
|
||||
|
||||
// Log summary
|
||||
uc.logger.Info("Completed bulk store operation",
|
||||
zap.Int("total_requested", len(items)),
|
||||
zap.Int("successful_stores", successCount),
|
||||
zap.Int("failed_stores", len(items)-successCount))
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
// monorepo/cloud/backend/internal/maplefile/usecase/fileobjectstorage/verify_object_exists.go
|
||||
package fileobjectstorage
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
|
||||
dom_file "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/file"
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
|
||||
)
|
||||
|
||||
type VerifyObjectExistsUseCase interface {
|
||||
Execute(storagePath string) (bool, error)
|
||||
}
|
||||
|
||||
type verifyObjectExistsUseCaseImpl struct {
|
||||
config *config.Configuration
|
||||
logger *zap.Logger
|
||||
repo dom_file.FileObjectStorageRepository
|
||||
}
|
||||
|
||||
func NewVerifyObjectExistsUseCase(
|
||||
config *config.Configuration,
|
||||
logger *zap.Logger,
|
||||
repo dom_file.FileObjectStorageRepository,
|
||||
) VerifyObjectExistsUseCase {
|
||||
logger = logger.Named("VerifyObjectExistsUseCase")
|
||||
return &verifyObjectExistsUseCaseImpl{config, logger, repo}
|
||||
}
|
||||
|
||||
func (uc *verifyObjectExistsUseCaseImpl) Execute(storagePath string) (bool, error) {
|
||||
//
|
||||
// STEP 1: Validation.
|
||||
//
|
||||
|
||||
e := make(map[string]string)
|
||||
if storagePath == "" {
|
||||
e["storage_path"] = "Storage path is required"
|
||||
}
|
||||
if len(e) != 0 {
|
||||
uc.logger.Warn("Failed validating verify if object exists",
|
||||
zap.Any("error", e))
|
||||
return false, httperror.NewForBadRequest(&e)
|
||||
}
|
||||
|
||||
//
|
||||
// STEP 2: Verify if object exists.
|
||||
//
|
||||
|
||||
exists, err := uc.repo.VerifyObjectExists(storagePath)
|
||||
if err != nil {
|
||||
uc.logger.Error("Failed to verify if object exists",
|
||||
zap.String("storage_path", storagePath),
|
||||
zap.Error(err))
|
||||
return false, err
|
||||
}
|
||||
|
||||
uc.logger.Debug("Object existence verified",
|
||||
zap.String("storage_path", storagePath),
|
||||
zap.Bool("exists", exists))
|
||||
|
||||
return exists, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue