Initial commit: Open sourcing all of the Maple Open Technologies code.

This commit is contained in:
Bartlomiej Mika 2025-12-02 14:33:08 -05:00
commit 755d54a99d
2010 changed files with 448675 additions and 0 deletions

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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)
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}