fix(remote download): improve file pre-upload validation (fix #2286)

This commit is contained in:
Aaron Liu
2025-04-24 15:26:58 +08:00
parent 224ac28ffe
commit 969e35192a
4 changed files with 76 additions and 26 deletions

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"math"
"path"
"time"
"github.com/cloudreve/Cloudreve/v4/ent"
@@ -15,6 +16,59 @@ import (
"github.com/cloudreve/Cloudreve/v4/pkg/util"
)
func (f *DBFS) PreValidateUpload(ctx context.Context, dst *fs.URI, files ...fs.PreValidateFile) error {
// Get navigator
navigator, err := f.getNavigator(ctx, dst, NavigatorCapabilityUploadFile, NavigatorCapabilityLockFile)
if err != nil {
return err
}
dstFile, err := f.getFileByPath(ctx, navigator, dst)
if err != nil {
return fmt.Errorf("failed to get destination folder: %w", err)
}
if dstFile.Type() != types.FileTypeFolder {
return fmt.Errorf("destination is not a folder")
}
// check permission
if err := f.EvaluatePermission(ctx, dstFile, types.FilePermissionCreate, false); err != nil {
return fmt.Errorf("failed to evaluate permission: %w", err)
}
total := int64(0)
for _, file := range files {
total += file.Size
}
// Get parent folder storage policy and performs validation
policy, err := f.getPreferredPolicy(ctx, dstFile, 0)
if err != nil {
return err
}
// validate upload request
for _, file := range files {
if file.OmitName {
if err := validateFileSize(file.Size, policy); err != nil {
return err
}
} else {
if err := validateNewFile(path.Base(file.Name), file.Size, policy); err != nil {
return err
}
}
}
// Validate available capacity
if err := f.validateUserCapacity(ctx, total, dstFile.Owner()); err != nil {
return err
}
return nil
}
func (f *DBFS) PrepareUpload(ctx context.Context, req *fs.UploadRequest, opts ...fs.Option) (*fs.UploadSession, error) {
// Get navigator
navigator, err := f.getNavigator(ctx, req.Props.Uri, NavigatorCapabilityUploadFile, NavigatorCapabilityLockFile)

View File

@@ -103,6 +103,8 @@ type (
CompleteUpload(ctx context.Context, session *UploadSession) (File, error)
// CancelUploadSession cancels an upload session. Delete the placeholder file if no other entity is created.
CancelUploadSession(ctx context.Context, path *URI, sessionID string, session *UploadSession) ([]Entity, error)
// PreValidateUpload pre-validates an upload request.
PreValidateUpload(ctx context.Context, dst *URI, files ...PreValidateFile) error
}
LockSystem interface {
@@ -369,6 +371,12 @@ type (
ParentFiles []int `json:"parent_files"`
PrimaryEntityParentFiles []int `json:"primary_entity_parent_files"`
}
PreValidateFile struct {
Name string
Size int64
OmitName bool // if true, file name will not be validated
}
)
const (