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
4244const (
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
4851type 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+ }
0 commit comments