Skip to content

Commit

Permalink
feat(graph): add GET /drive/<id>/root/permissions suppport
Browse files Browse the repository at this point in the history
Partial Fix: owncloud#8351
  • Loading branch information
rhafer committed Mar 27, 2024
1 parent 1e63a37 commit ee20f16
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 5 deletions.
57 changes: 57 additions & 0 deletions services/graph/mocks/drive_item_permissions_provider.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 48 additions & 5 deletions services/graph/pkg/service/v0/api_driveitem_permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@ import (
"github.com/owncloud/ocis/v2/services/graph/pkg/validate"
)

const invalidIdMsg = "invalid driveID or itemID"

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)
ListSpaceRootPermissions(ctx context.Context, driveID storageprovider.ResourceId) (libregraph.CollectionOfPermissionsWithAllowedValues, error)
}

// DriveItemPermissionsService contains the production business logic for everything that relates to permissions on drive items.
Expand Down Expand Up @@ -263,6 +266,27 @@ func (s DriveItemPermissionsService) ListPermissions(ctx context.Context, itemID
return collectionOfPermissions, nil
}

// ListSpaceRootPermissions handles ListPermissions request on project spaces
func (s DriveItemPermissionsService) ListSpaceRootPermissions(ctx context.Context, driveID storageprovider.ResourceId) (libregraph.CollectionOfPermissionsWithAllowedValues, error) {
collectionOfPermissions := libregraph.CollectionOfPermissionsWithAllowedValues{}
gatewayClient, err := s.gatewaySelector.Next()
if err != nil {
return collectionOfPermissions, err
}

space, err := utils.GetSpace(ctx, storagespace.FormatResourceID(driveID), gatewayClient)
if err != nil {
return collectionOfPermissions, err
}

if space.SpaceType != "project" {
return collectionOfPermissions, errorcode.New(errorcode.InvalidRequest, "unsupported space type")
}

rootResourceID := space.GetRoot()
return s.ListPermissions(ctx, *rootResourceID)
}

// 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 {
Expand All @@ -281,9 +305,8 @@ func NewDriveItemPermissionsApi(driveItemPermissionService DriveItemPermissionsP
func (api DriveItemPermissionsApi) Invite(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.InvalidRequest.Render(w, r, http.StatusUnprocessableEntity, msg)
api.logger.Debug().Err(err).Msg(invalidIdMsg)
errorcode.InvalidRequest.Render(w, r, http.StatusUnprocessableEntity, invalidIdMsg)
return
}

Expand Down Expand Up @@ -348,8 +371,7 @@ func (api DriveItemPermissionsApi) SpaceRootInvite(w http.ResponseWriter, r *htt
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)
api.logger.Debug().Err(err).Msg(invalidIdMsg)
errorcode.RenderError(w, r, err)
return
}
Expand All @@ -365,3 +387,24 @@ func (api DriveItemPermissionsApi) ListPermissions(w http.ResponseWriter, r *htt
render.Status(r, http.StatusOK)
render.JSON(w, r, permissions)
}

func (api DriveItemPermissionsApi) ListSpaceRootPermissions(w http.ResponseWriter, r *http.Request) {
driveID, err := parseIDParam(r, "driveID")
if err != nil {
msg := "could not parse driveID"
api.logger.Debug().Err(err).Msg(msg)
errorcode.InvalidRequest.Render(w, r, http.StatusUnprocessableEntity, msg)
return
}

ctx := r.Context()
permissions, err := api.driveItemPermissionsService.ListSpaceRootPermissions(ctx, driveID)

if err != nil {
errorcode.RenderError(w, r, err)
return
}

render.Status(r, http.StatusOK)
render.JSON(w, r, permissions)
}
48 changes: 48 additions & 0 deletions services/graph/pkg/service/v0/api_driveitem_permissions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,54 @@ var _ = Describe("DriveItemPermissionsService", func() {
Expect(len(permissions.LibreGraphPermissionsRolesAllowedValues)).ToNot(BeZero())
Expect(len(permissions.Value)).To(Equal(2))
})
})
Describe("ListSpaceRootPermissions", func() {
var (
listSpacesResponse *provider.ListStorageSpacesResponse
driveId provider.ResourceId
listPublicSharesResponse *link.ListPublicSharesResponse
)

BeforeEach(func() {
driveId = provider.ResourceId{
StorageId: "1",
SpaceId: "2",
}

listSpacesResponse = &provider.ListStorageSpacesResponse{
Status: status.NewOK(ctx),
StorageSpaces: []*provider.StorageSpace{
{
Id: &provider.StorageSpaceId{
OpaqueId: "2",
},
},
},
}
listPublicSharesResponse = &link.ListPublicSharesResponse{
Status: status.NewOK(ctx),
}
})

It("adds a user to a space as expected (happy path)", func() {
listSpacesResponse.StorageSpaces[0].SpaceType = "project"
listSpacesResponse.StorageSpaces[0].Root = &provider.ResourceId{
StorageId: "1",
SpaceId: "2",
OpaqueId: "2",
}

gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(listSpacesResponse, nil)
gatewayClient.On("ListPublicShares", mock.Anything, mock.Anything).Return(listPublicSharesResponse, nil)
statResponse.Info = &provider.ResourceInfo{
Id: listSpacesResponse.StorageSpaces[0].Root,
PermissionSet: roleconversions.NewViewerRole(false).CS3ResourcePermissions(),
}
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
permissions, err := driveItemPermissionsService.ListSpaceRootPermissions(context.Background(), driveId)
Expect(err).ToNot(HaveOccurred())
Expect(len(permissions.LibreGraphPermissionsActionsAllowedValues)).ToNot(BeZero())
})

})
})
Expand Down
3 changes: 3 additions & 0 deletions services/graph/pkg/service/v0/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,9 @@ func NewService(opts ...Option) (Graph, error) {
r.Route("/root", func(r chi.Router) {
r.Post("/children", drivesDriveItemApi.CreateDriveItem)
r.Post("/invite", driveItemPermissionsApi.SpaceRootInvite)
r.Route("/permissions", func(r chi.Router) {
r.Get("/", driveItemPermissionsApi.ListSpaceRootPermissions)
})
})
r.Route("/items/{itemID}", func(r chi.Router) {
r.Delete("/", drivesDriveItemApi.DeleteDriveItem)
Expand Down

0 comments on commit ee20f16

Please sign in to comment.