From e9c6a0a3cd225798bbf54bac7fc7891d812c0b89 Mon Sep 17 00:00:00 2001 From: Christian Richter Date: Thu, 5 Sep 2024 15:49:07 +0200 Subject: [PATCH] [WIP] Update OCM Shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jörn Friedrich Dreyer Signed-off-by: Christian Richter --- .../service/v0/api_driveitem_permissions.go | 24 +++- services/graph/pkg/service/v0/base.go | 128 ++++++++++++++++++ 2 files changed, 148 insertions(+), 4 deletions(-) diff --git a/services/graph/pkg/service/v0/api_driveitem_permissions.go b/services/graph/pkg/service/v0/api_driveitem_permissions.go index abf6b3b560..8510d86088 100644 --- a/services/graph/pkg/service/v0/api_driveitem_permissions.go +++ b/services/graph/pkg/service/v0/api_driveitem_permissions.go @@ -526,7 +526,14 @@ func (s DriveItemPermissionsService) DeleteSpaceRootPermission(ctx context.Conte func (s DriveItemPermissionsService) UpdatePermission(ctx context.Context, itemID *storageprovider.ResourceId, permissionID string, newPermission libregraph.Permission) (libregraph.Permission, error) { oldPermission, sharedResourceID, err := s.getPermissionByID(ctx, permissionID, itemID) if err != nil { - return libregraph.Permission{}, err + if s.config.IncludeOCMSharees { + oldPermission, sharedResourceID, err = s.getOCMPermissionByID(ctx, permissionID, itemID) + if err != nil { + return libregraph.Permission{}, err + } + } else { + return libregraph.Permission{}, err + } } // The resourceID of the shared resource need to match the item ID from the Request Path @@ -547,10 +554,19 @@ func (s DriveItemPermissionsService) UpdatePermission(ctx context.Context, itemI // This is a user share updatedPermission, err := s.updateUserShare(ctx, permissionID, sharedResourceID, &newPermission) - if err != nil { - return libregraph.Permission{}, err + if err == nil { + return *updatedPermission, nil } - return *updatedPermission, nil + + // This is an ocm share + if s.config.IncludeOCMSharees { + updatePermission, err := s.updateOCMPermission(ctx, permissionID, itemID, &newPermission) + if err == nil { + return *updatePermission, err + } + } + return libregraph.Permission{}, err + } // UpdateSpaceRootPermission updates a permission on the root item of a project space diff --git a/services/graph/pkg/service/v0/base.go b/services/graph/pkg/service/v0/base.go index 5e85e7c9c0..bf860345ad 100644 --- a/services/graph/pkg/service/v0/base.go +++ b/services/graph/pkg/service/v0/base.go @@ -836,6 +836,31 @@ func (g BaseGraphService) getCS3UserShareByID(ctx context.Context, permissionID return getShareResp.GetShare(), nil } +func (g BaseGraphService) getOCMPermissionByID(ctx context.Context, permissionID string, itemID *storageprovider.ResourceId) (*libregraph.Permission, *storageprovider.ResourceId, error) { + gatewayClient, err := g.gatewaySelector.Next() + if err != nil { + g.logger.Debug().Err(err).Msg("selecting gatewaySelevtor failed") + return nil, nil, err + } + ocmShare, err := g.getCS3OCMShareByID(ctx, permissionID) + if err != nil { + return nil, nil, err + } + resourceInfo, err := utils.GetResourceByID(ctx, itemID, gatewayClient) + if err != nil { + return nil, nil, err + } + condition, err := roleConditionForResourceType(resourceInfo) + if err != nil { + return nil, nil, err + } + permission, err := g.cs3OCMShareToPermission(ctx, ocmShare, condition) + if err != nil { + return nil, nil, err + } + return permission, ocmShare.GetResourceId(), nil +} + func (g BaseGraphService) getPermissionByID(ctx context.Context, permissionID string, itemID *storageprovider.ResourceId) (*libregraph.Permission, *storageprovider.ResourceId, error) { var errcode errorcode.Error gatewayClient, err := g.gatewaySelector.Next() @@ -893,6 +918,109 @@ func (g BaseGraphService) getPermissionByID(ctx context.Context, permissionID st return nil, nil, err } +func (g BaseGraphService) updateOCMPermission(ctx context.Context, permissionID string, itemID *storageprovider.ResourceId, newPermission *libregraph.Permission) (*libregraph.Permission, error) { + gatewayClient, err := g.gatewaySelector.Next() + if err != nil { + g.logger.Debug().Err(err).Msg("selecting gatewaySelector failed") + return nil, err + } + + resourceInfo, err := utils.GetResourceByID(ctx, itemID, gatewayClient) + if err != nil { + return nil, err + } + condition, err := roleConditionForResourceType(resourceInfo) + if err != nil { + return nil, err + } + var cs3UpdateOCMShareReq ocm.UpdateOCMShareRequest + cs3UpdateOCMShareReq.Ref = &ocm.ShareReference{ + Spec: &ocm.ShareReference_Id{ + Id: &ocm.ShareId{ + OpaqueId: permissionID, + }, + }, + } + if expiration, ok := newPermission.GetExpirationDateTimeOk(); ok { + cs3UpdateOCMShareReq.Field = append(cs3UpdateOCMShareReq.Field, &ocm.UpdateOCMShareRequest_UpdateField{ + Field: &ocm.UpdateOCMShareRequest_UpdateField_Expiration{ + Expiration: utils.TimeToTS(*expiration), + }, + }, + ) + } + + var allowedResourceActions []string + var permissionsUpdated bool + if roles, ok := newPermission.GetRolesOk(); ok { + if len(roles) > 0 { + for _, roleID := range roles { + role, err := unifiedrole.GetRole(unifiedrole.RoleFilterIDs(roleID)) + if err != nil { + g.logger.Debug().Err(err).Interface("role", role).Msg("unable to convert requested role") + return nil, err + } + + allowedResourceActions = unifiedrole.GetAllowedResourceActions(role, condition) + if len(allowedResourceActions) == 0 { + return nil, errorcode.New(errorcode.InvalidRequest, "role not applicable to this resource") + } + } + permissionsUpdated = true + + } else if allowedResourceActions, ok = newPermission.GetLibreGraphPermissionsActionsOk(); ok && len(allowedResourceActions) > 0 { + permissionsUpdated = true + } + + if permissionsUpdated { + cs3UpdateOCMShareReq.Field = append(cs3UpdateOCMShareReq.Field, &ocm.UpdateOCMShareRequest_UpdateField{ + Field: &ocm.UpdateOCMShareRequest_UpdateField_AccessMethods{ + AccessMethods: &ocm.AccessMethod{ + Term: &ocm.AccessMethod_WebdavOptions{ + WebdavOptions: &ocm.WebDAVAccessMethod{ + Permissions: unifiedrole.PermissionsToCS3ResourcePermissions( + []*libregraph.UnifiedRolePermission{ + { + + AllowedResourceActions: allowedResourceActions, + }, + }, + ), + }, + }, + }, + }, + }) + } + } + + updateOCMShareResp, err := gatewayClient.UpdateOCMShare(ctx, &cs3UpdateOCMShareReq) + if err != nil { + return nil, err + } + if err := errorcode.FromCS3Status(updateOCMShareResp.GetStatus(), err); err != nil { + return nil, err + } + + ocmShareResp, err := gatewayClient.GetOCMShare(ctx, &ocm.GetOCMShareRequest{ + Ref: &ocm.ShareReference{ + Spec: &ocm.ShareReference_Id{ + Id: &ocm.ShareId{ + OpaqueId: permissionID, + }, + }, + }, + }) + if err != nil { + return nil, err + } + permission, err := g.cs3OCMShareToPermission(ctx, ocmShareResp.GetShare(), condition) + if err != nil { + return nil, err + } + return permission, nil +} + func (g BaseGraphService) updateUserShare(ctx context.Context, permissionID string, itemID *storageprovider.ResourceId, newPermission *libregraph.Permission) (*libregraph.Permission, error) { gatewayClient, err := g.gatewaySelector.Next() if err != nil {