fix: share jail usage for the listSharedWithMe endpoint

This commit is contained in:
Florian Schade
2024-01-16 15:09:27 +01:00
committed by Ralf Haferkamp
parent fce4d19e3f
commit cf5f1bcb8e
+184 -116
View File
@@ -3,17 +3,19 @@ package svc
import ( import (
"context" "context"
"net/http" "net/http"
"reflect"
"strings" "strings"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/v2/pkg/storagespace"
"github.com/go-chi/render" "github.com/go-chi/render"
libregraph "github.com/owncloud/libre-graph-api-go" libregraph "github.com/owncloud/libre-graph-api-go"
"github.com/cs3org/reva/v2/pkg/storagespace"
"github.com/cs3org/reva/v2/pkg/utils"
"github.com/owncloud/ocis/v2/ocis-pkg/conversions"
"github.com/owncloud/ocis/v2/services/graph/pkg/errorcode" "github.com/owncloud/ocis/v2/services/graph/pkg/errorcode"
"github.com/owncloud/ocis/v2/services/graph/pkg/identity" "github.com/owncloud/ocis/v2/services/graph/pkg/unifiedrole"
) )
// ListSharedWithMe lists the files shared with the current user. // ListSharedWithMe lists the files shared with the current user.
@@ -38,185 +40,251 @@ func (g Graph) listSharedWithMe(ctx context.Context) ([]libregraph.DriveItem, er
} }
listReceivedSharesResponse, err := gatewayClient.ListReceivedShares(ctx, &collaboration.ListReceivedSharesRequest{}) listReceivedSharesResponse, err := gatewayClient.ListReceivedShares(ctx, &collaboration.ListReceivedSharesRequest{})
if err != nil { if errCode := errorcode.FromCS3Status(listReceivedSharesResponse.GetStatus(), err); errCode != nil {
g.logger.Error().Err(err).Msg("listing shares failed") g.logger.Error().Err(err).Msg("listing shares failed")
return nil, errorcode.New(errorcode.GeneralException, err.Error()) return nil, *errCode
}
switch listReceivedSharesResponse.Status.Code {
case rpc.Code_CODE_NOT_FOUND:
return nil, identity.ErrNotFound
} }
var driveItems []libregraph.DriveItem var driveItems []libregraph.DriveItem
for _, receivedShare := range listReceivedSharesResponse.GetShares() { for _, receivedShare := range listReceivedSharesResponse.GetShares() {
share := receivedShare.GetShare() statRequest := &storageprovider.StatRequest{}
if share == nil {
g.logger.Error().Interface("ListReceivedShares", listReceivedSharesResponse).Msg("unexpected empty ReceivedShare.Share") switch receivedShare.GetState() {
case collaboration.ShareState_SHARE_STATE_ACCEPTED:
statRequest.Ref = &storageprovider.Reference{
ResourceId: &storageprovider.ResourceId{
StorageId: utils.ShareStorageProviderID,
OpaqueId: receivedShare.GetShare().GetId().GetOpaqueId(),
SpaceId: utils.ShareStorageSpaceID,
},
}
case collaboration.ShareState_SHARE_STATE_PENDING:
// return no remoteItem
fallthrough
case collaboration.ShareState_SHARE_STATE_REJECTED:
// what to return here? same as pending?
statRequest.Ref = &storageprovider.Reference{
ResourceId: receivedShare.GetShare().GetResourceId(),
}
default:
continue continue
} }
driveItem := &libregraph.DriveItem{} statResponse, err := gatewayClient.Stat(ctx, statRequest)
if errCode := errorcode.FromCS3Status(statResponse.GetStatus(), err); errCode != nil {
statResponse, err := gatewayClient.Stat(ctx, &storageprovider.StatRequest{Ref: &storageprovider.Reference{ResourceId: share.GetResourceId()}})
if err != nil {
g.logger.Error().Err(err).Msg("could not stat") g.logger.Error().Err(err).Msg("could not stat")
continue continue
} }
if statResponse.GetStatus().GetCode() != rpc.Code_CODE_OK {
g.logger.Error().Err(err).Msg("invalid stat response")
continue
}
resourceInfo := statResponse.GetInfo()
var driveOwner *libregraph.Identity var commonResourceOwner *libregraph.Identity
if userID := statResponse.GetInfo().GetOwner(); userID != nil { if userID := statResponse.GetInfo().GetOwner(); userID != nil {
if user, err := g.identityCache.GetUser(ctx, userID.GetOpaqueId()); err != nil { if user, err := g.identityCache.GetUser(ctx, userID.GetOpaqueId()); err != nil {
g.logger.Error().Err(err).Msg("could not get user") g.logger.Error().Err(err).Msg("could not get user")
continue continue
} else { } else {
driveOwner = &libregraph.Identity{ commonResourceOwner = &libregraph.Identity{
DisplayName: user.GetDisplayName(), DisplayName: user.GetDisplayName(),
Id: libregraph.PtrString(user.GetId()), Id: libregraph.PtrString(user.GetId()),
} }
} }
} }
var shareCreator *libregraph.Identity var commonShareCreator *libregraph.Identity
if userID := share.GetCreator(); userID != nil { if userID := receivedShare.GetShare().GetCreator(); userID != nil {
if user, err := g.identityCache.GetUser(ctx, userID.GetOpaqueId()); err != nil { if user, err := g.identityCache.GetUser(ctx, userID.GetOpaqueId()); err != nil {
g.logger.Error().Err(err).Msg("could not get user") g.logger.Error().Err(err).Msg("could not get user")
continue continue
} else { } else {
shareCreator = &libregraph.Identity{ commonShareCreator = &libregraph.Identity{
DisplayName: user.GetDisplayName(), DisplayName: user.GetDisplayName(),
Id: libregraph.PtrString(user.GetId()), Id: libregraph.PtrString(user.GetId()),
} }
} }
} }
if cTime := share.GetCtime(); cTime != nil { var commonPermission *libregraph.Permission
driveItem.CreatedDateTime = libregraph.PtrTime(cs3TimestampToTime(cTime))
}
driveItem.ETag = libregraph.PtrString(strings.Trim(statResponse.GetInfo().GetEtag(), "\""))
if id := share.GetId().GetOpaqueId(); id != "" {
driveItem.Id = libregraph.PtrString(id)
}
if mTime := share.GetMtime(); mTime != nil {
driveItem.LastModifiedDateTime = libregraph.PtrTime(cs3TimestampToTime(mTime))
}
if name := resourceInfo.GetName(); name != "" {
driveItem.Name = libregraph.PtrString(name)
}
{ {
addParentReference := false permission := libregraph.NewPermission()
parentReference := &libregraph.ItemReference{}
if id := share.GetId().GetOpaqueId(); id != "" { if id := receivedShare.GetShare().GetId().GetOpaqueId(); id != "" {
parentReference.DriveId = libregraph.PtrString(id) permission.SetId(id)
addParentReference = true
} }
if addParentReference { if permissionSet := statResponse.GetInfo().GetPermissionSet(); permissionSet != nil {
driveItem.ParentReference = parentReference if actions := unifiedrole.CS3ResourcePermissionsToLibregraphActions(*permissionSet); len(actions) > 0 {
permission.SetLibreGraphPermissionsActions(actions)
}
if role := unifiedrole.CS3ResourcePermissionsToUnifiedRole(
*permissionSet,
unifiedrole.UnifiedRoleConditionGrantee,
g.config.FilesSharing.EnableResharing,
); role != nil {
permission.SetRoles([]string{role.GetId()})
}
}
if expiration := receivedShare.GetShare().GetExpiration(); expiration != nil {
permission.SetExpirationDateTime(cs3TimestampToTime(expiration))
}
switch grantee := receivedShare.GetShare().GetGrantee(); {
case grantee.GetType() == storageprovider.GranteeType_GRANTEE_TYPE_USER:
permission.SetGrantedToV2(libregraph.SharePointIdentitySet{
User: &libregraph.Identity{
Id: conversions.ToPointer(grantee.GetUserId().GetOpaqueId()),
},
})
case grantee.GetType() == storageprovider.GranteeType_GRANTEE_TYPE_GROUP:
permission.SetGrantedToV2(libregraph.SharePointIdentitySet{
Group: &libregraph.Identity{
Id: conversions.ToPointer(grantee.GetGroupId().GetOpaqueId()),
},
})
}
if !reflect.ValueOf(*permission).IsZero() {
commonPermission = permission
} }
} }
driveItem := libregraph.NewDriveItem()
{ {
remoteItem := &libregraph.RemoteItem{} if commonShareCreator != nil {
driveItem.SetCreatedBy(libregraph.IdentitySet{
if id := resourceInfo.GetId(); id != nil { User: commonShareCreator,
remoteItem.Id = libregraph.PtrString(storagespace.FormatResourceID(*id)) })
}
if mTime := resourceInfo.GetMtime(); mTime != nil {
remoteItem.LastModifiedDateTime = libregraph.PtrTime(cs3TimestampToTime(mTime))
}
if name := resourceInfo.GetName(); name != "" {
remoteItem.Name = libregraph.PtrString(name)
}
// fixMe:
// - negative permission could distort the size, am i right?
remoteItem.Size = libregraph.PtrInt64(int64(resourceInfo.GetSize()))
remoteItem.CreatedBy = &libregraph.IdentitySet{
User: driveOwner,
} }
{ {
parentReference := libregraph.NewItemReference()
addFileSystemInfo := false if spaceType := statResponse.GetInfo().GetSpace().GetSpaceType(); spaceType != "" {
fileSystemInfo := &libregraph.FileSystemInfo{} parentReference.SetDriveType(spaceType)
if cTime := share.GetCtime(); cTime != nil {
// fixMe:
// - ms uses the root resource ctime for that,
// the stat response does not contain any information about this, use share instead?
fileSystemInfo.CreatedDateTime = libregraph.PtrTime(cs3TimestampToTime(cTime))
addFileSystemInfo = true
} }
if mTime := resourceInfo.GetMtime(); mTime != nil { if root := statResponse.GetInfo().GetSpace().GetRoot(); root != nil {
fileSystemInfo.LastModifiedDateTime = libregraph.PtrTime(cs3TimestampToTime(mTime)) parentReference.SetDriveId(storagespace.FormatResourceID(*root))
addFileSystemInfo = true
} }
if addFileSystemInfo { if !reflect.ValueOf(*parentReference).IsZero() {
remoteItem.FileSystemInfo = fileSystemInfo driveItem.ParentReference = parentReference
} }
} }
}
switch resourceInfo.GetType() { switch receivedShare.GetState() {
case storageprovider.ResourceType_RESOURCE_TYPE_CONTAINER: case collaboration.ShareState_SHARE_STATE_ACCEPTED:
remoteItem.Folder = &libregraph.Folder{} if resourceID := statRequest.GetRef().GetResourceId(); resourceID != nil {
case storageprovider.ResourceType_RESOURCE_TYPE_FILE: driveItem.SetId(storagespace.FormatResourceID(*resourceID))
openGraphFile := &libregraph.OpenGraphFile{} }
if mimeType := resourceInfo.GetMimeType(); mimeType != "" { if name := receivedShare.GetMountPoint().GetPath(); name != "" {
openGraphFile.MimeType = libregraph.PtrString(mimeType) driveItem.SetName(receivedShare.GetMountPoint().GetPath())
} }
remoteItem.File = openGraphFile if mTime := receivedShare.GetShare().GetMtime(); mTime != nil {
case storageprovider.ResourceType_RESOURCE_TYPE_INVALID: driveItem.SetLastModifiedDateTime(cs3TimestampToTime(mTime))
g.logger.Error().Msg("invalid resource type") }
continue
if cTime := receivedShare.GetShare().GetCtime(); cTime != nil {
driveItem.SetCreatedDateTime(cs3TimestampToTime(cTime))
} }
{ {
addShared := false remoteItem := libregraph.NewRemoteItem()
shared := &libregraph.Shared{
Owner: &libregraph.IdentitySet{ if id := statResponse.GetInfo().GetId(); id != nil {
User: shareCreator, remoteItem.SetId(storagespace.FormatResourceID(*id))
},
SharedBy: &libregraph.IdentitySet{
User: shareCreator,
},
} }
if cTime := share.GetCtime(); cTime != nil { if mTime := statResponse.GetInfo().GetMtime(); mTime != nil {
shared.SharedDateTime = libregraph.PtrTime(cs3TimestampToTime(cTime)) remoteItem.SetLastModifiedDateTime(cs3TimestampToTime(mTime))
addShared = true
} }
if shareCreator != nil { if name := statResponse.GetInfo().GetName(); name != "" {
shared.Owner.User = shareCreator remoteItem.SetName(name)
shared.SharedBy.User = shareCreator
addShared = true
} }
if addShared { if size := statResponse.GetInfo().GetSize(); size != 0 {
remoteItem.Shared = shared remoteItem.SetSize(int64(size))
}
if etag := statResponse.GetInfo().GetEtag(); etag != "" {
remoteItem.SetETag(strings.Trim(etag, "\""))
}
if commonResourceOwner != nil {
remoteItem.SetCreatedBy(libregraph.IdentitySet{
User: commonResourceOwner,
})
}
switch info := statResponse.GetInfo(); {
case info.GetType() == storageprovider.ResourceType_RESOURCE_TYPE_CONTAINER:
remoteItem.Folder = libregraph.NewFolder()
case info.GetType() == storageprovider.ResourceType_RESOURCE_TYPE_FILE:
openGraphFile := libregraph.NewOpenGraphFile()
if mimeType := info.GetMimeType(); mimeType != "" {
openGraphFile.MimeType = &mimeType
}
remoteItem.File = openGraphFile
case info.GetType() == storageprovider.ResourceType_RESOURCE_TYPE_INVALID:
g.logger.Info().Interface("info", info).Msg("invalid resource type")
}
if commonPermission != nil {
remoteItem.SetPermissions([]libregraph.Permission{*commonPermission})
}
{
shared := libregraph.NewShared()
if cTime := receivedShare.GetShare().GetCtime(); cTime != nil {
shared.SetSharedDateTime(cs3TimestampToTime(cTime))
}
if commonResourceOwner != nil {
shared.SetOwner(libregraph.IdentitySet{
User: commonResourceOwner,
})
}
if commonShareCreator != nil {
shared.SetSharedBy(libregraph.IdentitySet{
User: commonShareCreator,
})
}
if !reflect.ValueOf(*shared).IsZero() {
remoteItem.SetShared(*shared)
}
}
if !reflect.ValueOf(*remoteItem).IsZero() {
driveItem.SetRemoteItem(*remoteItem)
} }
} }
case collaboration.ShareState_SHARE_STATE_PENDING:
fallthrough
case collaboration.ShareState_SHARE_STATE_REJECTED:
if id := statResponse.GetInfo().GetId(); id != nil {
driveItem.SetId(storagespace.FormatResourceID(*id))
}
driveItem.RemoteItem = remoteItem if name := statResponse.GetInfo().GetName(); name != "" {
driveItem.SetName(name)
}
if mTime := statResponse.GetInfo().GetMtime(); mTime != nil {
driveItem.SetLastModifiedDateTime(cs3TimestampToTime(mTime))
}
if commonPermission != nil {
driveItem.SetPermissions([]libregraph.Permission{*commonPermission})
}
} }
driveItems = append(driveItems, *driveItem) driveItems = append(driveItems, *driveItem)