bump reva to 22b1ead80cdd

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
This commit is contained in:
Jörn Friedrich Dreyer
2025-03-04 18:26:29 +01:00
parent 69a2086d5b
commit 23bcc87f35
10 changed files with 225 additions and 106 deletions

2
go.mod
View File

@@ -65,7 +65,7 @@ require (
github.com/onsi/ginkgo/v2 v2.22.2
github.com/onsi/gomega v1.36.2
github.com/open-policy-agent/opa v1.1.0
github.com/opencloud-eu/reva/v2 v2.27.3-0.20250228155248-34dee069adce
github.com/opencloud-eu/reva/v2 v2.27.3-0.20250304172421-22b1ead80cdd
github.com/orcaman/concurrent-map v1.0.0
github.com/owncloud/libre-graph-api-go v1.0.5-0.20240829135935-80dc00d6f5ea
github.com/pkg/errors v0.9.1

4
go.sum
View File

@@ -863,8 +863,8 @@ github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
github.com/open-policy-agent/opa v1.1.0 h1:HMz2evdEMTyNqtdLjmu3Vyx06BmhNYAx67Yz3Ll9q2s=
github.com/open-policy-agent/opa v1.1.0/go.mod h1:T1pASQ1/vwfTa+e2fYcfpLCvWgYtqtiUv+IuA/dLPQs=
github.com/opencloud-eu/reva/v2 v2.27.3-0.20250228155248-34dee069adce h1:Ovd0LG1qpsPUXLqE/XY03qfymsqe5OpWlHU3QCSMmTY=
github.com/opencloud-eu/reva/v2 v2.27.3-0.20250228155248-34dee069adce/go.mod h1:Zi6h/WupAKzY/umvteGJCY3q4GOvTyrlm4JZfiuHeds=
github.com/opencloud-eu/reva/v2 v2.27.3-0.20250304172421-22b1ead80cdd h1:n4w8SHHuk74HOHy7ZEsL6zw2N/SEarqr482jAh5C/p4=
github.com/opencloud-eu/reva/v2 v2.27.3-0.20250304172421-22b1ead80cdd/go.mod h1:Zi6h/WupAKzY/umvteGJCY3q4GOvTyrlm4JZfiuHeds=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=

View File

@@ -94,7 +94,13 @@ func New(m map[string]interface{}, stream events.Stream, log *zerolog.Logger) (s
return nil, fmt.Errorf("unknown metadata backend %s, only 'xattrs' or 'hybrid' (default) supported", o.MetadataBackend)
}
trashbin, err := trashbin.New(o, lu, log)
permissionsSelector, err := pool.PermissionsSelector(o.PermissionsSVC, pool.WithTLSMode(o.PermTLSMode))
if err != nil {
return nil, err
}
p := permissions.NewPermissions(node.NewPermissions(lu), permissionsSelector)
trashbin, err := trashbin.New(o, p, lu, log)
if err != nil {
return nil, err
}
@@ -113,12 +119,6 @@ func New(m map[string]interface{}, stream events.Stream, log *zerolog.Logger) (s
return nil, fmt.Errorf("the posix driver requires a shared id cache, e.g. nats-js-kv or redis")
}
permissionsSelector, err := pool.PermissionsSelector(o.PermissionsSVC, pool.WithTLSMode(o.PermTLSMode))
if err != nil {
return nil, err
}
p := permissions.NewPermissions(node.NewPermissions(lu), permissionsSelector)
tp, err := tree.New(lu, bs, um, trashbin, p, o, stream, store.Create(
store.Store(o.IDCache.Store),
store.TTL(o.IDCache.TTL),

View File

@@ -28,6 +28,8 @@ import (
"github.com/google/uuid"
"github.com/rs/zerolog"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/trace"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
@@ -39,9 +41,18 @@ import (
"github.com/opencloud-eu/reva/v2/pkg/utils"
)
var (
tracer trace.Tracer
)
func init() {
tracer = otel.Tracer("github.com/cs3org/reva/pkg/storage/fs/posix/trashbin")
}
type Trashbin struct {
fs storage.FS
o *options.Options
p Permissions
lu *lookup.Lookup
log *zerolog.Logger
}
@@ -70,10 +81,15 @@ const (
timeFormat = "2006-01-02T15:04:05"
)
type Permissions interface {
AssembleTrashPermissions(ctx context.Context, n *node.Node) (*provider.ResourcePermissions, error)
}
// New returns a new Trashbin
func New(o *options.Options, lu *lookup.Lookup, log *zerolog.Logger) (*Trashbin, error) {
func New(o *options.Options, p Permissions, lu *lookup.Lookup, log *zerolog.Logger) (*Trashbin, error) {
return &Trashbin{
o: o,
p: p,
lu: lu,
log: log,
}, nil
@@ -163,13 +179,11 @@ func (tb *Trashbin) MoveToTrash(ctx context.Context, n *node.Node, path string)
// ListRecycle returns the list of available recycle items
// ref -> the space (= resourceid), key -> deleted node id, relativePath = relative to key
func (tb *Trashbin) ListRecycle(ctx context.Context, ref *provider.Reference, key, relativePath string) ([]*provider.RecycleItem, error) {
n, err := tb.lu.NodeFromResource(ctx, ref)
if err != nil {
return nil, err
}
func (tb *Trashbin) ListRecycle(ctx context.Context, spaceID string, key, relativePath string) ([]*provider.RecycleItem, error) {
_, span := tracer.Start(ctx, "ListRecycle")
defer span.End()
trashRoot := trashRootForNode(n)
trashRoot := filepath.Join(tb.lu.InternalPath(spaceID, spaceID), ".Trash")
base := filepath.Join(trashRoot, "files")
var originalPath string
@@ -177,11 +191,12 @@ func (tb *Trashbin) ListRecycle(ctx context.Context, ref *provider.Reference, ke
if key != "" {
// this is listing a specific item/folder
base = filepath.Join(base, key+".trashitem", relativePath)
var err error
originalPath, ts, err = tb.readInfoFile(trashRoot, key)
originalPath = filepath.Join(originalPath, relativePath)
if err != nil {
return nil, err
}
originalPath = filepath.Join(originalPath, relativePath)
}
items := []*provider.RecycleItem{}
@@ -224,8 +239,8 @@ func (tb *Trashbin) ListRecycle(ctx context.Context, ref *provider.Reference, ke
Size: uint64(fi.Size()),
Ref: &provider.Reference{
ResourceId: &provider.ResourceId{
SpaceId: ref.GetResourceId().GetSpaceId(),
OpaqueId: ref.GetResourceId().GetSpaceId(),
SpaceId: spaceID,
OpaqueId: spaceID,
},
Path: entryOriginalPath,
},
@@ -244,22 +259,22 @@ func (tb *Trashbin) ListRecycle(ctx context.Context, ref *provider.Reference, ke
}
// RestoreRecycleItem restores the specified item
func (tb *Trashbin) RestoreRecycleItem(ctx context.Context, ref *provider.Reference, key, relativePath string, restoreRef *provider.Reference) error {
n, err := tb.lu.NodeFromResource(ctx, ref)
if err != nil {
return err
}
func (tb *Trashbin) RestoreRecycleItem(ctx context.Context, spaceID string, key, relativePath string, restoreRef *provider.Reference) error {
_, span := tracer.Start(ctx, "RestoreRecycleItem")
defer span.End()
trashRoot := trashRootForNode(n)
trashRoot := filepath.Join(tb.lu.InternalPath(spaceID, spaceID), ".Trash")
trashPath := filepath.Clean(filepath.Join(trashRoot, "files", key+".trashitem", relativePath))
// TODO why can we not use NodeFromResource here? It will use walk path. Do trashed items have a problem with that?
restoreBaseNode, err := tb.lu.NodeFromID(ctx, restoreRef.GetResourceId())
if err != nil {
return err
}
restorePath := filepath.Join(restoreBaseNode.InternalPath(), restoreRef.GetPath())
// TODO the decomposed trash also checks the permissions on the restore node
spaceID, id, _, err := tb.lu.MetadataBackend().IdentifyPath(ctx, trashPath)
_, id, _, err := tb.lu.MetadataBackend().IdentifyPath(ctx, trashPath)
if err != nil {
return err
}
@@ -284,8 +299,8 @@ func (tb *Trashbin) RestoreRecycleItem(ctx context.Context, ref *provider.Refere
if err != nil {
return err
}
if err := tb.lu.CacheID(ctx, n.SpaceID, string(id), restorePath); err != nil {
tb.log.Error().Err(err).Str("spaceID", n.SpaceID).Str("id", string(id)).Str("path", restorePath).Msg("trashbin: error caching id")
if err := tb.lu.CacheID(ctx, spaceID, string(id), restorePath); err != nil {
tb.log.Error().Err(err).Str("spaceID", spaceID).Str("id", string(id)).Str("path", restorePath).Msg("trashbin: error caching id")
}
// cleanup trash info
@@ -297,14 +312,12 @@ func (tb *Trashbin) RestoreRecycleItem(ctx context.Context, ref *provider.Refere
}
// PurgeRecycleItem purges the specified item, all its children and all their revisions
func (tb *Trashbin) PurgeRecycleItem(ctx context.Context, ref *provider.Reference, key, relativePath string) error {
n, err := tb.lu.NodeFromResource(ctx, ref)
if err != nil {
return err
}
func (tb *Trashbin) PurgeRecycleItem(ctx context.Context, spaceID, key, relativePath string) error {
_, span := tracer.Start(ctx, "PurgeRecycleItem")
defer span.End()
trashRoot := trashRootForNode(n)
err = os.RemoveAll(filepath.Clean(filepath.Join(trashRoot, "files", key+".trashitem", relativePath)))
trashRoot := filepath.Join(tb.lu.InternalPath(spaceID, spaceID), ".Trash")
err := os.RemoveAll(filepath.Clean(filepath.Join(trashRoot, "files", key+".trashitem", relativePath)))
if err != nil {
return err
}
@@ -317,14 +330,12 @@ func (tb *Trashbin) PurgeRecycleItem(ctx context.Context, ref *provider.Referenc
}
// EmptyRecycle empties the trash
func (tb *Trashbin) EmptyRecycle(ctx context.Context, ref *provider.Reference) error {
n, err := tb.lu.NodeFromResource(ctx, ref)
if err != nil {
return err
}
func (tb *Trashbin) EmptyRecycle(ctx context.Context, spaceID string) error {
_, span := tracer.Start(ctx, "EmptyRecycle")
defer span.End()
trashRoot := trashRootForNode(n)
err = os.RemoveAll(filepath.Clean(filepath.Join(trashRoot, "files")))
trashRoot := filepath.Join(tb.lu.InternalPath(spaceID, spaceID), ".Trash")
err := os.RemoveAll(filepath.Clean(filepath.Join(trashRoot, "files")))
if err != nil {
return err
}

View File

@@ -701,12 +701,12 @@ func (t *Tree) WarmupIDCache(root string, assimilate, onlyDirty bool) error {
sizes := make(map[string]int64)
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
// skip lock and upload files
if t.isIndex(path) || isTrash(path) || t.isUpload(path) {
return filepath.SkipDir
}
if t.isInternal(path) || isLockFile(path) {
return nil
}
if isTrash(path) || t.isUpload(path) {
return filepath.SkipDir
}
if err != nil {
return err
@@ -838,6 +838,9 @@ func (t *Tree) setDirty(path string, dirty bool) error {
func (t *Tree) isDirty(path string) (bool, error) {
dirtyAttr, err := xattr.Get(path, dirtyFlag)
if err != nil {
if metadata.IsAttrUnset(err) {
return true, nil
}
return false, err
}
return string(dirtyAttr) == "true", nil

View File

@@ -662,8 +662,14 @@ func (t *Tree) isUpload(path string) bool {
return strings.HasPrefix(path, t.options.UploadDirectory)
}
func (t *Tree) isIndex(path string) bool {
return strings.HasPrefix(path, filepath.Join(t.options.Root, "indexes"))
}
func (t *Tree) isInternal(path string) bool {
return path == t.options.Root || strings.HasPrefix(path, filepath.Join(t.options.Root, "indexes")) || strings.Contains(path, lookup.RevisionsDir)
return path == t.options.Root ||
path == filepath.Join(t.options.Root, "users") ||
t.isIndex(path) || strings.Contains(path, lookup.RevisionsDir)
}
func isLockFile(path string) bool {

View File

@@ -86,7 +86,7 @@ var (
)
func init() {
tracer = otel.Tracer("github.com/cs3org/reva/pkg/storage/utils/decomposedfs")
tracer = otel.Tracer("github.com/cs3org/reva/pkg/storage/pkg/decomposedfs")
}
// Session is the interface that DecomposedfsSession implements. By combining tus.Upload,
@@ -1222,17 +1222,145 @@ func (fs *Decomposedfs) Unlock(ctx context.Context, ref *provider.Reference, loc
return node.Unlock(ctx, lock)
}
func (fs *Decomposedfs) ListRecycle(ctx context.Context, ref *provider.Reference, key, relativePath string) ([]*provider.RecycleItem, error) {
return fs.trashbin.ListRecycle(ctx, ref, key, relativePath)
func (fs *Decomposedfs) ListRecycle(ctx context.Context, space *provider.Reference, key, relativePath string) ([]*provider.RecycleItem, error) {
_, span := tracer.Start(ctx, "ListRecycle")
defer span.End()
spaceID := space.GetResourceId().GetSpaceId()
if spaceID == "" {
return nil, errtypes.BadRequest("missing space reference, needs a space id")
}
if key == "" && relativePath != "" {
return nil, errtypes.BadRequest("key is required when navigating with a path")
}
// check permissions
trashnode, err := fs.lu.NodeFromSpaceID(ctx, spaceID)
if err != nil {
return nil, err
}
rp, err := fs.p.AssembleTrashPermissions(ctx, trashnode)
switch {
case err != nil:
return nil, err
case !rp.ListRecycle:
if rp.Stat {
return nil, errtypes.PermissionDenied(key)
}
return nil, errtypes.NotFound(key)
}
return fs.trashbin.ListRecycle(ctx, spaceID, key, relativePath)
}
func (fs *Decomposedfs) RestoreRecycleItem(ctx context.Context, ref *provider.Reference, key, relativePath string, restoreRef *provider.Reference) error {
return fs.trashbin.RestoreRecycleItem(ctx, ref, key, relativePath, restoreRef)
// RestoreRecycleItem restores a recycle item
// The ref is used to determine the space
// The key is used to determine the recycle item. It is the node id of the recycle item, returned by ListRecycle
// The relativePath is the path is the path relative to the recycle item in case a child should be restored
// The restoreRef is the reference where the item should be restored to
func (fs *Decomposedfs) RestoreRecycleItem(ctx context.Context, space *provider.Reference, key, relativePath string, restoreRef *provider.Reference) error {
_, span := tracer.Start(ctx, "RestoreRecycleItem")
defer span.End()
spaceID := space.GetResourceId().GetSpaceId()
if spaceID == "" {
return errtypes.BadRequest("missing space reference, needs a space id")
}
if key == "" && relativePath != "" {
return errtypes.BadRequest("key is required when navigating with a path")
}
trashItem := &provider.ResourceId{
SpaceId: spaceID,
OpaqueId: key,
}
restoreBaseNode, err := fs.lu.NodeFromID(ctx, trashItem)
if err != nil {
return err
}
// check permissions of deleted node
rp, err := fs.p.AssembleTrashPermissions(ctx, restoreBaseNode)
switch {
case err != nil:
return err
case !rp.RestoreRecycleItem:
if rp.Stat {
return errtypes.PermissionDenied(key)
}
return errtypes.NotFound(key)
}
return fs.trashbin.RestoreRecycleItem(ctx, spaceID, key, relativePath, restoreRef)
}
func (fs *Decomposedfs) PurgeRecycleItem(ctx context.Context, ref *provider.Reference, key, relativePath string) error {
return fs.trashbin.PurgeRecycleItem(ctx, ref, key, relativePath)
func (fs *Decomposedfs) PurgeRecycleItem(ctx context.Context, space *provider.Reference, key, relativePath string) error {
_, span := tracer.Start(ctx, "PurgeRecycleItem")
defer span.End()
spaceID := space.GetResourceId().GetSpaceId()
if spaceID == "" {
return errtypes.BadRequest("missing space reference, needs a space id")
}
if key == "" && relativePath != "" {
return errtypes.BadRequest("key is required when navigating with a path")
}
trashItem := &provider.ResourceId{
SpaceId: spaceID,
OpaqueId: key,
}
trashBaseNode, err := fs.lu.NodeFromID(ctx, trashItem)
if err != nil {
return err
}
// check permissions of deleted node
rp, err := fs.p.AssembleTrashPermissions(ctx, trashBaseNode)
switch {
case err != nil:
return err
case !rp.PurgeRecycle:
if rp.Stat {
return errtypes.PermissionDenied(key)
}
return errtypes.NotFound(key)
}
return fs.trashbin.PurgeRecycleItem(ctx, spaceID, key, relativePath)
}
func (fs *Decomposedfs) EmptyRecycle(ctx context.Context, ref *provider.Reference) error {
return fs.trashbin.EmptyRecycle(ctx, ref)
func (fs *Decomposedfs) EmptyRecycle(ctx context.Context, space *provider.Reference) error {
_, span := tracer.Start(ctx, "EmptyRecycle")
defer span.End()
spaceID := space.GetResourceId().GetSpaceId()
if spaceID == "" {
return errtypes.BadRequest("missing space reference, needs a space id")
}
trashItem := &provider.ResourceId{
SpaceId: spaceID,
OpaqueId: spaceID,
}
trashBaseNode, err := fs.lu.NodeFromID(ctx, trashItem)
if err != nil {
return err
}
// check permissions of space
rp, err := fs.p.AssembleTrashPermissions(ctx, trashBaseNode)
switch {
case err != nil:
return err
case !rp.ListRecycle && !rp.PurgeRecycle:
if rp.Stat {
return errtypes.PermissionDenied(spaceID)
}
return errtypes.NotFound(spaceID)
}
return fs.trashbin.EmptyRecycle(ctx, spaceID)
}
func (fs *Decomposedfs) getNodePath(ctx context.Context, n *node.Node, perms *provider.ResourcePermissions) (string, error) {

View File

@@ -64,35 +64,11 @@ func (tb *DecomposedfsTrashbin) Setup(fs storage.FS) error {
// ListRecycle returns the list of available recycle items
// ref -> the space (= resourceid), key -> deleted node id, relativePath = relative to key
func (tb *DecomposedfsTrashbin) ListRecycle(ctx context.Context, ref *provider.Reference, key, relativePath string) ([]*provider.RecycleItem, error) {
func (tb *DecomposedfsTrashbin) ListRecycle(ctx context.Context, spaceID string, key, relativePath string) ([]*provider.RecycleItem, error) {
_, span := tracer.Start(ctx, "ListRecycle")
defer span.End()
if ref == nil || ref.ResourceId == nil || ref.ResourceId.OpaqueId == "" {
return nil, errtypes.BadRequest("spaceid required")
}
if key == "" && relativePath != "" {
return nil, errtypes.BadRequest("key is required when navigating with a path")
}
spaceID := ref.ResourceId.OpaqueId
sublog := appctx.GetLogger(ctx).With().Str("spaceid", spaceID).Str("key", key).Str("relative_path", relativePath).Logger()
// check permissions
trashnode, err := tb.fs.lu.NodeFromSpaceID(ctx, spaceID)
if err != nil {
return nil, err
}
rp, err := tb.fs.p.AssembleTrashPermissions(ctx, trashnode)
switch {
case err != nil:
return nil, err
case !rp.ListRecycle:
if rp.Stat {
return nil, errtypes.PermissionDenied(key)
}
return nil, errtypes.NotFound(key)
}
if key == "" && relativePath == "" {
return tb.listTrashRoot(ctx, spaceID)
}
@@ -110,10 +86,10 @@ func (tb *DecomposedfsTrashbin) ListRecycle(ctx context.Context, ref *provider.R
origin := ""
raw, err := tb.fs.lu.MetadataBackend().All(ctx, originalNode)
attrs := node.Attributes(raw)
if err != nil {
return items, err
}
attrs := node.Attributes(raw)
// lookup origin path in extended attributes
origin = attrs.String(prefixes.TrashOriginAttr)
if origin == "" {
@@ -178,8 +154,8 @@ func (tb *DecomposedfsTrashbin) ListRecycle(ctx context.Context, ref *provider.R
for _, name := range names {
nodeID, err := node.ReadChildNodeFromLink(ctx, filepath.Join(childrenPath, name))
if err != nil {
sublog.Error().Err(err).Str("name", name).Msg("could not read child node")
provider.ResourceType_RESOURCE_TYPE_CONTAINER.Number()
sublog.Error().Err(err).Str("name", name).Msg("could not read child node, skipping")
continue
}
childNode := node.NewBaseNode(spaceID, nodeID, tb.fs.lu)
@@ -187,6 +163,10 @@ func (tb *DecomposedfsTrashbin) ListRecycle(ctx context.Context, ref *provider.R
size = 0
raw, err := tb.fs.lu.MetadataBackend().All(ctx, childNode)
if err != nil {
sublog.Error().Err(err).Str("name", name).Msg("could not read metadata, skipping")
continue
}
attrs := node.Attributes(raw)
typeInt, err := attrs.Int64(prefixes.TypeAttr)
if err != nil {
@@ -365,12 +345,9 @@ func (tb *DecomposedfsTrashbin) listTrashRoot(ctx context.Context, spaceID strin
}
// RestoreRecycleItem restores the specified item
func (tb *DecomposedfsTrashbin) RestoreRecycleItem(ctx context.Context, ref *provider.Reference, key, relativePath string, restoreRef *provider.Reference) error {
func (tb *DecomposedfsTrashbin) RestoreRecycleItem(ctx context.Context, spaceID string, key, relativePath string, restoreRef *provider.Reference) error {
_, span := tracer.Start(ctx, "RestoreRecycleItem")
defer span.End()
if ref == nil {
return errtypes.BadRequest("missing reference, needs a space id")
}
var targetNode *node.Node
if restoreRef != nil {
@@ -382,7 +359,7 @@ func (tb *DecomposedfsTrashbin) RestoreRecycleItem(ctx context.Context, ref *pro
targetNode = tn
}
rn, parent, restoreFunc, err := tb.fs.tp.(*tree.Tree).RestoreRecycleItemFunc(ctx, ref.ResourceId.SpaceId, key, relativePath, targetNode)
rn, parent, restoreFunc, err := tb.fs.tp.(*tree.Tree).RestoreRecycleItemFunc(ctx, spaceID, key, relativePath, targetNode)
if err != nil {
return err
}
@@ -420,14 +397,11 @@ func (tb *DecomposedfsTrashbin) RestoreRecycleItem(ctx context.Context, ref *pro
}
// PurgeRecycleItem purges the specified item, all its children and all their revisions
func (tb *DecomposedfsTrashbin) PurgeRecycleItem(ctx context.Context, ref *provider.Reference, key, relativePath string) error {
func (tb *DecomposedfsTrashbin) PurgeRecycleItem(ctx context.Context, spaceID, key, relativePath string) error {
_, span := tracer.Start(ctx, "PurgeRecycleItem")
defer span.End()
if ref == nil {
return errtypes.BadRequest("missing reference, needs a space id")
}
rn, purgeFunc, err := tb.fs.tp.(*tree.Tree).PurgeRecycleItemFunc(ctx, ref.ResourceId.OpaqueId, key, relativePath)
rn, purgeFunc, err := tb.fs.tp.(*tree.Tree).PurgeRecycleItemFunc(ctx, spaceID, key, relativePath)
if err != nil {
if errors.Is(err, iofs.ErrNotExist) {
return errtypes.NotFound(key)
@@ -452,26 +426,23 @@ func (tb *DecomposedfsTrashbin) PurgeRecycleItem(ctx context.Context, ref *provi
}
// EmptyRecycle empties the trash
func (tb *DecomposedfsTrashbin) EmptyRecycle(ctx context.Context, ref *provider.Reference) error {
func (tb *DecomposedfsTrashbin) EmptyRecycle(ctx context.Context, spaceID string) error {
_, span := tracer.Start(ctx, "EmptyRecycle")
defer span.End()
if ref == nil || ref.ResourceId == nil || ref.ResourceId.OpaqueId == "" {
return errtypes.BadRequest("spaceid must be set")
}
items, err := tb.ListRecycle(ctx, ref, "", "")
items, err := tb.ListRecycle(ctx, spaceID, "", "")
if err != nil {
return err
}
for _, i := range items {
if err := tb.PurgeRecycleItem(ctx, ref, i.Key, ""); err != nil {
if err := tb.PurgeRecycleItem(ctx, spaceID, i.Key, ""); err != nil {
return err
}
}
// TODO what permission should we check? we could check the root node of the user? or the owner permissions on his home root node?
// The current impl will wipe your own trash. or when no user provided the trash of 'root'
return os.RemoveAll(tb.getRecycleRoot(ref.ResourceId.SpaceId))
return os.RemoveAll(tb.getRecycleRoot(spaceID))
}
func (tb *DecomposedfsTrashbin) getRecycleRoot(spaceID string) string {

View File

@@ -28,8 +28,8 @@ import (
type Trashbin interface {
Setup(storage.FS) error
ListRecycle(ctx context.Context, ref *provider.Reference, key, relativePath string) ([]*provider.RecycleItem, error)
RestoreRecycleItem(ctx context.Context, ref *provider.Reference, key, relativePath string, restoreRef *provider.Reference) error
PurgeRecycleItem(ctx context.Context, ref *provider.Reference, key, relativePath string) error
EmptyRecycle(ctx context.Context, ref *provider.Reference) error
ListRecycle(ctx context.Context, spaceID, key, relativePath string) ([]*provider.RecycleItem, error)
RestoreRecycleItem(ctx context.Context, spaceID, key, relativePath string, restoreRef *provider.Reference) error
PurgeRecycleItem(ctx context.Context, spaceID, key, relativePath string) error
EmptyRecycle(ctx context.Context, spaceID string) error
}

2
vendor/modules.txt vendored
View File

@@ -1194,7 +1194,7 @@ github.com/open-policy-agent/opa/v1/types
github.com/open-policy-agent/opa/v1/util
github.com/open-policy-agent/opa/v1/util/decoding
github.com/open-policy-agent/opa/v1/version
# github.com/opencloud-eu/reva/v2 v2.27.3-0.20250228155248-34dee069adce
# github.com/opencloud-eu/reva/v2 v2.27.3-0.20250304172421-22b1ead80cdd
## explicit; go 1.23.1
github.com/opencloud-eu/reva/v2/cmd/revad/internal/grace
github.com/opencloud-eu/reva/v2/cmd/revad/runtime