From 096749ba422ce869cecc8ff8850c4b72df13f77a Mon Sep 17 00:00:00 2001 From: Ralf Haferkamp Date: Mon, 16 Mar 2026 14:32:19 +0100 Subject: [PATCH 1/4] Use filter to avoid including space membership in the sharedWithMe response --- services/gateway/pkg/revaconfig/config.go | 3 ++- .../v0/api_driveitem_permissions_test.go | 19 +++++++++++++++++++ services/graph/pkg/service/v0/base.go | 1 + 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/services/gateway/pkg/revaconfig/config.go b/services/gateway/pkg/revaconfig/config.go index 8bd8e20806..f851d31992 100644 --- a/services/gateway/pkg/revaconfig/config.go +++ b/services/gateway/pkg/revaconfig/config.go @@ -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, + "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, diff --git a/services/graph/pkg/service/v0/api_driveitem_permissions_test.go b/services/graph/pkg/service/v0/api_driveitem_permissions_test.go index 3adb5b2dc3..1c7f703856 100644 --- a/services/graph/pkg/service/v0/api_driveitem_permissions_test.go +++ b/services/graph/pkg/service/v0/api_driveitem_permissions_test.go @@ -391,6 +391,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{ diff --git a/services/graph/pkg/service/v0/base.go b/services/graph/pkg/service/v0/base.go index 4b2c8edd2c..6433484738 100644 --- a/services/graph/pkg/service/v0/base.go +++ b/services/graph/pkg/service/v0/base.go @@ -278,6 +278,7 @@ func (g BaseGraphService) listUserShares(ctx context.Context, filters []*collabo concreteFilters := []*collaboration.Filter{ share.UserGranteeFilter(), share.GroupGranteeFilter(), + share.SpaceRootFilter(false), } concreteFilters = append(concreteFilters, filters...) From aa2f1335b9dca42dac3db1a7bc6aa3f0fc818ff6 Mon Sep 17 00:00:00 2001 From: Ralf Haferkamp Date: Tue, 17 Mar 2026 13:18:17 +0100 Subject: [PATCH 2/4] graph: use share manager for managing space permissions This gets us rid of quite a bit of special casing for space permission. Also provides us with "real" permission IDs instead of those faked "u:" ones. --- .../service/v0/api_driveitem_permissions.go | 14 +-- .../v0/api_driveitem_permissions_test.go | 50 +++++--- services/graph/pkg/service/v0/base.go | 116 ++++-------------- services/graph/pkg/service/v0/driveitems.go | 49 ++------ services/graph/pkg/service/v0/sharedwithme.go | 7 +- 5 files changed, 83 insertions(+), 153 deletions(-) diff --git a/services/graph/pkg/service/v0/api_driveitem_permissions.go b/services/graph/pkg/service/v0/api_driveitem_permissions.go index aa68e8d0fe..f55ad2717d 100644 --- a/services/graph/pkg/service/v0/api_driveitem_permissions.go +++ b/services/graph/pkg/service/v0/api_driveitem_permissions.go @@ -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 { @@ -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{ @@ -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: diff --git a/services/graph/pkg/service/v0/api_driveitem_permissions_test.go b/services/graph/pkg/service/v0/api_driveitem_permissions_test.go index 1c7f703856..4a088664dd 100644 --- a/services/graph/pkg/service/v0/api_driveitem_permissions_test.go +++ b/services/graph/pkg/service/v0/api_driveitem_permissions_test.go @@ -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" @@ -461,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"}, @@ -685,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) @@ -784,12 +786,10 @@ 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{ @@ -797,7 +797,7 @@ var _ = Describe("DriveItemPermissionsService", func() { SpaceId: "2", OpaqueId: "2", }, - "u:userid", + "shareid", ) Expect(err).ToNot(HaveOccurred()) }) @@ -1064,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()) }) diff --git a/services/graph/pkg/service/v0/base.go b/services/graph/pkg/service/v0/base.go index 6433484738..fbbfa1edfe 100644 --- a/services/graph/pkg/service/v0/base.go +++ b/services/graph/pkg/service/v0/base.go @@ -51,22 +51,6 @@ type BaseGraphService struct { availableRoles []*libregraph.UnifiedRoleDefinition } -func (g BaseGraphService) getSpaceRootPermissions(ctx context.Context, spaceID *storageprovider.StorageSpaceId, countOnly bool) ([]libregraph.Permission, int, error) { - gatewayClient, err := g.gatewaySelector.Next() - - if err != nil { - g.logger.Debug().Err(err).Msg("selecting gatewaySelector failed") - return nil, 0, err - } - space, err := utils.GetSpace(ctx, spaceID.GetOpaqueId(), gatewayClient) - if err != nil { - return nil, 0, errorcode.FromUtilsStatusCodeError(err) - } - - perm, count := g.cs3SpacePermissionsToLibreGraph(ctx, space, countOnly, APIVersion_1_Beta_1) - return perm, count, nil -} - func (g BaseGraphService) getDriveItem(ctx context.Context, ref *storageprovider.Reference) (*libregraph.DriveItem, error) { gatewayClient, err := g.gatewaySelector.Next() if err != nil { @@ -269,6 +253,17 @@ func (g BaseGraphService) libreGraphPermissionFromCS3PublicShare(createdLink *li } func (g BaseGraphService) listUserShares(ctx context.Context, filters []*collaboration.Filter, driveItems driveItemsByResourceID) (driveItemsByResourceID, error) { + return g.listSharesWithSpaceRootFilter(ctx, false, filters, driveItems) +} + +// listSpaceRootUserShares lists user/group shares whose resource is a space root (i.e. space +// memberships). It uses SpaceRootFilter(true) so only space-root shares are returned, mirroring +// how listUserShares works for regular file/folder shares. +func (g BaseGraphService) listSpaceRootUserShares(ctx context.Context, filters []*collaboration.Filter, driveItems driveItemsByResourceID) (driveItemsByResourceID, error) { + return g.listSharesWithSpaceRootFilter(ctx, true, filters, driveItems) +} + +func (g BaseGraphService) listSharesWithSpaceRootFilter(ctx context.Context, spaceRoot bool, filters []*collaboration.Filter, driveItems driveItemsByResourceID) (driveItemsByResourceID, error) { gatewayClient, err := g.gatewaySelector.Next() if err != nil { g.logger.Error().Err(err).Msg("could not select next gateway client") @@ -278,7 +273,7 @@ func (g BaseGraphService) listUserShares(ctx context.Context, filters []*collabo concreteFilters := []*collaboration.Filter{ share.UserGranteeFilter(), share.GroupGranteeFilter(), - share.SpaceRootFilter(false), + share.SpaceRootFilter(spaceRoot), } concreteFilters = append(concreteFilters, filters...) @@ -563,9 +558,7 @@ func (g BaseGraphService) cs3OCMSharesToDriveItems(ctx context.Context, shares [ func (g BaseGraphService) cs3UserShareToPermission(ctx context.Context, share *collaboration.Share, roleCondition string) (*libregraph.Permission, error) { perm := libregraph.Permission{} perm.SetRoles([]string{}) - if roleCondition != unifiedrole.UnifiedRoleConditionDrive { - perm.SetId(share.GetId().GetOpaqueId()) - } + perm.SetId(share.GetId().GetOpaqueId()) grantedTo := libregraph.SharePointIdentitySet{} switch share.GetGrantee().GetType() { case storageprovider.GranteeType_GRANTEE_TYPE_USER: @@ -579,9 +572,6 @@ func (g BaseGraphService) cs3UserShareToPermission(ctx context.Context, share *c return nil, errorcode.New(errorcode.GeneralException, err.Error()) default: grantedTo.SetUser(user) - if roleCondition == unifiedrole.UnifiedRoleConditionDrive { - perm.SetId("u:" + user.GetId()) - } } case storageprovider.GranteeType_GRANTEE_TYPE_GROUP: group, err := groupIdToIdentity(ctx, g.identityCache, share.Grantee.GetGroupId().GetOpaqueId()) @@ -594,9 +584,6 @@ func (g BaseGraphService) cs3UserShareToPermission(ctx context.Context, share *c return nil, errorcode.New(errorcode.GeneralException, err.Error()) default: grantedTo.SetGroup(group) - if roleCondition == unifiedrole.UnifiedRoleConditionDrive { - perm.SetId("g:" + group.GetId()) - } } } @@ -927,35 +914,6 @@ func (g BaseGraphService) removeUserShare(ctx context.Context, permissionID stri return nil } -func (g BaseGraphService) removeSpacePermission(ctx context.Context, permissionID string, resourceId *storageprovider.ResourceId) error { - grantee, err := spacePermissionIdToCS3Grantee(permissionID) - if err != nil { - return err - } - - gatewayClient, err := g.gatewaySelector.Next() - if err != nil { - g.logger.Debug().Err(err).Msg("selecting gatewaySelector failed") - return err - } - removeShareResp, err := gatewayClient.RemoveShare(ctx, &collaboration.RemoveShareRequest{ - Ref: &collaboration.ShareReference{ - Spec: &collaboration.ShareReference_Key{ - Key: &collaboration.ShareKey{ - ResourceId: resourceId, - Grantee: &grantee, - }, - }, - }, - }) - if err := errorcode.FromCS3Status(removeShareResp.GetStatus(), err); err != nil { - return err - } - - // We need to return an untyped nil here otherwise the error==nil check won't work - return nil -} - func (g BaseGraphService) getOCMPermissionResourceID(ctx context.Context, permissionID string) (*storageprovider.ResourceId, error) { cs3Share, err := g.getCS3OCMShareByID(ctx, permissionID) if err != nil { @@ -1071,20 +1029,19 @@ func (g BaseGraphService) getPermissionByID(ctx context.Context, permissionID st } return permission, publicShare.GetResourceId(), nil case IsSpaceRoot(itemID): - // itemID is referencing a spaceroot this is a space permission. Handle - // that here and get space id - resourceInfo, err := utils.GetResourceByID(ctx, itemID, gatewayClient) + // itemID is referencing a space root — use the share manager to look up the permission + driveItems := make(driveItemsByResourceID) + driveItems, err = g.listSpaceRootUserShares(ctx, []*collaboration.Filter{ + share.ResourceIDFilter(itemID), + }, driveItems) if err != nil { return nil, nil, err } - - perms, _, err := g.getSpaceRootPermissions(ctx, resourceInfo.GetSpace().GetId(), false) - if err != nil { - return nil, nil, err - } - for _, p := range perms { - if p.GetId() == permissionID { - return &p, itemID, nil + for _, item := range driveItems { + for i := range item.Permissions { + if item.Permissions[i].GetId() == permissionID { + return &item.Permissions[i], itemID, nil + } } } case errors.As(err, &errcode) && errcode.GetCode() == errorcode.ItemNotFound: @@ -1239,29 +1196,10 @@ func (g BaseGraphService) updateUserShare(ctx context.Context, permissionID stri } var cs3UpdateShareReq collaboration.UpdateShareRequest - // When updating a space root we need to reference the share by resourceId and grantee - if IsSpaceRoot(itemID) { - grantee, err := spacePermissionIdToCS3Grantee(permissionID) - if err != nil { - g.logger.Debug().Err(err).Str("permissionid", permissionID).Msg("failed to parse space permission id") - return nil, err - } - cs3UpdateShareReq.Share = &collaboration.Share{ - ResourceId: itemID, - Grantee: &grantee, - } - cs3UpdateShareReq.Opaque = &types.Opaque{ - Map: map[string]*types.OpaqueEntry{ - "spacegrant": {}, - }, - } - cs3UpdateShareReq.Opaque = utils.AppendPlainToOpaque(cs3UpdateShareReq.Opaque, "spacetype", _spaceTypeProject) - } else { - cs3UpdateShareReq.Share = &collaboration.Share{ - Id: &collaboration.ShareId{ - OpaqueId: permissionID, - }, - } + cs3UpdateShareReq.Share = &collaboration.Share{ + Id: &collaboration.ShareId{ + OpaqueId: permissionID, + }, } fieldmask := []string{} if expiration, ok := newPermission.GetExpirationDateTimeOk(); ok { diff --git a/services/graph/pkg/service/v0/driveitems.go b/services/graph/pkg/service/v0/driveitems.go index da89e25bad..7a6615173b 100644 --- a/services/graph/pkg/service/v0/driveitems.go +++ b/services/graph/pkg/service/v0/driveitems.go @@ -15,8 +15,6 @@ import ( "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" cs3rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" @@ -349,35 +347,6 @@ func (g Graph) GetDriveItemChildren(w http.ResponseWriter, r *http.Request) { render.JSON(w, r, &ListResponse{Value: files}) } -func spacePermissionIdToCS3Grantee(permissionID string) (storageprovider.Grantee, error) { - // the permission ID for space permission is made of two parts - // the grantee type ('u' or user, 'g' for group) and the user or group id - var grantee storageprovider.Grantee - parts := strings.SplitN(permissionID, ":", 2) - if len(parts) != 2 { - return grantee, errorcode.New(errorcode.InvalidRequest, "invalid space permission id") - } - switch parts[0] { - case "u": - grantee.Type = storageprovider.GranteeType_GRANTEE_TYPE_USER - grantee.Id = &storageprovider.Grantee_UserId{ - UserId: &userpb.UserId{ - OpaqueId: parts[1], - }, - } - case "g": - grantee.Type = storageprovider.GranteeType_GRANTEE_TYPE_GROUP - grantee.Id = &storageprovider.Grantee_GroupId{ - GroupId: &grouppb.GroupId{ - OpaqueId: parts[1], - }, - } - default: - return grantee, errorcode.New(errorcode.InvalidRequest, "invalid space permission id") - } - return grantee, nil -} - func (g Graph) getRemoteItem(ctx context.Context, root *storageprovider.ResourceId, baseURL *url.URL) (*libregraph.RemoteItem, error) { gatewayClient, err := g.gatewaySelector.Next() if err != nil { @@ -461,14 +430,22 @@ func cs3ResourceToDriveItem(logger *log.Logger, res *storageprovider.ResourceInf parentRef.SetPath(path.Dir(res.GetPath())) driveItem.ParentReference = parentRef } - if res.GetType() == storageprovider.ResourceType_RESOURCE_TYPE_FILE && res.GetMimeType() != "" { + switch res.GetType() { + case storageprovider.ResourceType_RESOURCE_TYPE_FILE: + mimeType := res.GetMimeType() + if mimeType == "" { + mimeType = "application/octet-stream" + } // We cannot use a libregraph.File here because the openapi codegenerator autodetects 'File' as a go type ... driveItem.File = &libregraph.OpenGraphFile{ - MimeType: &res.MimeType, + MimeType: &mimeType, + } + case storageprovider.ResourceType_RESOURCE_TYPE_CONTAINER: + if IsSpaceRoot(res.GetId()) { + driveItem.SetRoot(map[string]any{}) + } else { + driveItem.SetFolder(libregraph.Folder{}) } - } - if res.GetType() == storageprovider.ResourceType_RESOURCE_TYPE_CONTAINER { - driveItem.Folder = &libregraph.Folder{} } if res.GetArbitraryMetadata() != nil { diff --git a/services/graph/pkg/service/v0/sharedwithme.go b/services/graph/pkg/service/v0/sharedwithme.go index f6e645e193..c9d1ca92cf 100644 --- a/services/graph/pkg/service/v0/sharedwithme.go +++ b/services/graph/pkg/service/v0/sharedwithme.go @@ -10,6 +10,7 @@ import ( ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1" "github.com/go-chi/render" libregraph "github.com/opencloud-eu/libre-graph-api-go" + "github.com/opencloud-eu/reva/v2/pkg/share" "github.com/opencloud-eu/opencloud/services/graph/pkg/errorcode" "github.com/opencloud-eu/opencloud/services/thumbnails/pkg/thumbnail" @@ -41,7 +42,11 @@ func (g Graph) listSharedWithMe(ctx context.Context, expandThumbnails bool) ([]l return nil, err } - listReceivedSharesResponse, err := gatewayClient.ListReceivedShares(ctx, &collaboration.ListReceivedSharesRequest{}) + listReceivedSharesResponse, err := gatewayClient.ListReceivedShares(ctx, &collaboration.ListReceivedSharesRequest{ + Filters: []*collaboration.Filter{ + share.SpaceRootFilter(false), + }, + }) if err := errorcode.FromCS3Status(listReceivedSharesResponse.GetStatus(), err); err != nil { g.logger.Error().Err(err).Msg("listing shares failed") return nil, err From b47a2aa9af77e6f26f2ec7450a5ac6600ab7bc89 Mon Sep 17 00:00:00 2001 From: Ralf Haferkamp Date: Wed, 25 Mar 2026 18:45:22 +0100 Subject: [PATCH 3/4] tests: Adjust acceptance test for recent Space sharing changes The `id` property of the `permissions` on a space root does not longer have that special `u:` format any. It now has the same format as the permission id on "normal" driveItems. --- .../acceptance/bootstrap/SharingNgContext.php | 23 +++++++----------- .../apiSharingNg1/listPermissions.feature | 10 ++++---- .../features/apiSharingNg1/sharedByMe.feature | 4 ++-- .../shareInvitations.feature | 2 +- .../updateShareInvitations.feature | 24 +++++++++---------- 5 files changed, 29 insertions(+), 34 deletions(-) diff --git a/tests/acceptance/bootstrap/SharingNgContext.php b/tests/acceptance/bootstrap/SharingNgContext.php index 7f9be3b011..df64e47e96 100644 --- a/tests/acceptance/bootstrap/SharingNgContext.php +++ b/tests/acceptance/bootstrap/SharingNgContext.php @@ -420,7 +420,7 @@ public function sendDriveShareInvitation( $expirationDateTime = (\array_key_exists('expirationDateTime', $rows)) ? \date(DATE_RFC3339, \strtotime($rows['expirationDateTime'])) : null; - return GraphHelper::sendSharingInvitationForDrive( + $response = GraphHelper::sendSharingInvitationForDrive( $this->featureContext->getBaseUrl(), $this->featureContext->getStepLineRef(), $user, @@ -432,6 +432,10 @@ public function sendDriveShareInvitation( $permissionsAction, $expirationDateTime ); + if ($response->getStatusCode() === 200) { + $this->featureContext->shareNgAddToCreatedUserGroupShares($response); + } + return $response; } /** @@ -651,12 +655,7 @@ public function userUpdatesTheSpaceShareForUserOrGroupWithFollowingUsingGraphApi string $sharee, TableNode $table ) { - $permissionID = ""; - if ($shareType === "user") { - $permissionID = "u:" . $this->featureContext->getAttributeOfCreatedUser($sharee, 'id'); - } elseif ($shareType === "group") { - $permissionID = "g:" . $this->featureContext->getAttributeOfCreatedGroup($sharee, 'id'); - } + $permissionID = $this->featureContext->shareNgGetLastCreatedUserGroupShareID(); $this->featureContext->setResponse( $this->updateResourceShare( @@ -1042,8 +1041,8 @@ public function removeAccessToSpace( $permissionID = match ($shareType) { 'link' => $this->featureContext->shareNgGetLastCreatedLinkShareID(), - 'user' => 'u:' . $this->featureContext->getAttributeOfCreatedUser($recipient, 'id'), - 'group' => 'g:' . $this->featureContext->getAttributeOfCreatedGroup($recipient, 'id'), + 'user' => $this->featureContext->shareNgGetLastCreatedUserGroupShareID(), + 'group' => $this->featureContext->shareNgGetLastCreatedUserGroupShareID(), default => throw new Exception("shareType '$shareType' does not match user|group|link "), }; @@ -1650,11 +1649,7 @@ public function userUpdatesTheLastDriveShareWithTheFollowingUsingRootEndpointOfT TableNode $table ): void { $bodyRows = $table->getRowsHash(); - $permissionID = match ($bodyRows['shareType']) { - 'user' => 'u:' . $this->featureContext->getAttributeOfCreatedUser($bodyRows['sharee'], 'id'), - 'group' => 'g:' . $this->featureContext->getAttributeOfCreatedGroup($bodyRows['sharee'], 'id'), - default => throw new Exception("shareType {$bodyRows['shareType']} does not match user|group "), - }; + $permissionID = $this->featureContext->shareNgGetLastCreatedUserGroupShareID(); $space = $bodyRows['space']; $spaceId = ($this->spacesContext->getSpaceByName($user, $space))["id"]; $body = []; diff --git a/tests/acceptance/features/apiSharingNg1/listPermissions.feature b/tests/acceptance/features/apiSharingNg1/listPermissions.feature index 1e1c62ea73..0c44e084e3 100644 --- a/tests/acceptance/features/apiSharingNg1/listPermissions.feature +++ b/tests/acceptance/features/apiSharingNg1/listPermissions.feature @@ -414,7 +414,7 @@ Feature: List a sharing permissions }, "id": { "type": "string", - "pattern": "^u:%user_id_pattern%$" + "pattern": "^%permissions_id_pattern%$" }, "roles": { "type": "array", @@ -456,7 +456,7 @@ Feature: List a sharing permissions }, "id": { "type": "string", - "pattern": "^u:%user_id_pattern%$" + "pattern": "^%permissions_id_pattern%$" }, "roles": { "type": "array", @@ -1428,7 +1428,7 @@ Feature: List a sharing permissions }, "id": { "type": "string", - "pattern": "^u:%user_id_pattern%$" + "pattern": "^%permissions_id_pattern%$" }, "roles": { "type": "array", @@ -1470,7 +1470,7 @@ Feature: List a sharing permissions }, "id": { "type": "string", - "pattern": "^u:%user_id_pattern%$" + "pattern": "^%permissions_id_pattern%$" }, "roles": { "type": "array", @@ -2769,4 +2769,4 @@ Feature: List a sharing permissions } } } - """ \ No newline at end of file + """ diff --git a/tests/acceptance/features/apiSharingNg1/sharedByMe.feature b/tests/acceptance/features/apiSharingNg1/sharedByMe.feature index 2b4d69ae60..1223b03c23 100644 --- a/tests/acceptance/features/apiSharingNg1/sharedByMe.feature +++ b/tests/acceptance/features/apiSharingNg1/sharedByMe.feature @@ -3407,7 +3407,7 @@ Feature: resources shared by user "name", "id", "eTag", - "folder", + "root", "lastModifiedDateTime", "size" ], @@ -3415,7 +3415,7 @@ Feature: resources shared by user "name": { "const": "." }, - "folder": { + "root": { "const": {} }, "id": { diff --git a/tests/acceptance/features/apiSharingNgShareInvitation/shareInvitations.feature b/tests/acceptance/features/apiSharingNgShareInvitation/shareInvitations.feature index 55813fcb69..1e81e376e4 100644 --- a/tests/acceptance/features/apiSharingNgShareInvitation/shareInvitations.feature +++ b/tests/acceptance/features/apiSharingNgShareInvitation/shareInvitations.feature @@ -1777,7 +1777,7 @@ Feature: Send a sharing invitations }, "id": { "type": "string", - "pattern": "^g:%group_id_pattern%$" + "pattern": "^%permissions_id_pattern%$" }, "roles": { "type": "array", diff --git a/tests/acceptance/features/apiSharingNgShareInvitation/updateShareInvitations.feature b/tests/acceptance/features/apiSharingNgShareInvitation/updateShareInvitations.feature index e8addc6a84..ad024c0069 100644 --- a/tests/acceptance/features/apiSharingNgShareInvitation/updateShareInvitations.feature +++ b/tests/acceptance/features/apiSharingNgShareInvitation/updateShareInvitations.feature @@ -278,7 +278,7 @@ Feature: Update permission of a share }, "id": { "type": "string", - "pattern": "^u:%user_id_pattern%$" + "pattern": "^%permissions_id_pattern%$" }, "roles": { "type": "array", @@ -437,7 +437,7 @@ Feature: Update permission of a share }, "id": { "type": "string", - "pattern": "^g:%group_id_pattern%$" + "pattern": "^%permissions_id_pattern%$" }, "roles": { "type": "array", @@ -517,7 +517,7 @@ Feature: Update permission of a share }, "id": { "type": "string", - "pattern": "^g:%group_id_pattern%$" + "pattern": "^%permissions_id_pattern%$" }, "roles": { "type": "array", @@ -602,7 +602,7 @@ Feature: Update permission of a share }, "id": { "type": "string", - "pattern": "^g:%group_id_pattern%$" + "pattern": "^%permissions_id_pattern%$" }, "roles": { "type": "array", @@ -680,7 +680,7 @@ Feature: Update permission of a share }, "id": { "type": "string", - "pattern": "^g:%group_id_pattern%$" + "pattern": "^%permissions_id_pattern%$" }, "roles": { "type": "array", @@ -766,7 +766,7 @@ Feature: Update permission of a share }, "id": { "type": "string", - "pattern": "^g:%group_id_pattern%$" + "pattern": "^%permissions_id_pattern%$" }, "roles": { "type": "array", @@ -842,7 +842,7 @@ Feature: Update permission of a share }, "id": { "type": "string", - "pattern": "^u:%user_id_pattern%$" + "pattern": "^%permissions_id_pattern%$" }, "roles": { "type": "array", @@ -918,7 +918,7 @@ Feature: Update permission of a share }, "id": { "type": "string", - "pattern": "^u:%user_id_pattern%$" + "pattern": "^%permissions_id_pattern%$" }, "roles": { "type": "array", @@ -1000,7 +1000,7 @@ Feature: Update permission of a share }, "id": { "type": "string", - "pattern": "^u:%user_id_pattern%$" + "pattern": "^%permissions_id_pattern%$" }, "roles": { "type": "array", @@ -1077,7 +1077,7 @@ Feature: Update permission of a share }, "id": { "type": "string", - "pattern": "^u:%user_id_pattern%$" + "pattern": "^%permissions_id_pattern%$" }, "roles": { "type": "array", @@ -1159,7 +1159,7 @@ Feature: Update permission of a share }, "id": { "type": "string", - "pattern": "^u:%user_id_pattern%$" + "pattern": "^%permissions_id_pattern%$" }, "roles": { "type": "array", @@ -1417,7 +1417,7 @@ Feature: Update permission of a share } }, "id": { - "pattern": "^u:%user_id_pattern%$" + "pattern": "^%permissions_id_pattern%$" } } } From bfcd472819d0055a54a7a53413a185f92cb2730e Mon Sep 17 00:00:00 2001 From: Ralf Haferkamp Date: Wed, 8 Apr 2026 16:40:05 +0200 Subject: [PATCH 4/4] bump reva to personal fork --- go.mod | 4 + go.sum | 8 +- .../cs3/identity/user/v1beta1/resources.pb.go | 261 ++++++++++++------ .../collaboration/v1beta1/resources.pb.go | 158 +++++++---- .../eventsmiddleware/conversion.go | 35 ++- .../interceptors/eventsmiddleware/events.go | 39 ++- .../grpc/services/gateway/storageprovider.go | 31 +++ .../services/gateway/usershareprovider.go | 36 ++- .../sharesstorageprovider.go | 17 +- .../usershareprovider/usershareprovider.go | 136 +++++++-- .../handlers/apps/sharing/shares/pending.go | 4 + .../handlers/apps/sharing/shares/shares.go | 9 +- .../handlers/apps/sharing/shares/spaces.go | 189 ++++--------- .../ocs/handlers/apps/sharing/shares/user.go | 3 +- .../http/services/owncloud/ocs/ocs.go | 7 + .../v2/pkg/share/manager/jsoncs3/jsoncs3.go | 17 -- .../v2/pkg/share/manager/memory/memory.go | 5 - .../opencloud-eu/reva/v2/pkg/share/share.go | 15 + vendor/modules.txt | 6 +- 19 files changed, 600 insertions(+), 380 deletions(-) diff --git a/go.mod b/go.mod index 1b4e3029c6..6cb1f96ad5 100644 --- a/go.mod +++ b/go.mod @@ -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-20260408142546-729b5181682a + +replace github.com/opencloud-eu/reva/v2 => github.com/rhafer/reva/v2 v2.0.0-20260409124525-45c05820c3b5 diff --git a/go.sum b/go.sum index 2a5a205ee4..37d6780c23 100644 --- a/go.sum +++ b/go.sum @@ -264,8 +264,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= @@ -954,8 +952,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.7-0.20260408072824-411780d0b756 h1:Jbftg+S89x2PD7NVWhQB0+vlI/Qo0wv9rBwnM1N50yc= -github.com/opencloud-eu/reva/v2 v2.42.7-0.20260408072824-411780d0b756/go.mod h1:hjMR/IerRm9xX4bthVRE9ZO/vhvrXVMbuvnnzwLjzK4= 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= @@ -1067,6 +1063,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-20260408142546-729b5181682a h1:0dSAz6SbOMQi/PyFxqlYDSC0GahKZglgWgYHwd2bpok= +github.com/rhafer/go-cs3apis v0.0.0-20260408142546-729b5181682a/go.mod h1:DedpcqXl193qF/08Y04IO0PpxyyMu8+GrkD6kWK2MEQ= +github.com/rhafer/reva/v2 v2.0.0-20260409124525-45c05820c3b5 h1:D/Z2Gry737M4tXRpNAdhUOxr4o/pb6kBVQdrpPvXyyU= +github.com/rhafer/reva/v2 v2.0.0-20260409124525-45c05820c3b5/go.mod h1:/gWwtjdZPsR0aB3g3P6ex6sfjppc/IQ8BM65l/wXP9o= 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= diff --git a/vendor/github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1/resources.pb.go b/vendor/github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1/resources.pb.go index 36dea172ad..b28770518e 100644 --- a/vendor/github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1/resources.pb.go +++ b/vendor/github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1/resources.pb.go @@ -116,6 +116,70 @@ func (UserType) EnumDescriptor() ([]byte, []int) { return file_cs3_identity_user_v1beta1_resources_proto_rawDescGZIP(), []int{0} } +// ExternalIdentity represents an external identifier of a user. +// This can be populated when multiple identities collapse onto +// the same user, for example when signing in with e-mail or with +// an SSO using an account with the same e-mail. +type ExternalIdentity struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // REQUIRED. + // The identity provider for the user. + Idp string `protobuf:"bytes,1,opt,name=idp,proto3" json:"idp,omitempty"` + // REQUIRED. + // the unique identifier for the user in the scope of + // the identity provider. + OpaqueId string `protobuf:"bytes,2,opt,name=opaque_id,json=opaqueId,proto3" json:"opaque_id,omitempty"` +} + +func (x *ExternalIdentity) Reset() { + *x = ExternalIdentity{} + if protoimpl.UnsafeEnabled { + mi := &file_cs3_identity_user_v1beta1_resources_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExternalIdentity) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExternalIdentity) ProtoMessage() {} + +func (x *ExternalIdentity) ProtoReflect() protoreflect.Message { + mi := &file_cs3_identity_user_v1beta1_resources_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExternalIdentity.ProtoReflect.Descriptor instead. +func (*ExternalIdentity) Descriptor() ([]byte, []int) { + return file_cs3_identity_user_v1beta1_resources_proto_rawDescGZIP(), []int{0} +} + +func (x *ExternalIdentity) GetIdp() string { + if x != nil { + return x.Idp + } + return "" +} + +func (x *ExternalIdentity) GetOpaqueId() string { + if x != nil { + return x.OpaqueId + } + return "" +} + // A UserId represents a unique identifier of a user. type UserId struct { state protoimpl.MessageState @@ -136,12 +200,16 @@ type UserId struct { // The tenant id of the user, if applicable. // This is used to identify users in multi-tenant systems. TenantId string `protobuf:"bytes,4,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"` + // OPTIONAL. + // External identities of the user, if applicable. + // This is used to track identities of the same user on multiple systems. + ExternalIdentities []*ExternalIdentity `protobuf:"bytes,5,rep,name=external_identities,json=externalIdentities,proto3" json:"external_identities,omitempty"` } func (x *UserId) Reset() { *x = UserId{} if protoimpl.UnsafeEnabled { - mi := &file_cs3_identity_user_v1beta1_resources_proto_msgTypes[0] + mi := &file_cs3_identity_user_v1beta1_resources_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -154,7 +222,7 @@ func (x *UserId) String() string { func (*UserId) ProtoMessage() {} func (x *UserId) ProtoReflect() protoreflect.Message { - mi := &file_cs3_identity_user_v1beta1_resources_proto_msgTypes[0] + mi := &file_cs3_identity_user_v1beta1_resources_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -167,7 +235,7 @@ func (x *UserId) ProtoReflect() protoreflect.Message { // Deprecated: Use UserId.ProtoReflect.Descriptor instead. func (*UserId) Descriptor() ([]byte, []int) { - return file_cs3_identity_user_v1beta1_resources_proto_rawDescGZIP(), []int{0} + return file_cs3_identity_user_v1beta1_resources_proto_rawDescGZIP(), []int{1} } func (x *UserId) GetIdp() string { @@ -198,6 +266,13 @@ func (x *UserId) GetTenantId() string { return "" } +func (x *UserId) GetExternalIdentities() []*ExternalIdentity { + if x != nil { + return x.ExternalIdentities + } + return nil +} + // Represents a user of the system. type User struct { state protoimpl.MessageState @@ -236,7 +311,7 @@ type User struct { func (x *User) Reset() { *x = User{} if protoimpl.UnsafeEnabled { - mi := &file_cs3_identity_user_v1beta1_resources_proto_msgTypes[1] + mi := &file_cs3_identity_user_v1beta1_resources_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -249,7 +324,7 @@ func (x *User) String() string { func (*User) ProtoMessage() {} func (x *User) ProtoReflect() protoreflect.Message { - mi := &file_cs3_identity_user_v1beta1_resources_proto_msgTypes[1] + mi := &file_cs3_identity_user_v1beta1_resources_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -262,7 +337,7 @@ func (x *User) ProtoReflect() protoreflect.Message { // Deprecated: Use User.ProtoReflect.Descriptor instead. func (*User) Descriptor() ([]byte, []int) { - return file_cs3_identity_user_v1beta1_resources_proto_rawDescGZIP(), []int{1} + return file_cs3_identity_user_v1beta1_resources_proto_rawDescGZIP(), []int{2} } func (x *User) GetId() *UserId { @@ -337,67 +412,77 @@ var file_cs3_identity_user_v1beta1_resources_proto_rawDesc = []byte{ 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1d, 0x63, 0x73, 0x33, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8d, 0x01, 0x0a, 0x06, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, - 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x69, - 0x64, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x49, 0x64, 0x12, - 0x37, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, - 0x63, 0x73, 0x33, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x75, 0x73, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, - 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6e, - 0x61, 0x6e, 0x74, 0x49, 0x64, 0x22, 0xba, 0x02, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x31, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x73, 0x33, - 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x61, 0x69, - 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x61, 0x69, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, - 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6d, 0x61, 0x69, 0x6c, 0x56, 0x65, - 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, - 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, - 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, - 0x73, 0x12, 0x31, 0x0a, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x52, 0x06, 0x6f, 0x70, - 0x61, 0x71, 0x75, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x69, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x69, 0x64, 0x4e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x69, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x67, 0x69, 0x64, 0x4e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x2a, 0xe7, 0x01, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x15, 0x0a, 0x11, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x56, - 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x10, 0x01, 0x12, 0x17, 0x0a, - 0x13, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x45, 0x43, 0x4f, 0x4e, - 0x44, 0x41, 0x52, 0x59, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x03, 0x12, 0x19, 0x0a, - 0x15, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, - 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x53, 0x45, 0x52, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x55, 0x45, 0x53, 0x54, 0x10, 0x05, 0x12, 0x17, 0x0a, - 0x13, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x45, 0x44, 0x45, 0x52, - 0x41, 0x54, 0x45, 0x44, 0x10, 0x06, 0x12, 0x19, 0x0a, 0x15, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x49, 0x47, 0x48, 0x54, 0x57, 0x45, 0x49, 0x47, 0x48, 0x54, 0x10, - 0x07, 0x12, 0x19, 0x0a, 0x15, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, - 0x50, 0x41, 0x43, 0x45, 0x5f, 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x10, 0x08, 0x42, 0xfa, 0x01, 0x0a, - 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, - 0x79, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0e, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x42, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x73, 0x33, - 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x6f, 0x2d, 0x63, 0x73, 0x33, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x63, - 0x73, 0x33, 0x2f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2f, 0x75, 0x73, 0x65, 0x72, - 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x49, 0x55, 0xaa, 0x02, 0x19, 0x43, 0x73, 0x33, - 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x56, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x19, 0x43, 0x73, 0x33, 0x5c, 0x49, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5c, 0x55, 0x73, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0xe2, 0x02, 0x25, 0x43, 0x73, 0x33, 0x5c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, - 0x79, 0x5c, 0x55, 0x73, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1c, 0x43, 0x73, 0x33, - 0x3a, 0x3a, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x3a, 0x55, 0x73, 0x65, 0x72, - 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x41, 0x0a, 0x10, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x70, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x69, 0x64, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6f, + 0x70, 0x61, 0x71, 0x75, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x49, 0x64, 0x22, 0xeb, 0x01, 0x0a, 0x06, 0x55, 0x73, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x69, 0x64, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, + 0x49, 0x64, 0x12, 0x37, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x23, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, + 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x73, 0x65, + 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, + 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x5c, 0x0a, 0x13, 0x65, 0x78, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x52, 0x12, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x22, 0xba, 0x02, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, + 0x31, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x73, + 0x33, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x61, + 0x69, 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x61, 0x69, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, + 0x69, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6d, 0x61, 0x69, 0x6c, 0x56, + 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x73, 0x12, 0x31, 0x0a, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x52, 0x06, 0x6f, + 0x70, 0x61, 0x71, 0x75, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x69, 0x64, 0x5f, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x69, 0x64, 0x4e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x69, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x67, 0x69, 0x64, 0x4e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x2a, 0xe7, 0x01, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x15, 0x0a, 0x11, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, + 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x55, 0x53, 0x45, 0x52, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x10, 0x01, 0x12, 0x17, + 0x0a, 0x13, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x45, 0x43, 0x4f, + 0x4e, 0x44, 0x41, 0x52, 0x59, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x55, 0x53, 0x45, 0x52, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x03, 0x12, 0x19, + 0x0a, 0x15, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x50, 0x50, 0x4c, + 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x53, 0x45, + 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x55, 0x45, 0x53, 0x54, 0x10, 0x05, 0x12, 0x17, + 0x0a, 0x13, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x45, 0x44, 0x45, + 0x52, 0x41, 0x54, 0x45, 0x44, 0x10, 0x06, 0x12, 0x19, 0x0a, 0x15, 0x55, 0x53, 0x45, 0x52, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x49, 0x47, 0x48, 0x54, 0x57, 0x45, 0x49, 0x47, 0x48, 0x54, + 0x10, 0x07, 0x12, 0x19, 0x0a, 0x15, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x10, 0x08, 0x42, 0xfa, 0x01, + 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, + 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x42, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x73, + 0x33, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x6f, 0x2d, 0x63, 0x73, 0x33, 0x61, 0x70, 0x69, 0x73, 0x2f, + 0x63, 0x73, 0x33, 0x2f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2f, 0x75, 0x73, 0x65, + 0x72, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x49, 0x55, 0xaa, 0x02, 0x19, 0x43, 0x73, + 0x33, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, + 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x19, 0x43, 0x73, 0x33, 0x5c, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5c, 0x55, 0x73, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0xe2, 0x02, 0x25, 0x43, 0x73, 0x33, 0x5c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x5c, 0x55, 0x73, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1c, 0x43, 0x73, + 0x33, 0x3a, 0x3a, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x3a, 0x55, 0x73, 0x65, + 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -413,22 +498,24 @@ func file_cs3_identity_user_v1beta1_resources_proto_rawDescGZIP() []byte { } var file_cs3_identity_user_v1beta1_resources_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_cs3_identity_user_v1beta1_resources_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_cs3_identity_user_v1beta1_resources_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_cs3_identity_user_v1beta1_resources_proto_goTypes = []interface{}{ - (UserType)(0), // 0: cs3.identity.user.v1beta1.UserType - (*UserId)(nil), // 1: cs3.identity.user.v1beta1.UserId - (*User)(nil), // 2: cs3.identity.user.v1beta1.User - (*v1beta1.Opaque)(nil), // 3: cs3.types.v1beta1.Opaque + (UserType)(0), // 0: cs3.identity.user.v1beta1.UserType + (*ExternalIdentity)(nil), // 1: cs3.identity.user.v1beta1.ExternalIdentity + (*UserId)(nil), // 2: cs3.identity.user.v1beta1.UserId + (*User)(nil), // 3: cs3.identity.user.v1beta1.User + (*v1beta1.Opaque)(nil), // 4: cs3.types.v1beta1.Opaque } var file_cs3_identity_user_v1beta1_resources_proto_depIdxs = []int32{ 0, // 0: cs3.identity.user.v1beta1.UserId.type:type_name -> cs3.identity.user.v1beta1.UserType - 1, // 1: cs3.identity.user.v1beta1.User.id:type_name -> cs3.identity.user.v1beta1.UserId - 3, // 2: cs3.identity.user.v1beta1.User.opaque:type_name -> cs3.types.v1beta1.Opaque - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 1, // 1: cs3.identity.user.v1beta1.UserId.external_identities:type_name -> cs3.identity.user.v1beta1.ExternalIdentity + 2, // 2: cs3.identity.user.v1beta1.User.id:type_name -> cs3.identity.user.v1beta1.UserId + 4, // 3: cs3.identity.user.v1beta1.User.opaque:type_name -> cs3.types.v1beta1.Opaque + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name } func init() { file_cs3_identity_user_v1beta1_resources_proto_init() } @@ -438,7 +525,7 @@ func file_cs3_identity_user_v1beta1_resources_proto_init() { } if !protoimpl.UnsafeEnabled { file_cs3_identity_user_v1beta1_resources_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserId); i { + switch v := v.(*ExternalIdentity); i { case 0: return &v.state case 1: @@ -450,6 +537,18 @@ func file_cs3_identity_user_v1beta1_resources_proto_init() { } } file_cs3_identity_user_v1beta1_resources_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UserId); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cs3_identity_user_v1beta1_resources_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*User); i { case 0: return &v.state @@ -468,7 +567,7 @@ func file_cs3_identity_user_v1beta1_resources_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_cs3_identity_user_v1beta1_resources_proto_rawDesc, NumEnums: 1, - NumMessages: 2, + NumMessages: 3, NumExtensions: 0, NumServices: 0, }, diff --git a/vendor/github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1/resources.pb.go b/vendor/github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1/resources.pb.go index 53fc1e43d2..2f646e6948 100644 --- a/vendor/github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1/resources.pb.go +++ b/vendor/github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1/resources.pb.go @@ -115,20 +115,27 @@ const ( Filter_TYPE_EXCLUDE_DENIALS Filter_Type = 6 Filter_TYPE_SPACE_ID Filter_Type = 7 Filter_TYPE_STATE Filter_Type = 8 + Filter_TYPE_GRANTEE Filter_Type = 9 + // Filter shares by whether the shared resource is a space root. + // When the term `space_root` is true, only shares on space roots are returned. + // When false, shares on space roots are excluded. + Filter_TYPE_SPACE_ROOT Filter_Type = 10 ) // Enum value maps for Filter_Type. var ( Filter_Type_name = map[int32]string{ - 0: "TYPE_INVALID", - 1: "TYPE_NO", - 2: "TYPE_RESOURCE_ID", - 3: "TYPE_OWNER", - 4: "TYPE_CREATOR", - 5: "TYPE_GRANTEE_TYPE", - 6: "TYPE_EXCLUDE_DENIALS", - 7: "TYPE_SPACE_ID", - 8: "TYPE_STATE", + 0: "TYPE_INVALID", + 1: "TYPE_NO", + 2: "TYPE_RESOURCE_ID", + 3: "TYPE_OWNER", + 4: "TYPE_CREATOR", + 5: "TYPE_GRANTEE_TYPE", + 6: "TYPE_EXCLUDE_DENIALS", + 7: "TYPE_SPACE_ID", + 8: "TYPE_STATE", + 9: "TYPE_GRANTEE", + 10: "TYPE_SPACE_ROOT", } Filter_Type_value = map[string]int32{ "TYPE_INVALID": 0, @@ -140,6 +147,8 @@ var ( "TYPE_EXCLUDE_DENIALS": 6, "TYPE_SPACE_ID": 7, "TYPE_STATE": 8, + "TYPE_GRANTEE": 9, + "TYPE_SPACE_ROOT": 10, } ) @@ -769,6 +778,8 @@ type Filter struct { // *Filter_GranteeType // *Filter_SpaceId // *Filter_State + // *Filter_Grantee + // *Filter_SpaceRoot Term isFilter_Term `protobuf_oneof:"term"` } @@ -860,6 +871,20 @@ func (x *Filter) GetState() ShareState { return ShareState_SHARE_STATE_INVALID } +func (x *Filter) GetGrantee() *v1beta1.Grantee { + if x, ok := x.GetTerm().(*Filter_Grantee); ok { + return x.Grantee + } + return nil +} + +func (x *Filter) GetSpaceRoot() bool { + if x, ok := x.GetTerm().(*Filter_SpaceRoot); ok { + return x.SpaceRoot + } + return false +} + type isFilter_Term interface { isFilter_Term() } @@ -888,6 +913,15 @@ type Filter_State struct { State ShareState `protobuf:"varint,8,opt,name=state,proto3,enum=cs3.sharing.collaboration.v1beta1.ShareState,oneof"` } +type Filter_Grantee struct { + Grantee *v1beta1.Grantee `protobuf:"bytes,9,opt,name=grantee,proto3,oneof"` +} + +type Filter_SpaceRoot struct { + // Used with TYPE_SPACE_ROOT. + SpaceRoot bool `protobuf:"varint,10,opt,name=space_root,json=spaceRoot,proto3,oneof"` +} + func (*Filter_ResourceId) isFilter_Term() {} func (*Filter_Owner) isFilter_Term() {} @@ -900,6 +934,10 @@ func (*Filter_SpaceId) isFilter_Term() {} func (*Filter_State) isFilter_Term() {} +func (*Filter_Grantee) isFilter_Term() {} + +func (*Filter_SpaceRoot) isFilter_Term() {} + var File_cs3_sharing_collaboration_v1beta1_resources_proto protoreflect.FileDescriptor var file_cs3_sharing_collaboration_v1beta1_resources_proto_rawDesc = []byte{ @@ -1017,7 +1055,7 @@ var file_cs3_sharing_collaboration_v1beta1_resources_proto_rawDesc = []byte{ 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x83, 0x05, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x8e, 0x06, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x42, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, @@ -1046,45 +1084,54 @@ var file_cs3_sharing_collaboration_v1beta1_resources_proto_rawDesc = []byte{ 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x22, 0xb1, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x4e, 0x4f, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x44, 0x10, 0x02, 0x12, 0x0e, - 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x10, 0x03, 0x12, 0x10, - 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x04, - 0x12, 0x15, 0x0a, 0x11, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x52, 0x41, 0x4e, 0x54, 0x45, 0x45, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x05, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x45, 0x58, 0x43, 0x4c, 0x55, 0x44, 0x45, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x41, 0x4c, 0x53, 0x10, - 0x06, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, - 0x49, 0x44, 0x10, 0x07, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x45, 0x10, 0x08, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x65, 0x72, 0x6d, 0x2a, 0x72, 0x0a, 0x0a, - 0x53, 0x68, 0x61, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x48, - 0x41, 0x52, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, - 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x45, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, - 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x43, 0x43, 0x45, - 0x50, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x03, - 0x42, 0xb3, 0x02, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x68, 0x61, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0e, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x53, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x73, 0x33, 0x6f, 0x72, 0x67, 0x2f, - 0x67, 0x6f, 0x2d, 0x63, 0x73, 0x33, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x63, 0x73, 0x33, 0x2f, 0x73, - 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x2f, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x63, 0x6f, 0x6c, - 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0xa2, 0x02, 0x03, 0x43, 0x53, 0x43, 0xaa, 0x02, 0x21, 0x43, 0x73, 0x33, 0x2e, 0x53, 0x68, - 0x61, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x21, 0x43, 0x73, - 0x33, 0x5c, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x62, - 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, - 0x02, 0x2d, 0x43, 0x73, 0x33, 0x5c, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x43, 0x6f, - 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, - 0x02, 0x24, 0x43, 0x73, 0x33, 0x3a, 0x3a, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, - 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x3a, 0x56, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x41, 0x0a, 0x07, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x48, 0x00, 0x52, 0x07, 0x67, 0x72, 0x61, 0x6e, + 0x74, 0x65, 0x65, 0x12, 0x1f, 0x0a, 0x0a, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x72, 0x6f, 0x6f, + 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x52, 0x6f, 0x6f, 0x74, 0x22, 0xd8, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, + 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, + 0x0b, 0x0a, 0x07, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4e, 0x4f, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x44, + 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x57, 0x4e, 0x45, 0x52, + 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, + 0x4f, 0x52, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x52, 0x41, + 0x4e, 0x54, 0x45, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x05, 0x12, 0x18, 0x0a, 0x14, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x45, 0x58, 0x43, 0x4c, 0x55, 0x44, 0x45, 0x5f, 0x44, 0x45, 0x4e, 0x49, + 0x41, 0x4c, 0x53, 0x10, 0x06, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x50, + 0x41, 0x43, 0x45, 0x5f, 0x49, 0x44, 0x10, 0x07, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x10, 0x08, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x47, 0x52, 0x41, 0x4e, 0x54, 0x45, 0x45, 0x10, 0x09, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x0a, 0x42, + 0x06, 0x0a, 0x04, 0x74, 0x65, 0x72, 0x6d, 0x2a, 0x72, 0x0a, 0x0a, 0x53, 0x68, 0x61, 0x72, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x53, + 0x54, 0x41, 0x54, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x17, + 0x0a, 0x13, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x50, 0x45, + 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x48, 0x41, 0x52, 0x45, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, + 0x02, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, + 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x03, 0x42, 0xb3, 0x02, 0x0a, 0x25, + 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x53, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x73, 0x33, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x6f, 0x2d, 0x63, 0x73, + 0x33, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x63, 0x73, 0x33, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x69, 0x6e, + 0x67, 0x2f, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, + 0x53, 0x43, 0xaa, 0x02, 0x21, 0x43, 0x73, 0x33, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x21, 0x43, 0x73, 0x33, 0x5c, 0x53, 0x68, 0x61, + 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x2d, 0x43, 0x73, 0x33, + 0x5c, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x24, 0x43, 0x73, 0x33, + 0x3a, 0x3a, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x43, 0x6f, 0x6c, 0x6c, 0x61, + 0x62, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1148,11 +1195,12 @@ var file_cs3_sharing_collaboration_v1beta1_resources_proto_depIdxs = []int32{ 12, // 24: cs3.sharing.collaboration.v1beta1.Filter.creator:type_name -> cs3.identity.user.v1beta1.UserId 16, // 25: cs3.sharing.collaboration.v1beta1.Filter.grantee_type:type_name -> cs3.storage.provider.v1beta1.GranteeType 0, // 26: cs3.sharing.collaboration.v1beta1.Filter.state:type_name -> cs3.sharing.collaboration.v1beta1.ShareState - 27, // [27:27] is the sub-list for method output_type - 27, // [27:27] is the sub-list for method input_type - 27, // [27:27] is the sub-list for extension type_name - 27, // [27:27] is the sub-list for extension extendee - 0, // [0:27] is the sub-list for field type_name + 11, // 27: cs3.sharing.collaboration.v1beta1.Filter.grantee:type_name -> cs3.storage.provider.v1beta1.Grantee + 28, // [28:28] is the sub-list for method output_type + 28, // [28:28] is the sub-list for method input_type + 28, // [28:28] is the sub-list for extension type_name + 28, // [28:28] is the sub-list for extension extendee + 0, // [0:28] is the sub-list for field type_name } func init() { file_cs3_sharing_collaboration_v1beta1_resources_proto_init() } @@ -1269,6 +1317,8 @@ func file_cs3_sharing_collaboration_v1beta1_resources_proto_init() { (*Filter_GranteeType)(nil), (*Filter_SpaceId)(nil), (*Filter_State)(nil), + (*Filter_Grantee)(nil), + (*Filter_SpaceRoot)(nil), } type x struct{} out := protoimpl.TypeBuilder{ diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/interceptors/eventsmiddleware/conversion.go b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/interceptors/eventsmiddleware/conversion.go index 6f7df8ca27..d0fd30d921 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/interceptors/eventsmiddleware/conversion.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/interceptors/eventsmiddleware/conversion.go @@ -414,38 +414,45 @@ func SpaceEnabled(r *provider.UpdateStorageSpaceResponse, req *provider.UpdateSt } // SpaceShared converts the response to an event -// func SpaceShared(req *provider.AddGrantRequest, executant, sharer *user.UserId, grantee *provider.Grantee) events.SpaceShared { -func SpaceShared(r *provider.AddGrantResponse, req *provider.AddGrantRequest, executant *user.User) events.SpaceShared { - id := storagespace.FormatStorageID(req.Ref.ResourceId.StorageId, req.Ref.ResourceId.SpaceId) +func SpaceShared(r *collaboration.CreateShareResponse, executant *user.User) events.SpaceShared { + id := storagespace.FormatStorageID(r.GetShare().GetResourceId().GetStorageId(), r.GetShare().GetResourceId().GetSpaceId()) return events.SpaceShared{ Executant: executant.GetId(), - Creator: req.Grant.Creator, - GranteeUserID: req.Grant.GetGrantee().GetUserId(), - GranteeGroupID: req.Grant.GetGrantee().GetGroupId(), + Creator: r.Share.GetCreator(), + GranteeUserID: r.Share.GetGrantee().GetUserId(), + GranteeGroupID: r.Share.GetGrantee().GetGroupId(), ID: &provider.StorageSpaceId{OpaqueId: id}, Timestamp: time.Now(), } } // SpaceShareUpdated converts the response to an events -func SpaceShareUpdated(r *provider.UpdateGrantResponse, req *provider.UpdateGrantRequest, executant *user.User) events.SpaceShareUpdated { - id := storagespace.FormatStorageID(req.Ref.ResourceId.StorageId, req.Ref.ResourceId.SpaceId) +func SpaceShareUpdated(r *collaboration.UpdateShareResponse, executant *user.User) events.SpaceShareUpdated { + id := storagespace.FormatStorageID(r.GetShare().GetResourceId().GetStorageId(), r.GetShare().GetResourceId().GetSpaceId()) return events.SpaceShareUpdated{ Executant: executant.GetId(), - GranteeUserID: req.Grant.GetGrantee().GetUserId(), - GranteeGroupID: req.Grant.GetGrantee().GetGroupId(), + GranteeUserID: r.GetShare().GetGrantee().GetUserId(), + GranteeGroupID: r.GetShare().GetGrantee().GetGroupId(), ID: &provider.StorageSpaceId{OpaqueId: id}, Timestamp: time.Now(), } } // SpaceUnshared converts the response to an event -func SpaceUnshared(r *provider.RemoveGrantResponse, req *provider.RemoveGrantRequest, executant *user.User) events.SpaceUnshared { - id := storagespace.FormatStorageID(req.Ref.ResourceId.StorageId, req.Ref.ResourceId.SpaceId) +func SpaceUnshared(r *collaboration.RemoveShareResponse, req *collaboration.RemoveShareRequest, executant *user.User) events.SpaceUnshared { + var ( + userid *user.UserId + groupid *group.GroupId + rid *provider.ResourceId + ) + _ = utils.ReadJSONFromOpaque(r.Opaque, "granteeuserid", &userid) + _ = utils.ReadJSONFromOpaque(r.Opaque, "granteegroupid", &groupid) + _ = utils.ReadJSONFromOpaque(r.Opaque, "resourceid", &rid) + id := storagespace.FormatStorageID(rid.StorageId, rid.SpaceId) return events.SpaceUnshared{ Executant: executant.GetId(), - GranteeUserID: req.Grant.GetGrantee().GetUserId(), - GranteeGroupID: req.Grant.GetGrantee().GetGroupId(), + GranteeUserID: userid, + GranteeGroupID: groupid, ID: &provider.StorageSpaceId{OpaqueId: id}, Timestamp: time.Now(), } diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/interceptors/eventsmiddleware/events.go b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/interceptors/eventsmiddleware/events.go index 7cd409d34b..4b376c2d57 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/interceptors/eventsmiddleware/events.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/interceptors/eventsmiddleware/events.go @@ -81,15 +81,30 @@ func NewUnary(m map[string]interface{}) (grpc.UnaryServerInterceptor, int, error switch v := res.(type) { case *collaboration.CreateShareResponse: if isSuccess(v) { - ev = ShareCreated(v, executant) + if utils.ExistsInOpaque(v.Opaque, "noevent") { + break + } + if utils.ExistsInOpaque(v.Opaque, "spacegrant") { + ev = SpaceShared(v, executant) + } else { + ev = ShareCreated(v, executant) + } } case *collaboration.RemoveShareResponse: if isSuccess(v) { - ev = ShareRemoved(v, req.(*collaboration.RemoveShareRequest), executant) + if utils.ExistsInOpaque(v.Opaque, "spacegrant") { + ev = SpaceUnshared(v, req.(*collaboration.RemoveShareRequest), executant) + } else { + ev = ShareRemoved(v, req.(*collaboration.RemoveShareRequest), executant) + } } case *collaboration.UpdateShareResponse: if isSuccess(v) { - ev = ShareUpdated(v, req.(*collaboration.UpdateShareRequest), executant) + if utils.ExistsInOpaque(v.Opaque, "spacegrant") { + ev = SpaceShareUpdated(v, executant) + } else { + ev = ShareUpdated(v, req.(*collaboration.UpdateShareRequest), executant) + } } case *collaboration.UpdateReceivedShareResponse: if isSuccess(v) { @@ -117,24 +132,6 @@ func NewUnary(m map[string]interface{}) (grpc.UnaryServerInterceptor, int, error if isSuccess(v) { ev = OCMCoreShareCreated(v, req.(*ocmcore.CreateOCMCoreShareRequest), executant) } - case *provider.AddGrantResponse: - // TODO: update CS3 APIs - // FIXME these should be part of the RemoveGrantRequest object - // https://github.com/owncloud/ocis/issues/4312 - r := req.(*provider.AddGrantRequest) - if isSuccess(v) && utils.ExistsInOpaque(r.Opaque, "spacegrant") { - ev = SpaceShared(v, r, executant) - } - case *provider.UpdateGrantResponse: - r := req.(*provider.UpdateGrantRequest) - if isSuccess(v) && utils.ExistsInOpaque(r.Opaque, "spacegrant") { - ev = SpaceShareUpdated(v, r, executant) - } - case *provider.RemoveGrantResponse: - r := req.(*provider.RemoveGrantRequest) - if isSuccess(v) && utils.ExistsInOpaque(r.Opaque, "spacegrant") { - ev = SpaceUnshared(v, req.(*provider.RemoveGrantRequest), executant) - } case *provider.CreateContainerResponse: if isSuccess(v) { ev = ContainerCreated(v, req.(*provider.CreateContainerRequest), ownerID, executant) diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/gateway/storageprovider.go b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/gateway/storageprovider.go index 539f13dadc..e78c46a9aa 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/gateway/storageprovider.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/gateway/storageprovider.go @@ -31,11 +31,14 @@ import ( "github.com/BurntSushi/toml" gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" + collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" collaborationv1beta1 "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" linkv1beta1 "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" registry "github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1" typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" + "github.com/opencloud-eu/reva/v2/pkg/conversions" + "github.com/rs/zerolog/log" "google.golang.org/grpc/codes" "github.com/golang-jwt/jwt/v5" @@ -226,6 +229,34 @@ func (s *svc) CreateStorageSpace(ctx context.Context, req *provider.CreateStorag }, nil } + // If the create space is not a "personal" space, we add a Share to the ShareProvider to give the creator + // of the space "manager" access to it. + // Note: the DecomposedFS storagadriver already adds a grant to the space root giving that access, the "CreateShare" + // here is happeing so that that grant is also visible when listing permission (shares) on the spaceroot. + if req.GetType() != "personal" && createRes.GetStatus().GetCode() == rpc.Code_CODE_OK { + u := ctxpkg.ContextMustGetUser(ctx) + shareReq := &collaboration.CreateShareRequest{ + ResourceInfo: &provider.ResourceInfo{ + Id: createRes.GetStorageSpace().GetRoot(), + }, + Grant: &collaborationv1beta1.ShareGrant{ + Grantee: &provider.Grantee{ + Type: provider.GranteeType_GRANTEE_TYPE_USER, + Id: &provider.Grantee_UserId{ + UserId: u.GetId(), + }, + }, + Permissions: &collaboration.SharePermissions{ + Permissions: conversions.NewManagerRole().CS3ResourcePermissions(), + }, + }, + } + csResp, err := s.CreateShare(ctx, shareReq) + if err != nil || csResp.GetStatus().GetCode() != rpc.Code_CODE_OK { + log.Error().Err(err).Interface("status", csResp.GetStatus()).Interface("space_id", createRes.GetStorageSpace().GetId()).Msg("failed to create share for space owner") + } + } + return createRes, nil } diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/gateway/usershareprovider.go b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/gateway/usershareprovider.go index 738faa8267..21349af51d 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/gateway/usershareprovider.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/gateway/usershareprovider.go @@ -150,7 +150,16 @@ func (s *svc) updateShare(ctx context.Context, req *collaboration.UpdateShareReq Expiration: res.GetShare().GetExpiration(), Creator: creator.GetId(), } - updateGrantStatus, err := s.updateGrant(ctx, res.GetShare().GetResourceId(), grant, nil) + var opaque *typesv1beta1.Opaque + if refIsSpaceRoot(res.GetShare().GetResourceId()) { + opaque = &typesv1beta1.Opaque{ + Map: map[string]*typesv1beta1.OpaqueEntry{ + "spacegrant": {}, + }, + } + utils.AppendPlainToOpaque(opaque, "spacetype", utils.ReadPlainFromOpaque(req.GetOpaque(), "spacetype")) + } + updateGrantStatus, err := s.updateGrant(ctx, res.GetShare().GetResourceId(), grant, opaque) if err != nil { return nil, errors.Wrap(err, "gateway: error calling updateGrant") @@ -613,13 +622,22 @@ func (s *svc) addShare(ctx context.Context, req *collaboration.CreateShareReques if s.c.CommitShareToStorageGrant { // If the share is a denial we call denyGrant instead. var status *rpc.Status + var opaque *typesv1beta1.Opaque + if refIsSpaceRoot(req.ResourceInfo.Id) { + opaque = &typesv1beta1.Opaque{ + Map: map[string]*typesv1beta1.OpaqueEntry{ + "spacegrant": {}, + }, + } + utils.AppendPlainToOpaque(opaque, "spacetype", req.ResourceInfo.GetSpace().GetSpaceType()) + } if grants.PermissionsEqual(req.Grant.Permissions.Permissions, &provider.ResourcePermissions{}) { - status, err = s.denyGrant(ctx, req.ResourceInfo.Id, req.Grant.Grantee, nil) + status, err = s.denyGrant(ctx, req.ResourceInfo.Id, req.Grant.Grantee, opaque) if err != nil { return nil, errors.Wrap(err, "gateway: error denying grant in storage") } } else { - status, err = s.addGrant(ctx, req.ResourceInfo.Id, req.Grant.Grantee, req.Grant.Permissions.Permissions, req.Grant.Expiration, nil) + status, err = s.addGrant(ctx, req.ResourceInfo.Id, req.Grant.Grantee, req.Grant.Permissions.Permissions, req.Grant.Expiration, opaque) if err != nil { appctx.GetLogger(ctx).Debug().Interface("status", status).Interface("req", req).Msg(err.Error()) rollBackFn(status) @@ -628,7 +646,7 @@ func (s *svc) addShare(ctx context.Context, req *collaboration.CreateShareReques } switch status.Code { - case rpc.Code_CODE_OK: + case rpc.Code_CODE_OK, rpc.Code_CODE_ALREADY_EXISTS: // ok case rpc.Code_CODE_UNIMPLEMENTED: appctx.GetLogger(ctx).Debug().Interface("status", status).Interface("req", req).Msg("storing grants not supported, ignoring") @@ -744,7 +762,15 @@ func (s *svc) removeShare(ctx context.Context, req *collaboration.RemoveShareReq } if s.c.CommitShareToStorageGrant { - removeGrantStatus, err := s.removeGrant(ctx, share.ResourceId, share.Grantee, share.Permissions.Permissions, nil) + var opaque *typesv1beta1.Opaque + if refIsSpaceRoot(share.ResourceId) { + opaque = &typesv1beta1.Opaque{ + Map: map[string]*typesv1beta1.OpaqueEntry{ + "spacegrant": {}, + }, + } + } + removeGrantStatus, err := s.removeGrant(ctx, share.ResourceId, share.Grantee, share.Permissions.Permissions, opaque) if err != nil { return nil, errors.Wrap(err, "gateway: error removing grant from storage") } diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go index 04c253e824..b36df8bda0 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go @@ -46,6 +46,7 @@ import ( "github.com/opencloud-eu/reva/v2/pkg/rgrpc" "github.com/opencloud-eu/reva/v2/pkg/rgrpc/status" "github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool" + "github.com/opencloud-eu/reva/v2/pkg/share" "github.com/opencloud-eu/reva/v2/pkg/sharedconf" "github.com/opencloud-eu/reva/v2/pkg/utils" "github.com/pkg/errors" @@ -1093,12 +1094,8 @@ func (s *service) resolveAcceptedShare(ctx context.Context, ref *provider.Refere if ref.ResourceId.OpaqueId == utils.ShareStorageProviderID && ref.Path != "." { lsRes, err := sharingCollaborationClient.ListReceivedShares(ctx, &collaboration.ListReceivedSharesRequest{ Filters: []*collaboration.Filter{ - { - Type: collaboration.Filter_TYPE_STATE, - Term: &collaboration.Filter_State{ - State: collaboration.ShareState_SHARE_STATE_ACCEPTED, - }, - }, + share.StateFilter(collaboration.ShareState_SHARE_STATE_ACCEPTED), + share.SpaceRootFilter(false), // TODO filter by mountpoint? }, }) @@ -1179,12 +1176,8 @@ func (s *service) fetchAcceptedShares(ctx context.Context, opaque *typesv1beta1. lsRes, err := sharingCollaborationClient.ListReceivedShares(ctx, &collaboration.ListReceivedSharesRequest{ Filters: []*collaboration.Filter{ - { - Type: collaboration.Filter_TYPE_STATE, - Term: &collaboration.Filter_State{ - State: collaboration.ShareState_SHARE_STATE_ACCEPTED, - }, - }, + share.StateFilter(collaboration.ShareState_SHARE_STATE_ACCEPTED), + share.SpaceRootFilter(false), }, }) if err != nil { diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/usershareprovider/usershareprovider.go b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/usershareprovider/usershareprovider.go index ac3629334e..ad93604b21 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/usershareprovider/usershareprovider.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/usershareprovider/usershareprovider.go @@ -27,10 +27,12 @@ import ( "strings" 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" rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" "github.com/mitchellh/mapstructure" "github.com/pkg/errors" "github.com/rs/zerolog" @@ -54,6 +56,9 @@ const ( _fieldMaskPathMountPoint = "mount_point" _fieldMaskPathPermissions = "permissions" _fieldMaskPathState = "state" + _spaceTypePersonal = "personal" + _spaceTypeProject = "project" + _spaceTypeVirtual = "virtual" ) func init() { @@ -166,13 +171,6 @@ func (s *service) isPathAllowed(path string) bool { func (s *service) CreateShare(ctx context.Context, req *collaboration.CreateShareRequest) (*collaboration.CreateShareResponse, error) { log := appctx.GetLogger(ctx) user := ctxpkg.ContextMustGetUser(ctx) - // Grants must not allow grant permissions - if HasGrantPermissions(req.GetGrant().GetPermissions().GetPermissions()) { - return &collaboration.CreateShareResponse{ - Status: status.NewInvalidArg(ctx, "resharing not supported"), - }, nil - } - // check if the grantee is a user or group if req.GetGrant().GetGrantee().GetType() == provider.GranteeType_GRANTEE_TYPE_USER { // check if the tenantId of the user matches the tenantId of the target user @@ -202,8 +200,8 @@ func (s *service) CreateShare(ctx context.Context, req *collaboration.CreateShar }, nil } + // use logged in user Idp as default, if the Grantee does not have an IDP set. if req.GetGrant().GetGrantee().GetType() == provider.GranteeType_GRANTEE_TYPE_USER && req.GetGrant().GetGrantee().GetUserId().GetIdp() == "" { - // use logged in user Idp as default. req.GetGrant().GetGrantee().Id = &provider.Grantee_UserId{ UserId: &userpb.UserId{ OpaqueId: req.GetGrant().GetGrantee().GetUserId().GetOpaqueId(), @@ -211,6 +209,16 @@ func (s *service) CreateShare(ctx context.Context, req *collaboration.CreateShar Type: userpb.UserType_USER_TYPE_PRIMARY}, } } + // some for group grantees + if req.GetGrant().GetGrantee().GetType() == provider.GranteeType_GRANTEE_TYPE_GROUP && req.GetGrant().GetGrantee().GetGroupId().GetIdp() == "" { + // use logged in user Idp as default. + req.GetGrant().GetGrantee().Id = &provider.Grantee_GroupId{ + GroupId: &grouppb.GroupId{ + OpaqueId: req.GetGrant().GetGrantee().GetGroupId().GetOpaqueId(), + Idp: user.GetId().GetIdp(), + Type: grouppb.GroupType_GROUP_TYPE_REGULAR}, + } + } sRes, err := gatewayClient.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{ResourceId: req.GetResourceInfo().GetId()}}) if err != nil { @@ -225,6 +233,55 @@ func (s *service) CreateShare(ctx context.Context, req *collaboration.CreateShar Status: status.NewPermissionDenied(ctx, nil, "no permission to add grants on shared resource"), }, err } + + isSpaceRoot := utils.IsSpaceRoot(sRes.GetInfo()) + var noEvent bool + + if isSpaceRoot { + if sRes.GetInfo().GetSpace().GetSpaceType() == _spaceTypePersonal || sRes.GetInfo().GetSpace().GetSpaceType() == _spaceTypeVirtual { + return &collaboration.CreateShareResponse{Status: status.NewInvalid(ctx, "space type is not eligible for sharing")}, nil + } + } + + // do not allow share to myself or the owner if share is for a user + if req.GetGrant().GetGrantee().GetType() == provider.GranteeType_GRANTEE_TYPE_USER && + (utils.UserEqual(req.GetGrant().GetGrantee().GetUserId(), user.Id) || utils.UserEqual(req.GetGrant().GetGrantee().GetUserId(), sRes.GetInfo().GetOwner())) { + + denySelfShare := true + // To allow adding the initial "mananger" share for the creator of a space when need to make an execption here + // if the shared resource is a space root, that does not have any Share existin yet. Note, that we have already + // verified that the user adding the share does really have "AddGrant" permissions on the affected resource, so + // this "hack" should be ok. + if isSpaceRoot { + shares, err := s.sm.ListShares( + ctx, + []*collaboration.Filter{share.ResourceIDFilter(req.GetResourceInfo().GetId())}, + ) + if err != nil { + return &collaboration.CreateShareResponse{ + Status: status.NewInternal(ctx, "failed to list existing shares"), + }, nil + } + if len(shares) == 0 { + denySelfShare = false + noEvent = true + } + } + if denySelfShare { + err := errtypes.BadRequest("jsoncs3: owner/creator and grantee are the same") + return nil, err + } + } + + // resharing is forbidden for not space roots + if !isSpaceRoot { + // Resharing of Files/Directories is forbidden. So the grants must not allow the "grant" permissions + if HasGrantPermissions(req.GetGrant().GetPermissions().GetPermissions()) { + return &collaboration.CreateShareResponse{ + Status: status.NewInvalidArg(ctx, "resharing not supported"), + }, nil + } + } // check if the share creator has sufficient permissions to do so. if shareCreationAllowed := conversions.SufficientCS3Permissions( sRes.GetInfo().GetPermissionSet(), @@ -256,10 +313,26 @@ func (s *service) CreateShare(ctx context.Context, req *collaboration.CreateShar }, nil } + var opaque *typesv1beta1.Opaque + if isSpaceRoot { + opaque = &typesv1beta1.Opaque{ + Map: map[string]*typesv1beta1.OpaqueEntry{ + "spacegrant": {}, + }, + } + } + + if noEvent { + opaque = &typesv1beta1.Opaque{ + Map: map[string]*typesv1beta1.OpaqueEntry{ + "noevent": {}, + }, + } + } return &collaboration.CreateShareResponse{ Status: status.NewOK(ctx), Share: createdShare, - Opaque: utils.AppendPlainToOpaque(nil, "resourcename", sRes.GetInfo().GetName()), + Opaque: utils.AppendPlainToOpaque(opaque, "resourcename", sRes.GetInfo().GetName()), }, nil } @@ -307,16 +380,24 @@ func (s *service) RemoveShare(ctx context.Context, req *collaboration.RemoveShar }, nil } - o := utils.AppendJSONToOpaque(nil, "resourceid", share.GetResourceId()) - o = utils.AppendPlainToOpaque(o, "resourcename", sRes.GetInfo().GetName()) + var opaque *typesv1beta1.Opaque + if utils.IsSpaceRoot(sRes.GetInfo()) { + opaque = &typesv1beta1.Opaque{ + Map: map[string]*typesv1beta1.OpaqueEntry{ + "spacegrant": {}, + }, + } + } + opaque = utils.AppendJSONToOpaque(opaque, "resourceid", share.GetResourceId()) + opaque = utils.AppendPlainToOpaque(opaque, "resourcename", sRes.GetInfo().GetName()) if user := share.GetGrantee().GetUserId(); user != nil { - o = utils.AppendJSONToOpaque(o, "granteeuserid", user) + opaque = utils.AppendJSONToOpaque(opaque, "granteeuserid", user) } else { - o = utils.AppendJSONToOpaque(o, "granteegroupid", share.GetGrantee().GetGroupId()) + opaque = utils.AppendJSONToOpaque(opaque, "granteegroupid", share.GetGrantee().GetGroupId()) } return &collaboration.RemoveShareResponse{ - Opaque: o, + Opaque: opaque, Status: status.NewOK(ctx), }, nil } @@ -361,13 +442,6 @@ func (s *service) UpdateShare(ctx context.Context, req *collaboration.UpdateShar log := appctx.GetLogger(ctx) user := ctxpkg.ContextMustGetUser(ctx) - // Grants must not allow grant permissions - if HasGrantPermissions(req.GetShare().GetPermissions().GetPermissions()) { - return &collaboration.UpdateShareResponse{ - Status: status.NewInvalidArg(ctx, "resharing not supported"), - }, nil - } - gatewayClient, err := s.gatewaySelector.Next() if err != nil { return nil, err @@ -427,6 +501,15 @@ func (s *service) UpdateShare(ctx context.Context, req *collaboration.UpdateShar }, err } + // resharing is forbidden for not space roots + if !utils.IsSpaceRoot(sRes.GetInfo()) { + // Resharing of Files/Directories is forbidden. So the grants must not allow the "grant" permissions + if HasGrantPermissions(req.GetShare().GetPermissions().GetPermissions()) { + return &collaboration.UpdateShareResponse{ + Status: status.NewInvalidArg(ctx, "resharing not supported"), + }, nil + } + } // If this is a permissions update, check if user's permissions on the resource are sufficient to set the desired permissions var newPermissions *provider.ResourcePermissions if slices.Contains(req.GetUpdateMask().GetPaths(), _fieldMaskPathPermissions) { @@ -457,10 +540,19 @@ func (s *service) UpdateShare(ctx context.Context, req *collaboration.UpdateShar }, nil } + var opaque *typesv1beta1.Opaque + if utils.IsSpaceRoot(sRes.GetInfo()) { + opaque = &typesv1beta1.Opaque{ + Map: map[string]*typesv1beta1.OpaqueEntry{ + "spacegrant": {}, + }, + } + } + res := &collaboration.UpdateShareResponse{ Status: status.NewOK(ctx), Share: share, - Opaque: utils.AppendPlainToOpaque(nil, "resourcename", sRes.GetInfo().GetName()), + Opaque: utils.AppendPlainToOpaque(opaque, "resourcename", sRes.GetInfo().GetName()), } return res, nil } diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/pending.go b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/pending.go index 7e6ac28d38..8b263d10c4 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/pending.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/pending.go @@ -179,6 +179,10 @@ func (h *Handler) UpdateReceivedShare(w http.ResponseWriter, r *http.Request) { response.WriteOCSSuccess(w, r, []*conversions.ShareData{data}) } +func (h *Handler) ReceivedShareNotFound(w http.ResponseWriter, r *http.Request) { + response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "cannot find share", nil) +} + func (h *Handler) updateReceivedShare(ctx context.Context, receivedShare *collaboration.ReceivedShare, fieldMask *fieldmaskpb.FieldMask) (*conversions.ShareData, response.Meta, error) { logger := appctx.GetLogger(ctx) diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go index d44c3316c6..753e1c8626 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go @@ -78,7 +78,6 @@ var ( type Handler struct { gatewayAddr string machineAuthAPIKey string - storageRegistryAddr string publicURL string sharePrefix string homeNamespace string @@ -129,7 +128,6 @@ type GatewayClientGetter func() (gateway.GatewayAPIClient, error) func (h *Handler) Init(c *config.Config) error { h.gatewayAddr = c.GatewaySvc h.machineAuthAPIKey = c.MachineAuthAPIKey - h.storageRegistryAddr = c.StorageregistrySvc h.publicURL = c.Config.Host h.sharePrefix = c.SharePrefix h.homeNamespace = c.HomeNamespace @@ -941,12 +939,11 @@ func (h *Handler) RemoveShare(w http.ResponseWriter, r *http.Request) { h.removeFederatedShare(w, r, shareID) return } - - if prov, ok := h.isSpaceShare(r, shareID); ok { - // The request is a remove space member request. - h.removeSpaceMember(w, r, shareID, prov) + if h.isSpaceShare(r, shareID) { + h.removeSpaceMember(w, r, shareID) return } + response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "cannot find share", nil) } diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go index 3a1a2f595c..476b2107ad 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go @@ -29,18 +29,12 @@ import ( rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" collaborationv1beta1 "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" - registry "github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1" types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" "github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/response" "github.com/opencloud-eu/reva/v2/pkg/appctx" "github.com/opencloud-eu/reva/v2/pkg/conversions" - "github.com/opencloud-eu/reva/v2/pkg/errtypes" - "github.com/opencloud-eu/reva/v2/pkg/rgrpc/status" - "github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool" - sdk "github.com/opencloud-eu/reva/v2/pkg/sdk/common" "github.com/opencloud-eu/reva/v2/pkg/storagespace" "github.com/opencloud-eu/reva/v2/pkg/utils" - "github.com/pkg/errors" "google.golang.org/protobuf/types/known/fieldmaskpb" ) @@ -131,45 +125,34 @@ func (h *Handler) addSpaceMember(w http.ResponseWriter, r *http.Request, info *p fieldmask = append(fieldmask, "expiration") } - ref := provider.Reference{ResourceId: info.GetId()} - p, err := h.findProvider(ctx, &ref) - if err != nil { - response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "error getting storage provider", err) - return - } - - providerClient, err := h.getStorageProviderClient(p) - if err != nil { - response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "error getting storage provider client", err) - return - } - - lgRes, err := providerClient.ListGrants(ctx, &provider.ListGrantsRequest{Ref: &ref}) - if err != nil || lgRes.Status.Code != rpc.Code_CODE_OK { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error listing space grants", err) + lsRes, err := client.ListShares(ctx, &collaborationv1beta1.ListSharesRequest{ + Filters: []*collaborationv1beta1.Filter{ + { + Type: collaborationv1beta1.Filter_TYPE_RESOURCE_ID, + Term: &collaborationv1beta1.Filter_ResourceId{ + ResourceId: info.GetId(), + }, + }, + }, + }) + if err != nil || lsRes.Status.Code != rpc.Code_CODE_OK { + response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error listing space members", err) return } - if !isSpaceManagerRemaining(lgRes.Grants, &grantee) { + if !isSpaceManagerRemainingInShares(lsRes.Shares, &grantee) { response.WriteOCSError(w, r, http.StatusForbidden, "the space must have at least one manager", nil) return } - // we have to send the update request to the gateway to give it a chance to invalidate its cache - // TODO the gateway no longer should cache stuff because invalidation is to expensive. The decomposedfs already has a better cache. - if granteeExists(lgRes.Grants, &grantee) { + if existingShare := findShareByGrantee(lsRes.Shares, &grantee); existingShare != nil { if permissions != nil { fieldmask = append(fieldmask, "permissions") } updateShareReq := &collaborationv1beta1.UpdateShareRequest{ - // TODO: change CS3 APIs - Opaque: &types.Opaque{ - Map: map[string]*types.OpaqueEntry{ - "spacegrant": {}, - }, - }, + Opaque: utils.AppendPlainToOpaque(nil, "spacetype", info.GetSpace().GetSpaceType()), Share: &collaborationv1beta1.Share{ - ResourceId: ref.GetResourceId(), + Id: existingShare.Id, Permissions: &collaborationv1beta1.SharePermissions{ Permissions: permissions, }, @@ -180,10 +163,9 @@ func (h *Handler) addSpaceMember(w http.ResponseWriter, r *http.Request, info *p Paths: fieldmask, }, } - updateShareReq.Opaque = utils.AppendPlainToOpaque(updateShareReq.Opaque, "spacetype", info.GetSpace().GetSpaceType()) updateShareRes, err := client.UpdateShare(ctx, updateShareReq) if err != nil || updateShareRes.Status.Code != rpc.Code_CODE_OK { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "could not update space member grant", err) + response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "could not update space member", err) return } } else { @@ -198,7 +180,7 @@ func (h *Handler) addSpaceMember(w http.ResponseWriter, r *http.Request, info *p }, }) if err != nil || createShareRes.Status.Code != rpc.Code_CODE_OK { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "could not add space member grant", err) + response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "could not add space member", err) return } } @@ -206,21 +188,12 @@ func (h *Handler) addSpaceMember(w http.ResponseWriter, r *http.Request, info *p response.WriteOCSSuccess(w, r, nil) } -func (h *Handler) isSpaceShare(r *http.Request, spaceID string) (*registry.ProviderInfo, bool) { - ref, err := storagespace.ParseReference(spaceID) - if err != nil { - return nil, false - } - - if ref.ResourceId.OpaqueId == "" { - ref.ResourceId.OpaqueId = ref.ResourceId.SpaceId - } - - p, err := h.findProvider(r.Context(), &ref) - return p, err == nil +func (h *Handler) isSpaceShare(r *http.Request, shareID string) bool { + _, err := storagespace.ParseReference(shareID) + return err == nil } -func (h *Handler) removeSpaceMember(w http.ResponseWriter, r *http.Request, spaceID string, prov *registry.ProviderInfo) { +func (h *Handler) removeSpaceMember(w http.ResponseWriter, r *http.Request, spaceID string) { ctx := r.Context() shareWith := r.URL.Query().Get("shareWith") @@ -245,129 +218,73 @@ func (h *Handler) removeSpaceMember(w http.ResponseWriter, r *http.Request, spac ref.ResourceId.OpaqueId = ref.ResourceId.SpaceId } - providerClient, err := h.getStorageProviderClient(prov) + client, err := h.getClient() if err != nil { - response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "error getting storage provider client", err) + response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "error getting gateway client", err) return } - lgRes, err := providerClient.ListGrants(ctx, &provider.ListGrantsRequest{Ref: &ref}) - if err != nil || lgRes.Status.Code != rpc.Code_CODE_OK { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error listing space grants", err) + lsRes, err := client.ListShares(ctx, &collaborationv1beta1.ListSharesRequest{ + Filters: []*collaborationv1beta1.Filter{ + { + Type: collaborationv1beta1.Filter_TYPE_RESOURCE_ID, + Term: &collaborationv1beta1.Filter_ResourceId{ + ResourceId: ref.ResourceId, + }, + }, + }, + }) + if err != nil || lsRes.Status.Code != rpc.Code_CODE_OK { + response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error listing space members", err) return } - if len(lgRes.Grants) == 1 || !isSpaceManagerRemaining(lgRes.Grants, &grantee) { + if len(lsRes.Shares) == 1 || !isSpaceManagerRemainingInShares(lsRes.Shares, &grantee) { response.WriteOCSError(w, r, http.StatusForbidden, "can't remove the last manager", nil) return } - gatewayClient, err := h.getClient() - if err != nil { - response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "error getting gateway client", err) + s := findShareByGrantee(lsRes.Shares, &grantee) + if s == nil { + response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "cannot find share", nil) return } - removeShareRes, err := gatewayClient.RemoveShare(ctx, &collaborationv1beta1.RemoveShareRequest{ + removeShareRes, err := client.RemoveShare(ctx, &collaborationv1beta1.RemoveShareRequest{ Ref: &collaborationv1beta1.ShareReference{ - Spec: &collaborationv1beta1.ShareReference_Key{ - Key: &collaborationv1beta1.ShareKey{ - ResourceId: ref.ResourceId, - Grantee: &grantee, - }, + Spec: &collaborationv1beta1.ShareReference_Id{ + Id: s.Id, }, }, }) if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error removing grant", err) + response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error removing space member", err) return } if removeShareRes.Status.Code != rpc.Code_CODE_OK { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error removing grant", err) + response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error removing space member", nil) return } response.WriteOCSSuccess(w, r, nil) } -func (h *Handler) getStorageProviderClient(p *registry.ProviderInfo) (provider.ProviderAPIClient, error) { - c, err := pool.GetStorageProviderServiceClient(p.Address) - if err != nil { - err = errors.Wrap(err, "shares spaces: error getting a storage provider client") - return nil, err - } - - return c, nil -} - -func (h *Handler) findProvider(ctx context.Context, ref *provider.Reference) (*registry.ProviderInfo, error) { - c, err := pool.GetStorageRegistryClient(h.storageRegistryAddr) - if err != nil { - return nil, errors.Wrap(err, "shares spaces: error getting storage registry client") - } - - filters := map[string]string{} - if ref.Path != "" { - filters["path"] = ref.Path - } - if ref.ResourceId != nil { - filters["storage_id"] = ref.ResourceId.StorageId - filters["space_id"] = ref.ResourceId.SpaceId - filters["opaque_id"] = ref.ResourceId.OpaqueId - } - - listReq := ®istry.ListStorageProvidersRequest{ - Opaque: &types.Opaque{}, - } - sdk.EncodeOpaqueMap(listReq.Opaque, filters) - - res, err := c.ListStorageProviders(ctx, listReq) - - if err != nil { - return nil, errors.Wrap(err, "shares spaces: error calling ListStorageProviders") - } - - if res.Status.Code != rpc.Code_CODE_OK { - switch res.Status.Code { - case rpc.Code_CODE_NOT_FOUND: - return nil, errtypes.NotFound("shares spaces: storage provider not found for reference:" + ref.String()) - case rpc.Code_CODE_PERMISSION_DENIED: - return nil, errtypes.PermissionDenied("shares spaces: " + res.Status.Message + " for " + ref.String() + " with code " + res.Status.Code.String()) - case rpc.Code_CODE_INVALID_ARGUMENT, rpc.Code_CODE_FAILED_PRECONDITION, rpc.Code_CODE_OUT_OF_RANGE: - return nil, errtypes.BadRequest("shares spaces: " + res.Status.Message + " for " + ref.String() + " with code " + res.Status.Code.String()) - case rpc.Code_CODE_UNIMPLEMENTED: - return nil, errtypes.NotSupported("shares spaces: " + res.Status.Message + " for " + ref.String() + " with code " + res.Status.Code.String()) - default: - return nil, status.NewErrorFromCode(res.Status.Code, "shares spaces") - } - } - - if len(res.Providers) < 1 { - return nil, errtypes.NotFound("shares spaces: no provider found") - } - - return res.Providers[0], nil -} - -func isSpaceManagerRemaining(grants []*provider.Grant, grantee *provider.Grantee) bool { - for _, g := range grants { - // RemoveGrant is currently the way to check for the manager role - // If it is not set than the current grant is not for a manager and - // we can just continue with the next one. - if g.Permissions.RemoveGrant && !isEqualGrantee(g.Grantee, grantee) { +func isSpaceManagerRemainingInShares(shares []*collaborationv1beta1.Share, grantee *provider.Grantee) bool { + for _, s := range shares { + if s.GetPermissions().GetPermissions().GetRemoveGrant() && !isEqualGrantee(s.Grantee, grantee) { return true } } return false } -func granteeExists(grants []*provider.Grant, grantee *provider.Grantee) bool { - for _, g := range grants { - if isEqualGrantee(g.Grantee, grantee) { - return true +func findShareByGrantee(shares []*collaborationv1beta1.Share, grantee *provider.Grantee) *collaborationv1beta1.Share { + for _, s := range shares { + if isEqualGrantee(s.Grantee, grantee) { + return s } } - return false + return nil } func isEqualGrantee(a, b *provider.Grantee) bool { diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/user.go b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/user.go index fbea09a260..ce45c6002d 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/user.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/user.go @@ -34,6 +34,7 @@ import ( ctxpkg "github.com/opencloud-eu/reva/v2/pkg/ctx" "github.com/opencloud-eu/reva/v2/pkg/permission" "github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool" + "github.com/opencloud-eu/reva/v2/pkg/share" "github.com/opencloud-eu/reva/v2/pkg/utils" ) @@ -330,7 +331,7 @@ func (h *Handler) listUserShares(r *http.Request, filters []*collaboration.Filte log := appctx.GetLogger(ctx) lsUserSharesRequest := collaboration.ListSharesRequest{ - Filters: filters, + Filters: append(filters, share.SpaceRootFilter(false)), } ocsDataPayload := make([]*conversions.ShareData, 0) diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/ocs.go b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/ocs.go index 40113a73f6..795827b30d 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/ocs.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/ocs.go @@ -123,6 +123,13 @@ func (s *svc) routerInit(log *zerolog.Logger) error { r.Delete("/", sharesHandler.RejectReceivedShare) r.Put("/", sharesHandler.UpdateReceivedShare) }) + r.Route("/pending", func(r chi.Router) { + r.Post("/", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusMethodNotAllowed) + }) + r.Delete("/", sharesHandler.ReceivedShareNotFound) + r.Put("/", sharesHandler.ReceivedShareNotFound) + }) r.Route("/remote_shares", func(r chi.Router) { r.Get("/", sharesHandler.ListFederatedShares) r.Get("/{shareid}", sharesHandler.GetFederatedShare) diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/jsoncs3/jsoncs3.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/jsoncs3/jsoncs3.go index eac37873f8..ba995639b8 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/jsoncs3/jsoncs3.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/jsoncs3/jsoncs3.go @@ -296,16 +296,6 @@ func (m *Manager) Share(ctx context.Context, md *provider.ResourceInfo, g *colla user := ctxpkg.ContextMustGetUser(ctx) ts := utils.TSNow() - // do not allow share to myself or the owner if share is for a user - // TODO: should this not already be caught at the gw level? - if g.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER && - (utils.UserEqual(g.Grantee.GetUserId(), user.Id) || utils.UserEqual(g.Grantee.GetUserId(), md.Owner)) { - err := errtypes.BadRequest("jsoncs3: owner/creator and grantee are the same") - span.RecordError(err) - span.SetStatus(codes.Error, err.Error()) - return nil, err - } - // check if share already exists. key := &collaboration.ShareKey{ // Owner: md.Owner, owner no longer matters as it belongs to the space @@ -508,17 +498,10 @@ func (m *Manager) Unshare(ctx context.Context, ref *collaboration.ShareReference return err } - user := ctxpkg.ContextMustGetUser(ctx) - s, err := m.get(ctx, ref) if err != nil { return err } - // TODO allow manager to unshare shares in a space created by other users - if !share.IsCreatedByUser(s, user) { - // TODO why not permission denied? - return errtypes.NotFound(ref.String()) - } return m.removeShare(ctx, s, false) } diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/memory/memory.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/memory/memory.go index 1e7dc7ef2d..8ade5926f1 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/memory/memory.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/memory/memory.go @@ -82,11 +82,6 @@ func (m *manager) Share(ctx context.Context, md *provider.ResourceInfo, g *colla Nanos: uint32(now % 1000000000), } - if g.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER && - (utils.UserEqual(g.Grantee.GetUserId(), user.Id) || utils.UserEqual(g.Grantee.GetUserId(), md.Owner)) { - return nil, errtypes.BadRequest("memory: owner/creator and grantee are the same") - } - // check if share already exists. key := &collaboration.ShareKey{ Owner: md.Owner, diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/share.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/share/share.go index 57e5c8226e..904cd41716 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/share.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/share/share.go @@ -136,6 +136,18 @@ func StateFilter(state collaboration.ShareState) *collaboration.Filter { } } +// SpaceRootFilter is an abstraction for filtering shares by whether the shared +// resource is a space root. Pass true to include only space-root shares (space +// membership), false to exclude them (file/folder shares only). +func SpaceRootFilter(spaceRoot bool) *collaboration.Filter { + return &collaboration.Filter{ + Type: collaboration.Filter_TYPE_SPACE_ROOT, + Term: &collaboration.Filter_SpaceRoot{ + SpaceRoot: spaceRoot, + }, + } +} + // IsCreatedByUser checks if the user is the owner or creator of the share. func IsCreatedByUser(share *collaboration.Share, user *userv1beta1.User) bool { return utils.UserEqual(user.Id, share.Owner) || utils.UserEqual(user.Id, share.Creator) @@ -172,6 +184,9 @@ func MatchesFilter(share *collaboration.Share, state collaboration.ShareState, f return share.ResourceId.SpaceId == filter.GetSpaceId() case collaboration.Filter_TYPE_STATE: return state == filter.GetState() + case collaboration.Filter_TYPE_SPACE_ROOT: + isSpaceRoot := share.ResourceId.SpaceId == share.ResourceId.OpaqueId + return isSpaceRoot == filter.GetSpaceRoot() default: return false } diff --git a/vendor/modules.txt b/vendor/modules.txt index 8506e9f033..f260625fac 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -316,7 +316,7 @@ github.com/crewjam/saml github.com/crewjam/saml/logger github.com/crewjam/saml/samlsp github.com/crewjam/saml/xmlenc -# github.com/cs3org/go-cs3apis v0.0.0-20260310080202-fb97596763d6 +# github.com/cs3org/go-cs3apis v0.0.0-20260310080202-fb97596763d6 => github.com/rhafer/go-cs3apis v0.0.0-20260408142546-729b5181682a ## explicit; go 1.21 github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1 github.com/cs3org/go-cs3apis/cs3/app/registry/v1beta1 @@ -1371,7 +1371,7 @@ github.com/opencloud-eu/icap-client # github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d ## explicit; go 1.18 github.com/opencloud-eu/libre-graph-api-go -# github.com/opencloud-eu/reva/v2 v2.42.7-0.20260408072824-411780d0b756 +# github.com/opencloud-eu/reva/v2 v2.42.7-0.20260408072824-411780d0b756 => github.com/rhafer/reva/v2 v2.0.0-20260409124525-45c05820c3b5 ## explicit; go 1.25.0 github.com/opencloud-eu/reva/v2/cmd/revad/internal/grace github.com/opencloud-eu/reva/v2/cmd/revad/runtime @@ -2729,3 +2729,5 @@ stash.kopano.io/kgol/rndm # github.com/unrolled/secure => github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4 # go-micro.dev/v4 => github.com/butonic/go-micro/v4 v4.11.1-0.20241115112658-b5d4de5ed9b3 # github.com/go-micro/plugins/v4/store/nats-js-kv => github.com/opencloud-eu/go-micro-plugins/v4/store/nats-js-kv v0.0.0-20250512152754-23325793059a +# github.com/cs3org/go-cs3apis => github.com/rhafer/go-cs3apis v0.0.0-20260408142546-729b5181682a +# github.com/opencloud-eu/reva/v2 => github.com/rhafer/reva/v2 v2.0.0-20260409124525-45c05820c3b5