Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhancement(sharing): Return space permissions when looking up space root #8642

Merged
merged 5 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions changelog/unreleased/sharing-ng-spacepermissions.md
Original file line number Diff line number Diff line change
@@ -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
45 changes: 38 additions & 7 deletions services/graph/pkg/service/v0/driveitems.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,14 +408,45 @@ func (g Graph) ListPermissions(w http.ResponseWriter, r *http.Request) {
}

driveItems := make(driveItemsByResourceID)
driveItems, err = g.listUserShares(ctx, []*collaboration.Filter{
share.ResourceIDFilter(conversions.ToPointer(itemID)),
}, driveItems)
if err != nil {
errorcode.RenderError(w, r, err)
return
}
if IsSpaceRoot(statResponse.GetInfo().GetId()) {
// this is a space root, get permissions via storage space API
filters := []*storageprovider.ListStorageSpacesRequest_Filter{
listStorageSpacesIDFilter(statResponse.GetInfo().GetSpace().GetId().GetOpaqueId()),
}
res, err := g.ListStorageSpacesWithFilters(ctx, filters, true)
switch {
case err != nil:
g.logger.Error().Err(err).Msg("could not get drive: transport error")
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
return
case res.Status.Code != cs3rpc.Code_CODE_OK:
if res.Status.Code == cs3rpc.Code_CODE_NOT_FOUND {
kobergj marked this conversation as resolved.
Show resolved Hide resolved
// the client is doing a lookup for a specific space, therefore we need to return
// not found to the caller
g.logger.Debug().Msg("could not get drive: not found")
errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, "drive not found")
return
}
g.logger.Debug().
Str("grpcmessage", res.GetStatus().GetMessage()).
Msg("could not get drive: grpc error")
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, res.Status.Message)
return
}
permissions := g.cs3PermissionsToLibreGraph(ctx, res.GetStorageSpaces()[0], APIVersion_1_Beta_1)
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)
Expand Down
68 changes: 63 additions & 5 deletions services/graph/pkg/service/v0/driveitems_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -1027,7 +1028,7 @@ var _ = Describe("Driveitems", func() {
})

It("fails with wrong role", func() {
driveItemInvite.Roles = []string{unifiedrole.NewCoownerUnifiedRole().GetId()}
driveItemInvite.Roles = []string{unifiedrole.NewManagerUnifiedRole().GetId()}
svc.Invite(
rr,
httptest.NewRequest(http.MethodPost, "/", toJSONReader(driveItemInvite)).
Expand Down Expand Up @@ -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 {
Expand All @@ -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)

Expand Down Expand Up @@ -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).
Expand All @@ -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() {
Expand Down
Loading