diff --git a/services/graph/pkg/service/v0/driveitems.go b/services/graph/pkg/service/v0/driveitems.go index 87f34f3e64..8307c3d200 100644 --- a/services/graph/pkg/service/v0/driveitems.go +++ b/services/graph/pkg/service/v0/driveitems.go @@ -29,8 +29,24 @@ import ( "github.com/opencloud-eu/opencloud/pkg/log" "github.com/opencloud-eu/opencloud/services/graph/pkg/errorcode" + "github.com/opencloud-eu/opencloud/services/graph/pkg/unifiedrole" ) +// opt-in driveItem instance annotations, returned only when requested via $select +const _selectAllowedValues = "@libre.graph.permissions.actions.allowedValues" + +// driveItemPropertySelected reports whether the given opt-in property was requested via $select +func driveItemPropertySelected(r *http.Request, property string) bool { + for _, values := range r.URL.Query()["$select"] { + for _, v := range strings.Split(values, ",") { + if v == property { + return true + } + } + } + return false +} + // CreateUploadSession create an upload session to allow your app to upload files up to the maximum file size. // An upload session allows your app to upload ranges of the file in sequential API requests, which allows the // transfer to be resumed if a connection is dropped while the upload is in progress. @@ -212,6 +228,12 @@ func (g Graph) GetRootDriveChildren(w http.ResponseWriter, r *http.Request) { return } + if driveItemPropertySelected(r, _selectAllowedValues) { + for i, info := range lRes.GetInfos() { + files[i].LibreGraphPermissionsActionsAllowedValues = unifiedrole.CS3ResourcePermissionsToLibregraphActions(info.GetPermissionSet()) + } + } + render.Status(r, http.StatusOK) render.JSON(w, r, &ListResponse{Value: files}) } @@ -276,6 +298,10 @@ func (g Graph) GetDriveItem(w http.ResponseWriter, r *http.Request) { return } + if driveItemPropertySelected(r, _selectAllowedValues) { + driveItem.LibreGraphPermissionsActionsAllowedValues = unifiedrole.CS3ResourcePermissionsToLibregraphActions(res.GetInfo().GetPermissionSet()) + } + render.Status(r, http.StatusOK) render.JSON(w, r, &driveItem) } diff --git a/services/graph/pkg/service/v0/driveitems_test.go b/services/graph/pkg/service/v0/driveitems_test.go index b32530fef7..b588638589 100644 --- a/services/graph/pkg/service/v0/driveitems_test.go +++ b/services/graph/pkg/service/v0/driveitems_test.go @@ -31,6 +31,7 @@ import ( "github.com/opencloud-eu/opencloud/services/graph/pkg/config/defaults" identitymocks "github.com/opencloud-eu/opencloud/services/graph/pkg/identity/mocks" service "github.com/opencloud-eu/opencloud/services/graph/pkg/service/v0" + "github.com/opencloud-eu/opencloud/services/graph/pkg/unifiedrole" ) type itemsList struct { @@ -196,6 +197,43 @@ var _ = Describe("Driveitems", func() { Expect(res.Value[0].GetLastModifiedDateTime().Equal(mtime)).To(BeTrue()) Expect(res.Value[0].GetETag()).To(Equal("etag")) Expect(res.Value[0].GetId()).To(Equal("storageid$spaceid!opaqueid")) + Expect(res.Value[0].LibreGraphPermissionsActionsAllowedValues).To(BeNil()) + }) + + It("returns the allowed actions when requested via $select", func() { + gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(&provider.ListStorageSpacesResponse{ + Status: status.NewOK(ctx), + StorageSpaces: []*provider.StorageSpace{{Owner: currentUser, Root: &provider.ResourceId{}}}, + }, nil) + gatewayClient.On("ListContainer", mock.Anything, mock.Anything).Return(&provider.ListContainerResponse{ + Status: status.NewOK(ctx), + Infos: []*provider.ResourceInfo{ + { + Type: provider.ResourceType_RESOURCE_TYPE_FILE, + Id: &provider.ResourceId{StorageId: "storageid", SpaceId: "spaceid", OpaqueId: "opaqueid"}, + Etag: "etag", + Mtime: utils.TimeToTS(time.Now()), + PermissionSet: &provider.ResourcePermissions{ + GetPath: true, + InitiateFileDownload: true, + }, + }, + }, + }, nil) + r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me/drive/root/children?$select=@libre.graph.permissions.actions.allowedValues", nil) + r = r.WithContext(revactx.ContextSetUser(ctx, currentUser)) + svc.GetRootDriveChildren(rr, r) + Expect(rr.Code).To(Equal(http.StatusOK)) + data, err := io.ReadAll(rr.Body) + Expect(err).ToNot(HaveOccurred()) + + res := itemsList{} + Expect(json.Unmarshal(data, &res)).To(Succeed()) + Expect(len(res.Value)).To(Equal(1)) + Expect(res.Value[0].GetLibreGraphPermissionsActionsAllowedValues()).To(ConsistOf( + unifiedrole.DriveItemPathRead, + unifiedrole.DriveItemContentRead, + )) }) })