From 052ee8910dccbba1325a1f694793b75eb1e3d0b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Duffeck?= Date: Thu, 5 Feb 2026 11:43:21 +0100 Subject: [PATCH] Bump reva --- go.mod | 2 +- go.sum | 4 +- .../internal/grpc/interceptors/auth/scope.go | 132 ++++++------------ .../pkg/storage/pkg/decomposedfs/node/node.go | 11 ++ vendor/modules.txt | 2 +- 5 files changed, 54 insertions(+), 97 deletions(-) diff --git a/go.mod b/go.mod index 362755a51..2f5910895 100644 --- a/go.mod +++ b/go.mod @@ -64,7 +64,7 @@ require ( github.com/open-policy-agent/opa v1.10.1 github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20250724122329-41ba6b191e76 - github.com/opencloud-eu/reva/v2 v2.40.1 + github.com/opencloud-eu/reva/v2 v2.40.2 github.com/opensearch-project/opensearch-go/v4 v4.5.0 github.com/orcaman/concurrent-map v1.0.0 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index c2cf34190..ca9ae61be 100644 --- a/go.sum +++ b/go.sum @@ -963,8 +963,8 @@ github.com/opencloud-eu/inotifywaitgo v0.0.0-20251111171128-a390bae3c5e9 h1:dIft github.com/opencloud-eu/inotifywaitgo v0.0.0-20251111171128-a390bae3c5e9/go.mod h1:JWyDC6H+5oZRdUJUgKuaye+8Ph5hEs6HVzVoPKzWSGI= github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20250724122329-41ba6b191e76 h1:vD/EdfDUrv4omSFjrinT8Mvf+8D7f9g4vgQ2oiDrVUI= github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20250724122329-41ba6b191e76/go.mod h1:pzatilMEHZFT3qV7C/X3MqOa3NlRQuYhlRhZTL+hN6Q= -github.com/opencloud-eu/reva/v2 v2.40.1 h1:QwMkbGMhwDSwfk2WxbnTpIig2BugPBaVFjWcy2DSU3U= -github.com/opencloud-eu/reva/v2 v2.40.1/go.mod h1:DGH08n2mvtsQLkt8o15FV6m51FwSJJGhjR8Ty+iIJww= +github.com/opencloud-eu/reva/v2 v2.40.2 h1:rsgOkwA6MwReuwu7RvhWh675PJEQhLWrTOew5OSpR/E= +github.com/opencloud-eu/reva/v2 v2.40.2/go.mod h1:DGH08n2mvtsQLkt8o15FV6m51FwSJJGhjR8Ty+iIJww= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/interceptors/auth/scope.go b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/interceptors/auth/scope.go index 561c366ce..7c0987094 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/interceptors/auth/scope.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/interceptors/auth/scope.go @@ -130,8 +130,13 @@ func expandAndVerifyScope(ctx context.Context, req interface{}, tokenScope map[s } func resolveLightweightScope(ctx context.Context, ref *provider.Reference, scope *authpb.Scope, user *userpb.User, client gateway.GatewayAPIClient, mgr token.Manager) error { + refString, err := storagespace.FormatReference(ref) + if err != nil { + // cannot format reference, so cannot be valid + return errtypes.PermissionDenied("invalid reference") + } // Check if this ref is cached - key := "lw:" + user.Id.OpaqueId + scopeDelimiter + getRefKey(ref) + key := "lw:" + user.Id.OpaqueId + scopeDelimiter + refString if _, err := scopeExpansionCache.Get(key); err == nil { return nil } @@ -164,13 +169,7 @@ func resolvePublicShare(ctx context.Context, ref *provider.Reference, scope *aut return err } - if err := checkCacheForNestedResource(ctx, ref, share.ResourceId, client, mgr); err == nil { - return nil - } - - // Some services like wopi don't access the shared resource relative to the - // share root but instead relative to the shared resources parent. - return checkRelativeReference(ctx, ref, share.ResourceId, client) + return checkCacheForNestedResource(ctx, ref, share.ResourceId, client, mgr) } func resolveOCMShare(ctx context.Context, ref *provider.Reference, scope *authpb.Scope, client gateway.GatewayAPIClient, mgr token.Manager) error { @@ -184,54 +183,7 @@ func resolveOCMShare(ctx context.Context, ref *provider.Reference, scope *authpb ref.ResourceId = share.GetResourceId() } - if err := checkCacheForNestedResource(ctx, ref, share.ResourceId, client, mgr); err == nil { - return nil - } - - // Some services like wopi don't access the shared resource relative to the - // share root but instead relative to the shared resources parent. - return checkRelativeReference(ctx, ref, share.ResourceId, client) -} - -// checkRelativeReference checks if the shared resource is being accessed via a relative reference -// e.g.: -// storage: abcd, space: efgh -// /root (id: efgh) -// - New file.txt (id: ijkl) <- shared resource -// -// If the requested reference looks like this: -// Reference{ResourceId: {StorageId: "abcd", SpaceId: "efgh"}, Path: "./New file.txt"} -// then the request is considered relative and this function would return true. -// Only references which are relative to the immediate parent of a resource are considered valid. -func checkRelativeReference(ctx context.Context, requested *provider.Reference, sharedResourceID *provider.ResourceId, client gateway.GatewayAPIClient) error { - sRes, err := client.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{ResourceId: sharedResourceID}}) - if err != nil { - return err - } - if sRes.Status.Code != rpc.Code_CODE_OK { - return statuspkg.NewErrorFromCode(sRes.Status.Code, "auth interceptor") - } - - sharedResource := sRes.Info - - // Is this a shared space - if sharedResource.ParentId == nil { - // Is the requested resource part of the shared space? - if requested.ResourceId.StorageId != sharedResource.Id.StorageId || requested.ResourceId.SpaceId != sharedResource.Id.SpaceId { - return errtypes.PermissionDenied("space access forbidden via public link") - } - } else { - parentID := sharedResource.ParentId - parentID.StorageId = sharedResource.Id.StorageId - - if !utils.ResourceIDEqual(parentID, requested.ResourceId) && utils.MakeRelativePath(sharedResource.Path) != requested.Path { - return errtypes.PermissionDenied("access forbidden via public link") - } - } - - key := storagespace.FormatResourceID(sharedResourceID) + scopeDelimiter + getRefKey(requested) - _ = scopeExpansionCache.SetWithExpire(key, nil, scopeCacheExpiration*time.Second) - return nil + return checkCacheForNestedResource(ctx, ref, share.ResourceId, client, mgr) } func resolveUserShare(ctx context.Context, ref *provider.Reference, scope *authpb.Scope, client gateway.GatewayAPIClient, mgr token.Manager) error { @@ -245,8 +197,14 @@ func resolveUserShare(ctx context.Context, ref *provider.Reference, scope *authp } func checkCacheForNestedResource(ctx context.Context, ref *provider.Reference, resource *provider.ResourceId, client gateway.GatewayAPIClient, mgr token.Manager) error { + refString, err := storagespace.FormatReference(ref) + if err != nil { + // cannot format reference, so cannot be valid + return errtypes.PermissionDenied("invalid reference") + } + // Check if this ref is cached - key := storagespace.FormatResourceID(resource) + scopeDelimiter + getRefKey(ref) + key := storagespace.FormatResourceID(resource) + scopeDelimiter + refString if _, err := scopeExpansionCache.Get(key); err == nil { return nil } @@ -270,40 +228,25 @@ func checkIfNestedResource(ctx context.Context, ref *provider.Reference, parent return false, statuspkg.NewErrorFromCode(statResponse.Status.Code, "auth interceptor") } - pathResp, err := client.GetPath(ctx, &provider.GetPathRequest{ResourceId: statResponse.GetInfo().GetId()}) - if err != nil { - return false, err - } - if pathResp.Status.Code != rpc.Code_CODE_OK { - return false, statuspkg.NewErrorFromCode(pathResp.Status.Code, "auth interceptor") - } - parentPath := pathResp.Path + parentInfo := statResponse.GetInfo() - childPath := ref.GetPath() - if childPath != "" && childPath != "." && strings.HasPrefix(childPath, parentPath) { - // if the request is relative from the root, we can return directly - return true, nil - } - - // The request is not relative to the root. We need to find out if the requested resource is child of the `parent` (coming from token scope) + // We need to find out if the requested resource is child of the `parent` (coming from token scope) // We mint a token as the owner of the public share and try to stat the reference // TODO(ishank011): We need to find a better alternative to this // NOTE: did somebody say service accounts? ... - var user *userpb.User - if statResponse.GetInfo().GetOwner().GetType() == userpb.UserType_USER_TYPE_SPACE_OWNER { + if parentInfo.GetOwner().GetType() == userpb.UserType_USER_TYPE_SPACE_OWNER { // fake a space owner user user = &userpb.User{ - Id: statResponse.GetInfo().GetOwner(), + Id: parentInfo.GetOwner(), } } else { - userResp, err := client.GetUser(ctx, &userpb.GetUserRequest{UserId: statResponse.Info.Owner, SkipFetchingUserGroups: true}) + userResp, err := client.GetUser(ctx, &userpb.GetUserRequest{UserId: parentInfo.GetOwner(), SkipFetchingUserGroups: true}) if err != nil || userResp.Status.Code != rpc.Code_CODE_OK { return false, err } user = userResp.User } - scope, err := scope.AddOwnerScope(map[string]*authpb.Scope{}) if err != nil { return false, err @@ -329,6 +272,24 @@ func checkIfNestedResource(ctx context.Context, ref *provider.Reference, parent if childStat.GetStatus().GetCode() != rpc.Code_CODE_OK { return false, statuspkg.NewErrorFromCode(childStat.Status.Code, "auth interceptor") } + childInfo := childStat.GetInfo() + + // child can only be a nested resource if it is within the same space as parent + if childInfo.GetId().GetStorageId() != parentInfo.GetId().GetStorageId() || + childInfo.GetId().GetSpaceId() != parentInfo.GetId().GetSpaceId() { + return false, nil + } + + // Both resources are in the same space, now check paths + pathResp, err := client.GetPath(ctx, &provider.GetPathRequest{ResourceId: statResponse.GetInfo().GetId()}) + if err != nil { + return false, err + } + if pathResp.Status.Code != rpc.Code_CODE_OK { + return false, statuspkg.NewErrorFromCode(pathResp.Status.Code, "auth interceptor") + } + parentPath := pathResp.Path + pathResp, err = client.GetPath(ctx, &provider.GetPathRequest{ResourceId: childStat.GetInfo().GetId()}) if err != nil { return false, err @@ -336,10 +297,9 @@ func checkIfNestedResource(ctx context.Context, ref *provider.Reference, parent if pathResp.GetStatus().GetCode() != rpc.Code_CODE_OK { return false, statuspkg.NewErrorFromCode(pathResp.Status.Code, "auth interceptor") } - childPath = pathResp.Path + childPath := pathResp.Path return strings.HasPrefix(childPath, parentPath), nil - } func extractRefFromListProvidersReq(v *registry.ListStorageProvidersRequest) (*provider.Reference, bool) { @@ -513,17 +473,3 @@ func extractShareRef(req interface{}) (*collaboration.ShareReference, bool) { } return nil, false } - -func getRefKey(ref *provider.Reference) string { - if ref.GetPath() != "" { - return ref.Path - } - - if ref.GetResourceId() != nil { - return storagespace.FormatResourceID(ref.ResourceId) - } - - // on malicious request both path and rid could be empty - // we still should not panic - return "" -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/node.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/node.go index fd5735c38..e468bb9df 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/node.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/node.go @@ -591,6 +591,17 @@ func (n *Node) readOwner(ctx context.Context) (*userpb.UserId, error) { return nil, err } + // lookup Tenant in extended attributes + attr, err = n.SpaceRoot.XattrString(ctx, prefixes.SpaceTenantIDAttr) + switch { + case err == nil: + owner.TenantId = attr + case metadata.IsAttrUnset(err): + // ignore + default: + return nil, err + } + // lookup type in extended attributes attr, err = n.SpaceRoot.XattrString(ctx, prefixes.OwnerTypeAttr) switch { diff --git a/vendor/modules.txt b/vendor/modules.txt index e76ede160..cd619e896 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1370,7 +1370,7 @@ github.com/opencloud-eu/icap-client # github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20250724122329-41ba6b191e76 ## explicit; go 1.18 github.com/opencloud-eu/libre-graph-api-go -# github.com/opencloud-eu/reva/v2 v2.40.1 +# github.com/opencloud-eu/reva/v2 v2.40.2 ## explicit; go 1.24.1 github.com/opencloud-eu/reva/v2/cmd/revad/internal/grace github.com/opencloud-eu/reva/v2/cmd/revad/runtime