Merge pull request #2274 from aduffeck/bump-reva-v2.40.2

Bump reva
This commit is contained in:
Andre Duffeck
2026-02-05 12:53:12 +01:00
committed by GitHub
5 changed files with 54 additions and 97 deletions
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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=
@@ -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 ""
}
@@ -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 {
+1 -1
View File
@@ -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