Skip to content

Commit

Permalink
allow accepting ocm shares via graph
Browse files Browse the repository at this point in the history
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
  • Loading branch information
butonic committed Apr 26, 2024
1 parent 17f3b91 commit 4e973f4
Show file tree
Hide file tree
Showing 5 changed files with 258 additions and 13 deletions.
61 changes: 61 additions & 0 deletions services/graph/mocks/base_graph_provider.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 62 additions & 0 deletions services/graph/mocks/drives_drive_item_provider.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

131 changes: 124 additions & 7 deletions services/graph/pkg/service/v0/api_drives_drive_item.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import (

gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1"
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/go-chi/render"
libregraph "github.com/owncloud/libre-graph-api-go"
"google.golang.org/protobuf/types/known/fieldmaskpb"

"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/storagespace"
"github.com/cs3org/reva/v2/pkg/utils"

"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/services/graph/pkg/errorcode"
Expand Down Expand Up @@ -76,6 +78,9 @@ type (
// MountShare mounts a share
MountShare(ctx context.Context, resourceID *storageprovider.ResourceId, name string) ([]*collaboration.ReceivedShare, error)

// MountOCMShare mounts an OCM share
MountOCMShare(ctx context.Context, resourceID *storageprovider.ResourceId, name string) ([]*ocm.ReceivedShare, error)

// UnmountShare unmounts a share
UnmountShare(ctx context.Context, shareID *collaboration.ShareId) error

Expand Down Expand Up @@ -235,6 +240,7 @@ func (s DrivesDriveItemService) UnmountShare(ctx context.Context, shareID *colla
// in some rare cases it could happen that none of the siblings could be mounted,
// then the error will be returned
func (s DrivesDriveItemService) MountShare(ctx context.Context, resourceID *storageprovider.ResourceId, name string) ([]*collaboration.ReceivedShare, error) {

if filepath.IsAbs(name) {
return nil, ErrAbsoluteNamePath
}
Expand Down Expand Up @@ -290,6 +296,106 @@ func (s DrivesDriveItemService) MountShare(ctx context.Context, resourceID *stor
return updatedShares, nil
}

func (s DrivesDriveItemService) MountOCMShare(ctx context.Context, resourceID *storageprovider.ResourceId, name string) ([]*ocm.ReceivedShare, error) {
gatewayClient, err := s.gatewaySelector.Next()
if err != nil {
return nil, err
}
receivedSharesResponse, err := gatewayClient.ListReceivedOCMShares(ctx, &ocm.ListReceivedOCMSharesRequest{
/* ocm has no filters, yet
Filters: []*collaboration.Filter{
{
Type: collaboration.Filter_TYPE_STATE,
Term: &collaboration.Filter_State{
State: collaboration.ShareState_SHARE_STATE_PENDING,
},
},
{
Type: collaboration.Filter_TYPE_STATE,
Term: &collaboration.Filter_State{
State: collaboration.ShareState_SHARE_STATE_REJECTED,
},
},
{
Type: collaboration.Filter_TYPE_RESOURCE_ID,
Term: &collaboration.Filter_ResourceId{
ResourceId: &resourceID,
},
},
},
*/
})
if err != nil {
return nil, err
}
if len(receivedSharesResponse.GetShares()) == 0 {
return nil, errorcode.New(errorcode.InvalidRequest, "invalid itemID")
}

var errs []error

var acceptedShares []*ocm.ReceivedShare

// try to accept all the received shares for this resource. So that the stat is in sync across all
// shares

for _, receivedShare := range receivedSharesResponse.GetShares() {
// we only accept shares that are for the same resource
if receivedShare.GetId().GetOpaqueId() != resourceID.GetSpaceId() {
continue
}
updateMask := &fieldmaskpb.FieldMask{Paths: []string{_fieldMaskPathState}}
receivedShare.State = ocm.ShareState_SHARE_STATE_ACCEPTED

// only update if mountPoint name is not empty and the path has changed
/* ocm shares have no mount point???
if name != "" {
mountPoint := receivedShare.GetMountPoint()
if mountPoint == nil {
mountPoint = &storageprovider.Reference{}
}
if filepath.Clean(mountPoint.GetPath()) != name {
mountPoint.Path = name
receivedShare.MountPoint = mountPoint
updateMask.Paths = append(updateMask.Paths, _fieldMaskPathMountPoint)
}
}
*/

updateReceivedShareRequest := &ocm.UpdateReceivedOCMShareRequest{
Share: receivedShare,
UpdateMask: updateMask,
}

gatewayClient, err = s.gatewaySelector.Next()
if err != nil {
return nil, err
}
updateReceivedShareResponse, err := gatewayClient.UpdateReceivedOCMShare(ctx, updateReceivedShareRequest)
switch errCode := errorcode.FromCS3Status(updateReceivedShareResponse.GetStatus(), err); {
case errCode == nil:
acceptedShares = append(acceptedShares, receivedShare)
default:
// Just log at debug level here. If a single accept for any of the received shares failed this
// is not a critical problem. We mainly need to handle the case where all accepts fail. (Outside
// the loop)
s.logger.Debug().Err(errCode).
Str("shareid", receivedShare.GetId().String()).
Str("remoteshareid", receivedShare.GetRemoteShareId()).
Msg("failed to accept ocm share")
errs = append(errs, errCode)
}
}

if len(receivedSharesResponse.GetShares()) == len(errs) {
// none of the received shares could be accepted. This is an error. Return it.
return nil, errors.Join(errs...)
}

return acceptedShares, nil
}

// DrivesDriveItemApi is the api that registers the http endpoints which expose needed operation to the graph api.
// the business logic is delegated to the space service and further down to the cs3 client.
type DrivesDriveItemApi struct {
Expand Down Expand Up @@ -419,15 +525,26 @@ func (api DrivesDriveItemApi) CreateDriveItem(w http.ResponseWriter, r *http.Req
return
}

mountedShares, err := api.drivesDriveItemService.
MountShare(ctx, &resourceId, requestDriveItem.GetName())
if err != nil {
api.logger.Debug().Err(err).Msg(ErrMountShare.Error())
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, ErrMountShare.Error())
return
var driveItems []libregraph.DriveItem
if resourceId.GetStorageId() == utils.OCMStorageProviderID {
mountedOcmShares, merr := api.drivesDriveItemService.MountOCMShare(ctx, &resourceId, requestDriveItem.GetName())
if merr != nil {
api.logger.Debug().Err(err).Msg(ErrMountShare.Error())
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, ErrMountShare.Error())
return
}
driveItems, err = api.baseGraphService.CS3ReceivedOCMSharesToDriveItems(ctx, mountedOcmShares)
} else {
// Get all shares that the user has received for this resource. There might be multiple
mountedShares, merr := api.drivesDriveItemService.MountShare(ctx, &resourceId, requestDriveItem.GetName())
if merr != nil {
api.logger.Debug().Err(err).Msg(ErrMountShare.Error())
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, ErrMountShare.Error())
return
}
driveItems, err = api.baseGraphService.CS3ReceivedSharesToDriveItems(ctx, mountedShares)
}

driveItems, err := api.baseGraphService.CS3ReceivedSharesToDriveItems(ctx, mountedShares)
switch {
case err != nil:
break
Expand Down
11 changes: 11 additions & 0 deletions services/graph/pkg/service/v0/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
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"
ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1"
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
Expand All @@ -34,6 +35,7 @@ import (
// BaseGraphProvider is the interface that wraps shared methods between the different graph providers
type BaseGraphProvider interface {
CS3ReceivedSharesToDriveItems(ctx context.Context, receivedShares []*collaboration.ReceivedShare) ([]libregraph.DriveItem, error)
CS3ReceivedOCMSharesToDriveItems(ctx context.Context, receivedOCMShares []*ocm.ReceivedShare) ([]libregraph.DriveItem, error)
}

// BaseGraphService implements a couple of helper functions that are
Expand Down Expand Up @@ -86,6 +88,15 @@ func (g BaseGraphService) CS3ReceivedSharesToDriveItems(ctx context.Context, rec
return cs3ReceivedSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, receivedShares)
}

func (g BaseGraphService) CS3ReceivedOCMSharesToDriveItems(ctx context.Context, receivedShares []*ocm.ReceivedShare) ([]libregraph.DriveItem, error) {
gatewayClient, err := g.gatewaySelector.Next()
if err != nil {
return nil, err
}

return cs3ReceivedOCMSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, receivedShares)
}

func (g BaseGraphService) cs3SpacePermissionsToLibreGraph(ctx context.Context, space *storageprovider.StorageSpace, apiVersion APIVersion) []libregraph.Permission {
if space.Opaque == nil {
return nil
Expand Down
6 changes: 0 additions & 6 deletions services/graph/pkg/service/v0/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,8 @@ import (
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1"
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"golang.org/x/sync/errgroup"

"github.com/cs3org/reva/v2/pkg/storagespace"
"github.com/cs3org/reva/v2/pkg/utils"
<<<<<<< HEAD

=======
>>>>>>> 3b76d7fff7 (work)
libregraph "github.com/owncloud/libre-graph-api-go"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/services/graph/pkg/errorcode"
Expand Down

0 comments on commit 4e973f4

Please sign in to comment.