From d7b66876a8ff8d54c1210aed73c8ef521dc55274 Mon Sep 17 00:00:00 2001 From: Roman Perekhod Date: Wed, 28 Feb 2024 11:13:38 +0100 Subject: [PATCH] [full-ci] disallow to share the personal drive via graph --- changelog/unreleased/fix-graph-invite.md | 6 ++ go.mod | 2 +- go.sum | 4 +- .../internal/grpc/services/gateway/gateway.go | 17 ++-- .../grpc/services/gateway/ocmshareprovider.go | 14 ++- .../services/gateway/publicshareprovider.go | 34 +------- .../grpc/services/gateway/storageprovider.go | 17 ---- .../services/gateway/storageprovidercache.go | 85 +++++++------------ .../services/gateway/usershareprovider.go | 14 ++- .../cs3org/reva/v2/pkg/rhttp/datatx/datatx.go | 6 -- .../pkg/rhttp/datatx/manager/simple/simple.go | 3 - .../pkg/rhttp/datatx/manager/spaces/spaces.go | 3 - .../v2/pkg/rhttp/datatx/manager/tus/tus.go | 5 -- .../utils/decomposedfs/decomposedfs.go | 9 -- .../utils/decomposedfs/node/permissions.go | 1 + .../utils/decomposedfs/options/options.go | 5 +- .../storage/utils/decomposedfs/tree/tree.go | 1 + .../reva/v2/pkg/storage/utils/metadata/cs3.go | 44 +++++++--- .../v2/pkg/storage/utils/metadata/storage.go | 3 +- .../cs3org/reva/v2/pkg/utils/grpc.go | 15 +++- vendor/modules.txt | 2 +- 21 files changed, 108 insertions(+), 182 deletions(-) create mode 100644 changelog/unreleased/fix-graph-invite.md diff --git a/changelog/unreleased/fix-graph-invite.md b/changelog/unreleased/fix-graph-invite.md new file mode 100644 index 00000000000..faee6ec73dd --- /dev/null +++ b/changelog/unreleased/fix-graph-invite.md @@ -0,0 +1,6 @@ +Bugfix: Fix graph drive invite + +We fixed the issue when sharing of personal drive is allowed via graph + +https://github.com/owncloud/ocis/pull/8538 +https://github.com/owncloud/ocis/issues/8494 diff --git a/go.mod b/go.mod index 99c853045ab..3f3ba7815c9 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/cenkalti/backoff v2.2.1+incompatible github.com/coreos/go-oidc/v3 v3.9.0 github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781 - github.com/cs3org/reva/v2 v2.19.1 + github.com/cs3org/reva/v2 v2.19.2-0.20240307063856-698d86209c3d github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25 github.com/disintegration/imaging v1.6.2 github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e diff --git a/go.sum b/go.sum index b64aa5d11ac..b438d2f45c4 100644 --- a/go.sum +++ b/go.sum @@ -1019,8 +1019,8 @@ github.com/crewjam/saml v0.4.14 h1:g9FBNx62osKusnFzs3QTN5L9CVA/Egfgm+stJShzw/c= github.com/crewjam/saml v0.4.14/go.mod h1:UVSZCf18jJkk6GpWNVqcyQJMD5HsRugBPf4I1nl2mME= github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781 h1:BUdwkIlf8IS2FasrrPg8gGPHQPOrQ18MS1Oew2tmGtY= github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= -github.com/cs3org/reva/v2 v2.19.1 h1:XryNNOSw+ogmJGIf6UA44eB3NZCd/z7o5aoiRaTnLd0= -github.com/cs3org/reva/v2 v2.19.1/go.mod h1:GRUrOp5HbFVwZTgR9bVrMZ/MvVy+Jhxw1PdMmhhKP9E= +github.com/cs3org/reva/v2 v2.19.2-0.20240307063856-698d86209c3d h1:ru/ebNMHDU0SJ9CyzYY9uHMpFXGXT4cDaAh6zib4xPg= +github.com/cs3org/reva/v2 v2.19.2-0.20240307063856-698d86209c3d/go.mod h1:GRUrOp5HbFVwZTgR9bVrMZ/MvVy+Jhxw1PdMmhhKP9E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/gateway.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/gateway.go index b8e6533da96..c3a30e12ca5 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/gateway.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/gateway.go @@ -35,6 +35,11 @@ import ( "google.golang.org/grpc" ) +const ( + _spaceTypePersonal = "personal" + _spaceTypeProject = "project" +) + func init() { rgrpc.Register("gateway", New) } @@ -67,7 +72,6 @@ type config struct { DataTransfersFolder string `mapstructure:"data_transfers_folder"` TokenManagers map[string]map[string]interface{} `mapstructure:"token_managers"` AllowedUserAgents map[string][]string `mapstructure:"allowed_user_agents"` // map[path][]user-agent - StatCacheConfig cache.Config `mapstructure:"stat_cache_config"` CreatePersonalSpaceCacheConfig cache.Config `mapstructure:"create_personal_space_cache_config"` ProviderCacheConfig cache.Config `mapstructure:"provider_cache_config"` UseCommonSpaceRootShareLogic bool `mapstructure:"use_common_space_root_share_logic"` @@ -117,14 +121,6 @@ func (c *config) init() { } // caching needs to be explicitly enabled - if c.StatCacheConfig.Store == "" { - c.StatCacheConfig.Store = "noop" - } - - if c.StatCacheConfig.Database == "" { - c.StatCacheConfig.Database = "reva" - } - if c.ProviderCacheConfig.Store == "" { c.ProviderCacheConfig.Store = "noop" } @@ -146,7 +142,6 @@ type svc struct { c *config dataGatewayURL url.URL tokenmgr token.Manager - statCache cache.StatCache providerCache cache.ProviderCache createPersonalSpaceCache cache.CreatePersonalSpaceCache } @@ -177,7 +172,6 @@ func New(m map[string]interface{}, _ *grpc.Server) (rgrpc.Service, error) { c: c, dataGatewayURL: *u, tokenmgr: tokenManager, - statCache: cache.GetStatCache(c.StatCacheConfig), providerCache: cache.GetProviderCache(c.ProviderCacheConfig), createPersonalSpaceCache: cache.GetCreatePersonalSpaceCache(c.CreatePersonalSpaceCacheConfig), } @@ -190,7 +184,6 @@ func (s *svc) Register(ss *grpc.Server) { } func (s *svc) Close() error { - s.statCache.Close() s.providerCache.Close() s.createPersonalSpaceCache.Close() return nil diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/ocmshareprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/ocmshareprovider.go index 6ee1182c4e5..3cdac238d26 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/ocmshareprovider.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/ocmshareprovider.go @@ -52,21 +52,17 @@ func (s *svc) CreateOCMShare(ctx context.Context, req *ocm.CreateOCMShareRequest } status, err := s.addGrant(ctx, req.ResourceId, req.Grantee, req.AccessMethods[0].GetWebdavOptions().Permissions, req.Expiration, nil) - if err != nil { + switch { + case err != nil: appctx.GetLogger(ctx).Debug().Interface("status", status).Interface("req", req).Msg(err.Error()) return nil, errors.Wrap(err, "gateway: error adding grant to storage") - } - - switch status.Code { - case rpc.Code_CODE_OK: - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.ResourceId) - case rpc.Code_CODE_UNIMPLEMENTED: + case status.Code == rpc.Code_CODE_UNIMPLEMENTED: appctx.GetLogger(ctx).Debug().Interface("status", status).Interface("req", req).Msg("storing grants not supported, ignoring") - default: + case status.Code != rpc.Code_CODE_OK: appctx.GetLogger(ctx).Debug().Interface("status", status).Interface("req", req).Msg("storing grants is not successful") return &ocm.CreateOCMShareResponse{ Status: status, - }, err + }, nil } return res, nil diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/publicshareprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/publicshareprovider.go index 7a683f18902..4738acd7c54 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/publicshareprovider.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/publicshareprovider.go @@ -21,11 +21,9 @@ package gateway import ( "context" - userprovider "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1" "github.com/cs3org/reva/v2/pkg/appctx" - ctxpkg "github.com/cs3org/reva/v2/pkg/ctx" "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool" "github.com/pkg/errors" ) @@ -39,15 +37,7 @@ func (s *svc) CreatePublicShare(ctx context.Context, req *link.CreatePublicShare return nil, err } - res, err := c.CreatePublicShare(ctx, req) - if err != nil { - return nil, err - } - - if res.GetShare() != nil { - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), res.Share.ResourceId) - } - return res, nil + return c.CreatePublicShare(ctx, req) } func (s *svc) RemovePublicShare(ctx context.Context, req *link.RemovePublicShareRequest) (*link.RemovePublicShareResponse, error) { @@ -58,13 +48,7 @@ func (s *svc) RemovePublicShare(ctx context.Context, req *link.RemovePublicShare if err != nil { return nil, err } - res, err := driver.RemovePublicShare(ctx, req) - if err != nil { - return nil, err - } - // TODO: How to find out the resourceId? -> get public share first, then delete - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), nil) - return res, nil + return driver.RemovePublicShare(ctx, req) } func (s *svc) GetPublicShareByToken(ctx context.Context, req *link.GetPublicShareByTokenRequest) (*link.GetPublicShareByTokenResponse, error) { @@ -137,17 +121,5 @@ func (s *svc) UpdatePublicShare(ctx context.Context, req *link.UpdatePublicShare }, nil } - res, err := pClient.UpdatePublicShare(ctx, req) - if err != nil { - return nil, errors.Wrap(err, "error updating share") - } - if res.GetShare() != nil { - s.statCache.RemoveStatContext(ctx, - &userprovider.UserId{ - OpaqueId: res.Share.Owner.GetOpaqueId(), - }, - res.Share.ResourceId, - ) - } - return res, nil + return pClient.UpdatePublicShare(ctx, req) } diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/storageprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/storageprovider.go index cf3a7387e3e..781295963da 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/storageprovider.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/storageprovider.go @@ -326,7 +326,6 @@ func (s *svc) UpdateStorageSpace(ctx context.Context, req *provider.UpdateStorag if res.Status.Code == rpc.Code_CODE_OK { id := res.StorageSpace.Root - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), id) s.providerCache.RemoveListStorageProviders(id) } return res, nil @@ -363,7 +362,6 @@ func (s *svc) DeleteStorageSpace(ctx context.Context, req *provider.DeleteStorag } id := &provider.ResourceId{OpaqueId: req.Id.OpaqueId} - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), id) s.providerCache.RemoveListStorageProviders(id) if dsRes.Status.Code != rpc.Code_CODE_OK { @@ -608,7 +606,6 @@ func (s *svc) InitiateFileUpload(ctx context.Context, req *provider.InitiateFile } } - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.Ref.ResourceId) return &gateway.InitiateFileUploadResponse{ Opaque: storageRes.Opaque, Status: storageRes.Status, @@ -645,7 +642,6 @@ func (s *svc) CreateContainer(ctx context.Context, req *provider.CreateContainer }, nil } - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.Ref.ResourceId) return res, nil } @@ -688,7 +684,6 @@ func (s *svc) Delete(ctx context.Context, req *provider.DeleteRequest) (*provide }, nil } - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.Ref.ResourceId) return res, nil } @@ -715,8 +710,6 @@ func (s *svc) Move(ctx context.Context, req *provider.MoveRequest) (*provider.Mo req.Source = sref req.Destination = dref - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.Source.ResourceId) - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.Destination.ResourceId) return c.Move(ctx, req) } @@ -739,7 +732,6 @@ func (s *svc) SetArbitraryMetadata(ctx context.Context, req *provider.SetArbitra return nil, errors.Wrap(err, "gateway: error calling SetArbitraryMetadata") } - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.Ref.ResourceId) return res, nil } @@ -761,7 +753,6 @@ func (s *svc) UnsetArbitraryMetadata(ctx context.Context, req *provider.UnsetArb } return nil, errors.Wrap(err, "gateway: error calling UnsetArbitraryMetadata") } - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.Ref.ResourceId) return res, nil } @@ -785,7 +776,6 @@ func (s *svc) SetLock(ctx context.Context, req *provider.SetLockRequest) (*provi return nil, errors.Wrap(err, "gateway: error calling SetLock") } - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.Ref.ResourceId) return res, nil } @@ -826,7 +816,6 @@ func (s *svc) RefreshLock(ctx context.Context, req *provider.RefreshLockRequest) return nil, errors.Wrap(err, "gateway: error calling RefreshLock") } - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.Ref.ResourceId) return res, nil } @@ -847,12 +836,10 @@ func (s *svc) Unlock(ctx context.Context, req *provider.UnlockRequest) (*provide return nil, errors.Wrap(err, "gateway: error calling Unlock") } - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.Ref.ResourceId) return res, nil } // Stat returns the Resoure info for a given resource by forwarding the request to the responsible provider. -// TODO cache info func (s *svc) Stat(ctx context.Context, req *provider.StatRequest) (*provider.StatResponse, error) { c, _, ref, err := s.findAndUnwrapUnique(ctx, req.Ref) if err != nil { @@ -927,7 +914,6 @@ func (s *svc) RestoreFileVersion(ctx context.Context, req *provider.RestoreFileV }, nil } - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.Ref.ResourceId) return res, nil } @@ -983,7 +969,6 @@ func (s *svc) RestoreRecycleItem(ctx context.Context, req *provider.RestoreRecyc }, nil } - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.Ref.ResourceId) return res, nil } @@ -1006,7 +991,6 @@ func (s *svc) PurgeRecycle(ctx context.Context, req *provider.PurgeRecycleReques }, nil } - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.Ref.ResourceId) return res, nil } @@ -1106,7 +1090,6 @@ func (s *svc) getStorageProviderClient(_ context.Context, p *registry.ProviderIn return &cachedAPIClient{ c: c, - statCache: s.statCache, createPersonalSpaceCache: s.createPersonalSpaceCache, }, nil } diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/storageprovidercache.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/storageprovidercache.go index 8dd5d720b5e..f3db156ec2d 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/storageprovidercache.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/storageprovidercache.go @@ -20,7 +20,6 @@ package gateway import ( "context" - "strings" rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" @@ -84,40 +83,9 @@ func (c *cachedRegistryClient) GetHome(ctx context.Context, in *registry.GetHome type cachedAPIClient struct { c provider.ProviderAPIClient - statCache cache.StatCache createPersonalSpaceCache cache.CreatePersonalSpaceCache } -// Stat looks in cache first before forwarding to storage provider -func (c *cachedAPIClient) Stat(ctx context.Context, in *provider.StatRequest, opts ...grpc.CallOption) (*provider.StatResponse, error) { - key := c.statCache.GetKey(ctxpkg.ContextMustGetUser(ctx).GetId(), in.GetRef(), in.GetArbitraryMetadataKeys(), in.GetFieldMask().GetPaths()) - if key != "" { - s := &provider.StatResponse{} - if err := c.statCache.PullFromCache(key, s); err == nil { - return s, nil - } - } - - resp, err := c.c.Stat(ctx, in, opts...) - switch { - case err != nil: - return nil, err - case resp.Status.Code != rpc.Code_CODE_OK: - return resp, nil - case key == "": - return resp, nil - case strings.Contains(key, "sid:"+utils.ShareStorageProviderID): - // We cannot cache shares at the moment: - // we do not know when to invalidate them - // FIXME: find a way to cache/invalidate them too - return resp, nil - case utils.ReadPlainFromOpaque(resp.GetInfo().GetOpaque(), "status") == "processing": - return resp, nil - default: - return resp, c.statCache.PushToCache(key, resp) - } -} - // CreateHome caches calls to CreateHome locally - anyways they only need to be called once per user func (c *cachedAPIClient) CreateHome(ctx context.Context, in *provider.CreateHomeRequest, opts ...grpc.CallOption) (*provider.CreateHomeResponse, error) { key := c.createPersonalSpaceCache.GetKey(ctxpkg.ContextMustGetUser(ctx).GetId()) @@ -140,8 +108,37 @@ func (c *cachedAPIClient) CreateHome(ctx context.Context, in *provider.CreateHom } } +// CreateStorageSpace creates a storage space +func (c *cachedAPIClient) CreateStorageSpace(ctx context.Context, in *provider.CreateStorageSpaceRequest, opts ...grpc.CallOption) (*provider.CreateStorageSpaceResponse, error) { + if in.Type == "personal" { + key := c.createPersonalSpaceCache.GetKey(ctxpkg.ContextMustGetUser(ctx).GetId()) + if key != "" { + s := &provider.CreateStorageSpaceResponse{} + if err := c.createPersonalSpaceCache.PullFromCache(key, s); err == nil { + return s, nil + } + } + resp, err := c.c.CreateStorageSpace(ctx, in, opts...) + switch { + case err != nil: + return nil, err + case resp.Status.Code != rpc.Code_CODE_OK && resp.Status.Code != rpc.Code_CODE_ALREADY_EXISTS: + return resp, nil + case key == "": + return resp, nil + default: + return resp, c.createPersonalSpaceCache.PushToCache(key, resp) + } + } + return c.c.CreateStorageSpace(ctx, in, opts...) +} + // methods below here are not cached, they just call the client directly +// Stat returns the Resoure info for a given resource +func (c *cachedAPIClient) Stat(ctx context.Context, in *provider.StatRequest, opts ...grpc.CallOption) (*provider.StatResponse, error) { + return c.c.Stat(ctx, in, opts...) +} func (c *cachedAPIClient) AddGrant(ctx context.Context, in *provider.AddGrantRequest, opts ...grpc.CallOption) (*provider.AddGrantResponse, error) { return c.c.AddGrant(ctx, in, opts...) } @@ -229,29 +226,6 @@ func (c *cachedAPIClient) Unlock(ctx context.Context, in *provider.UnlockRequest func (c *cachedAPIClient) GetHome(ctx context.Context, in *provider.GetHomeRequest, opts ...grpc.CallOption) (*provider.GetHomeResponse, error) { return c.c.GetHome(ctx, in, opts...) } -func (c *cachedAPIClient) CreateStorageSpace(ctx context.Context, in *provider.CreateStorageSpaceRequest, opts ...grpc.CallOption) (*provider.CreateStorageSpaceResponse, error) { - if in.Type == "personal" { - key := c.createPersonalSpaceCache.GetKey(ctxpkg.ContextMustGetUser(ctx).GetId()) - if key != "" { - s := &provider.CreateStorageSpaceResponse{} - if err := c.createPersonalSpaceCache.PullFromCache(key, s); err == nil { - return s, nil - } - } - resp, err := c.c.CreateStorageSpace(ctx, in, opts...) - switch { - case err != nil: - return nil, err - case resp.Status.Code != rpc.Code_CODE_OK && resp.Status.Code != rpc.Code_CODE_ALREADY_EXISTS: - return resp, nil - case key == "": - return resp, nil - default: - return resp, c.createPersonalSpaceCache.PushToCache(key, resp) - } - } - return c.c.CreateStorageSpace(ctx, in, opts...) -} func (c *cachedAPIClient) ListStorageSpaces(ctx context.Context, in *provider.ListStorageSpacesRequest, opts ...grpc.CallOption) (*provider.ListStorageSpacesResponse, error) { return c.c.ListStorageSpaces(ctx, in, opts...) } @@ -261,7 +235,6 @@ func (c *cachedAPIClient) UpdateStorageSpace(ctx context.Context, in *provider.U func (c *cachedAPIClient) DeleteStorageSpace(ctx context.Context, in *provider.DeleteStorageSpaceRequest, opts ...grpc.CallOption) (*provider.DeleteStorageSpaceResponse, error) { return c.c.DeleteStorageSpace(ctx, in, opts...) } - func (c *cachedAPIClient) TouchFile(ctx context.Context, in *provider.TouchFileRequest, opts ...grpc.CallOption) (*provider.TouchFileResponse, error) { return c.c.TouchFile(ctx, in, opts...) } diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/usershareprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/usershareprovider.go index 9a27f8f9c55..910375d4704 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/usershareprovider.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/usershareprovider.go @@ -154,7 +154,6 @@ func (s *svc) updateShare(ctx context.Context, req *collaboration.UpdateShareReq } } - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), res.Share.ResourceId) return res, nil } @@ -198,7 +197,6 @@ func (s *svc) updateSpaceShare(ctx context.Context, req *collaboration.UpdateSha return res, nil } - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.GetShare().GetResourceId()) s.providerCache.RemoveListStorageProviders(req.GetShare().GetResourceId()) return res, nil } @@ -282,7 +280,6 @@ func (s *svc) UpdateReceivedShare(ctx context.Context, req *collaboration.Update }, nil } - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.Share.Share.ResourceId) return c.UpdateReceivedShare(ctx, req) /* TODO: Leftover from master merge. Do we need this? @@ -551,7 +548,7 @@ func (s *svc) addShare(ctx context.Context, req *collaboration.CreateShareReques } if s.c.CommitShareToStorageGrant { - // If the share is a denial we call denyGrant instead. + // If the share is a denial we call denyGrant instead. var status *rpc.Status if grants.PermissionsEqual(req.Grant.Permissions.Permissions, &provider.ResourcePermissions{}) { status, err = s.denyGrant(ctx, req.ResourceInfo.Id, req.Grant.Grantee, nil) @@ -569,7 +566,7 @@ func (s *svc) addShare(ctx context.Context, req *collaboration.CreateShareReques switch status.Code { case rpc.Code_CODE_OK: - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.ResourceInfo.Id) + // ok case rpc.Code_CODE_UNIMPLEMENTED: appctx.GetLogger(ctx).Debug().Interface("status", status).Interface("req", req).Msg("storing grants not supported, ignoring") rollBackFn(status) @@ -585,6 +582,10 @@ func (s *svc) addShare(ctx context.Context, req *collaboration.CreateShareReques } func (s *svc) addSpaceShare(ctx context.Context, req *collaboration.CreateShareRequest) (*collaboration.CreateShareResponse, error) { + if refIsSpaceRoot(req.GetResourceInfo().GetId()) && + req.GetResourceInfo().GetSpace().GetSpaceType() == _spaceTypePersonal { + return nil, errors.New("gateway: space type is not eligible for sharing") + } // If the share is a denial we call denyGrant instead. var st *rpc.Status var err error @@ -613,7 +614,6 @@ func (s *svc) addSpaceShare(ctx context.Context, req *collaboration.CreateShareR switch st.Code { case rpc.Code_CODE_OK: - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.ResourceInfo.Id) s.providerCache.RemoveListStorageProviders(req.ResourceInfo.Id) case rpc.Code_CODE_UNIMPLEMENTED: appctx.GetLogger(ctx).Debug().Interface("status", st).Interface("req", req).Msg("storing grants not supported, ignoring") @@ -692,7 +692,6 @@ func (s *svc) removeShare(ctx context.Context, req *collaboration.RemoveShareReq } } - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), share.ResourceId) return res, nil } @@ -725,7 +724,6 @@ func (s *svc) removeSpaceShare(ctx context.Context, ref *provider.ResourceId, gr Status: removeGrantStatus, }, err } - s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), ref) s.providerCache.RemoveListStorageProviders(ref) return &collaboration.RemoveShareResponse{Status: status.NewOK(ctx)}, nil } diff --git a/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/datatx.go b/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/datatx.go index 23328aadd96..cdbb27052e4 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/datatx.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/datatx.go @@ -28,7 +28,6 @@ import ( provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" "github.com/cs3org/reva/v2/pkg/events" "github.com/cs3org/reva/v2/pkg/storage" - "github.com/cs3org/reva/v2/pkg/storage/cache" "github.com/cs3org/reva/v2/pkg/utils" ) @@ -53,8 +52,3 @@ func EmitFileUploadedEvent(spaceOwnerOrManager, executant *userv1beta1.UserId, r return events.Publish(context.Background(), publisher, uploadedEv) } - -// InvalidateCache is a helper function which invalidates the stat cache -func InvalidateCache(owner *userv1beta1.UserId, ref *provider.Reference, statCache cache.StatCache) { - statCache.RemoveStatContext(context.TODO(), owner, ref.GetResourceId()) -} diff --git a/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/manager/simple/simple.go b/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/manager/simple/simple.go index 6699c9f77a2..607d6336adc 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/manager/simple/simple.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/manager/simple/simple.go @@ -48,7 +48,6 @@ func init() { type manager struct { conf *cache.Config publisher events.Publisher - statCache cache.StatCache } func parseConfig(m map[string]interface{}) (*cache.Config, error) { @@ -70,7 +69,6 @@ func New(m map[string]interface{}, publisher events.Publisher) (datatx.DataTX, e return &manager{ conf: c, publisher: publisher, - statCache: cache.GetStatCache(*c), }, nil } @@ -110,7 +108,6 @@ func (m *manager) Handler(fs storage.FS) (http.Handler, error) { Body: r.Body, Length: r.ContentLength, }, func(spaceOwner, owner *userpb.UserId, ref *provider.Reference) { - datatx.InvalidateCache(owner, ref, m.statCache) if err := datatx.EmitFileUploadedEvent(spaceOwner, owner, ref, m.publisher); err != nil { sublog.Error().Err(err).Msg("failed to publish FileUploaded event") } diff --git a/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/manager/spaces/spaces.go b/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/manager/spaces/spaces.go index d39b12baa53..ce585ab5426 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/manager/spaces/spaces.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/manager/spaces/spaces.go @@ -50,7 +50,6 @@ func init() { type manager struct { conf *cache.Config publisher events.Publisher - statCache cache.StatCache } func parseConfig(m map[string]interface{}) (*cache.Config, error) { @@ -72,7 +71,6 @@ func New(m map[string]interface{}, publisher events.Publisher) (datatx.DataTX, e return &manager{ conf: c, publisher: publisher, - statCache: cache.GetStatCache(*c), }, nil } @@ -117,7 +115,6 @@ func (m *manager) Handler(fs storage.FS) (http.Handler, error) { Body: r.Body, Length: r.ContentLength, }, func(spaceOwner, owner *userpb.UserId, ref *provider.Reference) { - datatx.InvalidateCache(owner, ref, m.statCache) if err := datatx.EmitFileUploadedEvent(spaceOwner, owner, ref, m.publisher); err != nil { sublog.Error().Err(err).Msg("failed to publish FileUploaded event") } diff --git a/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/manager/tus/tus.go b/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/manager/tus/tus.go index e9b2a07b039..f86b100866c 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/manager/tus/tus.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/manager/tus/tus.go @@ -37,7 +37,6 @@ import ( "github.com/cs3org/reva/v2/pkg/rhttp/datatx/manager/registry" "github.com/cs3org/reva/v2/pkg/rhttp/datatx/metrics" "github.com/cs3org/reva/v2/pkg/storage" - "github.com/cs3org/reva/v2/pkg/storage/cache" "github.com/cs3org/reva/v2/pkg/storagespace" "github.com/mitchellh/mapstructure" ) @@ -47,7 +46,6 @@ func init() { } type TusConfig struct { - cache.Config CorsEnabled bool `mapstructure:"cors_enabled"` CorsAllowOrigin string `mapstructure:"cors_allow_origin"` CorsAllowCredentials bool `mapstructure:"cors_allow_credentials"` @@ -60,7 +58,6 @@ type TusConfig struct { type manager struct { conf *TusConfig publisher events.Publisher - statCache cache.StatCache } func parseConfig(m map[string]interface{}) (*TusConfig, error) { @@ -81,7 +78,6 @@ func New(m map[string]interface{}, publisher events.Publisher) (datatx.DataTX, e return &manager{ conf: c, publisher: publisher, - statCache: cache.GetStatCache(c.Config), }, nil } @@ -142,7 +138,6 @@ func (m *manager) Handler(fs storage.FS) (http.Handler, error) { up := ups[0] executant := up.Executant() ref := up.Reference() - datatx.InvalidateCache(&executant, &ref, m.statCache) if m.publisher != nil { if err := datatx.EmitFileUploadedEvent(up.SpaceOwner(), &executant, &ref, m.publisher); err != nil { appctx.GetLogger(context.Background()).Error().Err(err).Msg("failed to publish FileUploaded event") diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go index 35cc29663fc..f06a50f80ad 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go @@ -40,7 +40,6 @@ import ( "github.com/cs3org/reva/v2/pkg/rhttp/datatx/metrics" "github.com/cs3org/reva/v2/pkg/rhttp/datatx/utils/download" "github.com/cs3org/reva/v2/pkg/storage" - "github.com/cs3org/reva/v2/pkg/storage/cache" "github.com/cs3org/reva/v2/pkg/storage/utils/chunking" "github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/aspects" "github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/lookup" @@ -108,7 +107,6 @@ type Decomposedfs struct { p permissions.Permissions chunkHandler *chunking.ChunkHandler stream events.Stream - cache cache.StatCache sessionStore SessionStore UserCache *ttlcache.Cache @@ -209,7 +207,6 @@ func New(o *options.Options, aspects aspects.Aspects) (storage.FS, error) { p: aspects.Permissions, chunkHandler: chunking.NewChunkHandler(filepath.Join(o.Root, "uploads")), stream: aspects.EventStream, - cache: cache.GetStatCache(o.StatCache), UserCache: ttlcache.NewCache(), userSpaceIndex: userSpaceIndex, groupSpaceIndex: groupSpaceIndex, @@ -324,9 +321,6 @@ func (fs *Decomposedfs) Postprocessing(ch <-chan events.Event) { fs.sessionStore.Cleanup(ctx, session, revertNodeMetadata, keepUpload, unmarkPostprocessing) - // remove cache entry in gateway - fs.cache.RemoveStatContext(ctx, ev.ExecutingUser.GetId(), &provider.ResourceId{SpaceId: n.SpaceID, OpaqueId: n.ID}) - if err := events.Publish( ctx, fs.stream, @@ -494,9 +488,6 @@ func (fs *Decomposedfs) Postprocessing(ch <-chan events.Event) { } metrics.UploadSessionsScanned.Inc() - - // remove cache entry in gateway - fs.cache.RemoveStatContext(ctx, ev.ExecutingUser.GetId(), &provider.ResourceId{SpaceId: n.SpaceID, OpaqueId: n.ID}) default: log.Error().Interface("event", ev).Msg("Unknown event") } diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/node/permissions.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/node/permissions.go index 1367a6d5d89..4e3459a9467 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/node/permissions.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/node/permissions.go @@ -99,6 +99,7 @@ func ServiceAccountPermissions() provider.ResourcePermissions { PurgeRecycle: true, // for purge-trash-bin command RestoreRecycleItem: true, // for cli restore command Delete: true, // for cli restore command with replace option + CreateContainer: true, // for space provisioning } } diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/options/options.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/options/options.go index f21912687c2..086490879b7 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/options/options.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/options/options.go @@ -73,9 +73,10 @@ type Options struct { Tokens TokenOptions `mapstructure:"tokens"` - StatCache cache.Config `mapstructure:"statcache"` + // FileMetadataCache for file metadata FileMetadataCache cache.Config `mapstructure:"filemetadatacache"` - IDCache cache.Config `mapstructure:"idcache"` + // IDCache for symlink lookups of direntry to node id + IDCache cache.Config `mapstructure:"idcache"` MaxAcquireLockCycles int `mapstructure:"max_acquire_lock_cycles"` LockCycleDurationFactor int `mapstructure:"lock_cycle_duration_factor"` diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/tree/tree.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/tree/tree.go index 6fc5176af31..1a1dae32f90 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/tree/tree.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/tree/tree.go @@ -70,6 +70,7 @@ type Tree struct { options *options.Options + // used to cache symlink lookups for child names to node ids idCache store.Store } diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/metadata/cs3.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/metadata/cs3.go index c8ee7b9fb65..c68ce114fb6 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/metadata/cs3.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/metadata/cs3.go @@ -51,30 +51,41 @@ func init() { // CS3 represents a metadata storage with a cs3 storage backend type CS3 struct { + SpaceRoot *provider.ResourceId + providerAddr string gatewayAddr string + useSystemUser bool serviceUser *user.User machineAuthAPIKey string + dataGatewayClient *http.Client - SpaceRoot *provider.ResourceId } -// NewCS3Storage returns a new cs3 storage instance -func NewCS3Storage(gwAddr, providerAddr, serviceUserID, serviceUserIDP, machineAuthAPIKey string) (s Storage, err error) { - c := http.DefaultClient - +// NewCS3 returns a new CS3 instance. Use an authenticated context and be sure to define SpaceRoot manually. +func NewCS3(gwAddr, providerAddr string) (s *CS3) { return &CS3{ providerAddr: providerAddr, gatewayAddr: gwAddr, - dataGatewayClient: c, - machineAuthAPIKey: machineAuthAPIKey, - serviceUser: &user.User{ - Id: &user.UserId{ - OpaqueId: serviceUserID, - Idp: serviceUserIDP, - }, + dataGatewayClient: http.DefaultClient, + } +} + +// NewCS3Storage returns a new cs3 storage instance. Context passed to methods is irrelevant as the service user will be used. +// Be sure to call Init before using the storage. +func NewCS3Storage(gwAddr, providerAddr, serviceUserID, serviceUserIDP, machineAuthAPIKey string) (s Storage, err error) { + cs3 := NewCS3(gwAddr, providerAddr) + + cs3.useSystemUser = true + cs3.machineAuthAPIKey = machineAuthAPIKey + cs3.serviceUser = &user.User{ + Id: &user.UserId{ + OpaqueId: serviceUserID, + Idp: serviceUserIDP, }, - }, nil + } + + return cs3, nil } // Backend returns the backend name of the storage @@ -228,7 +239,8 @@ func (cs3 *CS3) Upload(ctx context.Context, req UploadRequest) (*UploadResponse, etag = ocEtag } return &UploadResponse{ - Etag: etag, + Etag: etag, + FileID: resp.Header.Get("OC-Fileid"), }, nil } @@ -505,6 +517,10 @@ func (cs3 *CS3) providerClient() (provider.ProviderAPIClient, error) { } func (cs3 *CS3) getAuthContext(ctx context.Context) (context.Context, error) { + if !cs3.useSystemUser { + return ctx, nil + } + // we need to start a new context to get rid of an existing x-access-token in the outgoing context authCtx := context.Background() authCtx, span := tracer.Start(authCtx, "getAuthContext", trace.WithLinks(trace.LinkFromContext(ctx))) diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/metadata/storage.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/metadata/storage.go index 7c6107cff0a..24e74f4a9f0 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/metadata/storage.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/metadata/storage.go @@ -43,7 +43,8 @@ type UploadRequest struct { // UploadResponse represents a upload response type UploadResponse struct { - Etag string + Etag string + FileID string // only for cs3 storage } // DownloadRequest represents a download request and its options diff --git a/vendor/github.com/cs3org/reva/v2/pkg/utils/grpc.go b/vendor/github.com/cs3org/reva/v2/pkg/utils/grpc.go index ae49c7ab8e2..d363d9f2da6 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/utils/grpc.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/utils/grpc.go @@ -38,8 +38,13 @@ var ( ) // GetServiceUserContext returns an authenticated context of the given service user +// Deprecated: Use GetServiceUserContextWithContext() func GetServiceUserContext(serviceUserID string, gwc gateway.GatewayAPIClient, serviceUserSecret string) (context.Context, error) { - ctx := context.Background() + return GetServiceUserContextWithContext(context.Background(), gwc, serviceUserID, serviceUserSecret) +} + +// GetServiceUserContextWithContext returns an authenticated context of the given service user +func GetServiceUserContextWithContext(ctx context.Context, gwc gateway.GatewayAPIClient, serviceUserID string, serviceUserSecret string) (context.Context, error) { authRes, err := gwc.Authenticate(ctx, &gateway.AuthenticateRequest{ Type: "serviceaccounts", ClientId: serviceUserID, @@ -57,8 +62,14 @@ func GetServiceUserContext(serviceUserID string, gwc gateway.GatewayAPIClient, s } // GetUser gets the specified user +// Deprecated: Use GetUserWithContext() func GetUser(userID *user.UserId, gwc gateway.GatewayAPIClient) (*user.User, error) { - getUserResponse, err := gwc.GetUser(context.Background(), &user.GetUserRequest{UserId: userID}) + return GetUserWithContext(context.Background(), userID, gwc) +} + +// GetUserWithContext gets the specified user +func GetUserWithContext(ctx context.Context, userID *user.UserId, gwc gateway.GatewayAPIClient) (*user.User, error) { + getUserResponse, err := gwc.GetUser(ctx, &user.GetUserRequest{UserId: userID}) if err != nil { return nil, err } diff --git a/vendor/modules.txt b/vendor/modules.txt index 3c7310e9a6a..cf2f6531ae6 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -359,7 +359,7 @@ github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1 github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1 github.com/cs3org/go-cs3apis/cs3/tx/v1beta1 github.com/cs3org/go-cs3apis/cs3/types/v1beta1 -# github.com/cs3org/reva/v2 v2.19.1 +# github.com/cs3org/reva/v2 v2.19.2-0.20240307063856-698d86209c3d ## explicit; go 1.21 github.com/cs3org/reva/v2/cmd/revad/internal/grace github.com/cs3org/reva/v2/cmd/revad/runtime