diff --git a/go.mod b/go.mod index ebb70b77b..5c4e5dba8 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index e6ebfc412..82f87d025 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/posix.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/posix.go index 35111482f..752156b90 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/posix.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/posix.go @@ -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), diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/trashbin/trashbin.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/trashbin/trashbin.go index 8dfa296a3..55d248612 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/trashbin/trashbin.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/trashbin/trashbin.go @@ -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 } diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/assimilation.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/assimilation.go index 42295ba1e..f1f5b1c9d 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/assimilation.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/assimilation.go @@ -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 diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/tree.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/tree.go index d2a4876b7..6308ff155 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/tree.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/tree.go @@ -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 { diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go index 38c6af186..45b2b452d 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go @@ -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) { diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/recycle.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/recycle.go index 8810a5208..ad9a9c774 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/recycle.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/recycle.go @@ -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 { diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/trashbin/trashbin.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/trashbin/trashbin.go index 3f17f0b6b..344dc07eb 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/trashbin/trashbin.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/trashbin/trashbin.go @@ -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 } diff --git a/vendor/modules.txt b/vendor/modules.txt index c76c39373..0248fe494 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -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