diff --git a/changelog/unreleased/fix_ocm_removegrant.md b/changelog/unreleased/fix_ocm_removegrant.md new file mode 100644 index 0000000000..f73559b40b --- /dev/null +++ b/changelog/unreleased/fix_ocm_removegrant.md @@ -0,0 +1,7 @@ +Bugfix: Deleting OCM share also updates storageprovider + +When remvoving an OCM share we're now also removing the related grant from +the storage provider. + +https://github.com/cs3org/reva/pull/4989 +https://github.com/owncloud/ocis/issues/10262 diff --git a/changelog/unreleased/ocm_sharecreated_event.md b/changelog/unreleased/ocm_sharecreated_event.md new file mode 100644 index 0000000000..15ced26f38 --- /dev/null +++ b/changelog/unreleased/ocm_sharecreated_event.md @@ -0,0 +1,4 @@ +Enhancement: Emit event when an ocm share is received + +https://github.com/cs3org/reva/pull/49xx +https://github.com/owncloud/ocis/issues/10718 diff --git a/internal/grpc/interceptors/eventsmiddleware/conversion.go b/internal/grpc/interceptors/eventsmiddleware/conversion.go index 1ed9ac9299..ed7a6c5054 100644 --- a/internal/grpc/interceptors/eventsmiddleware/conversion.go +++ b/internal/grpc/interceptors/eventsmiddleware/conversion.go @@ -23,6 +23,7 @@ import ( group "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1" user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + ocmcore "github.com/cs3org/go-cs3apis/cs3/ocm/core/v1beta1" collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" @@ -191,6 +192,26 @@ func LinkRemoved(r *link.RemovePublicShareResponse, req *link.RemovePublicShareR } } +func OCMCoreShareCreated(r *ocmcore.CreateOCMCoreShareResponse, req *ocmcore.CreateOCMCoreShareRequest, executant *user.User) events.OCMCoreShareCreated { + var permissions *provider.ResourcePermissions + for _, p := range req.GetProtocols() { + if p.GetWebdavOptions() != nil { + permissions = p.GetWebdavOptions().GetPermissions().GetPermissions() + break + } + } + return events.OCMCoreShareCreated{ + ShareID: r.GetId(), + Executant: executant.GetId(), + Sharer: req.GetSender(), + GranteeUserID: req.GetShareWith(), + ItemID: req.GetResourceId(), + ResourceName: req.GetName(), + CTime: r.GetCreated(), + Permissions: permissions, + } +} + // FileTouched converts the response to an event func FileTouched(r *provider.TouchFileResponse, req *provider.TouchFileRequest, spaceOwner *user.UserId, executant *user.User) events.FileTouched { return events.FileTouched{ diff --git a/internal/grpc/interceptors/eventsmiddleware/events.go b/internal/grpc/interceptors/eventsmiddleware/events.go index 0c77c4c951..6555b027ac 100644 --- a/internal/grpc/interceptors/eventsmiddleware/events.go +++ b/internal/grpc/interceptors/eventsmiddleware/events.go @@ -23,6 +23,7 @@ import ( "fmt" user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + ocmcore "github.com/cs3org/go-cs3apis/cs3/ocm/core/v1beta1" rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1" @@ -112,6 +113,10 @@ func NewUnary(m map[string]interface{}) (grpc.UnaryServerInterceptor, int, error } else { ev = LinkAccessFailed(v, req.(*link.GetPublicShareByTokenRequest), executant) } + case *ocmcore.CreateOCMCoreShareResponse: + if isSuccess(v) { + ev = OCMCoreShareCreated(v, req.(*ocmcore.CreateOCMCoreShareRequest), executant) + } case *provider.AddGrantResponse: // TODO: update CS3 APIs // FIXME these should be part of the RemoveGrantRequest object diff --git a/internal/grpc/services/gateway/ocmshareprovider.go b/internal/grpc/services/gateway/ocmshareprovider.go index d5e0f49916..4f8b943157 100644 --- a/internal/grpc/services/gateway/ocmshareprovider.go +++ b/internal/grpc/services/gateway/ocmshareprovider.go @@ -85,11 +85,37 @@ func (s *svc) RemoveOCMShare(ctx context.Context, req *ocm.RemoveOCMShareRequest }, nil } + getShareRes, err := c.GetOCMShare(ctx, &ocm.GetOCMShareRequest{ + Ref: req.Ref, + }) + if err != nil { + return nil, errors.Wrap(err, "gateway: error calling GetOCMShare") + } + if getShareRes.Status.Code != rpc.Code_CODE_OK { + res := &ocm.RemoveOCMShareResponse{ + Status: status.NewInternal(ctx, + "error getting ocm share when committing to the storage"), + } + return res, nil + } + share := getShareRes.Share + res, err := c.RemoveOCMShare(ctx, req) if err != nil { return nil, errors.Wrap(err, "gateway: error calling RemoveOCMShare") } + // remove the grant from the storage provider + status, err := s.removeGrant(ctx, share.GetResourceId(), share.GetGrantee(), share.GetAccessMethods()[0].GetWebdavOptions().GetPermissions(), nil) + if err != nil { + return nil, errors.Wrap(err, "gateway: error removing grant from storage") + } + if status.Code != rpc.Code_CODE_OK { + return &ocm.RemoveOCMShareResponse{ + Status: status, + }, err + } + return res, nil } diff --git a/pkg/events/ocmcore.go b/pkg/events/ocmcore.go new file mode 100644 index 0000000000..16661d535c --- /dev/null +++ b/pkg/events/ocmcore.go @@ -0,0 +1,46 @@ +// Copyright 2018-2024 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. + +package events + +import ( + "encoding/json" + + user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" +) + +// OCMCoreShareCreated is emitted when an ocm share is received +type OCMCoreShareCreated struct { + ShareID string + Executant *user.UserId + Sharer *user.UserId + GranteeUserID *user.UserId + ItemID string + ResourceName string + Permissions *provider.ResourcePermissions + CTime *types.Timestamp +} + +// Unmarshal to fulfill umarshaller interface +func (OCMCoreShareCreated) Unmarshal(v []byte) (interface{}, error) { + e := OCMCoreShareCreated{} + err := json.Unmarshal(v, &e) + return e, err +} diff --git a/pkg/ocm/storage/received/ocm.go b/pkg/ocm/storage/received/ocm.go index c76fe8141a..1b595eb017 100644 --- a/pkg/ocm/storage/received/ocm.go +++ b/pkg/ocm/storage/received/ocm.go @@ -33,7 +33,6 @@ import ( gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" - userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" ocmpb "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" @@ -539,7 +538,7 @@ func (d *driver) ListStorageSpaces(ctx context.Context, filters []*provider.List OpaqueId: storagespace.FormatResourceID(root), }, SpaceType: "mountpoint", - Owner: &userv1beta1.User{ + Owner: &userpb.User{ Id: share.Grantee.GetUserId(), }, Root: root, @@ -558,7 +557,7 @@ func (d *driver) ListStorageSpaces(ctx context.Context, filters []*provider.List OpaqueId: storagespace.FormatResourceID(root), }, SpaceType: "mountpoint", - Owner: &userv1beta1.User{ + Owner: &userpb.User{ Id: share.Grantee.GetUserId(), }, Root: root,