Skip to content
Draft
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
8 changes: 6 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ require (
github.com/thejerf/suture/v4 v4.0.6
github.com/tidwall/gjson v1.18.0
github.com/tidwall/sjson v1.2.5
github.com/tus/tusd/v2 v2.8.0
github.com/tus/tusd/v2 v2.9.2
github.com/unrolled/secure v1.16.0
github.com/vmihailenco/msgpack/v5 v5.4.1
github.com/xhit/go-simple-mail/v2 v2.16.0
Expand Down Expand Up @@ -392,7 +392,7 @@ require (
golang.org/x/sys v0.41.0 // indirect
golang.org/x/time v0.15.0 // indirect
golang.org/x/tools v0.41.0 // indirect
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect
google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
Expand All @@ -414,3 +414,7 @@ replace github.com/go-micro/plugins/v4/store/nats-js-kv => github.com/opencloud-

// to get the logger injection (https://github.com/pablodz/inotifywaitgo/pull/11)
replace github.com/pablodz/inotifywaitgo v0.0.9 => github.com/opencloud-eu/inotifywaitgo v0.0.0-20251111171128-a390bae3c5e9

replace github.com/cs3org/go-cs3apis => github.com/rhafer/go-cs3apis v0.0.0-20260312152349-0b5ca0d4b142

replace github.com/opencloud-eu/reva/v2 => github.com/rhafer/reva/v2 v2.0.0-20260317140355-5ba923b2b4a0
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,6 @@ github.com/crewjam/httperr v0.2.0 h1:b2BfXR8U3AlIHwNeFFvZ+BV1LFvKLlzMjzaTnZMybNo
github.com/crewjam/httperr v0.2.0/go.mod h1:Jlz+Sg/XqBQhyMjdDiC+GNNRzZTD7x39Gu3pglZ5oH4=
github.com/crewjam/saml v0.4.14 h1:g9FBNx62osKusnFzs3QTN5L9CVA/Egfgm+stJShzw/c=
github.com/crewjam/saml v0.4.14/go.mod h1:UVSZCf18jJkk6GpWNVqcyQJMD5HsRugBPf4I1nl2mME=
github.com/cs3org/go-cs3apis v0.0.0-20260310080202-fb97596763d6 h1:Akwn9gHJugKd8M48LyV+WeIQ6yMXoxZdgZabR53I9q4=
github.com/cs3org/go-cs3apis v0.0.0-20260310080202-fb97596763d6/go.mod h1:DedpcqXl193qF/08Y04IO0PpxyyMu8+GrkD6kWK2MEQ=
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
github.com/cyphar/filepath-securejoin v0.5.1 h1:eYgfMq5yryL4fbWfkLpFFy2ukSELzaJOTaUTuh+oF48=
github.com/cyphar/filepath-securejoin v0.5.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
Expand Down Expand Up @@ -959,8 +957,6 @@ github.com/opencloud-eu/inotifywaitgo v0.0.0-20251111171128-a390bae3c5e9 h1:dIft
github.com/opencloud-eu/inotifywaitgo v0.0.0-20251111171128-a390bae3c5e9/go.mod h1:JWyDC6H+5oZRdUJUgKuaye+8Ph5hEs6HVzVoPKzWSGI=
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d h1:JcqGDiyrcaQwVyV861TUyQgO7uEmsjkhfm7aQd84dOw=
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d/go.mod h1:pzatilMEHZFT3qV7C/X3MqOa3NlRQuYhlRhZTL+hN6Q=
github.com/opencloud-eu/reva/v2 v2.42.6-0.20260311175421-d77bc89ffe35 h1:Qfx8AelrxsyPk3Lacj3feWULGD7BD2Vsg1X6rve7bHU=
github.com/opencloud-eu/reva/v2 v2.42.6-0.20260311175421-d77bc89ffe35/go.mod h1:0k9+Qits/aemqVdCXs5hSEgTppPx9RZuxutuxqZKQF0=
github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4 h1:l2oB/RctH+t8r7QBj5p8thfEHCM/jF35aAY3WQ3hADI=
github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
Expand Down Expand Up @@ -1072,6 +1068,10 @@ github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKc
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 h1:bsUq1dX0N8AOIL7EB/X911+m4EHsnWEHeJ0c+3TTBrg=
github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rhafer/go-cs3apis v0.0.0-20260312152349-0b5ca0d4b142 h1:ZDS0bPCVjH8XaEYHlWMi/QUpuJabYsRAM91HL8Lvjlw=
github.com/rhafer/go-cs3apis v0.0.0-20260312152349-0b5ca0d4b142/go.mod h1:DedpcqXl193qF/08Y04IO0PpxyyMu8+GrkD6kWK2MEQ=
github.com/rhafer/reva/v2 v2.0.0-20260317140355-5ba923b2b4a0 h1:+Nep6ECoUTf6HByta891FFsl7AIJJP1VposCKmvpAws=
github.com/rhafer/reva/v2 v2.0.0-20260317140355-5ba923b2b4a0/go.mod h1:hB/Guu2yI14TcH3EIWW+KMfy4iakcfH9WcSfG5/v0K4=
github.com/riandyrn/otelchi v0.12.2 h1:6QhGv0LVw/dwjtPd12mnNrl0oEQF4ZAlmHcnlTYbeAg=
github.com/riandyrn/otelchi v0.12.2/go.mod h1:weZZeUJURvtCcbWsdb7Y6F8KFZGedJlSrgUjq9VirV8=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
Expand Down Expand Up @@ -1230,8 +1230,8 @@ github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208/go.mod h1:BzWtXXrXz
github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
github.com/trustelem/zxcvbn v1.0.1 h1:mp4JFtzdDYGj9WYSD3KQSkwwUumWNFzXaAjckaTYpsc=
github.com/trustelem/zxcvbn v1.0.1/go.mod h1:zonUyKeh7sw6psPf/e3DtRqkRyZvAbOfjNz/aO7YQ5s=
github.com/tus/tusd/v2 v2.8.0 h1:X2jGxQ05jAW4inDd2ogmOKqwnb4c/D0lw2yhgHayWyU=
github.com/tus/tusd/v2 v2.8.0/go.mod h1:3/zEOVQQIwmJhvNam8phV4x/UQt68ZmZiTzeuJUNhVo=
github.com/tus/tusd/v2 v2.9.2 h1:Dd/Dh0CG7+/wom4lDQnnhca+1p5qVwgnbyEBacj1v7c=
github.com/tus/tusd/v2 v2.9.2/go.mod h1:+a9uNLru2Qy+CUu7QUIshmQ+X0fLNw77eu8voKVxmgA=
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
Expand Down Expand Up @@ -1716,8 +1716,8 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb h1:ITgPrl429bc6+2ZraNSzMDk3I95nmQln2fuPstKwFDE=
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:sAo5UzpjUwgFBCzupwhcLcxHVDK7vG5IqI30YnwX2eE=
google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 h1:VQZ/yAbAtjkHgH80teYd2em3xtIkkHd7ZhqfH2N9CsM=
google.golang.org/genproto v0.0.0-20260128011058-8636f8732409/go.mod h1:rxKD3IEILWEu3P44seeNOAwZN4SaoKaQ/2eTg4mM6EM=
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0=
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ=
Expand Down
3 changes: 2 additions & 1 deletion services/gateway/pkg/revaconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ func GatewayConfigFromStruct(cfg *config.Config, logger log.Logger) map[string]i
"ocminvitemanagersvc": cfg.OCMEndpoint,
"ocmproviderauthorizersvc": cfg.OCMEndpoint,
"ocmcoresvc": cfg.OCMEndpoint,
"commit_share_to_storage_grant": cfg.CommitShareToStorageGrant,
"use_common_space_root_share_logic": true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this actually being used? I didn't find a reference to it in reva.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used in the gateway:

https://github.com/opencloud-eu/reva/blob/main/internal/grpc/services/gateway/gateway.go#L79

We should probably remove that config switch, if we decide to switch to the share-manager.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I thought it was a new flag being introduced with your change. Thanks.

"commit_share_to_storage_grant": cfg.CommitShareToStorageGrant,
"share_folder": cfg.ShareFolder, // ShareFolder is the location where to create shares in the recipient's storage provider.
// other
"disable_home_creation_on_login": cfg.DisableHomeCreationOnLogin,
Expand Down
14 changes: 4 additions & 10 deletions services/graph/pkg/service/v0/api_driveitem_permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,10 +245,6 @@ func (s DriveItemPermissionsService) Invite(ctx context.Context, resourceId *sto

if shareid != "" {
permission.Id = conversions.ToPointer(shareid)
} else if IsSpaceRoot(statResponse.GetInfo().GetId()) {
// permissions on a space root are not handled by a share manager so
// they don't get a share-id
permission.SetId(identitySetToSpacePermissionID(permission.GetGrantedToV2()))
}

if expiration != nil {
Expand Down Expand Up @@ -414,12 +410,12 @@ func (s DriveItemPermissionsService) ListPermissions(ctx context.Context, itemID
var permissionsCount int

if IsSpaceRoot(statResponse.GetInfo().GetId()) {
var permissions []libregraph.Permission
permissions, permissionsCount, err = s.getSpaceRootPermissions(ctx, statResponse.GetInfo().GetSpace().GetId(), queryOptions.NoValues)
driveItems, err = s.listSpaceRootUserShares(ctx, []*collaboration.Filter{
share.ResourceIDFilter(itemID),
}, driveItems)
if err != nil {
return collectionOfPermissions, err
}
collectionOfPermissions.Value = permissions
} else {
// "normal" driveItem, populate user permissions via share providers
driveItems, err = s.listUserShares(ctx, []*collaboration.Filter{
Expand Down Expand Up @@ -535,12 +531,10 @@ func (s DriveItemPermissionsService) DeletePermission(ctx context.Context, itemI
}

switch permissionType {
case User:
case User, Space:
return s.removeUserShare(ctx, permissionID)
case Public:
return s.removePublicShare(ctx, permissionID)
case Space:
return s.removeSpacePermission(ctx, permissionID, sharedResourceID)
case OCM:
return s.removeOCMPermission(ctx, permissionID)
default:
Expand Down
69 changes: 52 additions & 17 deletions services/graph/pkg/service/v0/api_driveitem_permissions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
"github.com/opencloud-eu/opencloud/services/graph/pkg/config"
"github.com/stretchr/testify/mock"
"github.com/tidwall/gjson"
"google.golang.org/grpc"

roleconversions "github.com/opencloud-eu/reva/v2/pkg/conversions"
revactx "github.com/opencloud-eu/reva/v2/pkg/ctx"
Expand Down Expand Up @@ -391,6 +390,25 @@ var _ = Describe("DriveItemPermissionsService", func() {
Expect(len(permissions.LibreGraphPermissionsActionsAllowedValues)).ToNot(BeZero())
Expect(len(permissions.LibreGraphPermissionsRolesAllowedValues)).ToNot(BeZero())
})
It("sends SpaceRootFilter(false) when listing shares for a non-space-root item", func() {
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
gatewayClient.On("ListPublicShares", mock.Anything, mock.Anything).Return(listPublicSharesResponse, nil)
gatewayClient.On("ListShares",
mock.Anything,
mock.MatchedBy(func(req *collaboration.ListSharesRequest) bool {
for _, f := range req.Filters {
if f.Type == collaboration.Filter_TYPE_SPACE_ROOT && !f.GetSpaceRoot() {
return true
}
}
return false
}),
).Return(listSharesResponse, nil)

_, err := driveItemPermissionsService.ListPermissions(context.Background(), itemID, svc.ListPermissionsQueryOptions{})
Expect(err).ToNot(HaveOccurred())
gatewayClient.AssertExpectations(GinkgoT())
})
It("returns one permission per share", func() {
statResponse.Info.PermissionSet = roleconversions.NewEditorRole().CS3ResourcePermissions()
listSharesResponse.Shares = []*collaboration.Share{
Expand Down Expand Up @@ -442,6 +460,8 @@ var _ = Describe("DriveItemPermissionsService", func() {
})
It("returns role denied", func() {
statResponse.Info.PermissionSet = roleconversions.NewManagerRole().CS3ResourcePermissions()
statResponse.Info.Type = provider.ResourceType_RESOURCE_TYPE_CONTAINER

listSharesResponse.Shares = []*collaboration.Share{
{
Id: &collaboration.ShareId{OpaqueId: "1"},
Expand Down Expand Up @@ -666,6 +686,7 @@ var _ = Describe("DriveItemPermissionsService", func() {
}

gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(listSpacesResponse, nil)
gatewayClient.On("ListShares", mock.Anything, mock.Anything).Return(&collaboration.ListSharesResponse{Status: status.NewOK(ctx)}, 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)
Expand Down Expand Up @@ -765,20 +786,18 @@ var _ = Describe("DriveItemPermissionsService", func() {

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
})
mock.MatchedBy(func(req *collaboration.RemoveShareRequest) bool {
return req.GetRef().GetId().GetOpaqueId() == "shareid"
}),
).Return(&collaboration.RemoveShareResponse{Status: status.NewOK(ctx)}, nil)

err := driveItemPermissionsService.DeletePermission(context.Background(),
&provider.ResourceId{
StorageId: "1",
SpaceId: "2",
OpaqueId: "2",
},
"u:userid",
"shareid",
)
Expect(err).ToNot(HaveOccurred())
})
Expand Down Expand Up @@ -1045,24 +1064,40 @@ var _ = Describe("DriveItemPermissionsService", func() {
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.UnifiedRoleFileEditorID})
spaceId := &provider.ResourceId{
StorageId: "1",
SpaceId: "2",
OpaqueId: "2",
}
res, err := driveItemPermissionsService.UpdatePermission(ctx, spaceId, "u:userid", driveItemPermission)
statResponse.Info.Id = spaceId
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)

gatewayClient.On("ListShares", mock.Anything, mock.Anything).Return(&collaboration.ListSharesResponse{
Status: status.NewOK(ctx),
Shares: []*collaboration.Share{
{
Id: &collaboration.ShareId{OpaqueId: "spaceShareId"},
ResourceId: spaceId,
Grantee: &provider.Grantee{
Type: provider.GranteeType_GRANTEE_TYPE_USER,
Id: &provider.Grantee_UserId{
UserId: &userpb.UserId{OpaqueId: "userid"},
},
},
Permissions: &collaboration.SharePermissions{
Permissions: roleconversions.NewSpaceViewerRole().CS3ResourcePermissions(),
},
},
},
}, nil)
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)

driveItemPermission.SetRoles([]string{unifiedrole.UnifiedRoleFileEditorID})
res, err := driveItemPermissionsService.UpdatePermission(ctx, spaceId, "spaceShareId", driveItemPermission)
Expect(err).To(MatchError(errorcode.New(errorcode.InvalidRequest, "role not applicable to this resource")))
Expect(res).To(BeZero())
})
Expand Down
Loading