mirror of https://github.com/cloudreve/Cloudreve
fix(blob path): validate save path to ensure unique physical save path
parent
7d97237593
commit
1bb82af5ae
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/cloudreve/Cloudreve/v4/ent"
|
"github.com/cloudreve/Cloudreve/v4/ent"
|
||||||
|
@ -139,7 +140,27 @@ func (f *DBFS) PrepareUpload(ctx context.Context, req *fs.UploadRequest, opts ..
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate save path by storage policy
|
// Check and generate save path by storage policy
|
||||||
|
mustContain := []string{"{randomkey16}", "{randomkey8}", "{uuid}"}
|
||||||
|
hasRandomElement := false
|
||||||
|
for _, c := range mustContain {
|
||||||
|
if strings.Contains(policy.FileNameRule, c) {
|
||||||
|
hasRandomElement = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(policy.DirNameRule, c) {
|
||||||
|
hasRandomElement = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !hasRandomElement {
|
||||||
|
if policy.DirNameRule == "" {
|
||||||
|
policy.DirNameRule = "uploads/{uid}/{path}"
|
||||||
|
}
|
||||||
|
policy.FileNameRule = "{uid}_{randomkey8}_{originname}"
|
||||||
|
}
|
||||||
|
|
||||||
isThumbnailAndPolicyNotAvailable := policy.ID != ancestor.Model.StoragePolicyFiles &&
|
isThumbnailAndPolicyNotAvailable := policy.ID != ancestor.Model.StoragePolicyFiles &&
|
||||||
(req.Props.EntityType != nil && *req.Props.EntityType == types.EntityTypeThumbnail) &&
|
(req.Props.EntityType != nil && *req.Props.EntityType == types.EntityTypeThumbnail) &&
|
||||||
req.ImportFrom == nil
|
req.ImportFrom == nil
|
||||||
|
@ -147,9 +168,8 @@ func (f *DBFS) PrepareUpload(ctx context.Context, req *fs.UploadRequest, opts ..
|
||||||
req.Props.SavePath = generateSavePath(policy, req, f.user)
|
req.Props.SavePath = generateSavePath(policy, req, f.user)
|
||||||
if isThumbnailAndPolicyNotAvailable {
|
if isThumbnailAndPolicyNotAvailable {
|
||||||
req.Props.SavePath = fmt.Sprintf(
|
req.Props.SavePath = fmt.Sprintf(
|
||||||
"%s.%s%s",
|
"%s%s",
|
||||||
req.Props.SavePath,
|
req.Props.SavePath,
|
||||||
util.RandStringRunes(16),
|
|
||||||
f.settingClient.ThumbEntitySuffix(ctx))
|
f.settingClient.ThumbEntitySuffix(ctx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import (
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SingleFileService 对单文件进行操作的五福,path为文件完整路径
|
// SingleFileService 对单文件进行操作的服务,path为文件完整路径
|
||||||
type SingleFileService struct {
|
type SingleFileService struct {
|
||||||
Path string `uri:"path" json:"path" binding:"required,min=1,max=65535"`
|
Path string `uri:"path" json:"path" binding:"required,min=1,max=65535"`
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue