diff --git a/changelog/unreleased/sharemanager-api-change.md b/changelog/unreleased/sharemanager-api-change.md new file mode 100644 index 0000000000..8210920deb --- /dev/null +++ b/changelog/unreleased/sharemanager-api-change.md @@ -0,0 +1,5 @@ +Change: Sharemanager API change + +This PR updates reva to reflect the share manager CS3 API changes. + +https://github.com/cs3org/reva/pull/2121 \ No newline at end of file diff --git a/cmd/reva/ocm-share-update-received.go b/cmd/reva/ocm-share-update-received.go index 40b2f7999e..7f88765f14 100644 --- a/cmd/reva/ocm-share-update-received.go +++ b/cmd/reva/ocm-share-update-received.go @@ -25,6 +25,7 @@ import ( rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1" "github.com/pkg/errors" + "google.golang.org/protobuf/types/known/fieldmaskpb" ) func ocmShareUpdateReceivedCommand() *command { @@ -57,7 +58,7 @@ func ocmShareUpdateReceivedCommand() *command { shareState := getOCMShareState(*state) - shareRequest := &ocm.UpdateReceivedOCMShareRequest{ + shareRes, err := shareClient.GetReceivedOCMShare(ctx, &ocm.GetReceivedOCMShareRequest{ Ref: &ocm.ShareReference{ Spec: &ocm.ShareReference_Id{ Id: &ocm.ShareId{ @@ -65,20 +66,27 @@ func ocmShareUpdateReceivedCommand() *command { }, }, }, - Field: &ocm.UpdateReceivedOCMShareRequest_UpdateField{ - Field: &ocm.UpdateReceivedOCMShareRequest_UpdateField_State{ - State: shareState, - }, - }, + }) + if err != nil { + return err + } + if shareRes.Status.Code != rpc.Code_CODE_OK { + return formatError(shareRes.Status) + } + shareRes.Share.State = shareState + + shareRequest := &ocm.UpdateReceivedOCMShareRequest{ + Share: shareRes.Share, + UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"state"}}, } - shareRes, err := shareClient.UpdateReceivedOCMShare(ctx, shareRequest) + updateRes, err := shareClient.UpdateReceivedOCMShare(ctx, shareRequest) if err != nil { return err } - if shareRes.Status.Code != rpc.Code_CODE_OK { - return formatError(shareRes.Status) + if updateRes.Status.Code != rpc.Code_CODE_OK { + return formatError(updateRes.Status) } fmt.Println("OK") diff --git a/cmd/reva/share-update-received.go b/cmd/reva/share-update-received.go index 7dd974efb7..624fe3e983 100644 --- a/cmd/reva/share-update-received.go +++ b/cmd/reva/share-update-received.go @@ -25,6 +25,7 @@ import ( rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" "github.com/pkg/errors" + "google.golang.org/protobuf/types/known/fieldmaskpb" ) func shareUpdateReceivedCommand() *command { @@ -57,7 +58,7 @@ func shareUpdateReceivedCommand() *command { shareState := getShareState(*state) - shareRequest := &collaboration.UpdateReceivedShareRequest{ + shareRes, err := shareClient.GetReceivedShare(ctx, &collaboration.GetReceivedShareRequest{ Ref: &collaboration.ShareReference{ Spec: &collaboration.ShareReference_Id{ Id: &collaboration.ShareId{ @@ -65,20 +66,27 @@ func shareUpdateReceivedCommand() *command { }, }, }, - Field: &collaboration.UpdateReceivedShareRequest_UpdateField{ - Field: &collaboration.UpdateReceivedShareRequest_UpdateField_State{ - State: shareState, - }, - }, + }) + if err != nil { + return err + } + if shareRes.Status.Code != rpc.Code_CODE_OK { + return formatError(shareRes.Status) + } + shareRes.Share.State = shareState + + shareRequest := &collaboration.UpdateReceivedShareRequest{ + Share: shareRes.Share, + UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"state"}}, } - shareRes, err := shareClient.UpdateReceivedShare(ctx, shareRequest) + updateRes, err := shareClient.UpdateReceivedShare(ctx, shareRequest) if err != nil { return err } - if shareRes.Status.Code != rpc.Code_CODE_OK { - return formatError(shareRes.Status) + if updateRes.Status.Code != rpc.Code_CODE_OK { + return formatError(updateRes.Status) } fmt.Println("OK") diff --git a/go.mod b/go.mod index f096f70fab..6063ba9a70 100644 --- a/go.mod +++ b/go.mod @@ -70,6 +70,7 @@ require ( golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f golang.org/x/sys v0.0.0-20210921065528-437939a70204 golang.org/x/term v0.0.0-20210916214954-140adaaadfaf + google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 google.golang.org/grpc v1.41.0 google.golang.org/protobuf v1.27.1 gopkg.in/square/go-jose.v2 v2.6.0 // indirect @@ -80,6 +81,8 @@ require ( go 1.16 replace ( + // FIXME remove the replace when upstream has merged https://github.com/cs3org/cs3apis/pull/144 and synced https://github.com/cs3org/go-cs3apis/pull/44 + github.com/cs3org/go-cs3apis => github.com/butonic/go-cs3apis v0.0.0-20210929095704-38ebc9ca8bd6 github.com/eventials/go-tus => github.com/andrewmostello/go-tus v0.0.0-20200314041820-904a9904af9a github.com/oleiade/reflections => github.com/oleiade/reflections v1.0.1 google.golang.org/grpc => google.golang.org/grpc v1.26.0 // temporary downgrade diff --git a/go.sum b/go.sum index 3b5a23e1a1..6a169bddee 100644 --- a/go.sum +++ b/go.sum @@ -74,6 +74,8 @@ github.com/bluele/gcache v0.0.2 h1:WcbfdXICg7G/DGBh1PFfcirkWOQV+v077yF1pSy3DGw= github.com/bluele/gcache v0.0.2/go.mod h1:m15KV+ECjptwSPxKhOhQoAFQVtUFjTVkc3H8o0t/fp0= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40 h1:y4B3+GPxKlrigF1ha5FFErxK+sr6sWxQovRMzwMhejo= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= +github.com/butonic/go-cs3apis v0.0.0-20210929095704-38ebc9ca8bd6 h1:Vtgscx8sMUk3UKumYulR7mMmflZKLOcFO/7Qd/AVUHc= +github.com/butonic/go-cs3apis v0.0.0-20210929095704-38ebc9ca8bd6/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= github.com/c-bata/go-prompt v0.2.5 h1:3zg6PecEywxNn0xiqcXHD96fkbxghD+gdB2tbsYfl+Y= github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -90,8 +92,6 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e h1:tqSPWQeueWTKnJVMJffz4pz0o1WuQxJ28+5x5JgaHD8= github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e/go.mod h1:XJEZ3/EQuI3BXTp/6DUzFr850vlxq11I6satRtz0YQ4= -github.com/cs3org/go-cs3apis v0.0.0-20210922150613-cb9e3c99f8de h1:N+AI8wz7yhDDqHDuq9EGaqQoFhAOi9XW37xt0ormflw= -github.com/cs3org/go-cs3apis v0.0.0-20210922150613-cb9e3c99f8de/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/internal/grpc/interceptors/auth/scope.go b/internal/grpc/interceptors/auth/scope.go index b8f7cf1f7b..7cac0416b3 100644 --- a/internal/grpc/interceptors/auth/scope.go +++ b/internal/grpc/interceptors/auth/scope.go @@ -195,7 +195,7 @@ func extractShareRef(req interface{}) (*collaboration.ShareReference, bool) { case *collaboration.GetReceivedShareRequest: return v.GetRef(), true case *collaboration.UpdateReceivedShareRequest: - return v.GetRef(), true + return &collaboration.ShareReference{Spec: &collaboration.ShareReference_Id{Id: v.GetShare().GetShare().GetId()}}, true } return nil, false } diff --git a/internal/grpc/services/gateway/ocmshareprovider.go b/internal/grpc/services/gateway/ocmshareprovider.go index d1d686a846..bd7ebb76bb 100644 --- a/internal/grpc/services/gateway/ocmshareprovider.go +++ b/internal/grpc/services/gateway/ocmshareprovider.go @@ -224,54 +224,64 @@ func (s *svc) UpdateReceivedOCMShare(ctx context.Context, req *ocm.UpdateReceive return res, nil } - // we don't commit to storage invalid update fields or empty display names. - if req.Field.GetState() == ocm.ShareState_SHARE_STATE_INVALID && req.Field.GetDisplayName() == "" { - log.Error().Msg("the update field is invalid, aborting reference manipulation") - return res, nil - - } - - // TODO(labkode): if update field is displayName we need to do a rename on the storage to align - // share display name and storage filename. - if req.Field.GetState() != ocm.ShareState_SHARE_STATE_INVALID { - if req.Field.GetState() == ocm.ShareState_SHARE_STATE_ACCEPTED { - getShareReq := &ocm.GetReceivedOCMShareRequest{Ref: req.Ref} - getShareRes, err := s.GetReceivedOCMShare(ctx, getShareReq) - if err != nil { - log.Err(err).Msg("gateway: error calling GetReceivedShare") - return &ocm.UpdateReceivedOCMShareResponse{ - Status: &rpc.Status{ - Code: rpc.Code_CODE_INTERNAL, + // properties are updated in the order they appear in the field mask + // when an error occurs the request ends and no further fields are updated + for i := range req.UpdateMask.Paths { + switch req.UpdateMask.Paths[i] { + case "state": + switch req.GetShare().GetState() { + case ocm.ShareState_SHARE_STATE_ACCEPTED: + getShareReq := &ocm.GetReceivedOCMShareRequest{ + Ref: &ocm.ShareReference{ + Spec: &ocm.ShareReference_Id{ + Id: req.Share.Share.Id, + }, }, - }, nil - } - - if getShareRes.Status.Code != rpc.Code_CODE_OK { - log.Error().Msg("gateway: error calling GetReceivedShare") + } + getShareRes, err := s.GetReceivedOCMShare(ctx, getShareReq) + if err != nil { + log.Err(err).Msg("gateway: error calling GetReceivedShare") + return &ocm.UpdateReceivedOCMShareResponse{ + Status: &rpc.Status{ + Code: rpc.Code_CODE_INTERNAL, + }, + }, nil + } + + if getShareRes.Status.Code != rpc.Code_CODE_OK { + log.Error().Msg("gateway: error calling GetReceivedShare") + return &ocm.UpdateReceivedOCMShareResponse{ + Status: &rpc.Status{ + Code: rpc.Code_CODE_INTERNAL, + }, + }, nil + } + + share := getShareRes.Share + if share == nil { + panic("gateway: error updating a received share: the share is nil") + } + + createRefStatus, err := s.createOCMReference(ctx, share.Share) return &ocm.UpdateReceivedOCMShareResponse{ - Status: &rpc.Status{ - Code: rpc.Code_CODE_INTERNAL, - }, - }, nil - } - - share := getShareRes.Share - if share == nil { - panic("gateway: error updating a received share: the share is nil") + Status: createRefStatus, + }, err + case ocm.ShareState_SHARE_STATE_REJECTED: + s.removeReference(ctx, req.GetShare().GetShare().ResourceId) // error is logged inside removeReference + // FIXME we are ignoring an error from removeReference here + return res, nil } - - createRefStatus, err := s.createOCMReference(ctx, share.Share) + case "mount_point": + // TODO(labkode): implementing updating mount point + err = errtypes.NotSupported("gateway: update of mount point is not yet implemented") return &ocm.UpdateReceivedOCMShareResponse{ - Status: createRefStatus, - }, err + Status: status.NewUnimplemented(ctx, err, "error updating received share"), + }, nil + default: + return nil, errtypes.NotSupported("updating " + req.UpdateMask.Paths[i] + " is not supported") } } - - // TODO(labkode): implementing updating display name - err = errtypes.NotSupported("gateway: update of display name is not yet implemented") - return &ocm.UpdateReceivedOCMShareResponse{ - Status: status.NewUnimplemented(ctx, err, "error updating received share"), - }, nil + return res, nil } func (s *svc) GetReceivedOCMShare(ctx context.Context, req *ocm.GetReceivedOCMShareRequest) (*ocm.GetReceivedOCMShareResponse, error) { diff --git a/internal/grpc/services/gateway/storageprovider.go b/internal/grpc/services/gateway/storageprovider.go index 84d24a3844..974349cac9 100644 --- a/internal/grpc/services/gateway/storageprovider.go +++ b/internal/grpc/services/gateway/storageprovider.go @@ -29,6 +29,7 @@ import ( "time" rtrace "github.com/cs3org/reva/pkg/trace" + "google.golang.org/protobuf/types/known/fieldmaskpb" collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" @@ -888,7 +889,7 @@ func (s *svc) Delete(ctx context.Context, req *provider.DeleteRequest) (*provide // the following will check that: // - the resource to delete is a share the current user received // - signal the storage the delete must not land in the trashbin - // - delete the resource and update the share status to pending + // - delete the resource and update the share status to "rejected" for _, share := range sRes.Shares { if statRes != nil && (share.Share.ResourceId.OpaqueId == statRes.Info.Id.OpaqueId) && (share.Share.ResourceId.StorageId == statRes.Info.Id.StorageId) { // this opaque needs explanation. It signals the storage the resource we're about to delete does not @@ -903,21 +904,13 @@ func (s *svc) Delete(ctx context.Context, req *provider.DeleteRequest) (*provide }, } - // the following block takes care of updating the state of the share to "pending". This will ensure the user + // the following block takes care of updating the state of the share to "rejected". This will ensure the user // can "Accept" the share once again. + // TODO should this be pending? If so, update the two comments above as well. If not, get rid of this comment. + share.State = collaboration.ShareState_SHARE_STATE_REJECTED r := &collaboration.UpdateReceivedShareRequest{ - Ref: &collaboration.ShareReference{ - Spec: &collaboration.ShareReference_Id{ - Id: &collaboration.ShareId{ - OpaqueId: share.Share.Id.OpaqueId, - }, - }, - }, - Field: &collaboration.UpdateReceivedShareRequest_UpdateField{ - Field: &collaboration.UpdateReceivedShareRequest_UpdateField_State{ - State: collaboration.ShareState_SHARE_STATE_REJECTED, - }, - }, + Share: share, + UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"state"}}, } _, err := s.UpdateReceivedShare(ctx, r) diff --git a/internal/grpc/services/gateway/usershareprovider.go b/internal/grpc/services/gateway/usershareprovider.go index 77f89bfc10..7243b4bae4 100644 --- a/internal/grpc/services/gateway/usershareprovider.go +++ b/internal/grpc/services/gateway/usershareprovider.go @@ -276,6 +276,27 @@ func (s *svc) GetReceivedShare(ctx context.Context, req *collaboration.GetReceiv // 2) if received share is not mounted: we only rename in user share provider. func (s *svc) UpdateReceivedShare(ctx context.Context, req *collaboration.UpdateReceivedShareRequest) (*collaboration.UpdateReceivedShareResponse, error) { log := appctx.GetLogger(ctx) + + // sanity checks + switch { + case req.GetShare() == nil: + return &collaboration.UpdateReceivedShareResponse{ + Status: status.NewInvalidArg(ctx, "updating requires a received share object"), + }, nil + case req.GetShare().GetShare() == nil: + return &collaboration.UpdateReceivedShareResponse{ + Status: status.NewInvalidArg(ctx, "share missing"), + }, nil + case req.GetShare().GetShare().GetId() == nil: + return &collaboration.UpdateReceivedShareResponse{ + Status: status.NewInvalidArg(ctx, "share id missing"), + }, nil + case req.GetShare().GetShare().GetId().GetOpaqueId() == "": + return &collaboration.UpdateReceivedShareResponse{ + Status: status.NewInvalidArg(ctx, "share id empty"), + }, nil + } + c, err := pool.GetUserShareProviderClient(s.c.UserShareProviderEndpoint) if err != nil { err = errors.Wrap(err, "gateway: error calling GetUserShareProviderClient") @@ -304,39 +325,44 @@ func (s *svc) UpdateReceivedShare(ctx context.Context, req *collaboration.Update return res, nil } - // we don't commit to storage invalid update fields or empty display names. - if req.Field.GetState() == collaboration.ShareState_SHARE_STATE_INVALID && req.Field.GetDisplayName() == "" { - log.Error().Msg("the update field is invalid, aborting reference manipulation") - return res, nil - + // check if we have a resource id in the update response that we can use to update references + if res.GetShare().GetShare().GetResourceId() == nil { + log.Err(err).Msg("gateway: UpdateReceivedShare must return a ResourceId") + return &collaboration.UpdateReceivedShareResponse{ + Status: &rpc.Status{ + Code: rpc.Code_CODE_INTERNAL, + }, + }, nil } - // TODO(labkode): if update field is displayName we need to do a rename on the storage to align - // share display name and storage filename. - if req.Field.GetState() != collaboration.ShareState_SHARE_STATE_INVALID { - if req.Field.GetState() == collaboration.ShareState_SHARE_STATE_ACCEPTED { - share := res.Share - if share == nil { - panic("gateway: error updating a received share: the share is nil") + // properties are updated in the order they appear in the field mask + // when an error occurs the request ends and no further fields are updated + for i := range req.UpdateMask.Paths { + switch req.UpdateMask.Paths[i] { + case "state": + switch req.GetShare().GetState() { + case collaboration.ShareState_SHARE_STATE_ACCEPTED: + rpcStatus := s.createReference(ctx, res.GetShare().GetShare().GetResourceId()) + if rpcStatus.Code != rpc.Code_CODE_OK { + return &collaboration.UpdateReceivedShareResponse{Status: rpcStatus}, nil + } + case collaboration.ShareState_SHARE_STATE_REJECTED: + rpcStatus := s.removeReference(ctx, res.GetShare().GetShare().ResourceId) + if rpcStatus.Code != rpc.Code_CODE_OK && rpcStatus.Code != rpc.Code_CODE_NOT_FOUND { + return &collaboration.UpdateReceivedShareResponse{Status: rpcStatus}, nil + } } - createRefStatus := s.createReference(ctx, share.Share.ResourceId) - rsp := &collaboration.UpdateReceivedShareResponse{Status: createRefStatus} - - if createRefStatus.Code == rpc.Code_CODE_OK { - rsp.Share = share - } - return rsp, nil - } else if req.Field.GetState() == collaboration.ShareState_SHARE_STATE_REJECTED { - s.removeReference(ctx, res.Share.Share.ResourceId) - return res, nil + case "mount_point": + // TODO(labkode): implementing updating mount point + err = errtypes.NotSupported("gateway: update of mount point is not yet implemented") + return &collaboration.UpdateReceivedShareResponse{ + Status: status.NewUnimplemented(ctx, err, "error updating received share"), + }, nil + default: + return nil, errtypes.NotSupported("updating " + req.UpdateMask.Paths[i] + " is not supported") } } - - // TODO(labkode): implementing updating display name - err = errtypes.NotSupported("gateway: update of display name is not yet implemented") - return &collaboration.UpdateReceivedShareResponse{ - Status: status.NewUnimplemented(ctx, err, "error updating received share"), - }, nil + return res, nil } func (s *svc) removeReference(ctx context.Context, resourceID *provider.ResourceId) *rpc.Status { diff --git a/internal/grpc/services/ocmshareprovider/ocmshareprovider.go b/internal/grpc/services/ocmshareprovider/ocmshareprovider.go index 1b4e8676db..78543eb799 100644 --- a/internal/grpc/services/ocmshareprovider/ocmshareprovider.go +++ b/internal/grpc/services/ocmshareprovider/ocmshareprovider.go @@ -247,7 +247,7 @@ func (s *service) ListReceivedOCMShares(ctx context.Context, req *ocm.ListReceiv } func (s *service) UpdateReceivedOCMShare(ctx context.Context, req *ocm.UpdateReceivedOCMShareRequest) (*ocm.UpdateReceivedOCMShareResponse, error) { - _, err := s.sm.UpdateReceivedShare(ctx, req.Ref, req.Field) // TODO(labkode): check what to update + _, err := s.sm.UpdateReceivedShare(ctx, req.Share, req.UpdateMask) // TODO(labkode): check what to update if err != nil { return &ocm.UpdateReceivedOCMShareResponse{ Status: status.NewInternal(ctx, err, "error updating received share"), diff --git a/internal/grpc/services/usershareprovider/usershareprovider.go b/internal/grpc/services/usershareprovider/usershareprovider.go index 5fb5a2e77f..9f5b0d1fc8 100644 --- a/internal/grpc/services/usershareprovider/usershareprovider.go +++ b/internal/grpc/services/usershareprovider/usershareprovider.go @@ -231,7 +231,7 @@ func (s *service) GetReceivedShare(ctx context.Context, req *collaboration.GetRe } func (s *service) UpdateReceivedShare(ctx context.Context, req *collaboration.UpdateReceivedShareRequest) (*collaboration.UpdateReceivedShareResponse, error) { - share, err := s.sm.UpdateReceivedShare(ctx, req.Ref, req.Field) // TODO(labkode): check what to update + share, err := s.sm.UpdateReceivedShare(ctx, req.Share, req.UpdateMask) // TODO(labkode): check what to update if err != nil { return &collaboration.UpdateReceivedShareResponse{ Status: status.NewInternal(ctx, err, "error updating received share"), diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/pending.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/pending.go index 76bc15fbef..1fe1bf5d39 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/pending.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/pending.go @@ -30,6 +30,7 @@ import ( "github.com/cs3org/reva/pkg/rgrpc/todo/pool" "github.com/go-chi/chi/v5" "github.com/pkg/errors" + "google.golang.org/protobuf/types/known/fieldmaskpb" ) // AcceptReceivedShare handles Post Requests on /apps/files_sharing/api/v1/shares/{shareid} @@ -54,28 +55,17 @@ func (h *Handler) updateReceivedShare(w http.ResponseWriter, r *http.Request, sh return } - ref := &collaboration.ShareReference{ - Spec: &collaboration.ShareReference_Id{ - Id: &collaboration.ShareId{ - OpaqueId: shareID, - }, - }, - } - shareRequest := &collaboration.UpdateReceivedShareRequest{ - Ref: ref, - Field: &collaboration.UpdateReceivedShareRequest_UpdateField{ - Field: &collaboration.UpdateReceivedShareRequest_UpdateField_State{ - State: collaboration.ShareState_SHARE_STATE_ACCEPTED, - }, + Share: &collaboration.ReceivedShare{ + Share: &collaboration.Share{Id: &collaboration.ShareId{OpaqueId: shareID}}, }, + UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"state"}}, } if rejectShare { - shareRequest.Field = &collaboration.UpdateReceivedShareRequest_UpdateField{ - Field: &collaboration.UpdateReceivedShareRequest_UpdateField_State{ - State: collaboration.ShareState_SHARE_STATE_REJECTED, - }, - } + shareRequest.Share.State = collaboration.ShareState_SHARE_STATE_REJECTED + } else { + // TODO find free mount point and pass it on with an updated field mask + shareRequest.Share.State = collaboration.ShareState_SHARE_STATE_ACCEPTED } shareRes, err := client.UpdateReceivedShare(ctx, shareRequest) diff --git a/pkg/auth/scope/receivedshare.go b/pkg/auth/scope/receivedshare.go index cc9b90353f..3fe2e99594 100644 --- a/pkg/auth/scope/receivedshare.go +++ b/pkg/auth/scope/receivedshare.go @@ -39,7 +39,7 @@ func receivedShareScope(scope *authpb.Scope, resource interface{}) (bool, error) case *collaboration.GetReceivedShareRequest: return checkShareRef(share.Share, v.GetRef()), nil case *collaboration.UpdateReceivedShareRequest: - return checkShareRef(share.Share, v.GetRef()), nil + return checkShare(share.Share, v.GetShare().GetShare()), nil case string: return checkSharePath(v) || checkResourcePath(v), nil } diff --git a/pkg/auth/scope/share.go b/pkg/auth/scope/share.go index de26f62a02..069a2d7d2a 100644 --- a/pkg/auth/scope/share.go +++ b/pkg/auth/scope/share.go @@ -90,6 +90,12 @@ func checkShareRef(s *collaboration.Share, ref *collaboration.ShareReference) bo } return false } +func checkShare(s1 *collaboration.Share, s2 *collaboration.Share) bool { + if s2.GetId() != nil { + return s2.GetId().OpaqueId == s1.Id.OpaqueId + } + return false +} func checkSharePath(path string) bool { paths := []string{ diff --git a/pkg/cbox/share/sql/sql.go b/pkg/cbox/share/sql/sql.go index 675f40ba0a..2cfe7d57e0 100644 --- a/pkg/cbox/share/sql/sql.go +++ b/pkg/cbox/share/sql/sql.go @@ -38,6 +38,7 @@ import ( "github.com/cs3org/reva/pkg/utils" "github.com/mitchellh/mapstructure" "github.com/pkg/errors" + "google.golang.org/genproto/protobuf/field_mask" // Provides mysql drivers _ "github.com/go-sql-driver/mysql" @@ -435,17 +436,26 @@ func (m *mgr) GetReceivedShare(ctx context.Context, ref *collaboration.ShareRefe } -func (m *mgr) UpdateReceivedShare(ctx context.Context, ref *collaboration.ShareReference, f *collaboration.UpdateReceivedShareRequest_UpdateField) (*collaboration.ReceivedShare, error) { +func (m *mgr) UpdateReceivedShare(ctx context.Context, share *collaboration.ReceivedShare, fieldMask *field_mask.FieldMask) (*collaboration.ReceivedShare, error) { user := ctxpkg.ContextMustGetUser(ctx) - rs, err := m.GetReceivedShare(ctx, ref) + rs, err := m.GetReceivedShare(ctx, &collaboration.ShareReference{Spec: &collaboration.ShareReference_Id{Id: share.Share.Id}}) if err != nil { return nil, err } + for i := range fieldMask.Paths { + switch fieldMask.Paths[i] { + case "state": + rs.State = share.State + default: + return nil, errtypes.NotSupported("updating " + fieldMask.Paths[i] + " is not supported") + } + } + var query, queryAccept string params := []interface{}{rs.Share.Id.OpaqueId, conversions.FormatUserID(user.Id)} - switch f.GetState() { + switch rs.GetState() { case collaboration.ShareState_SHARE_STATE_REJECTED: query = "insert into oc_share_acl(id, rejected_by) values(?, ?)" case collaboration.ShareState_SHARE_STATE_ACCEPTED: @@ -473,6 +483,5 @@ func (m *mgr) UpdateReceivedShare(ctx context.Context, ref *collaboration.ShareR } } - rs.State = f.GetState() return rs, nil } diff --git a/pkg/ocm/share/manager/json/json.go b/pkg/ocm/share/manager/json/json.go index f8b7f7fdc0..2d91faa42c 100644 --- a/pkg/ocm/share/manager/json/json.go +++ b/pkg/ocm/share/manager/json/json.go @@ -45,6 +45,7 @@ import ( "github.com/google/uuid" "github.com/mitchellh/mapstructure" "github.com/pkg/errors" + "google.golang.org/genproto/protobuf/field_mask" ) const createOCMCoreShareEndpoint = "shares" @@ -630,8 +631,8 @@ func (m *mgr) getReceived(ctx context.Context, ref *ocm.ShareReference) (*ocm.Re return nil, errtypes.NotFound(ref.String()) } -func (m *mgr) UpdateReceivedShare(ctx context.Context, ref *ocm.ShareReference, f *ocm.UpdateReceivedOCMShareRequest_UpdateField) (*ocm.ReceivedShare, error) { - rs, err := m.getReceived(ctx, ref) +func (m *mgr) UpdateReceivedShare(ctx context.Context, share *ocm.ReceivedShare, fieldMask *field_mask.FieldMask) (*ocm.ReceivedShare, error) { + rs, err := m.getReceived(ctx, &ocm.ShareReference{Spec: &ocm.ShareReference_Id{Id: share.Share.Id}}) if err != nil { return nil, err } @@ -639,12 +640,21 @@ func (m *mgr) UpdateReceivedShare(ctx context.Context, ref *ocm.ShareReference, m.Lock() defer m.Unlock() + for i := range fieldMask.Paths { + switch fieldMask.Paths[i] { + case "state": + rs.State = share.State + // TODO case "mount_point": + default: + return nil, errtypes.NotSupported("updating " + fieldMask.Paths[i] + " is not supported") + } + } + if err := m.model.ReadFile(); err != nil { err = errors.Wrap(err, "error reading model") return nil, err } - rs.State = f.GetState() encShare, err := utils.MarshalProtoV1ToJSON(rs) if err != nil { return nil, err diff --git a/pkg/ocm/share/share.go b/pkg/ocm/share/share.go index e4b7d1188d..522c3dc837 100644 --- a/pkg/ocm/share/share.go +++ b/pkg/ocm/share/share.go @@ -25,6 +25,7 @@ import ( ocmprovider "github.com/cs3org/go-cs3apis/cs3/ocm/provider/v1beta1" ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + "google.golang.org/genproto/protobuf/field_mask" ) // Manager is the interface that manipulates the OCM shares. @@ -53,7 +54,7 @@ type Manager interface { GetReceivedShare(ctx context.Context, ref *ocm.ShareReference) (*ocm.ReceivedShare, error) // UpdateReceivedShare updates the received share with share state. - UpdateReceivedShare(ctx context.Context, ref *ocm.ShareReference, f *ocm.UpdateReceivedOCMShareRequest_UpdateField) (*ocm.ReceivedShare, error) + UpdateReceivedShare(ctx context.Context, share *ocm.ReceivedShare, fieldMask *field_mask.FieldMask) (*ocm.ReceivedShare, error) } // ResourceIDFilter is an abstraction for creating filter by resource id. diff --git a/pkg/share/manager/json/json.go b/pkg/share/manager/json/json.go index fe47803f94..026682ce33 100644 --- a/pkg/share/manager/json/json.go +++ b/pkg/share/manager/json/json.go @@ -35,6 +35,7 @@ import ( "github.com/google/uuid" "github.com/mitchellh/mapstructure" "github.com/pkg/errors" + "google.golang.org/genproto/protobuf/field_mask" "github.com/cs3org/reva/pkg/share/manager/registry" "github.com/cs3org/reva/pkg/utils" @@ -448,8 +449,8 @@ func (m *mgr) getReceived(ctx context.Context, ref *collaboration.ShareReference return nil, errtypes.NotFound(ref.String()) } -func (m *mgr) UpdateReceivedShare(ctx context.Context, ref *collaboration.ShareReference, f *collaboration.UpdateReceivedShareRequest_UpdateField) (*collaboration.ReceivedShare, error) { - rs, err := m.getReceived(ctx, ref) +func (m *mgr) UpdateReceivedShare(ctx context.Context, receivedShare *collaboration.ReceivedShare, fieldMask *field_mask.FieldMask) (*collaboration.ReceivedShare, error) { + rs, err := m.getReceived(ctx, &collaboration.ShareReference{Spec: &collaboration.ShareReference_Id{Id: receivedShare.Share.Id}}) if err != nil { return nil, err } @@ -458,12 +459,22 @@ func (m *mgr) UpdateReceivedShare(ctx context.Context, ref *collaboration.ShareR m.Lock() defer m.Unlock() + for i := range fieldMask.Paths { + switch fieldMask.Paths[i] { + case "state": + rs.State = receivedShare.State + // TODO case "mount_point": + default: + return nil, errtypes.NotSupported("updating " + fieldMask.Paths[i] + " is not supported") + } + } + if v, ok := m.model.State[user.Id.String()]; ok { - v[rs.Share.Id.String()] = f.GetState() + v[rs.Share.Id.String()] = rs.GetState() m.model.State[user.Id.String()] = v } else { a := map[string]collaboration.ShareState{ - rs.Share.Id.String(): f.GetState(), + rs.Share.Id.String(): rs.GetState(), } m.model.State[user.Id.String()] = a } @@ -473,6 +484,5 @@ func (m *mgr) UpdateReceivedShare(ctx context.Context, ref *collaboration.ShareR return nil, err } - rs.State = f.GetState() return rs, nil } diff --git a/pkg/share/manager/memory/memory.go b/pkg/share/manager/memory/memory.go index 8f84c77d9b..fb365d7aa8 100644 --- a/pkg/share/manager/memory/memory.go +++ b/pkg/share/manager/memory/memory.go @@ -28,6 +28,7 @@ import ( ctxpkg "github.com/cs3org/reva/pkg/ctx" "github.com/cs3org/reva/pkg/share" + "google.golang.org/genproto/protobuf/field_mask" collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" @@ -309,8 +310,8 @@ func (m *manager) getReceived(ctx context.Context, ref *collaboration.ShareRefer return nil, errtypes.NotFound(ref.String()) } -func (m *manager) UpdateReceivedShare(ctx context.Context, ref *collaboration.ShareReference, f *collaboration.UpdateReceivedShareRequest_UpdateField) (*collaboration.ReceivedShare, error) { - rs, err := m.getReceived(ctx, ref) +func (m *manager) UpdateReceivedShare(ctx context.Context, receivedShare *collaboration.ReceivedShare, fieldMask *field_mask.FieldMask) (*collaboration.ReceivedShare, error) { + rs, err := m.getReceived(ctx, &collaboration.ShareReference{Spec: &collaboration.ShareReference_Id{Id: receivedShare.Share.Id}}) if err != nil { return nil, err } @@ -319,16 +320,25 @@ func (m *manager) UpdateReceivedShare(ctx context.Context, ref *collaboration.Sh m.lock.Lock() defer m.lock.Unlock() + for i := range fieldMask.Paths { + switch fieldMask.Paths[i] { + case "state": + rs.State = receivedShare.State + // TODO case "mount_point": + default: + return nil, errtypes.NotSupported("updating " + fieldMask.Paths[i] + " is not supported") + } + } + if v, ok := m.shareState[user.Id.String()]; ok { - v[rs.Share.Id] = f.GetState() + v[rs.Share.Id] = rs.GetState() m.shareState[user.Id.String()] = v } else { a := map[*collaboration.ShareId]collaboration.ShareState{ - rs.Share.Id: f.GetState(), + rs.Share.Id: rs.GetState(), } m.shareState[user.Id.String()] = a } - rs.State = f.GetState() return rs, nil } diff --git a/pkg/share/manager/nextcloud/nextcloud.go b/pkg/share/manager/nextcloud/nextcloud.go index 3b1de3d1e5..44e1985a09 100644 --- a/pkg/share/manager/nextcloud/nextcloud.go +++ b/pkg/share/manager/nextcloud/nextcloud.go @@ -39,6 +39,7 @@ import ( "github.com/cs3org/reva/pkg/share/manager/registry" "github.com/mitchellh/mapstructure" "github.com/pkg/errors" + "google.golang.org/genproto/protobuf/field_mask" ) func init() { @@ -403,13 +404,29 @@ func (sm *mgr) GetReceivedShare(ctx context.Context, ref *collaboration.ShareRef } // UpdateReceivedShare updates the received share with share state. -func (sm *mgr) UpdateReceivedShare(ctx context.Context, ref *collaboration.ShareReference, f *collaboration.UpdateReceivedShareRequest_UpdateField) (*collaboration.ReceivedShare, error) { +func (sm *mgr) UpdateReceivedShare(ctx context.Context, receivedShare *collaboration.ReceivedShare, fieldMask *field_mask.FieldMask) (*collaboration.ReceivedShare, error) { + type updateField struct { + State collaboration.ShareState `json:"state"` + // TODO: Add support for the new mountpoint field + } type paramsObj struct { - Ref *collaboration.ShareReference `json:"ref"` - F *collaboration.UpdateReceivedShareRequest_UpdateField `json:"f"` + Ref *collaboration.ShareReference `json:"ref"` + F *updateField `json:"f"` + } + + f := &updateField{} + for i := range fieldMask.Paths { + switch fieldMask.Paths[i] { + case "state": + f.State = receivedShare.State + // TODO case "mount_point": + default: + return nil, errtypes.NotSupported("updating " + fieldMask.Paths[i] + " is not supported") + } } + bodyObj := ¶msObj{ - Ref: ref, + Ref: &collaboration.ShareReference{Spec: &collaboration.ShareReference_Id{Id: receivedShare.Share.Id}}, F: f, } bodyStr, err := json.Marshal(bodyObj) diff --git a/pkg/share/manager/nextcloud/nextcloud_test.go b/pkg/share/manager/nextcloud/nextcloud_test.go index 4d7a305242..2a826d1a73 100644 --- a/pkg/share/manager/nextcloud/nextcloud_test.go +++ b/pkg/share/manager/nextcloud/nextcloud_test.go @@ -726,96 +726,4 @@ var _ = Describe("Nextcloud", func() { Expect(called[0]).To(Equal(`POST /apps/sciencemesh/~tester/api/share/GetReceivedShare {"Spec":{"Id":{"opaque_id":"some-share-id"}}}`)) }) }) - - // UpdateReceivedShare(ctx context.Context, ref *collaboration.ShareReference, f *collaboration.UpdateReceivedShareRequest_UpdateField) (*collaboration.ReceivedShare, error) - Describe("UpdateReceivedShare", func() { - It("calls the UpdateReceivedShare endpoint", func() { - called := make([]string, 0) - - h := nextcloud.GetNextcloudServerMock(&called) - mock, teardown := nextcloud.TestingHTTPClient(h) - defer teardown() - am, _ := nextcloud.NewShareManager(&nextcloud.ShareManagerConfig{ - EndPoint: "http://mock.com/apps/sciencemesh/", - }, mock) - receivedShare, err := am.UpdateReceivedShare(ctx, &collaboration.ShareReference{ - Spec: &collaboration.ShareReference_Id{ - Id: &collaboration.ShareId{ - OpaqueId: "some-share-id", - }, - }, - }, - &collaboration.UpdateReceivedShareRequest_UpdateField{ - Field: &collaboration.UpdateReceivedShareRequest_UpdateField_DisplayName{ - DisplayName: "some new name for this received share", - }, - }) - Expect(err).ToNot(HaveOccurred()) - Expect(*receivedShare).To(Equal(collaboration.ReceivedShare{ - Share: &collaboration.Share{ - Id: &collaboration.ShareId{}, - ResourceId: &provider.ResourceId{}, - Permissions: &collaboration.SharePermissions{ - Permissions: &provider.ResourcePermissions{ - AddGrant: true, - CreateContainer: true, - Delete: true, - GetPath: true, - GetQuota: true, - InitiateFileDownload: true, - InitiateFileUpload: true, - ListGrants: true, - ListContainer: true, - ListFileVersions: true, - ListRecycle: true, - Move: true, - RemoveGrant: true, - PurgeRecycle: true, - RestoreFileVersion: true, - RestoreRecycleItem: true, - Stat: true, - UpdateGrant: true, - DenyGrant: true, - }, - }, - Grantee: &provider.Grantee{ - Id: &provider.Grantee_UserId{ - UserId: &userpb.UserId{ - Idp: "0.0.0.0:19000", - OpaqueId: "f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c", - Type: userpb.UserType_USER_TYPE_PRIMARY, - }, - }, - }, - Owner: &userpb.UserId{ - Idp: "0.0.0.0:19000", - OpaqueId: "f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c", - Type: userpb.UserType_USER_TYPE_PRIMARY, - }, - Creator: &userpb.UserId{ - Idp: "0.0.0.0:19000", - OpaqueId: "f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c", - Type: userpb.UserType_USER_TYPE_PRIMARY, - }, - Ctime: &types.Timestamp{ - Seconds: 1234567890, - Nanos: 0, - XXX_NoUnkeyedLiteral: struct{}{}, - XXX_unrecognized: nil, - XXX_sizecache: 0, - }, - Mtime: &types.Timestamp{ - Seconds: 1234567890, - Nanos: 0, - XXX_NoUnkeyedLiteral: struct{}{}, - XXX_unrecognized: nil, - XXX_sizecache: 0, - }, - }, - State: collaboration.ShareState_SHARE_STATE_ACCEPTED, - })) - Expect(called[0]).To(Equal(`POST /apps/sciencemesh/~tester/api/share/UpdateReceivedShare {"ref":{"Spec":{"Id":{"opaque_id":"some-share-id"}}},"f":{"Field":{"DisplayName":"some new name for this received share"}}}`)) - }) - }) - }) diff --git a/pkg/share/manager/sql/sql.go b/pkg/share/manager/sql/sql.go index c43ef2b377..516bcbf526 100644 --- a/pkg/share/manager/sql/sql.go +++ b/pkg/share/manager/sql/sql.go @@ -37,6 +37,7 @@ import ( "github.com/cs3org/reva/pkg/utils" "github.com/mitchellh/mapstructure" "github.com/pkg/errors" + "google.golang.org/genproto/protobuf/field_mask" // Provides mysql drivers _ "github.com/go-sql-driver/mysql" @@ -382,14 +383,24 @@ func (m *mgr) GetReceivedShare(ctx context.Context, ref *collaboration.ShareRefe } -func (m *mgr) UpdateReceivedShare(ctx context.Context, ref *collaboration.ShareReference, f *collaboration.UpdateReceivedShareRequest_UpdateField) (*collaboration.ReceivedShare, error) { - rs, err := m.GetReceivedShare(ctx, ref) +func (m *mgr) UpdateReceivedShare(ctx context.Context, share *collaboration.ReceivedShare, fieldMask *field_mask.FieldMask) (*collaboration.ReceivedShare, error) { + rs, err := m.GetReceivedShare(ctx, &collaboration.ShareReference{Spec: &collaboration.ShareReference_Id{Id: share.Share.Id}}) if err != nil { return nil, err } + for i := range fieldMask.Paths { + switch fieldMask.Paths[i] { + case "state": + rs.State = share.State + // TODO case "mount_point": + default: + return nil, errtypes.NotSupported("updating " + fieldMask.Paths[i] + " is not supported") + } + } + var queryAccept string - switch f.GetState() { + switch rs.GetState() { case collaboration.ShareState_SHARE_STATE_REJECTED: queryAccept = "update oc_share set accepted=2 where id=?" case collaboration.ShareState_SHARE_STATE_ACCEPTED: @@ -407,7 +418,6 @@ func (m *mgr) UpdateReceivedShare(ctx context.Context, ref *collaboration.ShareR } } - rs.State = f.GetState() return rs, nil } diff --git a/pkg/share/manager/sql/sql_test.go b/pkg/share/manager/sql/sql_test.go index aba406862a..016ced3044 100644 --- a/pkg/share/manager/sql/sql_test.go +++ b/pkg/share/manager/sql/sql_test.go @@ -32,6 +32,7 @@ import ( "github.com/cs3org/reva/pkg/share" sqlmanager "github.com/cs3org/reva/pkg/share/manager/sql" mocks "github.com/cs3org/reva/pkg/share/manager/sql/mocks" + "google.golang.org/protobuf/types/known/fieldmaskpb" _ "github.com/mattn/go-sqlite3" "github.com/stretchr/testify/mock" @@ -199,7 +200,7 @@ var _ = Describe("SQL manager", func() { }) Describe("UpdateReceivedShare", func() { - It("updates the received share", func() { + It("returns an error when no valid field is set in the mask", func() { loginAs(otherUser) share, err := mgr.GetReceivedShare(ctx, shareRef) @@ -207,11 +208,21 @@ var _ = Describe("SQL manager", func() { Expect(share).ToNot(BeNil()) Expect(share.State).To(Equal(collaboration.ShareState_SHARE_STATE_ACCEPTED)) - share, err = mgr.UpdateReceivedShare(ctx, shareRef, &collaboration.UpdateReceivedShareRequest_UpdateField{ - Field: &collaboration.UpdateReceivedShareRequest_UpdateField_State{ - State: collaboration.ShareState_SHARE_STATE_REJECTED, - }, - }) + share.State = collaboration.ShareState_SHARE_STATE_REJECTED + _, err = mgr.UpdateReceivedShare(ctx, share, &fieldmaskpb.FieldMask{Paths: []string{"foo"}}) + Expect(err).To(HaveOccurred()) + }) + + It("updates the state when the state is set in the mask", func() { + loginAs(otherUser) + + share, err := mgr.GetReceivedShare(ctx, shareRef) + Expect(err).ToNot(HaveOccurred()) + Expect(share).ToNot(BeNil()) + Expect(share.State).To(Equal(collaboration.ShareState_SHARE_STATE_ACCEPTED)) + + share.State = collaboration.ShareState_SHARE_STATE_REJECTED + share, err = mgr.UpdateReceivedShare(ctx, share, &fieldmaskpb.FieldMask{Paths: []string{"state"}}) Expect(err).ToNot(HaveOccurred()) Expect(share.State).To(Equal(collaboration.ShareState_SHARE_STATE_REJECTED)) diff --git a/pkg/share/mocks/Manager.go b/pkg/share/mocks/Manager.go new file mode 100644 index 0000000000..5a80d362cf --- /dev/null +++ b/pkg/share/mocks/Manager.go @@ -0,0 +1,213 @@ +// Copyright 2018-2021 CERN +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// In applying this license, CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// Code generated by mockery v1.0.0. DO NOT EDIT. + +package mocks + +import ( + context "context" + + collaborationv1beta1 "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" + + fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb" + + mock "github.com/stretchr/testify/mock" + + providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" +) + +// Manager is an autogenerated mock type for the Manager type +type Manager struct { + mock.Mock +} + +// GetReceivedShare provides a mock function with given fields: ctx, ref +func (_m *Manager) GetReceivedShare(ctx context.Context, ref *collaborationv1beta1.ShareReference) (*collaborationv1beta1.ReceivedShare, error) { + ret := _m.Called(ctx, ref) + + var r0 *collaborationv1beta1.ReceivedShare + if rf, ok := ret.Get(0).(func(context.Context, *collaborationv1beta1.ShareReference) *collaborationv1beta1.ReceivedShare); ok { + r0 = rf(ctx, ref) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*collaborationv1beta1.ReceivedShare) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *collaborationv1beta1.ShareReference) error); ok { + r1 = rf(ctx, ref) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetShare provides a mock function with given fields: ctx, ref +func (_m *Manager) GetShare(ctx context.Context, ref *collaborationv1beta1.ShareReference) (*collaborationv1beta1.Share, error) { + ret := _m.Called(ctx, ref) + + var r0 *collaborationv1beta1.Share + if rf, ok := ret.Get(0).(func(context.Context, *collaborationv1beta1.ShareReference) *collaborationv1beta1.Share); ok { + r0 = rf(ctx, ref) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*collaborationv1beta1.Share) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *collaborationv1beta1.ShareReference) error); ok { + r1 = rf(ctx, ref) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListReceivedShares provides a mock function with given fields: ctx, filters +func (_m *Manager) ListReceivedShares(ctx context.Context, filters []*collaborationv1beta1.Filter) ([]*collaborationv1beta1.ReceivedShare, error) { + ret := _m.Called(ctx, filters) + + var r0 []*collaborationv1beta1.ReceivedShare + if rf, ok := ret.Get(0).(func(context.Context, []*collaborationv1beta1.Filter) []*collaborationv1beta1.ReceivedShare); ok { + r0 = rf(ctx, filters) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*collaborationv1beta1.ReceivedShare) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, []*collaborationv1beta1.Filter) error); ok { + r1 = rf(ctx, filters) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListShares provides a mock function with given fields: ctx, filters +func (_m *Manager) ListShares(ctx context.Context, filters []*collaborationv1beta1.Filter) ([]*collaborationv1beta1.Share, error) { + ret := _m.Called(ctx, filters) + + var r0 []*collaborationv1beta1.Share + if rf, ok := ret.Get(0).(func(context.Context, []*collaborationv1beta1.Filter) []*collaborationv1beta1.Share); ok { + r0 = rf(ctx, filters) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*collaborationv1beta1.Share) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, []*collaborationv1beta1.Filter) error); ok { + r1 = rf(ctx, filters) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Share provides a mock function with given fields: ctx, md, g +func (_m *Manager) Share(ctx context.Context, md *providerv1beta1.ResourceInfo, g *collaborationv1beta1.ShareGrant) (*collaborationv1beta1.Share, error) { + ret := _m.Called(ctx, md, g) + + var r0 *collaborationv1beta1.Share + if rf, ok := ret.Get(0).(func(context.Context, *providerv1beta1.ResourceInfo, *collaborationv1beta1.ShareGrant) *collaborationv1beta1.Share); ok { + r0 = rf(ctx, md, g) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*collaborationv1beta1.Share) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *providerv1beta1.ResourceInfo, *collaborationv1beta1.ShareGrant) error); ok { + r1 = rf(ctx, md, g) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Unshare provides a mock function with given fields: ctx, ref +func (_m *Manager) Unshare(ctx context.Context, ref *collaborationv1beta1.ShareReference) error { + ret := _m.Called(ctx, ref) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *collaborationv1beta1.ShareReference) error); ok { + r0 = rf(ctx, ref) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// UpdateReceivedShare provides a mock function with given fields: ctx, _a1, fieldMask +func (_m *Manager) UpdateReceivedShare(ctx context.Context, _a1 *collaborationv1beta1.ReceivedShare, fieldMask *fieldmaskpb.FieldMask) (*collaborationv1beta1.ReceivedShare, error) { + ret := _m.Called(ctx, _a1, fieldMask) + + var r0 *collaborationv1beta1.ReceivedShare + if rf, ok := ret.Get(0).(func(context.Context, *collaborationv1beta1.ReceivedShare, *fieldmaskpb.FieldMask) *collaborationv1beta1.ReceivedShare); ok { + r0 = rf(ctx, _a1, fieldMask) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*collaborationv1beta1.ReceivedShare) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *collaborationv1beta1.ReceivedShare, *fieldmaskpb.FieldMask) error); ok { + r1 = rf(ctx, _a1, fieldMask) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateShare provides a mock function with given fields: ctx, ref, p +func (_m *Manager) UpdateShare(ctx context.Context, ref *collaborationv1beta1.ShareReference, p *collaborationv1beta1.SharePermissions) (*collaborationv1beta1.Share, error) { + ret := _m.Called(ctx, ref, p) + + var r0 *collaborationv1beta1.Share + if rf, ok := ret.Get(0).(func(context.Context, *collaborationv1beta1.ShareReference, *collaborationv1beta1.SharePermissions) *collaborationv1beta1.Share); ok { + r0 = rf(ctx, ref, p) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*collaborationv1beta1.Share) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *collaborationv1beta1.ShareReference, *collaborationv1beta1.SharePermissions) error); ok { + r1 = rf(ctx, ref, p) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} diff --git a/pkg/share/share.go b/pkg/share/share.go index 9184e0d93c..9847216507 100644 --- a/pkg/share/share.go +++ b/pkg/share/share.go @@ -23,8 +23,11 @@ import ( collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + "google.golang.org/genproto/protobuf/field_mask" ) +//go:generate mockery -name Manager + // Manager is the interface that manipulates shares. type Manager interface { // Create a new share in fn with the given acl. @@ -50,7 +53,7 @@ type Manager interface { GetReceivedShare(ctx context.Context, ref *collaboration.ShareReference) (*collaboration.ReceivedShare, error) // UpdateReceivedShare updates the received share with share state. - UpdateReceivedShare(ctx context.Context, ref *collaboration.ShareReference, f *collaboration.UpdateReceivedShareRequest_UpdateField) (*collaboration.ReceivedShare, error) + UpdateReceivedShare(ctx context.Context, share *collaboration.ReceivedShare, fieldMask *field_mask.FieldMask) (*collaboration.ReceivedShare, error) } // GroupGranteeFilter is an abstraction for creating filter by grantee type group.