From 6278273d5e0615bc400590cb3825f4b22dab77d7 Mon Sep 17 00:00:00 2001 From: Florian Schade Date: Tue, 30 Jan 2024 12:44:57 +0100 Subject: [PATCH] enhancement: add basic share unmount --- .../pkg/service/v0/api_drives_drive_item.go | 94 +++++++++++++++++-- 1 file changed, 85 insertions(+), 9 deletions(-) diff --git a/services/graph/pkg/service/v0/api_drives_drive_item.go b/services/graph/pkg/service/v0/api_drives_drive_item.go index acddf061a..77cd66ac6 100644 --- a/services/graph/pkg/service/v0/api_drives_drive_item.go +++ b/services/graph/pkg/service/v0/api_drives_drive_item.go @@ -19,9 +19,15 @@ import ( "github.com/owncloud/ocis/v2/services/graph/pkg/errorcode" ) +const ( + _fieldMaskPathState = "state" + _fieldMaskPathMountPoint = "mount_point" +) + // DrivesDriveItemProvider is the interface that needs to be implemented by the individual space service type DrivesDriveItemProvider interface { MountShare(ctx context.Context, resourceID storageprovider.ResourceId, name string) (libregraph.DriveItem, error) + UnmountShare(ctx context.Context, resourceID storageprovider.ResourceId) error } // DrivesDriveItemService contains the production business logic for everything that relates to drives @@ -38,6 +44,55 @@ func NewDrivesDriveItemService(logger log.Logger, gatewaySelector pool.Selectabl }, nil } +func (s DrivesDriveItemService) UnmountShare(ctx context.Context, resourceID storageprovider.ResourceId) error { + gatewayClient, err := s.gatewaySelector.Next() + if err != nil { + return err + } + + receivedSharesResponse, err := gatewayClient.ListReceivedShares(ctx, &collaboration.ListReceivedSharesRequest{ + Filters: []*collaboration.Filter{ + { + Type: collaboration.Filter_TYPE_STATE, + Term: &collaboration.Filter_State{ + State: collaboration.ShareState_SHARE_STATE_ACCEPTED, + }, + }, + { + Type: collaboration.Filter_TYPE_RESOURCE_ID, + Term: &collaboration.Filter_ResourceId{ + ResourceId: &resourceID, + }, + }, + }, + }) + if err != nil { + return err + } + + var errs []error + + for _, receivedShare := range receivedSharesResponse.GetShares() { + receivedShare.State = collaboration.ShareState_SHARE_STATE_REJECTED + + updateReceivedShareRequest := &collaboration.UpdateReceivedShareRequest{ + Share: receivedShare, + UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{_fieldMaskPathState}}, + } + + updateReceivedShareResponse, err := gatewayClient.UpdateReceivedShare(ctx, updateReceivedShareRequest) + if err != nil { + errs = append(errs, err) + continue + } + + // fixMe: send to nirvana, wait for toDriverItem func + _ = updateReceivedShareResponse + } + + return errors.Join(errs...) +} + // MountShare mounts a share func (s DrivesDriveItemService) MountShare(ctx context.Context, resourceID storageprovider.ResourceId, name string) (libregraph.DriveItem, error) { gatewayClient, err := s.gatewaySelector.Next() @@ -74,7 +129,7 @@ func (s DrivesDriveItemService) MountShare(ctx context.Context, resourceID stora var errs []error for _, receivedShare := range receivedSharesResponse.GetShares() { - updateMask := &fieldmaskpb.FieldMask{Paths: []string{"state"}} + updateMask := &fieldmaskpb.FieldMask{Paths: []string{_fieldMaskPathState}} receivedShare.State = collaboration.ShareState_SHARE_STATE_ACCEPTED // only update if mountPoint name is not empty and the path has changed @@ -88,7 +143,7 @@ func (s DrivesDriveItemService) MountShare(ctx context.Context, resourceID stora if mountPoint.GetPath() != newPath { mountPoint.Path = newPath receivedShare.MountPoint = mountPoint - updateMask.Paths = append(updateMask.Paths, "mount_point") + updateMask.Paths = append(updateMask.Paths, _fieldMaskPathMountPoint) } } @@ -129,12 +184,33 @@ func NewDrivesDriveItemApi(drivesDriveItemService DrivesDriveItemProvider, logge // Routes returns the routes that should be registered for this api func (api DrivesDriveItemApi) Routes() []Route { return []Route{ - {http.MethodPost, "/v1beta1/drives/{driveID}/items/{itemID}/children", api.CreateChildren}, + {http.MethodPost, "/v1beta1/drives/{driveID}/items/{itemID}/children", api.CreateDriveItem}, + {http.MethodDelete, "/v1beta1/drives/{driveID}/items/{itemID}", api.DeleteDriveItem}, } } -// CreateChildren exposes the CreateChildren operation of the space service as an http endpoint -func (api DrivesDriveItemApi) CreateChildren(w http.ResponseWriter, r *http.Request) { +func (api DrivesDriveItemApi) DeleteDriveItem(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + _, itemID, err := GetDriveAndItemIDParam(r, &api.logger) + if err != nil { + msg := "invalid driveID or itemID" + api.logger.Debug().Err(err).Msg(msg) + errorcode.InvalidRequest.Render(w, r, http.StatusUnprocessableEntity, msg) + return + } + + if err := api.drivesDriveItemService.UnmountShare(ctx, itemID); err != nil { + msg := "unmounting share failed" + api.logger.Debug().Err(err).Msg(msg) + errorcode.InvalidRequest.Render(w, r, http.StatusFailedDependency, msg) + return + } + + render.Status(r, http.StatusOK) +} + +// CreateDriveItem creates a drive item +func (api DrivesDriveItemApi) CreateDriveItem(w http.ResponseWriter, r *http.Request) { ctx := r.Context() driveID, itemID, err := GetDriveAndItemIDParam(r, &api.logger) if err != nil { @@ -168,8 +244,8 @@ func (api DrivesDriveItemApi) CreateChildren(w http.ResponseWriter, r *http.Requ return } - responseDriveItem, err := api.drivesDriveItemService. - MountShare(ctx, resourceId, remoteItem.GetName()) + mountShareResponse, err := api.drivesDriveItemService. + MountShare(ctx, resourceId, requestDriveItem.GetName()) if err != nil { msg := "mounting share failed" api.logger.Debug().Err(err).Msg(msg) @@ -177,6 +253,6 @@ func (api DrivesDriveItemApi) CreateChildren(w http.ResponseWriter, r *http.Requ return } - render.Status(r, http.StatusOK) - render.JSON(w, r, responseDriveItem) + render.Status(r, http.StatusCreated) + render.JSON(w, r, mountShareResponse) }