fix: align admin behavior and Kratos integrations
This commit is contained in:
+18
-45
@@ -13,62 +13,35 @@ import (
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type MediaFile struct {
|
||||
ID uint
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
Name string
|
||||
CategoryID int
|
||||
URL, Tag, Key string
|
||||
Size int64
|
||||
Mime, MD5 string
|
||||
UserID uint
|
||||
}
|
||||
type AttachmentCategory struct {
|
||||
ID uint
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
Name string
|
||||
ParentID uint
|
||||
Children []*AttachmentCategory
|
||||
}
|
||||
type MediaMetadataRepo interface {
|
||||
CreateMedia(context.Context, *MediaFile) error
|
||||
FindMedia(context.Context, uint) (*MediaFile, error)
|
||||
FindMediaByHash(context.Context, uint, string) (*MediaFile, error)
|
||||
ListMedia(context.Context, int, int, string, int, string, uint) ([]*MediaFile, int64, error)
|
||||
UpdateMediaName(context.Context, uint, string) error
|
||||
DeleteMedia(context.Context, uint) error
|
||||
MediaKeyReferences(context.Context, string) (int64, error)
|
||||
CreateMediaBatch(context.Context, []*MediaFile) error
|
||||
SaveCategory(context.Context, *AttachmentCategory) error
|
||||
DeleteCategory(context.Context, uint) error
|
||||
ListCategories(context.Context) ([]*AttachmentCategory, error)
|
||||
}
|
||||
|
||||
type MediaRepo interface {
|
||||
MediaMetadataRepo
|
||||
UploadRepo
|
||||
}
|
||||
|
||||
type MediaUsecase struct {
|
||||
repo MediaRepo
|
||||
MediaRepo
|
||||
files FileStorage
|
||||
}
|
||||
|
||||
func NewMediaUsecase(repo MediaRepo, files FileStorage) *MediaUsecase {
|
||||
return &MediaUsecase{repo: repo, files: files}
|
||||
return &MediaUsecase{MediaRepo: repo, files: files}
|
||||
}
|
||||
func (uc *MediaUsecase) Repo() MediaRepo { return uc.repo }
|
||||
|
||||
var blockedExtensions = map[string]bool{".exe": true, ".dll": true, ".bat": true, ".cmd": true, ".sh": true, ".php": true, ".jsp": true, ".asp": true, ".aspx": true, ".html": true, ".htm": true, ".svg": true}
|
||||
var allowedMediaExtensions = map[string]bool{
|
||||
".jpg": true, ".jpeg": true, ".png": true, ".gif": true, ".webp": true, ".bmp": true, ".ico": true, ".avif": true,
|
||||
".mp3": true, ".wav": true, ".ogg": true, ".m4a": true, ".flac": true, ".aac": true,
|
||||
".mp4": true, ".webm": true, ".mov": true, ".avi": true, ".mkv": true,
|
||||
".txt": true, ".md": true, ".csv": true, ".json": true, ".log": true, ".pdf": true,
|
||||
".doc": true, ".docx": true, ".xls": true, ".xlsx": true, ".ppt": true, ".pptx": true,
|
||||
".zip": true, ".rar": true, ".7z": true, ".tar": true, ".gz": true, ".tgz": true, ".bin": true,
|
||||
}
|
||||
|
||||
func validateMediaName(name string) error {
|
||||
if name == "" || filepath.Base(name) != name {
|
||||
return errors.New("文件名不合法")
|
||||
if name == "" || strings.TrimSpace(name) != name || strings.ContainsAny(name, `/\`) {
|
||||
return errors.New("file extension is not allowed")
|
||||
}
|
||||
if blockedExtensions[strings.ToLower(filepath.Ext(name))] {
|
||||
return errors.New("文件类型不允许上传")
|
||||
if !allowedMediaExtensions[strings.ToLower(filepath.Ext(name))] {
|
||||
return errors.New("file extension is not allowed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -85,7 +58,7 @@ func (uc *MediaUsecase) Upload(ctx context.Context, userID uint, name, mime stri
|
||||
}
|
||||
media := &MediaFile{Name: name, CategoryID: categoryID, URL: stored.URL, Tag: strings.TrimPrefix(ext, "."), Key: key, Size: stored.Size, Mime: mime, MD5: hex.EncodeToString(hash.Sum(nil)), UserID: userID}
|
||||
if save {
|
||||
if err = uc.repo.CreateMedia(ctx, media); err != nil {
|
||||
if err = uc.CreateMedia(ctx, media); err != nil {
|
||||
_ = uc.files.Delete(ctx, key)
|
||||
return nil, err
|
||||
}
|
||||
@@ -93,11 +66,11 @@ func (uc *MediaUsecase) Upload(ctx context.Context, userID uint, name, mime stri
|
||||
return media, nil
|
||||
}
|
||||
func (uc *MediaUsecase) Delete(ctx context.Context, id uint) error {
|
||||
media, err := uc.repo.FindMedia(ctx, id)
|
||||
media, err := uc.FindMedia(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
count, err := uc.repo.MediaKeyReferences(ctx, media.Key)
|
||||
count, err := uc.MediaKeyReferences(ctx, media.Key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -106,7 +79,7 @@ func (uc *MediaUsecase) Delete(ctx context.Context, id uint) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return uc.repo.DeleteMedia(ctx, id)
|
||||
return uc.DeleteMedia(ctx, id)
|
||||
}
|
||||
func (uc *MediaUsecase) ListStorage(ctx context.Context, prefix, cursor string, limit int) ([]*StoredFile, string, bool, error) {
|
||||
return uc.files.List(ctx, prefix, cursor, limit)
|
||||
|
||||
Reference in New Issue
Block a user