Files
QSfera/services/graph/pkg/service/v0/api_driveitem_permissions_test.go
T
Ralf Haferkamp 26b4927ed8 Address go-vet reported issues
mainly "copylocks: return copies lock value" related things
2024-07-11 16:59:25 +02:00

1176 lines
47 KiB
Go

package svc_test
import (
"bytes"
"context"
"encoding/json"
"errors"
"net/http"
"net/http/httptest"
"time"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
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"
storageprovider "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"
libregraph "github.com/owncloud/libre-graph-api-go"
"github.com/stretchr/testify/mock"
"github.com/tidwall/gjson"
"google.golang.org/grpc"
roleconversions "github.com/cs3org/reva/v2/pkg/conversions"
revactx "github.com/cs3org/reva/v2/pkg/ctx"
"github.com/cs3org/reva/v2/pkg/rgrpc/status"
"github.com/cs3org/reva/v2/pkg/storagespace"
"github.com/cs3org/reva/v2/pkg/utils"
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/services/graph/mocks"
"github.com/owncloud/ocis/v2/services/graph/pkg/config/defaults"
"github.com/owncloud/ocis/v2/services/graph/pkg/errorcode"
"github.com/owncloud/ocis/v2/services/graph/pkg/identity"
"github.com/owncloud/ocis/v2/services/graph/pkg/linktype"
svc "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0"
"github.com/owncloud/ocis/v2/services/graph/pkg/unifiedrole"
)
var _ = Describe("DriveItemPermissionsService", func() {
var (
driveItemPermissionsService svc.DriveItemPermissionsService
gatewayClient *cs3mocks.GatewayAPIClient
gatewaySelector *mocks.Selectable[gateway.GatewayAPIClient]
getUserResponse *userpb.GetUserResponse
listPublicSharesResponse *link.ListPublicSharesResponse
listSpacesResponse *provider.ListStorageSpacesResponse
currentUser = &userpb.User{
Id: &userpb.UserId{
OpaqueId: "user",
},
}
statResponse *provider.StatResponse
driveItemId *provider.ResourceId
ctx context.Context
)
BeforeEach(func() {
logger := log.NewLogger()
gatewayClient = cs3mocks.NewGatewayAPIClient(GinkgoT())
gatewaySelector = mocks.NewSelectable[gateway.GatewayAPIClient](GinkgoT())
gatewaySelector.On("Next").Return(gatewayClient, nil)
cache := identity.NewIdentityCache(identity.IdentityCacheWithGatewaySelector(gatewaySelector))
cfg := defaults.FullDefaultConfig()
service, err := svc.NewDriveItemPermissionsService(logger, gatewaySelector, cache, cfg)
Expect(err).ToNot(HaveOccurred())
driveItemPermissionsService = service
ctx = revactx.ContextSetUser(context.Background(), currentUser)
statResponse = &provider.StatResponse{
Status: status.NewOK(ctx),
}
getUserResponse = &userpb.GetUserResponse{
Status: status.NewOK(ctx),
User: &userpb.User{
Id: &userpb.UserId{OpaqueId: "1"},
DisplayName: "Cem Kaner",
},
}
listPublicSharesResponse = &link.ListPublicSharesResponse{
Status: status.NewOK(ctx),
}
driveItemId = &provider.ResourceId{
StorageId: "1",
SpaceId: "2",
OpaqueId: "3",
}
})
Describe("Invite", func() {
var (
createShareResponse *collaboration.CreateShareResponse
driveItemInvite libregraph.DriveItemInvite
getGroupResponse *grouppb.GetGroupResponse
)
BeforeEach(func() {
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
statResponse.Info = &provider.ResourceInfo{
Id: driveItemId,
Type: provider.ResourceType_RESOURCE_TYPE_FILE,
}
getGroupResponse = &grouppb.GetGroupResponse{
Status: status.NewOK(ctx),
Group: &grouppb.Group{
Id: &grouppb.GroupId{OpaqueId: "2"},
GroupName: "Florida Institute of Technology",
DisplayName: "Florida Institute of Technology",
},
}
createShareResponse = &collaboration.CreateShareResponse{
Status: status.NewOK(ctx),
}
})
It("creates user shares as expected (happy path)", func() {
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("CreateShare", mock.Anything, mock.Anything).Return(createShareResponse, nil)
driveItemInvite.Recipients = []libregraph.DriveRecipient{
{ObjectId: libregraph.PtrString("1"), LibreGraphRecipientType: libregraph.PtrString("user")},
}
driveItemInvite.ExpirationDateTime = libregraph.PtrTime(time.Now().Add(time.Hour))
createShareResponse.Share = &collaboration.Share{
Id: &collaboration.ShareId{OpaqueId: "123"},
Expiration: utils.TimeToTS(*driveItemInvite.ExpirationDateTime),
}
permission, err := driveItemPermissionsService.Invite(context.Background(), driveItemId, driveItemInvite)
Expect(err).ToNot(HaveOccurred())
Expect(permission.GetId()).To(Equal("123"))
Expect(permission.GetExpirationDateTime().Equal(*driveItemInvite.ExpirationDateTime)).To(BeTrue())
Expect(permission.GrantedToV2.User.GetDisplayName()).To(Equal(getUserResponse.User.DisplayName))
Expect(permission.GrantedToV2.User.GetId()).To(Equal("1"))
})
It("creates group shares as expected (happy path)", func() {
gatewayClient.On("GetGroup", mock.Anything, mock.Anything).Return(getGroupResponse, nil)
gatewayClient.On("CreateShare", mock.Anything, mock.Anything).Return(createShareResponse, nil)
driveItemInvite.Recipients = []libregraph.DriveRecipient{
{ObjectId: libregraph.PtrString("2"), LibreGraphRecipientType: libregraph.PtrString("group")},
}
driveItemInvite.ExpirationDateTime = libregraph.PtrTime(time.Now().Add(time.Hour))
createShareResponse.Share = &collaboration.Share{
Id: &collaboration.ShareId{OpaqueId: "123"},
Expiration: utils.TimeToTS(*driveItemInvite.ExpirationDateTime),
}
permission, err := driveItemPermissionsService.Invite(context.Background(), driveItemId, driveItemInvite)
Expect(err).ToNot(HaveOccurred())
Expect(permission.GetId()).To(Equal("123"))
Expect(permission.GetExpirationDateTime().Equal(*driveItemInvite.ExpirationDateTime)).To(BeTrue())
Expect(permission.GrantedToV2.Group.GetDisplayName()).To(Equal(getGroupResponse.Group.DisplayName))
Expect(permission.GrantedToV2.Group.GetId()).To(Equal("2"))
})
It("succeeds with file roles (happy path)", func() {
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("CreateShare", mock.Anything, mock.Anything).Return(createShareResponse, nil)
driveItemInvite.Recipients = []libregraph.DriveRecipient{
{ObjectId: libregraph.PtrString("1"), LibreGraphRecipientType: libregraph.PtrString("user")},
}
driveItemInvite.Roles = []string{unifiedrole.NewViewerUnifiedRole().GetId()}
permission, err := driveItemPermissionsService.Invite(context.Background(), driveItemId, driveItemInvite)
Expect(err).ToNot(HaveOccurred())
Expect(permission.GetRoles()).To(HaveLen(1))
Expect(permission.GetRoles()[0]).To(Equal(unifiedrole.NewViewerUnifiedRole().GetId()))
})
It("succeeds with folder roles (happy path)", func() {
statResponse.Info.Type = provider.ResourceType_RESOURCE_TYPE_CONTAINER
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("CreateShare", mock.Anything, mock.Anything).Return(createShareResponse, nil)
driveItemInvite.Recipients = []libregraph.DriveRecipient{
{ObjectId: libregraph.PtrString("1"), LibreGraphRecipientType: libregraph.PtrString("user")},
}
driveItemInvite.Roles = []string{unifiedrole.NewEditorUnifiedRole().GetId()}
permission, err := driveItemPermissionsService.Invite(context.Background(), driveItemId, driveItemInvite)
Expect(err).ToNot(HaveOccurred())
Expect(permission.GetRoles()).To(HaveLen(1))
Expect(permission.GetRoles()[0]).To(Equal(unifiedrole.NewEditorUnifiedRole().GetId()))
})
It("fails with when trying to set a space role on a file", func() {
driveItemInvite.Recipients = []libregraph.DriveRecipient{
{ObjectId: libregraph.PtrString("1"), LibreGraphRecipientType: libregraph.PtrString("user")},
}
driveItemInvite.Roles = []string{unifiedrole.NewManagerUnifiedRole().GetId()}
permission, err := driveItemPermissionsService.Invite(context.Background(), driveItemId, driveItemInvite)
Expect(err).To(MatchError(errorcode.New(errorcode.InvalidRequest, "role not applicable to this resource")))
Expect(permission).To(BeZero())
})
It("fails with when trying to set a folder role on a file", func() {
driveItemInvite.Recipients = []libregraph.DriveRecipient{
{ObjectId: libregraph.PtrString("1"), LibreGraphRecipientType: libregraph.PtrString("user")},
}
driveItemInvite.Roles = []string{unifiedrole.NewEditorUnifiedRole().GetId()}
permission, err := driveItemPermissionsService.Invite(context.Background(), driveItemId, driveItemInvite)
Expect(err).To(MatchError(errorcode.New(errorcode.InvalidRequest, "role not applicable to this resource")))
Expect(permission).To(BeZero())
})
It("fails with when trying to set a file role on a folder", func() {
statResponse.Info.Type = provider.ResourceType_RESOURCE_TYPE_CONTAINER
driveItemInvite.Recipients = []libregraph.DriveRecipient{
{ObjectId: libregraph.PtrString("1"), LibreGraphRecipientType: libregraph.PtrString("user")},
}
driveItemInvite.Roles = []string{unifiedrole.NewFileEditorUnifiedRole().GetId()}
permission, err := driveItemPermissionsService.Invite(context.Background(), driveItemId, driveItemInvite)
Expect(err).To(MatchError(errorcode.New(errorcode.InvalidRequest, "role not applicable to this resource")))
Expect(permission).To(BeZero())
})
It("with actions (happy path)", func() {
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("CreateShare", mock.Anything, mock.Anything).Return(createShareResponse, nil)
driveItemInvite.Recipients = []libregraph.DriveRecipient{
{ObjectId: libregraph.PtrString("1"), LibreGraphRecipientType: libregraph.PtrString("user")},
}
driveItemInvite.Roles = nil
driveItemInvite.LibreGraphPermissionsActions = []string{unifiedrole.DriveItemContentRead}
permission, err := driveItemPermissionsService.Invite(context.Background(), driveItemId, driveItemInvite)
Expect(err).ToNot(HaveOccurred())
Expect(permission).NotTo(BeZero())
Expect(permission.GetRoles()).To(HaveLen(0))
Expect(permission.GetLibreGraphPermissionsActions()).To(HaveLen(1))
Expect(permission.GetLibreGraphPermissionsActions()[0]).To(Equal(unifiedrole.DriveItemContentRead))
})
It("fails with a missing driveritem", func() {
statResponse.Status = status.NewNotFound(context.Background(), "not found")
permission, err := driveItemPermissionsService.Invite(context.Background(), driveItemId, driveItemInvite)
Expect(err).To(HaveOccurred())
Expect(err).To(MatchError(errorcode.New(errorcode.ItemNotFound, "not found").WithOrigin(errorcode.ErrorOriginCS3)))
Expect(permission).To(BeZero())
})
})
Describe("SpaceRootInvite", func() {
var (
createShareResponse *collaboration.CreateShareResponse
driveItemInvite libregraph.DriveItemInvite
driveId *provider.ResourceId
getUserResponse *userpb.GetUserResponse
)
BeforeEach(func() {
driveId = &provider.ResourceId{
StorageId: "1",
SpaceId: "2",
}
listSpacesResponse = &provider.ListStorageSpacesResponse{
Status: status.NewOK(ctx),
StorageSpaces: []*provider.StorageSpace{
{
Id: &provider.StorageSpaceId{
OpaqueId: "2",
},
},
},
}
getUserResponse = &userpb.GetUserResponse{
Status: status.NewOK(ctx),
User: &userpb.User{
Id: &userpb.UserId{OpaqueId: "1"},
DisplayName: "Cem Kaner",
},
}
createShareResponse = &collaboration.CreateShareResponse{
Status: status.NewOK(ctx),
}
statResponse.Info = &provider.ResourceInfo{}
})
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: "3",
}
statResponse.Info.Id = listSpacesResponse.StorageSpaces[0].Root
statResponse.Info.Space = &provider.StorageSpace{
Root: listSpacesResponse.StorageSpaces[0].Root,
}
gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(listSpacesResponse, nil)
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
gatewayClient.On("CreateShare", mock.Anything, mock.Anything).Return(createShareResponse, nil)
driveItemInvite.Recipients = []libregraph.DriveRecipient{
{ObjectId: libregraph.PtrString("1"), LibreGraphRecipientType: libregraph.PtrString("user")},
}
driveItemInvite.ExpirationDateTime = libregraph.PtrTime(time.Now().Add(time.Hour))
createShareResponse.Share = &collaboration.Share{
Id: &collaboration.ShareId{OpaqueId: "123"},
Expiration: utils.TimeToTS(*driveItemInvite.ExpirationDateTime),
}
permission, err := driveItemPermissionsService.SpaceRootInvite(context.Background(), driveId, driveItemInvite)
Expect(err).ToNot(HaveOccurred())
Expect(permission.GetId()).To(Equal("123"))
Expect(permission.GetExpirationDateTime().Equal(*driveItemInvite.ExpirationDateTime)).To(BeTrue())
Expect(permission.GrantedToV2.User.GetDisplayName()).To(Equal(getUserResponse.User.DisplayName))
Expect(permission.GrantedToV2.User.GetId()).To(Equal("1"))
})
It("rejects to add a user to a personal space", func() {
gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(listSpacesResponse, nil)
driveItemInvite.Recipients = []libregraph.DriveRecipient{
{ObjectId: libregraph.PtrString("1"), LibreGraphRecipientType: libregraph.PtrString("user")},
}
driveItemInvite.ExpirationDateTime = libregraph.PtrTime(time.Now().Add(time.Hour))
createShareResponse.Share = &collaboration.Share{
Id: &collaboration.ShareId{OpaqueId: "123"},
Expiration: utils.TimeToTS(*driveItemInvite.ExpirationDateTime),
}
permission, err := driveItemPermissionsService.SpaceRootInvite(context.Background(), driveId, driveItemInvite)
Expect(err).To(HaveOccurred())
Expect(err).To(MatchError(errorcode.New(errorcode.InvalidRequest, "unsupported space type")))
Expect(permission).To(BeZero())
})
})
Describe("ListPermissions", func() {
var (
itemID *provider.ResourceId
listSharesResponse *collaboration.ListSharesResponse
)
BeforeEach(func() {
itemID = &provider.ResourceId{
StorageId: "1",
SpaceId: "2",
OpaqueId: "3",
}
listSharesResponse = &collaboration.ListSharesResponse{
Status: status.NewOK(ctx),
Shares: []*collaboration.Share{},
}
statResponse.Info = &provider.ResourceInfo{
Id: itemID,
Type: provider.ResourceType_RESOURCE_TYPE_FILE,
PermissionSet: roleconversions.NewViewerRole().CS3ResourcePermissions(),
}
})
It("populates allowedValues for files that are not shared", func() {
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
gatewayClient.On("ListShares", mock.Anything, mock.Anything).Return(listSharesResponse, nil)
gatewayClient.On("ListPublicShares", mock.Anything, mock.Anything).Return(listPublicSharesResponse, nil)
permissions, err := driveItemPermissionsService.ListPermissions(context.Background(), itemID)
Expect(err).ToNot(HaveOccurred())
Expect(len(permissions.LibreGraphPermissionsActionsAllowedValues)).ToNot(BeZero())
Expect(len(permissions.LibreGraphPermissionsRolesAllowedValues)).ToNot(BeZero())
})
It("returns one permission per share", func() {
statResponse.Info.PermissionSet = roleconversions.NewEditorRole().CS3ResourcePermissions()
listSharesResponse.Shares = []*collaboration.Share{
{
Id: &collaboration.ShareId{OpaqueId: "1"},
Permissions: &collaboration.SharePermissions{
Permissions: roleconversions.NewViewerRole().CS3ResourcePermissions(),
},
ResourceId: &provider.ResourceId{
StorageId: "1",
SpaceId: "2",
OpaqueId: "3",
},
Grantee: &provider.Grantee{
Type: provider.GranteeType_GRANTEE_TYPE_USER,
Id: &provider.Grantee_UserId{
UserId: &userpb.UserId{
OpaqueId: "user-id",
},
},
},
},
}
listPublicSharesResponse.Share = []*link.PublicShare{
{
Id: &link.PublicShareId{
OpaqueId: "public-share-id",
},
Token: "public-share-token",
ResourceId: &provider.ResourceId{
StorageId: "storageid",
SpaceId: "spaceid",
OpaqueId: "public-share-opaqueid",
},
Permissions: &link.PublicSharePermissions{Permissions: roleconversions.NewViewerRole().CS3ResourcePermissions()},
},
}
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
gatewayClient.On("ListShares", mock.Anything, mock.Anything).Return(listSharesResponse, nil)
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("ListPublicShares", mock.Anything, mock.Anything).Return(listPublicSharesResponse, nil)
permissions, err := driveItemPermissionsService.ListPermissions(context.Background(), itemID)
Expect(err).ToNot(HaveOccurred())
Expect(len(permissions.LibreGraphPermissionsActionsAllowedValues)).ToNot(BeZero())
Expect(len(permissions.LibreGraphPermissionsRolesAllowedValues)).ToNot(BeZero())
Expect(len(permissions.Value)).To(Equal(2))
})
})
Describe("ListSpaceRootPermissions", func() {
var (
driveId *provider.ResourceId
)
BeforeEach(func() {
driveId = &provider.ResourceId{
StorageId: "1",
SpaceId: "2",
}
listSpacesResponse = &provider.ListStorageSpacesResponse{
Status: status.NewOK(ctx),
StorageSpaces: []*provider.StorageSpace{
{
Id: &provider.StorageSpaceId{
OpaqueId: "2",
},
},
},
}
statResponse.Info = &provider.ResourceInfo{
Type: provider.ResourceType_RESOURCE_TYPE_FILE,
PermissionSet: roleconversions.NewViewerRole().CS3ResourcePermissions(),
}
})
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.Id = listSpacesResponse.StorageSpaces[0].Root
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())
})
})
Describe("DeletePermission", func() {
var (
getShareResponse collaboration.GetShareResponse
getPublicShareResponse link.GetPublicShareResponse
)
BeforeEach(func() {
getPublicShareResponse.Status = status.NewOK(context.Background())
getShareResponse.Status = status.NewOK(context.Background())
getShareResponse.Share = &collaboration.Share{
Id: &collaboration.ShareId{
OpaqueId: "permissionid",
},
ResourceId: &provider.ResourceId{
StorageId: "1",
SpaceId: "2",
OpaqueId: "3",
},
}
})
It("fails to deletes a public link permission when it can be resolved", func() {
gatewayClient.On("GetPublicShare", mock.Anything, mock.Anything).Return(&getPublicShareResponse, nil)
err := driveItemPermissionsService.DeletePermission(context.Background(),
getShareResponse.Share.ResourceId,
"permissionid",
)
Expect(err).To(MatchError(errorcode.New(errorcode.ItemNotFound, "failed to resolve resource id for shared resource")))
})
It("deletes a user permission as expected", func() {
getPublicShareResponse.Status = status.NewNotFound(context.Background(), "")
gatewayClient.On("GetPublicShare", mock.Anything, mock.Anything).Return(&getPublicShareResponse, nil)
gatewayClient.On("GetShare",
mock.Anything,
mock.MatchedBy(func(req *collaboration.GetShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
}),
).Return(&getShareResponse, nil)
rmShareMockResponse := &collaboration.RemoveShareResponse{
Status: status.NewOK(ctx),
}
gatewayClient.On("RemoveShare",
mock.Anything,
mock.MatchedBy(func(req *collaboration.RemoveShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
}),
).Return(rmShareMockResponse, nil)
err := driveItemPermissionsService.DeletePermission(context.Background(),
getShareResponse.Share.ResourceId,
"permissionid",
)
Expect(err).ToNot(HaveOccurred())
})
It("deletes a link permission as expected", func() {
getPublicShareResponse.Share = &link.PublicShare{
Id: &link.PublicShareId{
OpaqueId: "linkpermissionid",
},
ResourceId: &provider.ResourceId{
StorageId: "1",
SpaceId: "2",
OpaqueId: "3",
},
}
gatewayClient.On("GetPublicShare", mock.Anything, mock.Anything).Return(&getPublicShareResponse, nil)
gatewayClient.On("RemovePublicShare",
mock.Anything,
mock.MatchedBy(func(req *link.RemovePublicShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "linkpermissionid"
}),
).Return(
&link.RemovePublicShareResponse{
Status: status.NewOK(ctx),
}, nil,
)
err := driveItemPermissionsService.DeletePermission(context.Background(),
getShareResponse.Share.ResourceId,
"linkpermissionid",
)
Expect(err).ToNot(HaveOccurred())
})
It("deletes a space permission as expected", func() {
getPublicShareResponse.Status = status.NewNotFound(context.Background(), "")
gatewayClient.On("GetPublicShare", mock.Anything, mock.Anything).Return(&getPublicShareResponse, nil)
gatewayClient.On("RemoveShare",
mock.Anything,
mock.Anything,
).Return(func(ctx context.Context, in *collaboration.RemoveShareRequest, opts ...grpc.CallOption) (*collaboration.RemoveShareResponse, error) {
Expect(in.Ref.GetKey()).ToNot(BeNil())
Expect(in.Ref.GetKey().GetGrantee().GetUserId().GetOpaqueId()).To(Equal("userid"))
return &collaboration.RemoveShareResponse{Status: status.NewOK(ctx)}, nil
})
err := driveItemPermissionsService.DeletePermission(context.Background(),
&provider.ResourceId{
StorageId: "1",
SpaceId: "2",
OpaqueId: "2",
},
"u:userid",
)
Expect(err).ToNot(HaveOccurred())
})
It("fails to delete permission when the item id does not match the shared resource's id", func() {
getPublicShareResponse.Status = status.NewNotFound(context.Background(), "")
gatewayClient.On("GetPublicShare", mock.Anything, mock.Anything).Return(&getPublicShareResponse, nil)
getShareResponse.Share.ResourceId = &provider.ResourceId{
StorageId: "3",
SpaceId: "4",
OpaqueId: "5",
}
gatewayClient.On("GetShare",
mock.Anything,
mock.MatchedBy(func(req *collaboration.GetShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
}),
).Return(&getShareResponse, nil)
rctx := chi.NewRouteContext()
rctx.URLParams.Add("driveID", "1$2")
rctx.URLParams.Add("itemID", "1$2!3")
rctx.URLParams.Add("permissionID", "permissionid")
ctx = context.WithValue(context.Background(), chi.RouteCtxKey, rctx)
err := driveItemPermissionsService.DeletePermission(context.Background(),
&provider.ResourceId{
StorageId: "1",
SpaceId: "2",
OpaqueId: "3",
},
"permissionid",
)
Expect(err).To(MatchError(errorcode.New(errorcode.InvalidRequest, "permissionID and itemID do not match")))
})
})
Describe("UpdatePermission", func() {
var (
driveItemPermission libregraph.Permission
getShareMockResponse *collaboration.GetShareResponse
getPublicShareMockResponse *link.GetPublicShareResponse
updateShareMockResponse *collaboration.UpdateShareResponse
updatePublicShareMockResponse *link.UpdatePublicShareResponse
)
const TestLinkName = "Test Link"
BeforeEach(func() {
ctx = revactx.ContextSetUser(context.Background(), currentUser)
driveItemPermission = libregraph.Permission{}
share := &collaboration.Share{
Id: &collaboration.ShareId{
OpaqueId: "permissionid",
},
ResourceId: driveItemId,
Grantee: &provider.Grantee{
Type: provider.GranteeType_GRANTEE_TYPE_USER,
Id: &provider.Grantee_UserId{
UserId: &userpb.UserId{
OpaqueId: "userid",
},
},
},
Permissions: &collaboration.SharePermissions{
Permissions: roleconversions.NewViewerRole().CS3ResourcePermissions(),
},
}
getShareMockResponse = &collaboration.GetShareResponse{
Status: status.NewOK(ctx),
Share: share,
}
updateShareMockResponse = &collaboration.UpdateShareResponse{
Status: status.NewOK(ctx),
Share: share,
}
updatePublicShareMockResponse = &link.UpdatePublicShareResponse{
Status: status.NewOK(ctx),
Share: &link.PublicShare{DisplayName: TestLinkName},
}
getPublicShareMockResponse = &link.GetPublicShareResponse{
Status: status.NewOK(ctx),
Share: &link.PublicShare{
Id: &link.PublicShareId{
OpaqueId: "permissionid",
},
ResourceId: driveItemId,
Permissions: &link.PublicSharePermissions{
Permissions: linktype.NewViewLinkPermissionSet().GetPermissions(),
},
Token: "token",
},
}
statResponse = &provider.StatResponse{
Status: status.NewOK(ctx),
Info: &provider.ResourceInfo{
Id: driveItemId,
Type: provider.ResourceType_RESOURCE_TYPE_CONTAINER,
},
}
grantMapJSON, _ := json.Marshal(
map[string]*provider.ResourcePermissions{
"userid": roleconversions.NewSpaceViewerRole().CS3ResourcePermissions(),
},
)
spaceOpaque := &types.Opaque{
Map: map[string]*types.OpaqueEntry{
"grants": {
Decoder: "json",
Value: grantMapJSON,
},
},
}
listSpacesResponse = &provider.ListStorageSpacesResponse{
Status: status.NewOK(ctx),
StorageSpaces: []*provider.StorageSpace{
{
Id: &provider.StorageSpaceId{
OpaqueId: "2",
},
Opaque: spaceOpaque,
},
},
}
})
It("fails when no share is found", func() {
getShareMockResponse.Share = nil
getShareMockResponse.Status = status.NewNotFound(ctx, "not found")
gatewayClient.On("GetShare", mock.Anything, mock.MatchedBy(func(req *collaboration.GetShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
})).Return(getShareMockResponse, nil)
getPublicShareMockResponse.Share = nil
getPublicShareMockResponse.Status = status.NewNotFound(ctx, "not found")
gatewayClient.On("GetPublicShare", mock.Anything, mock.MatchedBy(func(req *link.GetPublicShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
})).Return(getPublicShareMockResponse, nil)
res, err := driveItemPermissionsService.UpdatePermission(context.Background(), driveItemId, "permissionid", driveItemPermission)
Expect(err).To(HaveOccurred())
Expect(res).To(BeZero())
})
It("fails to update permission when the resourceID mismatches with the shared resource's id", func() {
getShareMockResponse.Share = nil
getShareMockResponse.Status = status.NewNotFound(ctx, "not found")
getPublicShareMockResponse.Share.ResourceId = &provider.ResourceId{
StorageId: "1",
SpaceId: "2",
OpaqueId: "4",
}
gatewayClient.On("GetPublicShare", mock.Anything, mock.MatchedBy(func(req *link.GetPublicShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
})).Return(getPublicShareMockResponse, nil)
driveItemPermission.SetExpirationDateTime(time.Now().Add(time.Hour))
res, err := driveItemPermissionsService.UpdatePermission(context.Background(), driveItemId, "permissionid", driveItemPermission)
Expect(err).To(MatchError(errorcode.New(errorcode.InvalidRequest, "permissionID and itemID do not match")))
Expect(res).To(BeZero())
})
It("succeeds when trying to update a link permission with displayname", func() {
gatewayClient.On("GetPublicShare", mock.Anything, mock.MatchedBy(func(req *link.GetPublicShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
})).Return(getPublicShareMockResponse, nil)
gatewayClient.On("Stat", mock.Anything, mock.MatchedBy(func(req *provider.StatRequest) bool {
return utils.ResourceIDEqual(req.GetRef().GetResourceId(), driveItemId) && req.GetRef().GetPath() == "."
})).Return(statResponse, nil)
gatewayClient.On("UpdatePublicShare",
mock.Anything,
mock.MatchedBy(func(req *link.UpdatePublicShareRequest) bool {
if req.GetRef().GetId().GetOpaqueId() == "permissionid" {
return req.Update.GetDisplayName() == TestLinkName
}
return false
}),
).Return(updatePublicShareMockResponse, nil)
link := libregraph.NewSharingLink()
link.SetLibreGraphDisplayName(TestLinkName)
driveItemPermission.SetLink(*link)
res, err := driveItemPermissionsService.UpdatePermission(context.Background(), driveItemId, "permissionid", driveItemPermission)
Expect(err).ToNot(HaveOccurred())
Expect(res.Link).ToNot(BeNil())
Expect(res.Link.GetLibreGraphDisplayName() == TestLinkName)
})
It("updates the expiration date", func() {
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
getPublicShareMockResponse.Share = nil
getPublicShareMockResponse.Status = status.NewNotFound(ctx, "not found")
gatewayClient.On("GetPublicShare", mock.Anything, mock.MatchedBy(func(req *link.GetPublicShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
})).Return(getPublicShareMockResponse, nil)
gatewayClient.On("GetShare", mock.Anything, mock.MatchedBy(func(req *collaboration.GetShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
})).Return(getShareMockResponse, nil)
expiration := time.Now().Add(time.Hour)
updateShareMockResponse.Share.Expiration = utils.TimeToTS(expiration)
gatewayClient.On("UpdateShare",
mock.Anything,
mock.MatchedBy(func(req *collaboration.UpdateShareRequest) bool {
if req.GetShare().GetId().GetOpaqueId() == "permissionid" {
return expiration.Equal(utils.TSToTime(req.GetShare().GetExpiration()))
}
return false
}),
).Return(updateShareMockResponse, nil)
driveItemPermission.SetExpirationDateTime(expiration)
res, err := driveItemPermissionsService.UpdatePermission(context.Background(), driveItemId, "permissionid", driveItemPermission)
Expect(err).ToNot(HaveOccurred())
Expect(res.GetExpirationDateTime().Equal(expiration)).To(BeTrue())
})
It("deletes the expiration date", func() {
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
getPublicShareMockResponse.Share = nil
getPublicShareMockResponse.Status = status.NewNotFound(ctx, "not found")
gatewayClient.On("GetPublicShare", mock.Anything, mock.MatchedBy(func(req *link.GetPublicShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
})).Return(getPublicShareMockResponse, nil)
gatewayClient.On("GetShare", mock.Anything, mock.MatchedBy(func(req *collaboration.GetShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
})).Return(getShareMockResponse, nil)
gatewayClient.On("UpdateShare",
mock.Anything,
mock.MatchedBy(func(req *collaboration.UpdateShareRequest) bool {
if req.GetShare().GetId().GetOpaqueId() == "permissionid" {
return true
}
return false
}),
).Return(updateShareMockResponse, nil)
driveItemPermission.SetExpirationDateTimeNil()
res, err := driveItemPermissionsService.UpdatePermission(context.Background(), driveItemId, "permissionid", driveItemPermission)
Expect(err).ToNot(HaveOccurred())
_, ok := res.GetExpirationDateTimeOk()
Expect(ok).To(BeFalse())
})
It("fails to update the share permissions for a file share when setting a space specific role", func() {
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
getPublicShareMockResponse.Share = nil
getPublicShareMockResponse.Status = status.NewNotFound(ctx, "not found")
gatewayClient.On("GetPublicShare", mock.Anything, mock.MatchedBy(func(req *link.GetPublicShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
})).Return(getPublicShareMockResponse, nil)
gatewayClient.On("GetShare", mock.Anything, mock.MatchedBy(func(req *collaboration.GetShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
})).Return(getShareMockResponse, nil)
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
driveItemPermission.SetRoles([]string{unifiedrole.NewSpaceViewerUnifiedRole().GetId()})
res, err := driveItemPermissionsService.UpdatePermission(context.Background(), driveItemId, "permissionid", driveItemPermission)
Expect(err).To(MatchError(errorcode.New(errorcode.InvalidRequest, "role not applicable to this resource")))
Expect(res).To(BeZero())
})
It("fails to update the space permissions for a space share when setting a file specific role", func() {
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
getPublicShareMockResponse.Share = nil
getPublicShareMockResponse.Status = status.NewNotFound(ctx, "not found")
gatewayClient.On("GetPublicShare", mock.Anything, mock.Anything).Return(getPublicShareMockResponse, nil)
gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(listSpacesResponse, nil)
statResponse.Info.Id = listSpacesResponse.StorageSpaces[0].Root
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
driveItemPermission.SetRoles([]string{unifiedrole.NewFileEditorUnifiedRole().GetId()})
spaceId := &provider.ResourceId{
StorageId: "1",
SpaceId: "2",
OpaqueId: "2",
}
res, err := driveItemPermissionsService.UpdatePermission(context.Background(), spaceId, "u:userid", driveItemPermission)
Expect(err).To(MatchError(errorcode.New(errorcode.InvalidRequest, "role not applicable to this resource")))
Expect(res).To(BeZero())
})
It("updates the share permissions when changing the resource permission actions", func() {
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
getPublicShareMockResponse.Share = nil
getPublicShareMockResponse.Status = status.NewNotFound(ctx, "not found")
gatewayClient.On("GetPublicShare", mock.Anything, mock.Anything).Return(getPublicShareMockResponse, nil)
gatewayClient.On("GetShare", mock.Anything, mock.MatchedBy(func(req *collaboration.GetShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
})).Return(getShareMockResponse, nil)
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
updateShareMockResponse.Share.Permissions = &collaboration.SharePermissions{
Permissions: &provider.ResourcePermissions{
GetPath: true,
},
}
gatewayClient.On("UpdateShare",
mock.Anything,
mock.MatchedBy(func(req *collaboration.UpdateShareRequest) bool {
return req.GetShare().GetId().GetOpaqueId() == "permissionid"
}),
).Return(updateShareMockResponse, nil)
driveItemPermission.SetLibreGraphPermissionsActions([]string{unifiedrole.DriveItemPathRead})
res, err := driveItemPermissionsService.UpdatePermission(context.Background(), driveItemId, "permissionid", driveItemPermission)
Expect(err).ToNot(HaveOccurred())
_, ok := res.GetRolesOk()
Expect(ok).To(BeFalse())
_, ok = res.GetLibreGraphPermissionsActionsOk()
Expect(ok).To(BeTrue())
})
It("updates the expiration date on a public share", func() {
gatewayClient.On("GetPublicShare", mock.Anything, mock.Anything).Return(getPublicShareMockResponse, nil)
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
expiration := time.Now().UTC().Add(time.Hour)
updatePublicShareMockResponse.Share.Expiration = utils.TimeToTS(expiration)
gatewayClient.On("UpdatePublicShare",
mock.Anything,
mock.MatchedBy(func(req *link.UpdatePublicShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
}),
).Return(updatePublicShareMockResponse, nil)
driveItemPermission.SetExpirationDateTime(expiration)
res, err := driveItemPermissionsService.UpdatePermission(context.Background(), driveItemId, "permissionid", driveItemPermission)
Expect(err).ToNot(HaveOccurred())
Expect(res.GetExpirationDateTime().Equal(expiration)).To(BeTrue())
})
It("updates the permissions on a public share", func() {
gatewayClient.On("GetPublicShare", mock.Anything, mock.Anything).Return(getPublicShareMockResponse, nil)
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
newLink := libregraph.NewSharingLink()
newLinkType, err := libregraph.NewSharingLinkTypeFromValue("edit")
Expect(err).ToNot(HaveOccurred())
newLink.SetType(*newLinkType)
updatePublicShareMockResponse.Share.Permissions = &link.PublicSharePermissions{
Permissions: linktype.NewFolderEditLinkPermissionSet().Permissions,
}
gatewayClient.On("UpdatePublicShare",
mock.Anything,
mock.MatchedBy(func(req *link.UpdatePublicShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
}),
).Return(updatePublicShareMockResponse, nil)
driveItemPermission.SetLink(*newLink)
res, err := driveItemPermissionsService.UpdatePermission(context.Background(), driveItemId, "permissionid", driveItemPermission)
Expect(err).ToNot(HaveOccurred())
linkType := res.Link.GetType()
Expect(string(linkType)).To(Equal("edit"))
})
It("updates the public share to internal link", func() {
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
getPublicShareMockResponse.Share = &link.PublicShare{
Id: &link.PublicShareId{
OpaqueId: "permissionid",
},
ResourceId: &provider.ResourceId{
StorageId: "1",
SpaceId: "2",
OpaqueId: "3",
},
PasswordProtected: true,
Permissions: &link.PublicSharePermissions{
Permissions: linktype.NewFileEditLinkPermissionSet().GetPermissions(),
},
Token: "token",
}
gatewayClient.On("GetPublicShare",
mock.Anything,
mock.MatchedBy(func(req *link.GetPublicShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
}),
).Return(getPublicShareMockResponse, nil)
newLink := libregraph.NewSharingLink()
newLinkType, err := libregraph.NewSharingLinkTypeFromValue("internal")
Expect(err).ToNot(HaveOccurred())
newLink.SetType(*newLinkType)
updatePublicShareMockResponse.Share.Permissions = &link.PublicSharePermissions{
Permissions: linktype.NewInternalLinkPermissionSet().Permissions,
}
gatewayClient.On("UpdatePublicShare",
mock.Anything,
mock.MatchedBy(func(req *link.UpdatePublicShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
}),
).Return(updatePublicShareMockResponse, nil)
driveItemPermission.SetLink(*newLink)
res, err := driveItemPermissionsService.UpdatePermission(context.Background(), driveItemId, "permissionid", driveItemPermission)
Expect(err).ToNot(HaveOccurred())
linkType := res.Link.GetType()
Expect(string(linkType)).To(Equal("internal"))
pp, hasPP := res.GetHasPasswordOk()
Expect(hasPP).To(Equal(true))
Expect(*pp).To(Equal(false))
})
It("fails when updating the expiration date on a public share", func() {
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
gatewayClient.On("GetPublicShare", mock.Anything, mock.Anything).Return(getPublicShareMockResponse, nil)
expiration := time.Now().UTC().AddDate(0, 0, -1)
updatePublicShareMock := gatewayClient.On("UpdatePublicShare",
mock.Anything,
mock.MatchedBy(func(req *link.UpdatePublicShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "permissionid"
}),
)
updatePublicShareMockResponse.Share = nil
updatePublicShareMockResponse.Status = status.NewFailedPrecondition(ctx, nil, "expiration date is in the past")
updatePublicShareMock.Return(updatePublicShareMockResponse, nil)
driveItemPermission.SetExpirationDateTime(expiration)
res, err := driveItemPermissionsService.UpdatePermission(context.Background(), driveItemId, "permissionid", driveItemPermission)
Expect(err).To(MatchError(errorcode.New(errorcode.InvalidRequest, "expiration date is in the past").WithOrigin(errorcode.ErrorOriginCS3)))
Expect(res).To(BeZero())
})
})
})
var _ = Describe("DriveItemPermissionsApi", func() {
var (
mockProvider *mocks.DriveItemPermissionsProvider
httpAPI svc.DriveItemPermissionsApi
rCTX *chi.Context
invite libregraph.DriveItemInvite
)
BeforeEach(func() {
logger := log.NewLogger()
mockProvider = mocks.NewDriveItemPermissionsProvider(GinkgoT())
api, err := svc.NewDriveItemPermissionsApi(mockProvider, logger)
Expect(err).ToNot(HaveOccurred())
httpAPI = api
rCTX = chi.NewRouteContext()
rCTX.URLParams.Add("driveID", "1$2")
invite = libregraph.DriveItemInvite{
Recipients: []libregraph.DriveRecipient{
{
ObjectId: libregraph.PtrString("1"),
LibreGraphRecipientType: libregraph.PtrString("user")},
},
Roles: []string{unifiedrole.NewViewerUnifiedRole().GetId()},
}
})
checkDriveIDAndItemIDValidation := func(handler http.HandlerFunc) {
rCTX.URLParams.Add("itemID", "3$4!5")
responseRecorder := httptest.NewRecorder()
request := httptest.NewRequest(http.MethodPost, "/", nil).
WithContext(
context.WithValue(context.Background(), chi.RouteCtxKey, rCTX),
)
handler(responseRecorder, request)
Expect(responseRecorder.Code).To(Equal(http.StatusUnprocessableEntity))
jsonData := gjson.Get(responseRecorder.Body.String(), "error")
Expect(jsonData.Get("message").String()).To(Equal("invalid driveID or itemID"))
}
Describe("Invite", func() {
It("validates the driveID and itemID url param", func() {
checkDriveIDAndItemIDValidation(httpAPI.Invite)
})
It("return an error when the Invite provider errors", func() {
rCTX.URLParams.Add("itemID", "1$2!3")
responseRecorder := httptest.NewRecorder()
inviteJson, err := json.Marshal(invite)
Expect(err).ToNot(HaveOccurred())
request := httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer(inviteJson)).
WithContext(
context.WithValue(context.Background(), chi.RouteCtxKey, rCTX),
)
onInvite := mockProvider.On("Invite", mock.Anything, mock.Anything, mock.Anything)
onInvite.Return(func(ctx context.Context, resourceID *storageprovider.ResourceId, invite libregraph.DriveItemInvite) (libregraph.Permission, error) {
return libregraph.Permission{}, errors.New("any")
}).Once()
httpAPI.Invite(responseRecorder, request)
Expect(responseRecorder.Code).To(Equal(http.StatusInternalServerError))
})
It("call the Invite provider with the correct arguments", func() {
rCTX.URLParams.Add("itemID", "1$2!3")
responseRecorder := httptest.NewRecorder()
inviteJson, err := json.Marshal(invite)
Expect(err).ToNot(HaveOccurred())
onInvite := mockProvider.On("Invite", mock.Anything, mock.Anything, mock.Anything)
onInvite.Return(func(ctx context.Context, resourceID *storageprovider.ResourceId, invite libregraph.DriveItemInvite) (libregraph.Permission, error) {
Expect(storagespace.FormatResourceID(resourceID)).To(Equal("1$2!3"))
return libregraph.Permission{}, nil
}).Once()
request := httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer(inviteJson)).
WithContext(
context.WithValue(context.Background(), chi.RouteCtxKey, rCTX),
)
httpAPI.Invite(responseRecorder, request)
Expect(responseRecorder.Code).To(Equal(http.StatusOK))
})
})
Describe("SpaceRootInvite", func() {
It("call the Invite provider with the correct arguments", func() {
responseRecorder := httptest.NewRecorder()
inviteJson, err := json.Marshal(invite)
Expect(err).ToNot(HaveOccurred())
onInvite := mockProvider.On("SpaceRootInvite", mock.Anything, mock.Anything, mock.Anything)
onInvite.Return(func(ctx context.Context, driveID *storageprovider.ResourceId, invite libregraph.DriveItemInvite) (libregraph.Permission, error) {
Expect(storagespace.FormatResourceID(driveID)).To(Equal("1$2"))
return libregraph.Permission{}, nil
}).Once()
request := httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer(inviteJson)).
WithContext(
context.WithValue(context.Background(), chi.RouteCtxKey, rCTX),
)
httpAPI.SpaceRootInvite(responseRecorder, request)
Expect(responseRecorder.Code).To(Equal(http.StatusOK))
})
It("fails with an empty driveid", func() {
rCTX.URLParams.Add("driveID", "")
responseRecorder := httptest.NewRecorder()
inviteJson, err := json.Marshal(invite)
Expect(err).ToNot(HaveOccurred())
request := httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer(inviteJson)).
WithContext(
context.WithValue(context.Background(), chi.RouteCtxKey, rCTX),
)
httpAPI.SpaceRootInvite(responseRecorder, request)
Expect(responseRecorder.Code).To(Equal(http.StatusUnprocessableEntity))
})
})
Describe("ListPermissions", func() {
It("calls the ListPermissions provider with the correct arguments", func() {
rCTX.URLParams.Add("itemID", "1$2!3")
responseRecorder := httptest.NewRecorder()
inviteJson, err := json.Marshal(invite)
Expect(err).ToNot(HaveOccurred())
mockProvider.On("ListPermissions", mock.Anything, mock.Anything, mock.Anything).
Return(func(ctx context.Context, itemid *storageprovider.ResourceId) (libregraph.CollectionOfPermissionsWithAllowedValues, error) {
Expect(storagespace.FormatResourceID(itemid)).To(Equal("1$2!3"))
return libregraph.CollectionOfPermissionsWithAllowedValues{}, nil
}).Once()
request := httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer(inviteJson)).
WithContext(
context.WithValue(context.Background(), chi.RouteCtxKey, rCTX),
)
httpAPI.ListPermissions(responseRecorder, request)
Expect(responseRecorder.Code).To(Equal(http.StatusOK))
})
It("fails with an empty itemid", func() {
responseRecorder := httptest.NewRecorder()
inviteJson, err := json.Marshal(invite)
Expect(err).ToNot(HaveOccurred())
request := httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer(inviteJson)).
WithContext(
context.WithValue(context.Background(), chi.RouteCtxKey, rCTX),
)
httpAPI.ListPermissions(responseRecorder, request)
Expect(responseRecorder.Code).To(Equal(http.StatusBadRequest))
})
})
})