graph(sharing-ng): Permission on Spaceroots need to have an id

In order to work with (e.g. get/delete) permissions granted to space
we need to give them a stable id. As the CS3 API don't provide an id
we generate it base on the id of the identity that the permission applies
to. For users we use "u:<userid>" for groups "g:<groupid>".

Closes: #8352
This commit is contained in:
Ralf Haferkamp
2024-03-18 11:53:57 +01:00
committed by Ralf Haferkamp
parent a326d95232
commit 2352145b98
4 changed files with 85 additions and 4 deletions
@@ -0,0 +1,7 @@
Enhancement: The graph endpoints for listing permission works for spaces now
We enhanced the 'graph/v1beta1/drives/{{driveid}}/items/{{itemid}}/permissions' endpoint
to list permission of the space when the 'itemid' refers to a space root.
https://github.com/owncloud/ocis/pull/8642
https://github.com/owncloud/ocis/issues/8352
@@ -17,6 +17,7 @@ import (
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"
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/go-chi/chi/v5"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
@@ -1156,6 +1157,7 @@ var _ = Describe("Driveitems", func() {
listSharesResponse *collaboration.ListSharesResponse
listPublicSharesMock *mock.Call
listPublicSharesResponse *link.ListPublicSharesResponse
rctx *chi.Context
)
toResourceID := func(in string) *provider.ResourceId {
@@ -1166,10 +1168,7 @@ var _ = Describe("Driveitems", func() {
}
BeforeEach(func() {
rctx := chi.NewRouteContext()
rctx.URLParams.Add("driveID", "1$2")
rctx.URLParams.Add("itemID", "1$2!3")
rctx = chi.NewRouteContext()
ctx = context.WithValue(ctx, chi.RouteCtxKey, rctx)
ctx = revactx.ContextSetUser(ctx, currentUser)
@@ -1210,6 +1209,9 @@ var _ = Describe("Driveitems", func() {
})
It("lists permissions", func() {
rctx.URLParams.Add("driveID", "1$2")
rctx.URLParams.Add("itemID", "1$2!3")
svc.ListPermissions(
rr,
httptest.NewRequest(http.MethodGet, "/", nil).
@@ -1230,6 +1232,62 @@ var _ = Describe("Driveitems", func() {
Expect(value.Get("#").Num).To(Equal(float64(1)))
Expect(value.Get("0.id").Str).To(Equal("123"))
})
It("lists permissions on a storage space", func() {
rctx.URLParams.Add("driveID", "1$2")
rctx.URLParams.Add("itemID", "1$2!2")
statResponse.Info.Id.OpaqueId = "2"
grantMap := map[string]*provider.ResourcePermissions{
"userid": roleconversions.NewSpaceViewerRole().CS3ResourcePermissions(),
}
grantMapJSON, _ := json.Marshal(grantMap)
spaceOpaque := &types.Opaque{
Map: map[string]*types.OpaqueEntry{
"grants": {
Decoder: "json",
Value: grantMapJSON,
},
},
}
listSpacesMock := gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything)
listSpacesResponse := &provider.ListStorageSpacesResponse{
Status: status.NewOK(ctx),
StorageSpaces: []*provider.StorageSpace{
{
Id: &provider.StorageSpaceId{
OpaqueId: "2",
},
Opaque: spaceOpaque,
},
},
}
listSpacesMock.Return(listSpacesResponse, nil)
getUserMock := gatewayClient.On("GetUser", mock.Anything, mock.Anything)
getUserMockResponse := &userpb.GetUserResponse{
Status: status.NewOK(ctx),
User: &userpb.User{
Id: &userpb.UserId{OpaqueId: "userid"},
DisplayName: "Test User",
},
}
getUserMock.Return(getUserMockResponse, nil)
svc.ListPermissions(
rr,
httptest.NewRequest(http.MethodGet, "/", nil).
WithContext(ctx),
)
Expect(rr.Code).To(Equal(http.StatusOK))
p := libregraph.NewCollectionOfPermissions()
err := json.Unmarshal(rr.Body.Bytes(), p)
Expect(err).To(BeNil())
permissions := p.GetValue()
Expect(len(permissions)).To(Equal(1))
Expect(permissions[0].GetId()).ToNot(Equal(""))
})
})
Describe("GetRootDriveChildren", func() {
+1
View File
@@ -916,6 +916,7 @@ func (g Graph) cs3PermissionsToLibreGraph(ctx context.Context, space *storagepro
} else {
identitySet.SetUser(identity)
}
p.SetId(identitySetToSpacePermissionID(identitySet))
p.SetGrantedToV2(identitySet)
}
+15
View File
@@ -131,6 +131,21 @@ func groupIdToIdentity(ctx context.Context, cache identity.IdentityCache, groupI
return identity, err
}
// identitySetToSpacePermissionID generates an Id for a permission from an identitySet. In libregraph
// permissions need to have an id. For user share permission we just use the cs3 share id as the permission-id
// As permissions on space to not map to a cs3 share we need something else of the ids. So we just
// construct the id for the id of the user or group that the permission applies to and prefix that
// with a "u:" for userids and "g:" for group ids.
func identitySetToSpacePermissionID(identitySet libregraph.SharePointIdentitySet) (id string) {
switch {
case identitySet.HasUser():
id = "u:" + identitySet.User.GetId()
case identitySet.HasGroup():
id = "g:" + identitySet.Group.GetId()
}
return id
}
func cs3ReceivedSharesToDriveItems(ctx context.Context,
logger *log.Logger,
gatewayClient gateway.GatewayAPIClient,