diff --git a/services/graph/mocks/drive_item_permissions_provider.go b/services/graph/mocks/drive_item_permissions_provider.go index 9f05a266cfc..49b76f131d8 100644 --- a/services/graph/mocks/drive_item_permissions_provider.go +++ b/services/graph/mocks/drive_item_permissions_provider.go @@ -82,6 +82,63 @@ func (_c *DriveItemPermissionsProvider_Invite_Call) RunAndReturn(run func(contex return _c } +// ListPermissions provides a mock function with given fields: ctx, itemID +func (_m *DriveItemPermissionsProvider) ListPermissions(ctx context.Context, itemID providerv1beta1.ResourceId) (libregraph.CollectionOfPermissionsWithAllowedValues, error) { + ret := _m.Called(ctx, itemID) + + if len(ret) == 0 { + panic("no return value specified for ListPermissions") + } + + var r0 libregraph.CollectionOfPermissionsWithAllowedValues + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, providerv1beta1.ResourceId) (libregraph.CollectionOfPermissionsWithAllowedValues, error)); ok { + return rf(ctx, itemID) + } + if rf, ok := ret.Get(0).(func(context.Context, providerv1beta1.ResourceId) libregraph.CollectionOfPermissionsWithAllowedValues); ok { + r0 = rf(ctx, itemID) + } else { + r0 = ret.Get(0).(libregraph.CollectionOfPermissionsWithAllowedValues) + } + + if rf, ok := ret.Get(1).(func(context.Context, providerv1beta1.ResourceId) error); ok { + r1 = rf(ctx, itemID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DriveItemPermissionsProvider_ListPermissions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListPermissions' +type DriveItemPermissionsProvider_ListPermissions_Call struct { + *mock.Call +} + +// ListPermissions is a helper method to define mock.On call +// - ctx context.Context +// - itemID providerv1beta1.ResourceId +func (_e *DriveItemPermissionsProvider_Expecter) ListPermissions(ctx interface{}, itemID interface{}) *DriveItemPermissionsProvider_ListPermissions_Call { + return &DriveItemPermissionsProvider_ListPermissions_Call{Call: _e.mock.On("ListPermissions", ctx, itemID)} +} + +func (_c *DriveItemPermissionsProvider_ListPermissions_Call) Run(run func(ctx context.Context, itemID providerv1beta1.ResourceId)) *DriveItemPermissionsProvider_ListPermissions_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(providerv1beta1.ResourceId)) + }) + return _c +} + +func (_c *DriveItemPermissionsProvider_ListPermissions_Call) Return(_a0 libregraph.CollectionOfPermissionsWithAllowedValues, _a1 error) *DriveItemPermissionsProvider_ListPermissions_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *DriveItemPermissionsProvider_ListPermissions_Call) RunAndReturn(run func(context.Context, providerv1beta1.ResourceId) (libregraph.CollectionOfPermissionsWithAllowedValues, error)) *DriveItemPermissionsProvider_ListPermissions_Call { + _c.Call.Return(run) + return _c +} + // SpaceRootInvite provides a mock function with given fields: ctx, driveID, invite func (_m *DriveItemPermissionsProvider) SpaceRootInvite(ctx context.Context, driveID providerv1beta1.ResourceId, invite libregraph.DriveItemInvite) (libregraph.Permission, error) { ret := _m.Called(ctx, driveID, invite) diff --git a/services/graph/pkg/service/v0/api_driveitem_permissions.go b/services/graph/pkg/service/v0/api_driveitem_permissions.go index 67f3fb5b6aa..9bf4d9134d0 100644 --- a/services/graph/pkg/service/v0/api_driveitem_permissions.go +++ b/services/graph/pkg/service/v0/api_driveitem_permissions.go @@ -8,8 +8,11 @@ import ( grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1" userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" + link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1" storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + "github.com/cs3org/reva/v2/pkg/publicshare" "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool" + "github.com/cs3org/reva/v2/pkg/share" "github.com/cs3org/reva/v2/pkg/storagespace" "github.com/cs3org/reva/v2/pkg/utils" "github.com/go-chi/render" @@ -26,6 +29,7 @@ import ( type DriveItemPermissionsProvider interface { Invite(ctx context.Context, resourceId storageprovider.ResourceId, invite libregraph.DriveItemInvite) (libregraph.Permission, error) SpaceRootInvite(ctx context.Context, driveID storageprovider.ResourceId, invite libregraph.DriveItemInvite) (libregraph.Permission, error) + ListPermissions(ctx context.Context, itemID storageprovider.ResourceId) (libregraph.CollectionOfPermissionsWithAllowedValues, error) } // DriveItemPermissionsService contains the production business logic for everything that relates to permissions on drive items. @@ -188,6 +192,77 @@ func (s DriveItemPermissionsService) SpaceRootInvite(ctx context.Context, driveI return s.Invite(ctx, *rootResourceID, invite) } +// ListPermissions lists the permissions of a driveItem +func (s DriveItemPermissionsService) ListPermissions(ctx context.Context, itemID storageprovider.ResourceId) (libregraph.CollectionOfPermissionsWithAllowedValues, error) { + collectionOfPermissions := libregraph.CollectionOfPermissionsWithAllowedValues{} + gatewayClient, err := s.gatewaySelector.Next() + if err != nil { + return collectionOfPermissions, err + } + + statResponse, err := gatewayClient.Stat(ctx, &storageprovider.StatRequest{Ref: &storageprovider.Reference{ResourceId: &itemID}}) + if errCode := errorcode.FromStat(statResponse, err); errCode != nil { + s.logger.Warn().Err(errCode).Interface("stat.res", statResponse).Msg("stat failed") + return collectionOfPermissions, err + } + + condition := unifiedrole.UnifiedRoleConditionGrantee + if IsSpaceRoot(statResponse.GetInfo().GetId()) { + condition = unifiedrole.UnifiedRoleConditionOwner + } + + permissionSet := *statResponse.GetInfo().GetPermissionSet() + allowedActions := unifiedrole.CS3ResourcePermissionsToLibregraphActions(permissionSet) + + collectionOfPermissions = libregraph.CollectionOfPermissionsWithAllowedValues{ + LibreGraphPermissionsActionsAllowedValues: allowedActions, + LibreGraphPermissionsRolesAllowedValues: conversions.ToValueSlice( + unifiedrole.GetApplicableRoleDefinitionsForActions( + allowedActions, + condition, + s.config.FilesSharing.EnableResharing, + false, + ), + ), + } + + for i, definition := range collectionOfPermissions.LibreGraphPermissionsRolesAllowedValues { + // the openapi spec defines that the rolePermissions should not be part of the response + definition.RolePermissions = nil + collectionOfPermissions.LibreGraphPermissionsRolesAllowedValues[i] = definition + } + + driveItems := make(driveItemsByResourceID) + if IsSpaceRoot(statResponse.GetInfo().GetId()) { + permissions, err := s.getSpaceRootPermissions(ctx, statResponse.GetInfo().GetSpace().GetId()) + if err != nil { + return collectionOfPermissions, err + } + collectionOfPermissions.Value = permissions + } else { + // "normal" driveItem, populate user permissions via share providers + driveItems, err = s.listUserShares(ctx, []*collaboration.Filter{ + share.ResourceIDFilter(conversions.ToPointer(itemID)), + }, driveItems) + if err != nil { + return collectionOfPermissions, err + } + } + // finally get public shares, which are possible for spaceroots and "normal" resources + driveItems, err = s.listPublicShares(ctx, []*link.ListPublicSharesRequest_Filter{ + publicshare.ResourceIDFilter(conversions.ToPointer(itemID)), + }, driveItems) + if err != nil { + return collectionOfPermissions, err + } + + for _, driveItem := range driveItems { + collectionOfPermissions.Value = append(collectionOfPermissions.Value, driveItem.Permissions...) + } + + return collectionOfPermissions, nil +} + // DriveItemPermissionsService is the api that registers the http endpoints which expose needed operation to the graph api. // the business logic is delegated to the permissions service and further down to the cs3 client. type DriveItemPermissionsApi struct { @@ -269,3 +344,24 @@ func (api DriveItemPermissionsApi) SpaceRootInvite(w http.ResponseWriter, r *htt render.Status(r, http.StatusOK) render.JSON(w, r, &ListResponse{Value: []interface{}{permission}}) } + +func (api DriveItemPermissionsApi) ListPermissions(w http.ResponseWriter, r *http.Request) { + _, itemID, err := GetDriveAndItemIDParam(r, &api.logger) + if err != nil { + msg := "invalid driveID or itemID" + api.logger.Debug().Err(err).Msg(msg) + errorcode.RenderError(w, r, err) + return + } + + ctx := r.Context() + + permissions, err := api.driveItemPermissionsService.ListPermissions(ctx, itemID) + if err != nil { + errorcode.RenderError(w, r, err) + return + } + + render.Status(r, http.StatusOK) + render.JSON(w, r, permissions) +} diff --git a/services/graph/pkg/service/v0/api_driveitem_permissions_test.go b/services/graph/pkg/service/v0/api_driveitem_permissions_test.go index 452ecb2a8aa..ed5d838ab8f 100644 --- a/services/graph/pkg/service/v0/api_driveitem_permissions_test.go +++ b/services/graph/pkg/service/v0/api_driveitem_permissions_test.go @@ -13,8 +13,10 @@ import ( grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1" userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" + link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + roleconversions "github.com/cs3org/reva/v2/pkg/conversions" revactx "github.com/cs3org/reva/v2/pkg/ctx" "github.com/cs3org/reva/v2/pkg/rgrpc/status" "github.com/cs3org/reva/v2/pkg/storagespace" @@ -40,11 +42,14 @@ var _ = Describe("DriveItemPermissionsService", func() { driveItemPermissionsService svc.DriveItemPermissionsService gatewayClient *cs3mocks.GatewayAPIClient gatewaySelector *mocks.Selectable[gateway.GatewayAPIClient] + getUserResponse *userpb.GetUserResponse currentUser = &userpb.User{ Id: &userpb.UserId{ OpaqueId: "user", }, } + statResponse *provider.StatResponse + ctx context.Context ) BeforeEach(func() { @@ -60,6 +65,18 @@ var _ = Describe("DriveItemPermissionsService", func() { service, err := svc.NewDriveItemPermissionsService(logger, gatewaySelector, cache, cfg) Expect(err).ToNot(HaveOccurred()) driveItemPermissionsService = service + ctx = revactx.ContextSetUser(context.Background(), currentUser) + statResponse = &provider.StatResponse{ + Status: status.NewOK(ctx), + } + getUserResponse = &userpb.GetUserResponse{ + Status: status.NewOK(ctx), + User: &userpb.User{ + Id: &userpb.UserId{OpaqueId: "1"}, + DisplayName: "Cem Kaner", + }, + } + }) Describe("Invite", func() { @@ -67,8 +84,6 @@ var _ = Describe("DriveItemPermissionsService", func() { createShareResponse *collaboration.CreateShareResponse driveItemInvite libregraph.DriveItemInvite driveItemId provider.ResourceId - statResponse *provider.StatResponse - getUserResponse *userpb.GetUserResponse getGroupResponse *grouppb.GetGroupResponse ) @@ -78,21 +93,9 @@ var _ = Describe("DriveItemPermissionsService", func() { SpaceId: "2", OpaqueId: "3", } - ctx := revactx.ContextSetUser(context.Background(), currentUser) - statResponse = &provider.StatResponse{ - Status: status.NewOK(ctx), - } gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil) - getUserResponse = &userpb.GetUserResponse{ - Status: status.NewOK(ctx), - User: &userpb.User{ - Id: &userpb.UserId{OpaqueId: "1"}, - DisplayName: "Cem Kaner", - }, - } - getGroupResponse = &grouppb.GetGroupResponse{ Status: status.NewOK(ctx), Group: &grouppb.Group{ @@ -204,7 +207,6 @@ var _ = Describe("DriveItemPermissionsService", func() { createShareResponse *collaboration.CreateShareResponse driveItemInvite libregraph.DriveItemInvite driveId provider.ResourceId - statResponse *provider.StatResponse getUserResponse *userpb.GetUserResponse ) @@ -213,11 +215,6 @@ var _ = Describe("DriveItemPermissionsService", func() { StorageId: "1", SpaceId: "2", } - ctx := revactx.ContextSetUser(context.Background(), currentUser) - - statResponse = &provider.StatResponse{ - Status: status.NewOK(ctx), - } listSpacesResponse = &provider.ListStorageSpacesResponse{ Status: status.NewOK(ctx), @@ -288,6 +285,92 @@ var _ = Describe("DriveItemPermissionsService", func() { Expect(permission).To(BeZero()) }) }) + Describe("ListPermissions", func() { + var ( + itemID provider.ResourceId + listSharesResponse *collaboration.ListSharesResponse + listPublicSharesResponse *link.ListPublicSharesResponse + ) + BeforeEach(func() { + itemID = provider.ResourceId{ + StorageId: "1", + SpaceId: "2", + OpaqueId: "3", + } + listSharesResponse = &collaboration.ListSharesResponse{ + Status: status.NewOK(ctx), + Shares: []*collaboration.Share{}, + } + listPublicSharesResponse = &link.ListPublicSharesResponse{ + Status: status.NewOK(ctx), + } + }) + It("populates allowedValues for files that are not shared", func() { + statResponse.Info = &provider.ResourceInfo{ + Id: &itemID, + PermissionSet: roleconversions.NewViewerRole(false).CS3ResourcePermissions(), + } + gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil) + gatewayClient.On("ListShares", mock.Anything, mock.Anything).Return(listSharesResponse, nil) + gatewayClient.On("ListPublicShares", mock.Anything, mock.Anything).Return(listPublicSharesResponse, nil) + permissions, err := driveItemPermissionsService.ListPermissions(context.Background(), itemID) + Expect(err).ToNot(HaveOccurred()) + Expect(len(permissions.LibreGraphPermissionsActionsAllowedValues)).ToNot(BeZero()) + Expect(len(permissions.LibreGraphPermissionsRolesAllowedValues)).ToNot(BeZero()) + }) + It("returns one permission per share", func() { + statResponse.Info = &provider.ResourceInfo{ + Id: &itemID, + PermissionSet: roleconversions.NewEditorRole(false).CS3ResourcePermissions(), + } + listSharesResponse.Shares = []*collaboration.Share{ + { + Id: &collaboration.ShareId{OpaqueId: "1"}, + Permissions: &collaboration.SharePermissions{ + Permissions: roleconversions.NewViewerRole(false).CS3ResourcePermissions(), + }, + ResourceId: &provider.ResourceId{ + StorageId: "1", + SpaceId: "2", + OpaqueId: "3", + }, + Grantee: &provider.Grantee{ + Type: provider.GranteeType_GRANTEE_TYPE_USER, + Id: &provider.Grantee_UserId{ + UserId: &userpb.UserId{ + OpaqueId: "user-id", + }, + }, + }, + }, + } + listPublicSharesResponse.Share = []*link.PublicShare{ + { + Id: &link.PublicShareId{ + OpaqueId: "public-share-id", + }, + Token: "public-share-token", + ResourceId: &provider.ResourceId{ + StorageId: "storageid", + SpaceId: "spaceid", + OpaqueId: "public-share-opaqueid", + }, + Permissions: &link.PublicSharePermissions{Permissions: roleconversions.NewViewerRole(false).CS3ResourcePermissions()}, + }, + } + + gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil) + gatewayClient.On("ListShares", mock.Anything, mock.Anything).Return(listSharesResponse, nil) + gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil) + gatewayClient.On("ListPublicShares", mock.Anything, mock.Anything).Return(listPublicSharesResponse, nil) + permissions, err := driveItemPermissionsService.ListPermissions(context.Background(), itemID) + Expect(err).ToNot(HaveOccurred()) + Expect(len(permissions.LibreGraphPermissionsActionsAllowedValues)).ToNot(BeZero()) + Expect(len(permissions.LibreGraphPermissionsRolesAllowedValues)).ToNot(BeZero()) + Expect(len(permissions.Value)).To(Equal(2)) + }) + + }) }) var _ = Describe("DriveItemPermissionsApi", func() { @@ -405,7 +488,7 @@ var _ = Describe("DriveItemPermissionsApi", func() { Expect(responseRecorder.Code).To(Equal(http.StatusOK)) }) - It("call the Invite provider with the correct arguments", func() { + It("fails with an empty driveid", func() { rCTX.URLParams.Add("driveID", "") responseRecorder := httptest.NewRecorder() inviteJson, err := json.Marshal(invite) @@ -420,4 +503,39 @@ var _ = Describe("DriveItemPermissionsApi", func() { Expect(responseRecorder.Code).To(Equal(http.StatusUnprocessableEntity)) }) }) + Describe("ListPermissions", func() { + It("calls the ListPermissions provider with the correct arguments", func() { + rCTX.URLParams.Add("itemID", "1$2!3") + responseRecorder := httptest.NewRecorder() + inviteJson, err := json.Marshal(invite) + Expect(err).ToNot(HaveOccurred()) + + mockProvider.On("ListPermissions", mock.Anything, mock.Anything, mock.Anything). + Return(func(ctx context.Context, itemid storageprovider.ResourceId) (libregraph.CollectionOfPermissionsWithAllowedValues, error) { + Expect(storagespace.FormatResourceID(itemid)).To(Equal("1$2!3")) + return libregraph.CollectionOfPermissionsWithAllowedValues{}, nil + }).Once() + + request := httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer(inviteJson)). + WithContext( + context.WithValue(context.Background(), chi.RouteCtxKey, rCTX), + ) + httpAPI.ListPermissions(responseRecorder, request) + + Expect(responseRecorder.Code).To(Equal(http.StatusOK)) + }) + It("fails with an empty itemid", func() { + responseRecorder := httptest.NewRecorder() + inviteJson, err := json.Marshal(invite) + Expect(err).ToNot(HaveOccurred()) + + request := httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer(inviteJson)). + WithContext( + context.WithValue(context.Background(), chi.RouteCtxKey, rCTX), + ) + httpAPI.ListPermissions(responseRecorder, request) + + Expect(responseRecorder.Code).To(Equal(http.StatusBadRequest)) + }) + }) }) diff --git a/services/graph/pkg/service/v0/driveitems.go b/services/graph/pkg/service/v0/driveitems.go index 231b998b600..cb6752d8f4b 100644 --- a/services/graph/pkg/service/v0/driveitems.go +++ b/services/graph/pkg/service/v0/driveitems.go @@ -27,14 +27,10 @@ import ( "golang.org/x/crypto/sha3" "google.golang.org/protobuf/types/known/fieldmaskpb" - "github.com/cs3org/reva/v2/pkg/publicshare" - "github.com/cs3org/reva/v2/pkg/share" - revactx "github.com/cs3org/reva/v2/pkg/ctx" "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/ocis-pkg/log" "github.com/owncloud/ocis/v2/services/graph/pkg/errorcode" "github.com/owncloud/ocis/v2/services/graph/pkg/unifiedrole" @@ -367,90 +363,6 @@ func (g Graph) GetDriveItemChildren(w http.ResponseWriter, r *http.Request) { render.JSON(w, r, &ListResponse{Value: files}) } -// ListPermissions lists the permissions of a driveItem -func (g Graph) ListPermissions(w http.ResponseWriter, r *http.Request) { - gatewayClient, ok := g.GetGatewayClient(w, r) - if !ok { - return - } - - _, itemID, err := GetDriveAndItemIDParam(r, g.logger) - if err != nil { - errorcode.RenderError(w, r, err) - return - } - - ctx := r.Context() - - statResponse, err := gatewayClient.Stat(ctx, &storageprovider.StatRequest{Ref: &storageprovider.Reference{ResourceId: &itemID}}) - if errCode := errorcode.FromStat(statResponse, err); errCode != nil { - g.logger.Warn().Err(errCode).Interface("stat.res", statResponse).Msg("stat failed") - errCode.Render(w, r) - return - } - - condition := unifiedrole.UnifiedRoleConditionGrantee - if IsSpaceRoot(statResponse.GetInfo().GetId()) { - condition = unifiedrole.UnifiedRoleConditionOwner - } - - permissionSet := *statResponse.GetInfo().GetPermissionSet() - allowedActions := unifiedrole.CS3ResourcePermissionsToLibregraphActions(permissionSet) - - collectionOfPermissions := libregraph.CollectionOfPermissionsWithAllowedValues{ - LibreGraphPermissionsActionsAllowedValues: allowedActions, - LibreGraphPermissionsRolesAllowedValues: conversions.ToValueSlice( - unifiedrole.GetApplicableRoleDefinitionsForActions( - allowedActions, - condition, - g.config.FilesSharing.EnableResharing, - false, - ), - ), - } - - for i, definition := range collectionOfPermissions.LibreGraphPermissionsRolesAllowedValues { - // the openapi spec defines that the rolePermissions should not be part of the response - definition.RolePermissions = nil - collectionOfPermissions.LibreGraphPermissionsRolesAllowedValues[i] = definition - } - - driveItems := make(driveItemsByResourceID) - if IsSpaceRoot(statResponse.GetInfo().GetId()) { - permissions, err := g.getSpaceRootPermissions(ctx, statResponse.GetInfo().GetSpace().GetId()) - if err != nil { - errorcode.RenderError(w, r, err) - return - } - collectionOfPermissions.Value = permissions - } else { - // "normal" driveItem, populate user permissions via share providers - driveItems, err = g.listUserShares(ctx, []*collaboration.Filter{ - share.ResourceIDFilter(conversions.ToPointer(itemID)), - }, driveItems) - if err != nil { - errorcode.RenderError(w, r, err) - return - } - - } - // finally get public shares, which are possible for spaceroots and "normal" resources - driveItems, err = g.listPublicShares(ctx, []*link.ListPublicSharesRequest_Filter{ - publicshare.ResourceIDFilter(conversions.ToPointer(itemID)), - }, driveItems) - if err != nil { - errorcode.RenderError(w, r, err) - return - } - - for _, driveItem := range driveItems { - collectionOfPermissions.Value = append(collectionOfPermissions.Value, driveItem.Permissions...) - } - - render.Status(r, http.StatusOK) - render.JSON(w, r, collectionOfPermissions) -} - // UpdatePermission updates a Permission of a Drive item func (g Graph) UpdatePermission(w http.ResponseWriter, r *http.Request) { _, itemID, err := GetDriveAndItemIDParam(r, g.logger) diff --git a/services/graph/pkg/service/v0/service.go b/services/graph/pkg/service/v0/service.go index b20f81ba941..2ed6ecbb99b 100644 --- a/services/graph/pkg/service/v0/service.go +++ b/services/graph/pkg/service/v0/service.go @@ -118,7 +118,6 @@ type Service interface { CreateLink(w http.ResponseWriter, r *http.Request) SetLinkPassword(writer http.ResponseWriter, request *http.Request) - ListPermissions(w http.ResponseWriter, r *http.Request) UpdatePermission(w http.ResponseWriter, r *http.Request) DeletePermission(w http.ResponseWriter, r *http.Request) @@ -253,7 +252,7 @@ func NewService(opts ...Option) (Graph, error) { r.Delete("/", drivesDriveItemApi.DeleteDriveItem) r.Post("/invite", driveItemPermissionsApi.Invite) r.Route("/permissions", func(r chi.Router) { - r.Get("/", svc.ListPermissions) + r.Get("/", driveItemPermissionsApi.ListPermissions) r.Route("/{permissionID}", func(r chi.Router) { r.Delete("/", svc.DeletePermission) r.Patch("/", svc.UpdatePermission)