Skip to content

Commit 2e4f611

Browse files
committed
graph: Use godata Parser to parse query paramters in ListPermissions
Also add initial $select support to ListSpaceRootPermissions()
1 parent db7d053 commit 2e4f611

4 files changed

Lines changed: 77 additions & 38 deletions

File tree

services/graph/mocks/drive_item_permissions_provider.go

Lines changed: 15 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

services/graph/pkg/service/v0/api_driveitem_permissions.go

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import (
66
"net/http"
77
"net/url"
88
"slices"
9+
"strings"
910

11+
"github.com/CiscoM31/godata"
1012
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
1113
grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
1214
userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
@@ -40,16 +42,17 @@ import (
4042
)
4143

4244
const (
43-
invalidIdMsg = "invalid driveID or itemID"
44-
parseDriveIDErrMsg = "could not parse driveID"
45+
invalidIdMsg = "invalid driveID or itemID"
46+
parseDriveIDErrMsg = "could not parse driveID"
47+
federatedRolesODataFilter = "@libre.graph.permissions.roles.allowedValues/rolePermissions/any(p:contains(p/condition, '@Subject.UserType==\"Federated\"'))"
4548
)
4649

4750
// DriveItemPermissionsProvider contains the methods related to handling permissions on drive items
4851
type DriveItemPermissionsProvider interface {
4952
Invite(ctx context.Context, resourceId *storageprovider.ResourceId, invite libregraph.DriveItemInvite) (libregraph.Permission, error)
5053
SpaceRootInvite(ctx context.Context, driveID *storageprovider.ResourceId, invite libregraph.DriveItemInvite) (libregraph.Permission, error)
5154
ListPermissions(ctx context.Context, itemID *storageprovider.ResourceId, listFederatedRoles, selectRoles bool) (libregraph.CollectionOfPermissionsWithAllowedValues, error)
52-
ListSpaceRootPermissions(ctx context.Context, driveID *storageprovider.ResourceId) (libregraph.CollectionOfPermissionsWithAllowedValues, error)
55+
ListSpaceRootPermissions(ctx context.Context, driveID *storageprovider.ResourceId, selectRoles bool) (libregraph.CollectionOfPermissionsWithAllowedValues, error)
5356
DeletePermission(ctx context.Context, itemID *storageprovider.ResourceId, permissionID string) error
5457
DeleteSpaceRootPermission(ctx context.Context, driveID *storageprovider.ResourceId, permissionID string) error
5558
UpdatePermission(ctx context.Context, itemID *storageprovider.ResourceId, permissionID string, newPermission libregraph.Permission) (libregraph.Permission, error)
@@ -438,7 +441,7 @@ func (s DriveItemPermissionsService) ListPermissions(ctx context.Context, itemID
438441
}
439442

440443
// ListSpaceRootPermissions handles ListPermissions request on project spaces
441-
func (s DriveItemPermissionsService) ListSpaceRootPermissions(ctx context.Context, driveID *storageprovider.ResourceId) (libregraph.CollectionOfPermissionsWithAllowedValues, error) {
444+
func (s DriveItemPermissionsService) ListSpaceRootPermissions(ctx context.Context, driveID *storageprovider.ResourceId, selectRoles bool) (libregraph.CollectionOfPermissionsWithAllowedValues, error) {
442445
collectionOfPermissions := libregraph.CollectionOfPermissionsWithAllowedValues{}
443446
gatewayClient, err := s.gatewaySelector.Next()
444447
if err != nil {
@@ -456,7 +459,7 @@ func (s DriveItemPermissionsService) ListSpaceRootPermissions(ctx context.Contex
456459
}
457460

458461
rootResourceID := space.GetRoot()
459-
return s.ListPermissions(ctx, rootResourceID, false, false) // federated roles are not supported for spaces
462+
return s.ListPermissions(ctx, rootResourceID, false, selectRoles) // federated roles are not supported for spaces
460463
}
461464

462465
// DeletePermission deletes a permission from a drive item
@@ -701,14 +704,26 @@ func (api DriveItemPermissionsApi) ListPermissions(w http.ResponseWriter, r *htt
701704
return
702705
}
703706

707+
sanitizedPath := strings.TrimPrefix(r.URL.Path, "/graph/v1.0/")
708+
odataReq, err := godata.ParseRequest(r.Context(), sanitizedPath, r.URL.Query())
709+
if err != nil {
710+
api.logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("Error parsing ListPermissionRequest: query error")
711+
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
712+
return
713+
}
714+
704715
var listFederatedRoles bool
705-
if GetFilterParam(r) == "@libre.graph.permissions.roles.allowedValues/rolePermissions/any(p:contains(p/condition, '@Subject.UserType==\"Federated\"'))" {
706-
listFederatedRoles = true
716+
if odataReq.Query.Filter != nil {
717+
if odataReq.Query.Filter.RawValue == federatedRolesODataFilter {
718+
listFederatedRoles = true
719+
}
707720
}
708721

709-
var selectRoles bool
710-
if GetSelectParam(r) == "@libre.graph.permissions.roles.allowedValues" {
711-
selectRoles = true
722+
selectRoles, err := api.listPermissionsQuerySelectValues(odataReq.Query)
723+
if err != nil {
724+
api.logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("Error parsing ListPermissionRequest: query error")
725+
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
726+
return
712727
}
713728

714729
ctx := r.Context()
@@ -746,8 +761,23 @@ func (api DriveItemPermissionsApi) ListSpaceRootPermissions(w http.ResponseWrite
746761
return
747762
}
748763

764+
sanitizedPath := strings.TrimPrefix(r.URL.Path, "/graph/v1.0/")
765+
odataReq, err := godata.ParseRequest(r.Context(), sanitizedPath, r.URL.Query())
766+
if err != nil {
767+
api.logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("Error parsing ListPermissionRequest: query error")
768+
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
769+
return
770+
}
771+
772+
selectRoles, err := api.listPermissionsQuerySelectValues(odataReq.Query)
773+
if err != nil {
774+
api.logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("Error parsing ListPermissionRequest: query error")
775+
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
776+
return
777+
}
778+
749779
ctx := r.Context()
750-
permissions, err := api.driveItemPermissionsService.ListSpaceRootPermissions(ctx, &driveID)
780+
permissions, err := api.driveItemPermissionsService.ListSpaceRootPermissions(ctx, &driveID, selectRoles)
751781

752782
if err != nil {
753783
errorcode.RenderError(w, r, err)
@@ -903,3 +933,21 @@ func (api DriveItemPermissionsApi) UpdateSpaceRootPermission(w http.ResponseWrit
903933
render.Status(r, http.StatusOK)
904934
render.JSON(w, r, &updatedPermission)
905935
}
936+
937+
func (api DriveItemPermissionsApi) listPermissionsQuerySelectValues(odataQuery *godata.GoDataQuery) (bool, error) {
938+
if odataQuery.Select != nil {
939+
for _, item := range odataQuery.Select.SelectItems {
940+
if len(item.Segments) != 1 {
941+
api.logger.Debug().Msg("Error parsing ListPermissionRequest: unsupported select item")
942+
return false, errorcode.New(errorcode.InvalidRequest, "unsupported select item")
943+
}
944+
// for now we only support the select for the roles
945+
if item.Segments[0].Value != "@libre.graph.permissions.roles.allowedValues" {
946+
api.logger.Debug().Msg("Error parsing ListPermissionRequest: unsupported select item")
947+
return false, errorcode.New(errorcode.InvalidRequest, "unsupported select item")
948+
}
949+
return true, nil
950+
}
951+
}
952+
return false, nil
953+
}

services/graph/pkg/service/v0/api_driveitem_permissions_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ import (
2020
"github.com/go-chi/chi/v5"
2121
. "github.com/onsi/ginkgo/v2"
2222
. "github.com/onsi/gomega"
23-
"github.com/opencloud-eu/opencloud/services/graph/pkg/config"
2423
libregraph "github.com/opencloud-eu/libre-graph-api-go"
24+
"github.com/opencloud-eu/opencloud/services/graph/pkg/config"
2525
"github.com/stretchr/testify/mock"
2626
"github.com/tidwall/gjson"
2727
"google.golang.org/grpc"
@@ -555,7 +555,7 @@ var _ = Describe("DriveItemPermissionsService", func() {
555555
gatewayClient.On("ListPublicShares", mock.Anything, mock.Anything).Return(listPublicSharesResponse, nil)
556556
statResponse.Info.Id = listSpacesResponse.StorageSpaces[0].Root
557557
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
558-
permissions, err := driveItemPermissionsService.ListSpaceRootPermissions(context.Background(), driveId)
558+
permissions, err := driveItemPermissionsService.ListSpaceRootPermissions(context.Background(), driveId, false)
559559
Expect(err).ToNot(HaveOccurred())
560560
Expect(len(permissions.LibreGraphPermissionsActionsAllowedValues)).ToNot(BeZero())
561561
})

services/graph/pkg/service/v0/utils.go

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ import (
1313
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
1414
ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1"
1515
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
16+
libregraph "github.com/opencloud-eu/libre-graph-api-go"
1617
"github.com/opencloud-eu/reva/v2/pkg/storagespace"
1718
"github.com/opencloud-eu/reva/v2/pkg/utils"
18-
libregraph "github.com/opencloud-eu/libre-graph-api-go"
1919
"golang.org/x/sync/errgroup"
2020

2121
"github.com/opencloud-eu/opencloud/pkg/log"
@@ -73,16 +73,6 @@ func GetDriveAndItemIDParam(r *http.Request, logger *log.Logger) (*storageprovid
7373
return &driveID, &itemID, nil
7474
}
7575

76-
// GetFilterParam returns the $filter query parameter from the request. If you need to parse the filter use godata.ParseRequest
77-
func GetFilterParam(r *http.Request) string {
78-
return r.URL.Query().Get("$filter")
79-
}
80-
81-
// GetSelectParam returns the $select query parameter from the request. If you need to parse the select filter use godata.ParseRequest
82-
func GetSelectParam(r *http.Request) string {
83-
return r.URL.Query().Get("$select")
84-
}
85-
8676
// GetGatewayClient returns a gateway client from the gatewaySelector.
8777
func (g Graph) GetGatewayClient(w http.ResponseWriter, r *http.Request) (gateway.GatewayAPIClient, bool) {
8878
gatewayClient, err := g.gatewaySelector.Next()

0 commit comments

Comments
 (0)