diff --git a/cmd/portal/main.go b/cmd/portal/main.go index 5184d71..0dda246 100644 --- a/cmd/portal/main.go +++ b/cmd/portal/main.go @@ -1,22 +1,24 @@ package main import ( + "flag" + "net/http" + "git.lumeweb.com/LumeWeb/portal/account" "git.lumeweb.com/LumeWeb/portal/api" _config "git.lumeweb.com/LumeWeb/portal/config" "git.lumeweb.com/LumeWeb/portal/cron" "git.lumeweb.com/LumeWeb/portal/db" _logger "git.lumeweb.com/LumeWeb/portal/logger" + "git.lumeweb.com/LumeWeb/portal/metadata" "git.lumeweb.com/LumeWeb/portal/protocols" "git.lumeweb.com/LumeWeb/portal/renter" "git.lumeweb.com/LumeWeb/portal/storage" - flag "github.com/spf13/pflag" "github.com/spf13/viper" "go.uber.org/fx" "go.uber.org/fx/fxevent" "go.uber.org/zap" "go.uber.org/zap/zapcore" - "net/http" ) func main() { @@ -66,6 +68,7 @@ func main() { storage.Module, cron.Module, account.Module, + metadata.Module, protocols.BuildProtocols(config), api.BuildApis(config), fx.Provide(api.NewCasbin), diff --git a/metadata/metadata.go b/metadata/metadata.go new file mode 100644 index 0000000..9d29131 --- /dev/null +++ b/metadata/metadata.go @@ -0,0 +1,136 @@ +package metadata + +import ( + "context" + "encoding/hex" + "errors" + "time" + + "git.lumeweb.com/LumeWeb/portal/db/models" + + "go.uber.org/fx" + "gorm.io/gorm" +) + +var ErrNotFound = gorm.ErrRecordNotFound + +type UploadMetadata struct { + UserID uint `json:"userId"` + Hash []byte `json:"hash"` + MimeType string `json:"mimeType"` + Protocol string `json:"protocol"` + UploaderIP string `json:"uploaderIp"` + Size uint64 `json:"size"` + Created time.Time `json:"created"` +} + +func (u UploadMetadata) IsEmpty() bool { + if u.UserID != 0 || u.MimeType != "" || u.Protocol != "" || u.UploaderIP != "" || u.Size != 0 { + return false + } + + if !u.Created.IsZero() { + return false + } + + if len(u.Hash) != 0 { + return false + } + + return true +} + +var Module = fx.Module("metadata", + fx.Provide( + NewMetadataService, + ), +) + +type MetadataService interface { + SaveUpload(ctx context.Context, metadata UploadMetadata) error + GetUpload(ctx context.Context, objectHash []byte) (UploadMetadata, error) + DeleteUpload(ctx context.Context, objectHash []byte) error +} + +type MetadataServiceDefault struct { + db *gorm.DB +} + +type MetadataServiceParams struct { + fx.In + Db *gorm.DB +} + +func NewMetadataService(params MetadataServiceParams) *MetadataServiceDefault { + return &MetadataServiceDefault{ + db: params.Db, + } +} + +func (m *MetadataServiceDefault) SaveUpload(ctx context.Context, metadata UploadMetadata) error { + var upload models.Upload + + upload.Hash = hex.EncodeToString(metadata.Hash) + + ret := m.db.WithContext(ctx).Model(&models.Upload{}).Where(&upload).First(&upload) + + if ret.Error != nil { + if !errors.Is(ret.Error, gorm.ErrRecordNotFound) { + return ret.Error + } + } + + if ret.RowsAffected > 0 { + return nil + } + + upload.UserID = metadata.UserID + upload.MimeType = metadata.MimeType + upload.Protocol = metadata.Protocol + upload.UploaderIP = metadata.UploaderIP + upload.Size = metadata.Size + + return m.db.Save(&metadata).Error +} + +func (m *MetadataServiceDefault) GetUpload(ctx context.Context, objectHash []byte) (UploadMetadata, error) { + var upload models.Upload + + upload.Hash = hex.EncodeToString(objectHash) + + ret := m.db.WithContext(ctx).Model(&models.Upload{}).Where(&upload).First(&upload) + + if ret.Error != nil { + if errors.Is(ret.Error, gorm.ErrRecordNotFound) { + return UploadMetadata{}, ret.Error + } + } + + hash, err := hex.DecodeString(upload.Hash) + if err != nil { + return UploadMetadata{}, err + } + + return UploadMetadata{ + UserID: upload.UserID, + Hash: hash, + MimeType: upload.MimeType, + Protocol: upload.Protocol, + UploaderIP: upload.UploaderIP, + Size: upload.Size, + }, nil +} + +func (m *MetadataServiceDefault) DeleteUpload(ctx context.Context, objectHash []byte) error { + var upload models.Upload + + upload.Hash = hex.EncodeToString(objectHash) + + ret := m.db.WithContext(ctx).Model(&models.Upload{}).Where(&upload).First(&upload) + + if ret.Error != nil { + return ret.Error + } + + return m.db.Delete(&upload).Error +}