Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions drivers/alias/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ func (d *Alias) Get(ctx context.Context, path string) (model.Obj, error) {
}
obj = &ret
if d.ProviderPassThrough && !obj.IsDir() {
if storage, err := fs.GetStorage(rawPath, &fs.GetStoragesArgs{}); err == nil {
if storage, err := fs.GetStorage(rawPath); err == nil {
obj = &model.ObjectProvider{
Object: ret,
Provider: model.Provider{
Expand Down Expand Up @@ -536,7 +536,7 @@ func (d *Alias) GetDetails(ctx context.Context) (*model.StorageDetails, error) {
backends := d.pathMap[d.rootOrder[0]]
var storage driver.Driver
for _, backend := range backends {
s, err := fs.GetStorage(backend, &fs.GetStoragesArgs{})
s, err := fs.GetStorage(backend)
if err != nil {
return nil, errs.NotImplement
}
Expand Down
12 changes: 6 additions & 6 deletions drivers/alias/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ func getRandomObjByQuotaBalanced(ctx context.Context, reqPath BalancedObjs, stri
detailsChan := make(chan detailWithIndex, len(reqPath))
workerCount := 0
for i, p := range reqPath {
s, err := fs.GetStorage(p.GetPath(), &fs.GetStoragesArgs{})
s, err := fs.GetStorage(p.GetPath())
if err != nil {
continue
}
Expand Down Expand Up @@ -347,7 +347,7 @@ func (d *Alias) getCopyObjs(ctx context.Context, srcObj, dstDir model.Obj) (Bala
dstStorageMap := make(map[string][]model.Obj)
allocatingDst := make(map[model.Obj]struct{})
for _, o := range dstObjs {
storage, e := fs.GetStorage(o.GetPath(), &fs.GetStoragesArgs{})
storage, e := fs.GetStorage(o.GetPath())
if e != nil {
return nil, nil, errors.WithMessagef(e, "cannot copy to virtual path [%s]", o.GetPath())
}
Expand All @@ -361,7 +361,7 @@ func (d *Alias) getCopyObjs(ctx context.Context, srcObj, dstDir model.Obj) (Bala
}
srcObjs := make(BalancedObjs, 0, len(dstObjs))
for _, src := range tmpSrcObjs {
storage, e := fs.GetStorage(src.GetPath(), &fs.GetStoragesArgs{})
storage, e := fs.GetStorage(src.GetPath())
if e != nil {
continue
}
Expand Down Expand Up @@ -405,7 +405,7 @@ func (d *Alias) getMoveObjs(ctx context.Context, srcObj, dstDir model.Obj) (Bala
dstStorageMap := make(map[string][]model.Obj)
allocatingDst := make(map[model.Obj]struct{})
for _, o := range dstObjs {
storage, e := fs.GetStorage(o.GetPath(), &fs.GetStoragesArgs{})
storage, e := fs.GetStorage(o.GetPath())
if e != nil {
return nil, nil, errors.WithMessagef(e, "cannot move to virtual path [%s]", o.GetPath())
}
Expand All @@ -416,7 +416,7 @@ func (d *Alias) getMoveObjs(ctx context.Context, srcObj, dstDir model.Obj) (Bala
srcObjs := make(BalancedObjs, 0, len(tmpSrcObjs))
restSrcObjs := make(BalancedObjs, 0, len(tmpSrcObjs)-len(dstObjs))
for _, src := range tmpSrcObjs {
storage, e := fs.GetStorage(src.GetPath(), &fs.GetStoragesArgs{})
storage, e := fs.GetStorage(src.GetPath())
if e != nil {
continue
}
Expand Down Expand Up @@ -499,7 +499,7 @@ func getAllSort(dirs []model.Obj) model.Sort {
if dir == nil {
continue
}
storage, err := fs.GetStorage(dir.GetPath(), &fs.GetStoragesArgs{})
storage, err := fs.GetStorage(dir.GetPath())
if err != nil {
continue
}
Expand Down
8 changes: 3 additions & 5 deletions drivers/chunk/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"strconv"
"strings"

"github.com/OpenListTeam/OpenList/v4/internal/conf"
"github.com/OpenListTeam/OpenList/v4/internal/driver"
"github.com/OpenListTeam/OpenList/v4/internal/errs"
"github.com/OpenListTeam/OpenList/v4/internal/fs"
Expand Down Expand Up @@ -472,10 +471,9 @@ func (d *Chunk) Put(ctx context.Context, dstDir model.Obj, file model.FileStream
UpdateProgress: up,
}
dst := stdpath.Join(remoteActualPath, dstDir.GetPath(), d.ChunkPrefix+file.GetName())
skipHookCtx := context.WithValue(ctx, conf.SkipHookKey, struct{}{})
if d.StoreHash {
for ht, value := range file.GetHash().All() {
_ = op.Put(skipHookCtx, remoteStorage, dst, &stream.FileStream{
_ = op.Put(ctx, remoteStorage, dst, &stream.FileStream{
Obj: &model.Object{
Name: fmt.Sprintf("hash_%s_%s%s", ht.Name, value, d.CustomExt),
Size: 1,
Expand All @@ -494,7 +492,7 @@ func (d *Chunk) Put(ctx context.Context, dstDir model.Obj, file model.FileStream
}
partIndex := 0
for partIndex < fullPartCount {
err = op.Put(skipHookCtx, remoteStorage, dst, &stream.FileStream{
err = op.Put(ctx, remoteStorage, dst, &stream.FileStream{
Obj: &model.Object{
Name: d.getPartName(partIndex),
Size: d.PartSize,
Expand Down Expand Up @@ -529,7 +527,7 @@ func (d *Chunk) getPartName(part int) string {
}

func (d *Chunk) GetDetails(ctx context.Context) (*model.StorageDetails, error) {
remoteStorage, err := fs.GetStorage(d.RemotePath, &fs.GetStoragesArgs{})
remoteStorage, err := fs.GetStorage(d.RemotePath)
if err != nil {
return nil, errs.NotImplement
}
Expand Down
54 changes: 35 additions & 19 deletions drivers/strm/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,45 @@ import (
stdpath "path"
"path/filepath"
"strings"
"sync"

"github.com/OpenListTeam/OpenList/v4/internal/model"
"github.com/OpenListTeam/OpenList/v4/internal/op"
"github.com/OpenListTeam/OpenList/v4/internal/stream"
"github.com/OpenListTeam/OpenList/v4/pkg/http_range"
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
log "github.com/sirupsen/logrus"
"github.com/tchap/go-patricia/v2/patricia"
)

var strmTrie = patricia.NewTrie()
var (
strmTrie = patricia.NewTrie()
strmTrieMu sync.RWMutex
)

func UpdateLocalStrm(ctx context.Context, path string, objs []model.Obj) {
path = utils.FixAndCleanPath(path)
type target struct {
driver *Strm
basePath string
}
var targets []target
strmTrieMu.RLock()
_ = strmTrie.VisitPrefixes(patricia.Prefix(path), func(needPathPrefix patricia.Prefix, item patricia.Item) error {
needPath := string(needPathPrefix)
restPath := strings.TrimPrefix(path, needPath)
if len(restPath) > 0 && restPath[0] != '/' {
return nil
}
for _, strmDriver := range item.([]*Strm) {
targets = append(targets, target{
driver: strmDriver,
basePath: stdpath.Join(stdpath.Base(needPath), restPath),
})
}
return nil
})
strmTrieMu.RUnlock()

updateLocal := func(driver *Strm, basePath string, objs []model.Obj) {
relParent := strings.TrimPrefix(basePath, utils.GetActualMountPath(driver.MountPath))
localParentPath := stdpath.Join(driver.SaveStrmLocalPath, relParent)
Expand All @@ -38,22 +63,15 @@ func UpdateLocalStrm(ctx context.Context, path string, objs []model.Obj) {
deleteExtraFiles(driver, localParentPath, objs)
}

_ = strmTrie.VisitPrefixes(patricia.Prefix(path), func(needPathPrefix patricia.Prefix, item patricia.Item) error {
strmDrivers := item.([]*Strm)
needPath := string(needPathPrefix)
restPath := strings.TrimPrefix(path, needPath)
if len(restPath) > 0 && restPath[0] != '/' {
return nil
}
for _, strmDriver := range strmDrivers {
strmObjs := strmDriver.convert2strmObjs(ctx, path, objs)
updateLocal(strmDriver, stdpath.Join(stdpath.Base(needPath), restPath), strmObjs)
}
return nil
})
for _, target := range targets {
strmObjs := target.driver.convert2strmObjs(ctx, path, objs)
updateLocal(target.driver, target.basePath, strmObjs)
}
}

func InsertStrm(dstPath string, d *Strm) error {
strmTrieMu.Lock()
defer strmTrieMu.Unlock()
prefix := patricia.Prefix(strings.TrimRight(dstPath, "/"))
existing := strmTrie.Get(prefix)

Expand All @@ -73,6 +91,8 @@ func InsertStrm(dstPath string, d *Strm) error {
}

func RemoveStrm(dstPath string, d *Strm) {
strmTrieMu.Lock()
defer strmTrieMu.Unlock()
prefix := patricia.Prefix(strings.TrimRight(dstPath, "/"))
existing := strmTrie.Get(prefix)
if existing == nil {
Expand Down Expand Up @@ -249,7 +269,3 @@ func getLocalDirsAndFiles(localPath string) ([]string, []string, error) {
}
return files, dirs, nil
}

func init() {
op.RegisterObjsUpdateHook(UpdateLocalStrm)
}
98 changes: 98 additions & 0 deletions internal/authz/policy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package authz

import (
"path"
"slices"
"strings"

"github.com/OpenListTeam/OpenList/v4/internal/model"
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
"github.com/dlclark/regexp2"
)

func CanRead(user *model.User, meta *model.Meta, reqPath string) bool {
if user == nil {
return true
}
return meta == nil || len(meta.ReadUsers) == 0 || slices.Contains(meta.ReadUsers, user.ID) ||
!MetaCoversPath(meta.Path, reqPath, meta.ReadUsersSub)
}

func CanWrite(user *model.User, meta *model.Meta, reqPath string) bool {
if user == nil {
return true
}
return meta == nil || len(meta.WriteUsers) == 0 || slices.Contains(meta.WriteUsers, user.ID) ||
!MetaCoversPath(meta.Path, reqPath, meta.WriteUsersSub)
}

func CanWriteContentBypassUserPerms(meta *model.Meta, reqPath string) bool {
if meta == nil || !meta.Write {
return false
}
return utils.PathEqual(meta.Path, reqPath) || meta.WSub && utils.IsSubPath(meta.Path, reqPath)
}

func IsHidden(user *model.User, meta *model.Meta, reqPath string) bool {
return matchesHidden(hidePatterns(user, meta, path.Dir(reqPath)), path.Base(reqPath))
}

func FilterHidden(user *model.User, meta *model.Meta, parentPath string, objs []model.Obj) []model.Obj {
patterns := hidePatterns(user, meta, parentPath)
if len(patterns) == 0 {
return objs
}
return slices.DeleteFunc(objs, func(obj model.Obj) bool {
return matchesHidden(patterns, obj.GetName())
})
}

func hidePatterns(user *model.User, meta *model.Meta, parentPath string) []*regexp2.Regexp {
if user == nil || user.CanSeeHides() || meta == nil || meta.Hide == "" ||
!MetaCoversPath(meta.Path, parentPath, meta.HSub) {
return nil
}
patterns := make([]*regexp2.Regexp, 0, strings.Count(meta.Hide, "\n")+1)
for hide := range strings.SplitSeq(meta.Hide, "\n") {
patterns = append(patterns, regexp2.MustCompile(hide, regexp2.None))
}
return patterns
}

func matchesHidden(patterns []*regexp2.Regexp, name string) bool {
for _, pattern := range patterns {
matched, _ := pattern.MatchString(name)
if matched {
return true
}
}
return false
}

func CanAccess(user *model.User, meta *model.Meta, reqPath, password string) bool {
if IsHidden(user, meta, reqPath) || !CanRead(user, meta, reqPath) {
return false
}
if user.CanAccessWithoutPassword() || meta == nil || meta.Password == "" {
return true
}
return !MetaCoversPath(meta.Path, reqPath, meta.PSub) || meta.Password == password
}

func MetaCoversPath(metaPath, reqPath string, applyToSubFolder bool) bool {
metaPath = utils.FixAndCleanPath(metaPath)
reqPath = utils.FixAndCleanPath(reqPath)
if strings.EqualFold(metaPath, reqPath) {
return true
}
if !applyToSubFolder {
return false
}
for reqPath != "/" {
reqPath = path.Dir(reqPath)
if strings.EqualFold(metaPath, reqPath) {
return true
}
}
return false
}
Loading
Loading