Move reva to stable-2.19 branch

stable-5.0 does no longer use edge
This commit is contained in:
Ralf Haferkamp
2024-03-12 16:57:44 +01:00
parent a6dd02e75b
commit a0c1be452a
20 changed files with 226 additions and 50 deletions
+1 -1
View File
@@ -13,7 +13,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.2-0.20240307091744-fa2caba1f4e4
github.com/cs3org/reva/v2 v2.19.2-0.20240312163431-16d783d7996a
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
+2 -2
View File
@@ -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.2-0.20240307091744-fa2caba1f4e4 h1:dOApLUv2cYnWU1Z8pqEBk8a9BEGe6VRl/f0sFmwzLw4=
github.com/cs3org/reva/v2 v2.19.2-0.20240307091744-fa2caba1f4e4/go.mod h1:GRUrOp5HbFVwZTgR9bVrMZ/MvVy+Jhxw1PdMmhhKP9E=
github.com/cs3org/reva/v2 v2.19.2-0.20240312163431-16d783d7996a h1:SknznyF5yndPT+juCpMQcwauYkGEXFycnov3W+1mHfw=
github.com/cs3org/reva/v2 v2.19.2-0.20240312163431-16d783d7996a/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=
@@ -216,6 +216,24 @@ func FileDownloaded(r *provider.InitiateFileDownloadResponse, req *provider.Init
}
}
// FileLocked converts the response to an events
func FileLocked(r *provider.SetLockResponse, req *provider.SetLockRequest, owner, executant *user.UserId) events.FileLocked {
return events.FileLocked{
Executant: executant,
Ref: req.Ref,
Timestamp: utils.TSNow(),
}
}
// FileUnlocked converts the response to an event
func FileUnlocked(r *provider.UnlockResponse, req *provider.UnlockRequest, owner, executant *user.UserId) events.FileUnlocked {
return events.FileUnlocked{
Executant: executant,
Ref: req.Ref,
Timestamp: utils.TSNow(),
}
}
// ItemTrashed converts the response to an event
func ItemTrashed(r *provider.DeleteResponse, req *provider.DeleteRequest, spaceOwner, executant *user.UserId) events.ItemTrashed {
opaqueID := utils.ReadPlainFromOpaque(r.Opaque, "opaque_id")
@@ -184,6 +184,15 @@ func NewUnary(m map[string]interface{}) (grpc.UnaryServerInterceptor, int, error
if isSuccess(v) {
ev = FileTouched(v, req.(*provider.TouchFileRequest), ownerID, executantID)
}
case *provider.SetLockResponse:
fmt.Println("set lock response", v)
if isSuccess(v) {
ev = FileLocked(v, req.(*provider.SetLockRequest), ownerID, executantID)
}
case *provider.UnlockResponse:
if isSuccess(v) {
ev = FileUnlocked(v, req.(*provider.UnlockRequest), ownerID, executantID)
}
}
if ev != nil {
@@ -38,6 +38,7 @@ import (
const (
_spaceTypePersonal = "personal"
_spaceTypeProject = "project"
_spaceTypeVirtual = "virtual"
)
func init() {
@@ -72,6 +73,7 @@ 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"`
@@ -121,6 +123,14 @@ 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"
}
@@ -142,6 +152,7 @@ type svc struct {
c *config
dataGatewayURL url.URL
tokenmgr token.Manager
statCache cache.StatCache
providerCache cache.ProviderCache
createPersonalSpaceCache cache.CreatePersonalSpaceCache
}
@@ -172,6 +183,7 @@ 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),
}
@@ -184,6 +196,7 @@ func (s *svc) Register(ss *grpc.Server) {
}
func (s *svc) Close() error {
s.statCache.Close()
s.providerCache.Close()
s.createPersonalSpaceCache.Close()
return nil
@@ -52,17 +52,21 @@ 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)
switch {
case err != nil:
if 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")
case status.Code == rpc.Code_CODE_UNIMPLEMENTED:
}
switch status.Code {
case rpc.Code_CODE_OK:
s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.ResourceId)
case rpc.Code_CODE_UNIMPLEMENTED:
appctx.GetLogger(ctx).Debug().Interface("status", status).Interface("req", req).Msg("storing grants not supported, ignoring")
case status.Code != rpc.Code_CODE_OK:
default:
appctx.GetLogger(ctx).Debug().Interface("status", status).Interface("req", req).Msg("storing grants is not successful")
return &ocm.CreateOCMShareResponse{
Status: status,
}, nil
}, err
}
return res, nil
@@ -21,9 +21,11 @@ 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"
)
@@ -37,7 +39,15 @@ func (s *svc) CreatePublicShare(ctx context.Context, req *link.CreatePublicShare
return nil, err
}
return c.CreatePublicShare(ctx, req)
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
}
func (s *svc) RemovePublicShare(ctx context.Context, req *link.RemovePublicShareRequest) (*link.RemovePublicShareResponse, error) {
@@ -48,7 +58,13 @@ func (s *svc) RemovePublicShare(ctx context.Context, req *link.RemovePublicShare
if err != nil {
return nil, err
}
return driver.RemovePublicShare(ctx, req)
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
}
func (s *svc) GetPublicShareByToken(ctx context.Context, req *link.GetPublicShareByTokenRequest) (*link.GetPublicShareByTokenResponse, error) {
@@ -121,5 +137,17 @@ func (s *svc) UpdatePublicShare(ctx context.Context, req *link.UpdatePublicShare
}, nil
}
return pClient.UpdatePublicShare(ctx, req)
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
}
@@ -326,6 +326,7 @@ 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
@@ -362,6 +363,7 @@ 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 {
@@ -606,6 +608,7 @@ 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,
@@ -642,6 +645,7 @@ 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
}
@@ -684,6 +688,7 @@ 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
}
@@ -710,6 +715,8 @@ 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)
}
@@ -732,6 +739,7 @@ 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
}
@@ -753,6 +761,7 @@ 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
}
@@ -776,6 +785,7 @@ 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
}
@@ -816,6 +826,7 @@ 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
}
@@ -836,10 +847,12 @@ 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 {
@@ -914,6 +927,7 @@ 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
}
@@ -969,6 +983,7 @@ 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
}
@@ -991,6 +1006,7 @@ 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
}
@@ -1090,6 +1106,7 @@ func (s *svc) getStorageProviderClient(_ context.Context, p *registry.ProviderIn
return &cachedAPIClient{
c: c,
statCache: s.statCache,
createPersonalSpaceCache: s.createPersonalSpaceCache,
}, nil
}
@@ -20,6 +20,7 @@ package gateway
import (
"context"
"strings"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
@@ -83,9 +84,40 @@ 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())
@@ -108,37 +140,8 @@ 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...)
}
@@ -226,6 +229,29 @@ 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...)
}
@@ -235,6 +261,7 @@ 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...)
}
@@ -154,6 +154,7 @@ func (s *svc) updateShare(ctx context.Context, req *collaboration.UpdateShareReq
}
}
s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), res.Share.ResourceId)
return res, nil
}
@@ -197,6 +198,7 @@ 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
}
@@ -280,6 +282,7 @@ 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?
@@ -548,7 +551,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)
@@ -566,7 +569,7 @@ func (s *svc) addShare(ctx context.Context, req *collaboration.CreateShareReques
switch status.Code {
case rpc.Code_CODE_OK:
// ok
s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), req.ResourceInfo.Id)
case rpc.Code_CODE_UNIMPLEMENTED:
appctx.GetLogger(ctx).Debug().Interface("status", status).Interface("req", req).Msg("storing grants not supported, ignoring")
rollBackFn(status)
@@ -583,8 +586,8 @@ 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")
(req.GetResourceInfo().GetSpace().GetSpaceType() == _spaceTypePersonal || req.GetResourceInfo().GetSpace().GetSpaceType() == _spaceTypeVirtual) {
return &collaboration.CreateShareResponse{Status: status.NewInvalid(ctx, "space type is not eligible for sharing")}, nil
}
// If the share is a denial we call denyGrant instead.
var st *rpc.Status
@@ -614,6 +617,7 @@ 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,6 +696,7 @@ func (s *svc) removeShare(ctx context.Context, req *collaboration.RemoveShareReq
}
}
s.statCache.RemoveStatContext(ctx, ctxpkg.ContextMustGetUser(ctx).GetId(), share.ResourceId)
return res, nil
}
@@ -724,6 +729,7 @@ 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
}
@@ -255,7 +255,7 @@ func (h *DavHandler) Handler(s *svc) http.Handler {
sig := q.Get("signature")
expiration := q.Get("expiration")
// We restrict the pre-signed urls to downloads.
if sig != "" && expiration != "" && r.Method != http.MethodGet {
if sig != "" && expiration != "" && !(r.Method == http.MethodGet || r.Method == http.MethodHead) {
w.WriteHeader(http.StatusUnauthorized)
return
}
+30
View File
@@ -88,6 +88,36 @@ func (FileDownloaded) Unmarshal(v []byte) (interface{}, error) {
return e, err
}
// FileLocked is emitted when a file is locked
type FileLocked struct {
Executant *user.UserId
Ref *provider.Reference
Owner *user.UserId
Timestamp *types.Timestamp
}
// Unmarshal to fulfill umarshaller interface
func (FileLocked) Unmarshal(v []byte) (interface{}, error) {
e := FileLocked{}
err := json.Unmarshal(v, &e)
return e, err
}
// FileUnlocked is emitted when a file is unlocked
type FileUnlocked struct {
Executant *user.UserId
Ref *provider.Reference
Owner *user.UserId
Timestamp *types.Timestamp
}
// Unmarshal to fulfill umarshaller interface
func (FileUnlocked) Unmarshal(v []byte) (interface{}, error) {
e := FileUnlocked{}
err := json.Unmarshal(v, &e)
return e, err
}
// ItemTrashed is emitted when a file or folder is trashed
type ItemTrashed struct {
SpaceOwner *user.UserId
+6
View File
@@ -28,6 +28,7 @@ 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"
)
@@ -52,3 +53,8 @@ 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())
}
@@ -48,6 +48,7 @@ func init() {
type manager struct {
conf *cache.Config
publisher events.Publisher
statCache cache.StatCache
}
func parseConfig(m map[string]interface{}) (*cache.Config, error) {
@@ -69,6 +70,7 @@ func New(m map[string]interface{}, publisher events.Publisher) (datatx.DataTX, e
return &manager{
conf: c,
publisher: publisher,
statCache: cache.GetStatCache(*c),
}, nil
}
@@ -108,6 +110,7 @@ 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")
}
@@ -50,6 +50,7 @@ func init() {
type manager struct {
conf *cache.Config
publisher events.Publisher
statCache cache.StatCache
}
func parseConfig(m map[string]interface{}) (*cache.Config, error) {
@@ -71,6 +72,7 @@ func New(m map[string]interface{}, publisher events.Publisher) (datatx.DataTX, e
return &manager{
conf: c,
publisher: publisher,
statCache: cache.GetStatCache(*c),
}, nil
}
@@ -115,6 +117,7 @@ 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")
}
+5
View File
@@ -37,6 +37,7 @@ 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"
)
@@ -46,6 +47,7 @@ func init() {
}
type TusConfig struct {
cache.Config
CorsEnabled bool `mapstructure:"cors_enabled"`
CorsAllowOrigin string `mapstructure:"cors_allow_origin"`
CorsAllowCredentials bool `mapstructure:"cors_allow_credentials"`
@@ -58,6 +60,7 @@ type TusConfig struct {
type manager struct {
conf *TusConfig
publisher events.Publisher
statCache cache.StatCache
}
func parseConfig(m map[string]interface{}) (*TusConfig, error) {
@@ -78,6 +81,7 @@ func New(m map[string]interface{}, publisher events.Publisher) (datatx.DataTX, e
return &manager{
conf: c,
publisher: publisher,
statCache: cache.GetStatCache(c.Config),
}, nil
}
@@ -138,6 +142,7 @@ 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")
@@ -40,6 +40,7 @@ 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"
@@ -107,6 +108,7 @@ type Decomposedfs struct {
p permissions.Permissions
chunkHandler *chunking.ChunkHandler
stream events.Stream
cache cache.StatCache
sessionStore SessionStore
UserCache *ttlcache.Cache
@@ -207,6 +209,7 @@ 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,
@@ -321,6 +324,9 @@ 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,
@@ -488,6 +494,9 @@ 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")
}
@@ -73,10 +73,9 @@ type Options struct {
Tokens TokenOptions `mapstructure:"tokens"`
// FileMetadataCache for file metadata
StatCache cache.Config `mapstructure:"statcache"`
FileMetadataCache cache.Config `mapstructure:"filemetadatacache"`
// IDCache for symlink lookups of direntry to node id
IDCache cache.Config `mapstructure:"idcache"`
IDCache cache.Config `mapstructure:"idcache"`
MaxAcquireLockCycles int `mapstructure:"max_acquire_lock_cycles"`
LockCycleDurationFactor int `mapstructure:"lock_cycle_duration_factor"`
@@ -70,7 +70,6 @@ type Tree struct {
options *options.Options
// used to cache symlink lookups for child names to node ids
idCache store.Store
}
+1 -1
View File
@@ -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.2-0.20240307091744-fa2caba1f4e4
# github.com/cs3org/reva/v2 v2.19.2-0.20240312163431-16d783d7996a
## explicit; go 1.21
github.com/cs3org/reva/v2/cmd/revad/internal/grace
github.com/cs3org/reva/v2/cmd/revad/runtime