diff --git a/changelog/unreleased/remove-resharing.md b/changelog/unreleased/remove-resharing.md new file mode 100644 index 000000000..495c5ea9e --- /dev/null +++ b/changelog/unreleased/remove-resharing.md @@ -0,0 +1,5 @@ +Enhancement: Remove resharing + +Removed resharing feature from codebase + +https://github.com/owncloud/ocis/pull/8762 diff --git a/go.mod b/go.mod index 2d16503d5..4e3d9d29c 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/cenkalti/backoff v2.2.1+incompatible github.com/coreos/go-oidc/v3 v3.10.0 github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781 - github.com/cs3org/reva/v2 v2.19.2-0.20240328104440-9c04f2d8ab7e + github.com/cs3org/reva/v2 v2.19.2-0.20240404085416-251ba8d12f6f github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25 github.com/disintegration/imaging v1.6.2 github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e diff --git a/go.sum b/go.sum index d9c13e7b0..ebf56da2b 100644 --- a/go.sum +++ b/go.sum @@ -1022,8 +1022,8 @@ 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-20231023073225-7748710e0781 h1:BUdwkIlf8IS2FasrrPg8gGPHQPOrQ18MS1Oew2tmGtY= github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= -github.com/cs3org/reva/v2 v2.19.2-0.20240328104440-9c04f2d8ab7e h1:WkmwnjiTC9FBDQqJhv4IUBBXDEvqKhlgfaJ1sZ3T3N8= -github.com/cs3org/reva/v2 v2.19.2-0.20240328104440-9c04f2d8ab7e/go.mod h1:GRUrOp5HbFVwZTgR9bVrMZ/MvVy+Jhxw1PdMmhhKP9E= +github.com/cs3org/reva/v2 v2.19.2-0.20240404085416-251ba8d12f6f h1:t4jFaaEmPX8J/jvybuvI7aC1TbU2zSGZabUDQvA5Mr8= +github.com/cs3org/reva/v2 v2.19.2-0.20240404085416-251ba8d12f6f/go.mod h1:GRUrOp5HbFVwZTgR9bVrMZ/MvVy+Jhxw1PdMmhhKP9E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= diff --git a/services/frontend/pkg/config/config.go b/services/frontend/pkg/config/config.go index dd1259659..6404c33cc 100644 --- a/services/frontend/pkg/config/config.go +++ b/services/frontend/pkg/config/config.go @@ -31,7 +31,6 @@ type Config struct { UploadMaxChunkSize int `yaml:"upload_max_chunk_size" env:"FRONTEND_UPLOAD_MAX_CHUNK_SIZE" desc:"Sets the max chunk sizes in bytes for uploads via the clients." introductionVersion:"pre5.0"` UploadHTTPMethodOverride string `yaml:"upload_http_method_override" env:"FRONTEND_UPLOAD_HTTP_METHOD_OVERRIDE" desc:"Advise TUS to replace PATCH requests by POST requests." introductionVersion:"pre5.0"` DefaultUploadProtocol string `yaml:"default_upload_protocol" env:"FRONTEND_DEFAULT_UPLOAD_PROTOCOL" desc:"The default upload protocol to use in clients. Currently only 'tus' is available. See the developer API documentation for more details about TUS." introductionVersion:"pre5.0"` - EnableResharing bool `yaml:"enable_resharing" env:"OCIS_ENABLE_RESHARING;FRONTEND_ENABLE_RESHARING" desc:"Changing this value is NOT supported. Enables the support for re-sharing in the clients." introductionVersion:"pre5.0" deprecationVersion:"5.0" deprecationInfo:"Re-sharing will be removed in the future."` EnableFederatedSharingIncoming bool `yaml:"enable_federated_sharing_incoming" env:"FRONTEND_ENABLE_FEDERATED_SHARING_INCOMING" desc:"Changing this value is NOT supported. Enables support for incoming federated sharing for clients. The backend behaviour is not changed." introductionVersion:"pre5.0"` EnableFederatedSharingOutgoing bool `yaml:"enable_federated_sharing_outgoing" env:"FRONTEND_ENABLE_FEDERATED_SHARING_OUTGOING" desc:"Changing this value is NOT supported. Enables support for outgoing federated sharing for clients. The backend behaviour is not changed." introductionVersion:"pre5.0"` SearchMinLength int `yaml:"search_min_length" env:"FRONTEND_SEARCH_MIN_LENGTH" desc:"Minimum number of characters to enter before a client should start a search for Share receivers. This setting can be used to customize the user experience if e.g too many results are displayed." introductionVersion:"pre5.0"` diff --git a/services/frontend/pkg/config/defaults/defaultconfig.go b/services/frontend/pkg/config/defaults/defaultconfig.go index 2364191d0..4f214f457 100644 --- a/services/frontend/pkg/config/defaults/defaultconfig.go +++ b/services/frontend/pkg/config/defaults/defaultconfig.go @@ -85,7 +85,6 @@ func DefaultConfig() *config.Config { UploadMaxChunkSize: 1e+7, UploadHTTPMethodOverride: "", DefaultUploadProtocol: "tus", - EnableResharing: false, DefaultLinkPermissions: 1, SearchMinLength: 3, Edition: "Community", diff --git a/services/frontend/pkg/revaconfig/config.go b/services/frontend/pkg/revaconfig/config.go index f4d43ea23..769a6f6d1 100644 --- a/services/frontend/pkg/revaconfig/config.go +++ b/services/frontend/pkg/revaconfig/config.go @@ -229,7 +229,6 @@ func FrontendConfigFromStruct(cfg *config.Config, logger log.Logger) (map[string }, "files_sharing": map[string]interface{}{ "api_enabled": true, - "resharing": cfg.EnableResharing, "group_sharing": true, "sharing_roles": true, "deny_access": cfg.OCS.EnableDenials, diff --git a/services/graph/pkg/config/config.go b/services/graph/pkg/config/config.go index ed2133483..6d2bfb426 100644 --- a/services/graph/pkg/config/config.go +++ b/services/graph/pkg/config/config.go @@ -33,8 +33,6 @@ type Config struct { Keycloak Keycloak `yaml:"keycloak"` ServiceAccount ServiceAccount `yaml:"service_account"` - FilesSharing FilesSharing `yaml:"files_sharing"` - Context context.Context `yaml:"-"` } @@ -151,8 +149,3 @@ type ServiceAccount struct { ServiceAccountID string `yaml:"service_account_id" env:"OCIS_SERVICE_ACCOUNT_ID;GRAPH_SERVICE_ACCOUNT_ID" desc:"The ID of the service account the service should use. See the 'auth-service' service description for more details." introductionVersion:"5.0"` ServiceAccountSecret string `yaml:"service_account_secret" env:"OCIS_SERVICE_ACCOUNT_SECRET;GRAPH_SERVICE_ACCOUNT_SECRET" desc:"The service account secret." introductionVersion:"5.0"` } - -// FilesSharing is the configuration for the files sharing -type FilesSharing struct { - EnableResharing bool `yaml:"enable_resharing" env:"OCIS_ENABLE_RESHARING;GRAPH_ENABLE_RESHARING" desc:"Changing this value is NOT supported. Enables the support for re-sharing." introductionVersion:"5.0" deprecationVersion:"5.0" deprecationInfo:"Resharing will be removed in the future."` -} diff --git a/services/graph/pkg/config/defaults/defaultconfig.go b/services/graph/pkg/config/defaults/defaultconfig.go index d665b2f20..6ac2e2ab1 100644 --- a/services/graph/pkg/config/defaults/defaultconfig.go +++ b/services/graph/pkg/config/defaults/defaultconfig.go @@ -107,9 +107,6 @@ func DefaultConfig() *config.Config { Cluster: "ocis-cluster", EnableTLS: false, }, - FilesSharing: config.FilesSharing{ - EnableResharing: false, - }, } } diff --git a/services/graph/pkg/service/v0/api_driveitem_permissions.go b/services/graph/pkg/service/v0/api_driveitem_permissions.go index dc6d4041e..1fd6caa56 100644 --- a/services/graph/pkg/service/v0/api_driveitem_permissions.go +++ b/services/graph/pkg/service/v0/api_driveitem_permissions.go @@ -96,7 +96,7 @@ func (s DriveItemPermissionsService) Invite(ctx context.Context, resourceId stor unifiedRolePermissions := []*libregraph.UnifiedRolePermission{{AllowedResourceActions: invite.LibreGraphPermissionsActions}} for _, roleID := range invite.GetRoles() { - role, err := unifiedrole.NewUnifiedRoleFromID(roleID, s.config.FilesSharing.EnableResharing) + role, err := unifiedrole.NewUnifiedRoleFromID(roleID) if err != nil { s.logger.Debug().Err(err).Interface("role", invite.GetRoles()[0]).Msg("unable to convert requested role") return libregraph.Permission{}, err @@ -125,7 +125,7 @@ func (s DriveItemPermissionsService) Invite(ctx context.Context, resourceId stor } permission := &libregraph.Permission{} - if role := unifiedrole.CS3ResourcePermissionsToUnifiedRole(*cs3ResourcePermissions, condition, s.config.FilesSharing.EnableResharing); role != nil { + if role := unifiedrole.CS3ResourcePermissionsToUnifiedRole(*cs3ResourcePermissions, condition); role != nil { permission.Roles = []string{role.GetId()} } @@ -246,7 +246,6 @@ func (s DriveItemPermissionsService) ListPermissions(ctx context.Context, itemID unifiedrole.GetApplicableRoleDefinitionsForActions( allowedActions, condition, - s.config.FilesSharing.EnableResharing, false, ), ), 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 755aacb89..3c2d25bb8 100644 --- a/services/graph/pkg/service/v0/api_driveitem_permissions_test.go +++ b/services/graph/pkg/service/v0/api_driveitem_permissions_test.go @@ -164,13 +164,13 @@ var _ = Describe("DriveItemPermissionsService", func() { driveItemInvite.Recipients = []libregraph.DriveRecipient{ {ObjectId: libregraph.PtrString("1"), LibreGraphRecipientType: libregraph.PtrString("user")}, } - driveItemInvite.Roles = []string{unifiedrole.NewViewerUnifiedRole(true).GetId()} + driveItemInvite.Roles = []string{unifiedrole.NewViewerUnifiedRole().GetId()} permission, err := driveItemPermissionsService.Invite(context.Background(), driveItemId, driveItemInvite) Expect(err).ToNot(HaveOccurred()) Expect(permission.GetRoles()).To(HaveLen(1)) - Expect(permission.GetRoles()[0]).To(Equal(unifiedrole.NewViewerUnifiedRole(true).GetId())) + Expect(permission.GetRoles()[0]).To(Equal(unifiedrole.NewViewerUnifiedRole().GetId())) }) It("fails with wrong role", func() { @@ -311,7 +311,7 @@ var _ = Describe("DriveItemPermissionsService", func() { It("populates allowedValues for files that are not shared", func() { statResponse.Info = &provider.ResourceInfo{ Id: &itemID, - PermissionSet: roleconversions.NewViewerRole(false).CS3ResourcePermissions(), + PermissionSet: roleconversions.NewViewerRole().CS3ResourcePermissions(), } gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil) gatewayClient.On("ListShares", mock.Anything, mock.Anything).Return(listSharesResponse, nil) @@ -324,13 +324,13 @@ var _ = Describe("DriveItemPermissionsService", func() { It("returns one permission per share", func() { statResponse.Info = &provider.ResourceInfo{ Id: &itemID, - PermissionSet: roleconversions.NewEditorRole(false).CS3ResourcePermissions(), + PermissionSet: roleconversions.NewEditorRole().CS3ResourcePermissions(), } listSharesResponse.Shares = []*collaboration.Share{ { Id: &collaboration.ShareId{OpaqueId: "1"}, Permissions: &collaboration.SharePermissions{ - Permissions: roleconversions.NewViewerRole(false).CS3ResourcePermissions(), + Permissions: roleconversions.NewViewerRole().CS3ResourcePermissions(), }, ResourceId: &provider.ResourceId{ StorageId: "1", @@ -358,7 +358,7 @@ var _ = Describe("DriveItemPermissionsService", func() { SpaceId: "spaceid", OpaqueId: "public-share-opaqueid", }, - Permissions: &link.PublicSharePermissions{Permissions: roleconversions.NewViewerRole(false).CS3ResourcePermissions()}, + Permissions: &link.PublicSharePermissions{Permissions: roleconversions.NewViewerRole().CS3ResourcePermissions()}, }, } @@ -408,7 +408,7 @@ var _ = Describe("DriveItemPermissionsService", func() { gatewayClient.On("ListPublicShares", mock.Anything, mock.Anything).Return(listPublicSharesResponse, nil) statResponse.Info = &provider.ResourceInfo{ Id: listSpacesResponse.StorageSpaces[0].Root, - PermissionSet: roleconversions.NewViewerRole(false).CS3ResourcePermissions(), + PermissionSet: roleconversions.NewViewerRole().CS3ResourcePermissions(), } gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil) permissions, err := driveItemPermissionsService.ListSpaceRootPermissions(context.Background(), driveId) @@ -586,7 +586,7 @@ var _ = Describe("DriveItemPermissionsService", func() { }, }, Permissions: &collaboration.SharePermissions{ - Permissions: roleconversions.NewViewerRole(true).CS3ResourcePermissions(), + Permissions: roleconversions.NewViewerRole().CS3ResourcePermissions(), }, } getShareMockResponse = &collaboration.GetShareResponse{ @@ -798,7 +798,7 @@ var _ = Describe("DriveItemPermissionsService", func() { gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil) gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil) - driveItemPermission.SetRoles([]string{unifiedrole.NewFileEditorUnifiedRole(false).GetId()}) + driveItemPermission.SetRoles([]string{unifiedrole.NewFileEditorUnifiedRole().GetId()}) spaceId := provider.ResourceId{ StorageId: "1", SpaceId: "2", @@ -980,7 +980,7 @@ var _ = Describe("DriveItemPermissionsApi", func() { ObjectId: libregraph.PtrString("1"), LibreGraphRecipientType: libregraph.PtrString("user")}, }, - Roles: []string{unifiedrole.NewViewerUnifiedRole(true).GetId()}, + Roles: []string{unifiedrole.NewViewerUnifiedRole().GetId()}, } }) diff --git a/services/graph/pkg/service/v0/api_drives_drive_item.go b/services/graph/pkg/service/v0/api_drives_drive_item.go index deb1f3ee3..76c2516ff 100644 --- a/services/graph/pkg/service/v0/api_drives_drive_item.go +++ b/services/graph/pkg/service/v0/api_drives_drive_item.go @@ -34,19 +34,17 @@ type DrivesDriveItemProvider interface { // DrivesDriveItemService contains the production business logic for everything that relates to drives type DrivesDriveItemService struct { - logger log.Logger - gatewaySelector pool.Selectable[gateway.GatewayAPIClient] - identityCache identity.IdentityCache - resharingEnabled bool + logger log.Logger + gatewaySelector pool.Selectable[gateway.GatewayAPIClient] + identityCache identity.IdentityCache } // NewDrivesDriveItemService creates a new DrivesDriveItemService -func NewDrivesDriveItemService(logger log.Logger, gatewaySelector pool.Selectable[gateway.GatewayAPIClient], identityCache identity.IdentityCache, resharing bool) (DrivesDriveItemService, error) { +func NewDrivesDriveItemService(logger log.Logger, gatewaySelector pool.Selectable[gateway.GatewayAPIClient], identityCache identity.IdentityCache) (DrivesDriveItemService, error) { return DrivesDriveItemService{ - logger: log.Logger{Logger: logger.With().Str("graph api", "DrivesDriveItemService").Logger()}, - gatewaySelector: gatewaySelector, - identityCache: identityCache, - resharingEnabled: resharing, + logger: log.Logger{Logger: logger.With().Str("graph api", "DrivesDriveItemService").Logger()}, + gatewaySelector: gatewaySelector, + identityCache: identityCache, }, nil } @@ -211,8 +209,8 @@ func (s DrivesDriveItemService) MountShare(ctx context.Context, resourceID stora return libregraph.DriveItem{}, errors.Join(errs...) } - // As the accepted shares are all for the same resource they should collapse to a single drive-item - items, err := cs3ReceivedSharesToDriveItems(ctx, &s.logger, gatewayClient, s.identityCache, s.resharingEnabled, acceptedShares) + // As the accepted shares are all for the same resource they should collapse to a single driveitem + items, err := cs3ReceivedSharesToDriveItems(ctx, &s.logger, gatewayClient, s.identityCache, acceptedShares) switch { case err != nil: return libregraph.DriveItem{}, nil diff --git a/services/graph/pkg/service/v0/api_drives_drive_item_test.go b/services/graph/pkg/service/v0/api_drives_drive_item_test.go index 3b0f482a1..c526d49c1 100644 --- a/services/graph/pkg/service/v0/api_drives_drive_item_test.go +++ b/services/graph/pkg/service/v0/api_drives_drive_item_test.go @@ -47,7 +47,7 @@ var _ = Describe("DrivesDriveItemService", func() { cache := identity.NewIdentityCache(identity.IdentityCacheWithGatewaySelector(gatewaySelector)) - service, err := svc.NewDrivesDriveItemService(logger, gatewaySelector, cache, false) + service, err := svc.NewDrivesDriveItemService(logger, gatewaySelector, cache) Expect(err).ToNot(HaveOccurred()) drivesDriveItemService = service }) diff --git a/services/graph/pkg/service/v0/base.go b/services/graph/pkg/service/v0/base.go index 959191379..e1bec9109 100644 --- a/services/graph/pkg/service/v0/base.go +++ b/services/graph/pkg/service/v0/base.go @@ -165,7 +165,7 @@ func (g BaseGraphService) cs3SpacePermissionsToLibreGraph(ctx context.Context, s p.SetExpirationDateTime(time.Unix(int64(exp.GetSeconds()), int64(exp.GetNanos()))) } - if role := unifiedrole.CS3ResourcePermissionsToUnifiedRole(*perm, unifiedrole.UnifiedRoleConditionOwner, false); role != nil { + if role := unifiedrole.CS3ResourcePermissionsToUnifiedRole(*perm, unifiedrole.UnifiedRoleConditionOwner); role != nil { switch apiVersion { case APIVersion_1: if r := unifiedrole.GetLegacyName(*role); r != "" { @@ -354,7 +354,6 @@ func (g BaseGraphService) cs3UserShareToPermission(ctx context.Context, share *c role := unifiedrole.CS3ResourcePermissionsToUnifiedRole( *share.GetPermissions().GetPermissions(), condition, - g.config.FilesSharing.EnableResharing, ) if role != nil { perm.SetRoles([]string{role.GetId()}) @@ -627,7 +626,7 @@ func (g BaseGraphService) updateUserShare(ctx context.Context, permissionID stri var permissionsUpdated, ok bool if roles, ok = newPermission.GetRolesOk(); ok && len(roles) > 0 { for _, roleID := range roles { - role, err := unifiedrole.NewUnifiedRoleFromID(roleID, g.config.FilesSharing.EnableResharing) + role, err := unifiedrole.NewUnifiedRoleFromID(roleID) if err != nil { g.logger.Debug().Err(err).Interface("role", role).Msg("unable to convert requested role") return nil, err diff --git a/services/graph/pkg/service/v0/rolemanagement.go b/services/graph/pkg/service/v0/rolemanagement.go index 549fbbab8..d092421bc 100644 --- a/services/graph/pkg/service/v0/rolemanagement.go +++ b/services/graph/pkg/service/v0/rolemanagement.go @@ -15,7 +15,7 @@ import ( // GetRoleDefinitions a list of permission roles than can be used when sharing with users or groups func (g Graph) GetRoleDefinitions(w http.ResponseWriter, r *http.Request) { render.Status(r, http.StatusOK) - render.JSON(w, r, unifiedrole.GetBuiltinRoleDefinitionList(g.config.FilesSharing.EnableResharing)) + render.JSON(w, r, unifiedrole.GetBuiltinRoleDefinitionList()) } // GetRoleDefinition a permission role than can be used when sharing with users or groups @@ -27,7 +27,7 @@ func (g Graph) GetRoleDefinition(w http.ResponseWriter, r *http.Request) { errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping role id failed") return } - role, err := getRoleDefinition(roleID, g.config.FilesSharing.EnableResharing) + role, err := getRoleDefinition(roleID) if err != nil { logger.Debug().Str("roleID", roleID).Msg("could not get role: not found") errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, err.Error()) @@ -37,8 +37,8 @@ func (g Graph) GetRoleDefinition(w http.ResponseWriter, r *http.Request) { render.JSON(w, r, role) } -func getRoleDefinition(roleID string, resharing bool) (*libregraph.UnifiedRoleDefinition, error) { - roleList := unifiedrole.GetBuiltinRoleDefinitionList(resharing) +func getRoleDefinition(roleID string) (*libregraph.UnifiedRoleDefinition, error) { + roleList := unifiedrole.GetBuiltinRoleDefinitionList() for _, role := range roleList { if role != nil && role.Id != nil && *role.Id == roleID { return role, nil diff --git a/services/graph/pkg/service/v0/service.go b/services/graph/pkg/service/v0/service.go index df4e99aad..6c4cc35e1 100644 --- a/services/graph/pkg/service/v0/service.go +++ b/services/graph/pkg/service/v0/service.go @@ -199,7 +199,7 @@ func NewService(opts ...Option) (Graph, error) { requireAdmin = options.RequireAdminMiddleware } - drivesDriveItemService, err := NewDrivesDriveItemService(options.Logger, options.GatewaySelector, identityCache, options.Config.FilesSharing.EnableResharing) + drivesDriveItemService, err := NewDrivesDriveItemService(options.Logger, options.GatewaySelector, identityCache) if err != nil { return svc, err } diff --git a/services/graph/pkg/service/v0/sharedbyme_test.go b/services/graph/pkg/service/v0/sharedbyme_test.go index 9902f23a6..6d4840686 100644 --- a/services/graph/pkg/service/v0/sharedbyme_test.go +++ b/services/graph/pkg/service/v0/sharedbyme_test.go @@ -52,7 +52,7 @@ var _ = Describe("sharedbyme", func() { ) expiration := time.Now() - editorResourcePermissions := conversions.NewEditorRole(true).CS3ResourcePermissions() + editorResourcePermissions := conversions.NewEditorRole().CS3ResourcePermissions() userShare := collaboration.Share{ Id: &collaboration.ShareId{ OpaqueId: "share-id", @@ -243,7 +243,6 @@ var _ = Describe("sharedbyme", func() { cfg.TokenManager.JWTSecret = "loremipsum" cfg.Commons = &shared.Commons{} cfg.GRPCClientTLS = &shared.GRPCClientTLS{} - cfg.FilesSharing.EnableResharing = true svc, _ = service.NewService( service.Config(cfg), diff --git a/services/graph/pkg/service/v0/sharedwithme.go b/services/graph/pkg/service/v0/sharedwithme.go index e23ca660b..42d02d76c 100644 --- a/services/graph/pkg/service/v0/sharedwithme.go +++ b/services/graph/pkg/service/v0/sharedwithme.go @@ -39,5 +39,5 @@ func (g Graph) listSharedWithMe(ctx context.Context) ([]libregraph.DriveItem, er return nil, *errCode } - return cs3ReceivedSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, g.config.FilesSharing.EnableResharing, listReceivedSharesResponse.GetShares()) + return cs3ReceivedSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, listReceivedSharesResponse.GetShares()) } diff --git a/services/graph/pkg/service/v0/sharedwithme_test.go b/services/graph/pkg/service/v0/sharedwithme_test.go index 6bafe9626..84b00507b 100644 --- a/services/graph/pkg/service/v0/sharedwithme_test.go +++ b/services/graph/pkg/service/v0/sharedwithme_test.go @@ -155,7 +155,7 @@ var _ = Describe("SharedWithMe", func() { OpaqueId: "sh:are:id", }, Permissions: &collaborationv1beta1.SharePermissions{ - Permissions: roleconversions.NewViewerRole(true).CS3ResourcePermissions(), + Permissions: roleconversions.NewViewerRole().CS3ResourcePermissions(), }, Creator: getUserResponseShareCreator.User.Id, Ctime: utils.TSNow(), @@ -351,29 +351,6 @@ var _ = Describe("SharedWithMe", func() { Expect(jsonData.Get("file.mimeType").String()).To(Equal(resourceInfo.MimeType)) }) - // that is resharing test. Please delete after disable resharing feature - - // It("populates the driveItem.remoteItem.permissions properties", func() { - // resourceInfo := statResponse.Info - // resourceInfo.PermissionSet = roleconversions.NewViewerRole(false).CS3ResourcePermissions() - - // svc.ListSharedWithMe( - // tape, - // httptest.NewRequest(http.MethodGet, "/graph/v1beta1/me/drive/sharedWithMe", nil), - // ) - - // driveitemJSON := gjson.Get(tape.Body.String(), "value.0") - // Expect(driveitemJSON.Get("@UI\\.Hidden").Exists()).To(BeTrue()) - // Expect(driveitemJSON.Get("@UI\\.Hidden").Bool()).To(BeFalse()) - // Expect(driveitemJSON.Get("@client\\.synchronize").Exists()).To(BeTrue()) - // Expect(driveitemJSON.Get("@client\\.synchronize").Bool()).To(BeTrue()) - - // permissionsJSON := driveitemJSON.Get("remoteItem.permissions.0") - // Expect(permissionsJSON.Get("id").String()).To(Equal(listReceivedSharesResponse.Shares[0].Share.Id.OpaqueId)) - // Expect(permissionsJSON.Get("roles.0").String()).To(Equal(unifiedrole.UnifiedRoleViewerID)) - // Expect(permissionsJSON.Get("invitation.invitedBy.user.id").String()).To(Equal(getUserResponseShareCreator.User.Id.OpaqueId)) - // }) - It("returns shares created on project space", func() { ownerID := &userv1beta1.UserId{ OpaqueId: "project-space-id", @@ -406,7 +383,7 @@ var _ = Describe("SharedWithMe", func() { OpaqueId: "sh:are:id2", }, Permissions: &collaborationv1beta1.SharePermissions{ - Permissions: roleconversions.NewViewerRole(true).CS3ResourcePermissions(), + Permissions: roleconversions.NewViewerRole().CS3ResourcePermissions(), }, Creator: getUserResponseShareCreator.User.Id, Ctime: utils.TSNow(), diff --git a/services/graph/pkg/service/v0/utils.go b/services/graph/pkg/service/v0/utils.go index ec8e6ce6a..55311185b 100644 --- a/services/graph/pkg/service/v0/utils.go +++ b/services/graph/pkg/service/v0/utils.go @@ -142,7 +142,6 @@ func cs3ReceivedSharesToDriveItems(ctx context.Context, logger *log.Logger, gatewayClient gateway.GatewayAPIClient, identityCache identity.IdentityCache, - resharing bool, receivedShares []*collaboration.ReceivedShare) ([]libregraph.DriveItem, error) { ch := make(chan libregraph.DriveItem) @@ -178,8 +177,7 @@ func cs3ReceivedSharesToDriveItems(ctx context.Context, return errCode } - driveItem, err := fillDriveItemPropertiesFromReceivedShare(ctx, logger, identityCache, - resharing, receivedShares) + driveItem, err := fillDriveItemPropertiesFromReceivedShare(ctx, logger, identityCache, receivedShares) if err != nil { return err } @@ -315,8 +313,7 @@ func cs3ReceivedSharesToDriveItems(ctx context.Context, } func fillDriveItemPropertiesFromReceivedShare(ctx context.Context, logger *log.Logger, - identityCache identity.IdentityCache, resharing bool, - receivedShares []*collaboration.ReceivedShare) (*libregraph.DriveItem, error) { + identityCache identity.IdentityCache, receivedShares []*collaboration.ReceivedShare) (*libregraph.DriveItem, error) { driveItem := libregraph.NewDriveItem() permissions := make([]libregraph.Permission, 0, len(receivedShares)) @@ -330,7 +327,7 @@ func fillDriveItemPropertiesFromReceivedShare(ctx context.Context, logger *log.L oldestReceivedShare = receivedShare } - permission, err := cs3ReceivedShareToLibreGraphPermissions(ctx, logger, identityCache, resharing, receivedShare) + permission, err := cs3ReceivedShareToLibreGraphPermissions(ctx, logger, identityCache, receivedShare) if err != nil { return driveItem, err } @@ -390,7 +387,7 @@ func fillDriveItemPropertiesFromReceivedShare(ctx context.Context, logger *log.L } func cs3ReceivedShareToLibreGraphPermissions(ctx context.Context, logger *log.Logger, - identityCache identity.IdentityCache, resharing bool, receivedShare *collaboration.ReceivedShare) (*libregraph.Permission, error) { + identityCache identity.IdentityCache, receivedShare *collaboration.ReceivedShare) (*libregraph.Permission, error) { permission := libregraph.NewPermission() if id := receivedShare.GetShare().GetId().GetOpaqueId(); id != "" { permission.SetId(id) @@ -404,7 +401,6 @@ func cs3ReceivedShareToLibreGraphPermissions(ctx context.Context, logger *log.Lo role := unifiedrole.CS3ResourcePermissionsToUnifiedRole( *permissionSet, unifiedrole.UnifiedRoleConditionGrantee, - resharing, ) if role != nil { diff --git a/services/graph/pkg/unifiedrole/unifiedrole.go b/services/graph/pkg/unifiedrole/unifiedrole.go index 7438d6770..91c3dfa36 100644 --- a/services/graph/pkg/unifiedrole/unifiedrole.go +++ b/services/graph/pkg/unifiedrole/unifiedrole.go @@ -69,8 +69,8 @@ var legacyNames map[string]string = map[string]string{ } // NewViewerUnifiedRole creates a viewer role. `sharing` indicates if sharing permission should be added -func NewViewerUnifiedRole(sharing bool) *libregraph.UnifiedRoleDefinition { - r := conversions.NewViewerRole(sharing) +func NewViewerUnifiedRole() *libregraph.UnifiedRoleDefinition { + r := conversions.NewViewerRole() return &libregraph.UnifiedRoleDefinition{ Id: proto.String(UnifiedRoleViewerID), Description: proto.String("View and download."), @@ -103,8 +103,8 @@ func NewSpaceViewerUnifiedRole() *libregraph.UnifiedRoleDefinition { } // NewEditorUnifiedRole creates an editor role. `sharing` indicates if sharing permission should be added -func NewEditorUnifiedRole(sharing bool) *libregraph.UnifiedRoleDefinition { - r := conversions.NewEditorRole(sharing) +func NewEditorUnifiedRole() *libregraph.UnifiedRoleDefinition { + r := conversions.NewEditorRole() return &libregraph.UnifiedRoleDefinition{ Id: proto.String(UnifiedRoleEditorID), Description: proto.String("View, download, upload, edit, add and delete."), @@ -137,8 +137,8 @@ func NewSpaceEditorUnifiedRole() *libregraph.UnifiedRoleDefinition { } // NewFileEditorUnifiedRole creates a file-editor role -func NewFileEditorUnifiedRole(sharing bool) *libregraph.UnifiedRoleDefinition { - r := conversions.NewFileEditorRole(sharing) +func NewFileEditorUnifiedRole() *libregraph.UnifiedRoleDefinition { + r := conversions.NewFileEditorRole() return &libregraph.UnifiedRoleDefinition{ Id: proto.String(UnifiedRoleFileEditorID), Description: proto.String("View, download and edit."), @@ -188,8 +188,8 @@ func NewManagerUnifiedRole() *libregraph.UnifiedRoleDefinition { } // NewUnifiedRoleFromID returns a unified role definition from the provided id -func NewUnifiedRoleFromID(id string, resharing bool) (*libregraph.UnifiedRoleDefinition, error) { - for _, definition := range GetBuiltinRoleDefinitionList(resharing) { +func NewUnifiedRoleFromID(id string) (*libregraph.UnifiedRoleDefinition, error) { + for _, definition := range GetBuiltinRoleDefinitionList() { if definition.GetId() != id { continue } @@ -200,13 +200,13 @@ func NewUnifiedRoleFromID(id string, resharing bool) (*libregraph.UnifiedRoleDef return nil, errors.New("role not found") } -func GetBuiltinRoleDefinitionList(resharing bool) []*libregraph.UnifiedRoleDefinition { +func GetBuiltinRoleDefinitionList() []*libregraph.UnifiedRoleDefinition { return []*libregraph.UnifiedRoleDefinition{ - NewViewerUnifiedRole(resharing), + NewViewerUnifiedRole(), NewSpaceViewerUnifiedRole(), - NewEditorUnifiedRole(resharing), + NewEditorUnifiedRole(), NewSpaceEditorUnifiedRole(), - NewFileEditorUnifiedRole(resharing), + NewFileEditorUnifiedRole(), NewUploaderUnifiedRole(), NewManagerUnifiedRole(), } @@ -214,8 +214,8 @@ func GetBuiltinRoleDefinitionList(resharing bool) []*libregraph.UnifiedRoleDefin // GetApplicableRoleDefinitionsForActions returns a list of role definitions // that match the provided actions and constraints -func GetApplicableRoleDefinitionsForActions(actions []string, constraints string, resharing, descending bool) []*libregraph.UnifiedRoleDefinition { - builtin := GetBuiltinRoleDefinitionList(resharing) +func GetApplicableRoleDefinitionsForActions(actions []string, constraints string, descending bool) []*libregraph.UnifiedRoleDefinition { + builtin := GetBuiltinRoleDefinitionList() definitions := make([]*libregraph.UnifiedRoleDefinition, 0, len(builtin)) for _, definition := range builtin { @@ -402,14 +402,14 @@ func GetLegacyName(role libregraph.UnifiedRoleDefinition) string { // CS3ResourcePermissionsToUnifiedRole tries to find the UnifiedRoleDefinition that matches the supplied // CS3 ResourcePermissions and constraints. -func CS3ResourcePermissionsToUnifiedRole(p provider.ResourcePermissions, constraints string, resharing bool) *libregraph.UnifiedRoleDefinition { +func CS3ResourcePermissionsToUnifiedRole(p provider.ResourcePermissions, constraints string) *libregraph.UnifiedRoleDefinition { actionSet := map[string]struct{}{} for _, action := range CS3ResourcePermissionsToLibregraphActions(p) { actionSet[action] = struct{}{} } var res *libregraph.UnifiedRoleDefinition - for _, uRole := range GetBuiltinRoleDefinitionList(resharing) { + for _, uRole := range GetBuiltinRoleDefinitionList() { matchFound := false for _, uPerm := range uRole.GetRolePermissions() { if uPerm.GetCondition() != constraints { @@ -448,6 +448,10 @@ func displayName(role *conversions.Role) *string { if role == nil { return nil } + + // linter wants this to be a var + canEdit := "Can edit" + var displayName string switch role.Name { case conversions.RoleViewer: @@ -455,11 +459,11 @@ func displayName(role *conversions.Role) *string { case conversions.RoleSpaceViewer: displayName = "Can view" case conversions.RoleEditor: - displayName = "Can edit" + displayName = canEdit case conversions.RoleSpaceEditor: - displayName = "Can edit" + displayName = canEdit case conversions.RoleFileEditor: - displayName = "Can edit" + displayName = canEdit case conversions.RoleUploader: displayName = "Can upload" case conversions.RoleManager: diff --git a/services/graph/pkg/unifiedrole/unifiedrole_test.go b/services/graph/pkg/unifiedrole/unifiedrole_test.go index add5ba63f..3c87114ab 100644 --- a/services/graph/pkg/unifiedrole/unifiedrole_test.go +++ b/services/graph/pkg/unifiedrole/unifiedrole_test.go @@ -20,13 +20,13 @@ var _ = Describe("unifiedroles", func() { func(legacyRole *rConversions.Role, unifiedRole *libregraph.UnifiedRoleDefinition, constraints string) { cs3perm := legacyRole.CS3ResourcePermissions() - r := unifiedrole.CS3ResourcePermissionsToUnifiedRole(*cs3perm, constraints, true) + r := unifiedrole.CS3ResourcePermissionsToUnifiedRole(*cs3perm, constraints) Expect(r.GetId()).To(Equal(unifiedRole.GetId())) }, - Entry(rConversions.RoleViewer, rConversions.NewViewerRole(true), unifiedrole.NewViewerUnifiedRole(true), unifiedrole.UnifiedRoleConditionGrantee), - Entry(rConversions.RoleEditor, rConversions.NewEditorRole(true), unifiedrole.NewEditorUnifiedRole(true), unifiedrole.UnifiedRoleConditionGrantee), - Entry(rConversions.RoleFileEditor, rConversions.NewFileEditorRole(true), unifiedrole.NewFileEditorUnifiedRole(true), unifiedrole.UnifiedRoleConditionGrantee), + Entry(rConversions.RoleViewer, rConversions.NewViewerRole(), unifiedrole.NewViewerUnifiedRole(), unifiedrole.UnifiedRoleConditionGrantee), + Entry(rConversions.RoleEditor, rConversions.NewEditorRole(), unifiedrole.NewEditorUnifiedRole(), unifiedrole.UnifiedRoleConditionGrantee), + Entry(rConversions.RoleFileEditor, rConversions.NewFileEditorRole(), unifiedrole.NewFileEditorUnifiedRole(), unifiedrole.UnifiedRoleConditionGrantee), Entry(rConversions.RoleManager, rConversions.NewManagerRole(), unifiedrole.NewManagerUnifiedRole(), unifiedrole.UnifiedRoleConditionOwner), Entry(rConversions.RoleSpaceViewer, rConversions.NewSpaceViewerRole(), unifiedrole.NewSpaceViewerUnifiedRole(), unifiedrole.UnifiedRoleConditionOwner), Entry(rConversions.RoleSpaceEditor, rConversions.NewSpaceEditorRole(), unifiedrole.NewSpaceEditorUnifiedRole(), unifiedrole.UnifiedRoleConditionOwner), @@ -49,11 +49,11 @@ var _ = Describe("unifiedroles", func() { Expect(permsFromCS3).To(matcher) }, - Entry(rConversions.RoleViewer, rConversions.NewViewerRole(true), unifiedrole.NewViewerUnifiedRole(true), true), - Entry(rConversions.RoleEditor, rConversions.NewEditorRole(true), unifiedrole.NewEditorUnifiedRole(true), true), - Entry(rConversions.RoleFileEditor, rConversions.NewFileEditorRole(true), unifiedrole.NewFileEditorUnifiedRole(true), true), + Entry(rConversions.RoleViewer, rConversions.NewViewerRole(), unifiedrole.NewViewerUnifiedRole(), true), + Entry(rConversions.RoleEditor, rConversions.NewEditorRole(), unifiedrole.NewEditorUnifiedRole(), true), + Entry(rConversions.RoleFileEditor, rConversions.NewFileEditorRole(), unifiedrole.NewFileEditorUnifiedRole(), true), Entry(rConversions.RoleManager, rConversions.NewManagerRole(), unifiedrole.NewManagerUnifiedRole(), true), - Entry("no match", rConversions.NewFileEditorRole(true), unifiedrole.NewManagerUnifiedRole(), false), + Entry("no match", rConversions.NewFileEditorRole(), unifiedrole.NewManagerUnifiedRole(), false), ) DescribeTable("WeightRoleDefinitions", @@ -66,25 +66,25 @@ var _ = Describe("unifiedroles", func() { Entry("ascending", []*libregraph.UnifiedRoleDefinition{ - unifiedrole.NewViewerUnifiedRole(false), - unifiedrole.NewFileEditorUnifiedRole(false), + unifiedrole.NewViewerUnifiedRole(), + unifiedrole.NewFileEditorUnifiedRole(), }, false, []*libregraph.UnifiedRoleDefinition{ - unifiedrole.NewViewerUnifiedRole(false), - unifiedrole.NewFileEditorUnifiedRole(false), + unifiedrole.NewViewerUnifiedRole(), + unifiedrole.NewFileEditorUnifiedRole(), }, ), Entry("descending", []*libregraph.UnifiedRoleDefinition{ - unifiedrole.NewViewerUnifiedRole(false), - unifiedrole.NewFileEditorUnifiedRole(false), + unifiedrole.NewViewerUnifiedRole(), + unifiedrole.NewFileEditorUnifiedRole(), }, true, []*libregraph.UnifiedRoleDefinition{ - unifiedrole.NewFileEditorUnifiedRole(false), - unifiedrole.NewViewerUnifiedRole(false), + unifiedrole.NewFileEditorUnifiedRole(), + unifiedrole.NewViewerUnifiedRole(), }, ), ) @@ -108,9 +108,9 @@ var _ = Describe("unifiedroles", func() { } DescribeTable("GetApplicableRoleDefinitionsForActions", - func(givenActions []string, constraints string, resharing bool, expectedDefinitions []*libregraph.UnifiedRoleDefinition) { + func(givenActions []string, constraints string, expectedDefinitions []*libregraph.UnifiedRoleDefinition) { - generatedDefinitions := unifiedrole.GetApplicableRoleDefinitionsForActions(givenActions, constraints, resharing, false) + generatedDefinitions := unifiedrole.GetApplicableRoleDefinitionsForActions(givenActions, constraints, false) Expect(len(generatedDefinitions)).To(Equal(len(expectedDefinitions))) @@ -129,90 +129,82 @@ var _ = Describe("unifiedroles", func() { Entry( "ViewerUnifiedRole", - rolesToAction(unifiedrole.NewViewerUnifiedRole(false)), + rolesToAction(unifiedrole.NewViewerUnifiedRole()), unifiedrole.UnifiedRoleConditionGrantee, - false, []*libregraph.UnifiedRoleDefinition{ - unifiedrole.NewViewerUnifiedRole(false), + unifiedrole.NewViewerUnifiedRole(), }, ), Entry( "ViewerUnifiedRole | share", - rolesToAction(unifiedrole.NewViewerUnifiedRole(true)), + rolesToAction(unifiedrole.NewViewerUnifiedRole()), unifiedrole.UnifiedRoleConditionGrantee, - true, []*libregraph.UnifiedRoleDefinition{ - unifiedrole.NewViewerUnifiedRole(true), + unifiedrole.NewViewerUnifiedRole(), }, ), Entry( "NewFileEditorUnifiedRole", - rolesToAction(unifiedrole.NewFileEditorUnifiedRole(false)), + rolesToAction(unifiedrole.NewFileEditorUnifiedRole()), unifiedrole.UnifiedRoleConditionGrantee, - false, []*libregraph.UnifiedRoleDefinition{ - unifiedrole.NewViewerUnifiedRole(false), - unifiedrole.NewFileEditorUnifiedRole(false), + unifiedrole.NewViewerUnifiedRole(), + unifiedrole.NewFileEditorUnifiedRole(), }, ), Entry( "NewFileEditorUnifiedRole - share", - rolesToAction(unifiedrole.NewFileEditorUnifiedRole(true)), + rolesToAction(unifiedrole.NewFileEditorUnifiedRole()), unifiedrole.UnifiedRoleConditionGrantee, - true, []*libregraph.UnifiedRoleDefinition{ - unifiedrole.NewViewerUnifiedRole(true), - unifiedrole.NewFileEditorUnifiedRole(true), + unifiedrole.NewViewerUnifiedRole(), + unifiedrole.NewFileEditorUnifiedRole(), }, ), Entry( "NewEditorUnifiedRole", - rolesToAction(unifiedrole.NewEditorUnifiedRole(false)), + rolesToAction(unifiedrole.NewEditorUnifiedRole()), unifiedrole.UnifiedRoleConditionGrantee, - false, []*libregraph.UnifiedRoleDefinition{ unifiedrole.NewUploaderUnifiedRole(), - unifiedrole.NewViewerUnifiedRole(false), - unifiedrole.NewFileEditorUnifiedRole(false), - unifiedrole.NewEditorUnifiedRole(false), + unifiedrole.NewViewerUnifiedRole(), + unifiedrole.NewFileEditorUnifiedRole(), + unifiedrole.NewEditorUnifiedRole(), }, ), Entry( "NewEditorUnifiedRole - share", - rolesToAction(unifiedrole.NewEditorUnifiedRole(true)), + rolesToAction(unifiedrole.NewEditorUnifiedRole()), unifiedrole.UnifiedRoleConditionGrantee, - true, []*libregraph.UnifiedRoleDefinition{ unifiedrole.NewUploaderUnifiedRole(), - unifiedrole.NewViewerUnifiedRole(true), - unifiedrole.NewFileEditorUnifiedRole(true), - unifiedrole.NewEditorUnifiedRole(true), + unifiedrole.NewViewerUnifiedRole(), + unifiedrole.NewFileEditorUnifiedRole(), + unifiedrole.NewEditorUnifiedRole(), }, ), Entry( "GetBuiltinRoleDefinitionList", - rolesToAction(unifiedrole.GetBuiltinRoleDefinitionList(false)...), + rolesToAction(unifiedrole.GetBuiltinRoleDefinitionList()...), unifiedrole.UnifiedRoleConditionGrantee, - false, []*libregraph.UnifiedRoleDefinition{ unifiedrole.NewUploaderUnifiedRole(), - unifiedrole.NewViewerUnifiedRole(false), - unifiedrole.NewFileEditorUnifiedRole(false), - unifiedrole.NewEditorUnifiedRole(false), + unifiedrole.NewViewerUnifiedRole(), + unifiedrole.NewFileEditorUnifiedRole(), + unifiedrole.NewEditorUnifiedRole(), }, ), Entry( "GetBuiltinRoleDefinitionList", - rolesToAction(unifiedrole.GetBuiltinRoleDefinitionList(false)...), + rolesToAction(unifiedrole.GetBuiltinRoleDefinitionList()...), unifiedrole.UnifiedRoleConditionOwner, - false, []*libregraph.UnifiedRoleDefinition{ unifiedrole.NewSpaceViewerUnifiedRole(), unifiedrole.NewSpaceEditorUnifiedRole(), @@ -222,14 +214,13 @@ var _ = Describe("unifiedroles", func() { Entry( "GetBuiltinRoleDefinitionList - share", - rolesToAction(unifiedrole.GetBuiltinRoleDefinitionList(true)...), + rolesToAction(unifiedrole.GetBuiltinRoleDefinitionList()...), unifiedrole.UnifiedRoleConditionGrantee, - true, []*libregraph.UnifiedRoleDefinition{ unifiedrole.NewUploaderUnifiedRole(), - unifiedrole.NewViewerUnifiedRole(true), - unifiedrole.NewFileEditorUnifiedRole(true), - unifiedrole.NewEditorUnifiedRole(true), + unifiedrole.NewViewerUnifiedRole(), + unifiedrole.NewFileEditorUnifiedRole(), + unifiedrole.NewEditorUnifiedRole(), }, ), @@ -237,7 +228,6 @@ var _ = Describe("unifiedroles", func() { "single", []string{unifiedrole.DriveItemQuotaRead}, unifiedrole.UnifiedRoleConditionGrantee, - true, []*libregraph.UnifiedRoleDefinition{}, ), @@ -245,7 +235,6 @@ var _ = Describe("unifiedroles", func() { "mixed", append(rolesToAction(unifiedrole.NewUploaderUnifiedRole()), unifiedrole.DriveItemQuotaRead), unifiedrole.UnifiedRoleConditionGrantee, - true, []*libregraph.UnifiedRoleDefinition{ unifiedrole.NewUploaderUnifiedRole(), }, @@ -255,29 +244,26 @@ var _ = Describe("unifiedroles", func() { { var newUnifiedRoleFromIDEntries []TableEntry - for _, resharing := range []bool{true, false} { - attachEntry := func(name, id string, definition *libregraph.UnifiedRoleDefinition, errors bool) { - e := Entry( - fmt.Sprintf("%s - resharing: %t", name, resharing), - id, - resharing, - definition, - errors, - ) + attachEntry := func(name, id string, definition *libregraph.UnifiedRoleDefinition, errors bool) { + e := Entry( + fmt.Sprintf("%s", name), + id, + definition, + errors, + ) - newUnifiedRoleFromIDEntries = append(newUnifiedRoleFromIDEntries, e) - } - - for _, definition := range unifiedrole.GetBuiltinRoleDefinitionList(resharing) { - attachEntry(definition.GetDisplayName(), definition.GetId(), definition, false) - } - - attachEntry("unknown", "123", nil, true) + newUnifiedRoleFromIDEntries = append(newUnifiedRoleFromIDEntries, e) } + for _, definition := range unifiedrole.GetBuiltinRoleDefinitionList() { + attachEntry(definition.GetDisplayName(), definition.GetId(), definition, false) + } + + attachEntry("unknown", "123", nil, true) + DescribeTable("NewUnifiedRoleFromID", - func(id string, resharing bool, expectedRole *libregraph.UnifiedRoleDefinition, expectError bool) { - role, err := unifiedrole.NewUnifiedRoleFromID(id, resharing) + func(id string, expectedRole *libregraph.UnifiedRoleDefinition, expectError bool) { + role, err := unifiedrole.NewUnifiedRoleFromID(id) if expectError { Expect(err).To(HaveOccurred()) diff --git a/services/graph/pkg/validate/libregraph.go b/services/graph/pkg/validate/libregraph.go index a727a5bbf..fa316d141 100644 --- a/services/graph/pkg/validate/libregraph.go +++ b/services/graph/pkg/validate/libregraph.go @@ -84,8 +84,8 @@ func rolesAndActions(sl validator.StructLevel, roles, actions []string, allowEmp var availableRoles []string var availableActions []string for _, definition := range append( - unifiedrole.GetBuiltinRoleDefinitionList(true), - unifiedrole.GetBuiltinRoleDefinitionList(false)..., + unifiedrole.GetBuiltinRoleDefinitionList(), + unifiedrole.GetBuiltinRoleDefinitionList()..., ) { if slices.Contains(availableRoles, definition.GetId()) { continue diff --git a/services/sharing/pkg/config/config.go b/services/sharing/pkg/config/config.go index 9ba270cb8..3561802b7 100644 --- a/services/sharing/pkg/config/config.go +++ b/services/sharing/pkg/config/config.go @@ -21,8 +21,6 @@ type Config struct { SkipUserGroupsInToken bool `yaml:"skip_user_groups_in_token" env:"SHARING_SKIP_USER_GROUPS_IN_TOKEN" desc:"Disables the loading of user's group memberships from the reva access token." introductionVersion:"pre5.0"` - EnableResharing bool `yaml:"enable_resharing" env:"OCIS_ENABLE_RESHARING;SHARING_ENABLE_RESHARING" desc:"Changing this value is NOT supported. Enables the support for resharing." introductionVersion:"5.0" deprecationVersion:"5.0" deprecationInfo:"Resharing will be removed in the future."` - UserSharingDriver string `yaml:"user_sharing_driver" env:"SHARING_USER_DRIVER" desc:"Driver to be used to persist shares. Supported values are 'jsoncs3', 'json', 'cs3' (deprecated) and 'owncloudsql'." introductionVersion:"pre5.0"` UserSharingDrivers UserSharingDrivers `yaml:"user_sharing_drivers"` PublicSharingDriver string `yaml:"public_sharing_driver" env:"SHARING_PUBLIC_DRIVER" desc:"Driver to be used to persist public shares. Supported values are 'jsoncs3', 'json' and 'cs3' (deprecated)." introductionVersion:"pre5.0"` diff --git a/services/sharing/pkg/config/defaults/defaultconfig.go b/services/sharing/pkg/config/defaults/defaultconfig.go index 6f0994fa2..57026e0b9 100644 --- a/services/sharing/pkg/config/defaults/defaultconfig.go +++ b/services/sharing/pkg/config/defaults/defaultconfig.go @@ -35,7 +35,6 @@ func DefaultConfig() *config.Config { Name: "sharing", }, Reva: shared.DefaultRevaConfig(), - EnableResharing: false, UserSharingDriver: "jsoncs3", UserSharingDrivers: config.UserSharingDrivers{ JSON: config.UserSharingJSONDriver{ diff --git a/services/sharing/pkg/revaconfig/config.go b/services/sharing/pkg/revaconfig/config.go index d13427f2f..8f02b796d 100644 --- a/services/sharing/pkg/revaconfig/config.go +++ b/services/sharing/pkg/revaconfig/config.go @@ -86,7 +86,6 @@ func SharingConfigFromStruct(cfg *config.Config, logger log.Logger) (map[string] }, }, }, - "disable_resharing": !cfg.EnableResharing, }, "publicshareprovider": map[string]interface{}{ "gateway_addr": cfg.Reva.Address, diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/ocmshareprovider/ocmshareprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/ocmshareprovider/ocmshareprovider.go index 0f68136fd..5c5824540 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/ocmshareprovider/ocmshareprovider.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/ocmshareprovider/ocmshareprovider.go @@ -327,7 +327,7 @@ func (s *service) CreateOCMShare(ctx context.Context, req *ocm.CreateOCMShareReq ProviderID: ocmshare.Id.OpaqueId, Owner: formatOCMUser(&userpb.UserId{ OpaqueId: info.Owner.OpaqueId, - Idp: s.conf.ProviderDomain, // FIXME: this is not generally true in case of resharing + Idp: s.conf.ProviderDomain, }), Sender: formatOCMUser(&userpb.UserId{ OpaqueId: user.Id.OpaqueId, diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go index 3df749f88..b987b96ac 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go @@ -593,7 +593,7 @@ func isInternalLink(req *link.UpdatePublicShareRequest, ps *link.PublicShare) bo } func enforcePassword(canOptOut bool, permissions *provider.ResourcePermissions, conf *config) bool { - isReadOnly := conversions.SufficientCS3Permissions(conversions.NewViewerRole(true).CS3ResourcePermissions(), permissions) + isReadOnly := conversions.SufficientCS3Permissions(conversions.NewViewerRole().CS3ResourcePermissions(), permissions) if isReadOnly && canOptOut { return false } diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/usershareprovider/usershareprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/usershareprovider/usershareprovider.go index 0c503e7cc..779409faa 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/usershareprovider/usershareprovider.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/usershareprovider/usershareprovider.go @@ -55,7 +55,6 @@ type config struct { Drivers map[string]map[string]interface{} `mapstructure:"drivers"` GatewayAddr string `mapstructure:"gateway_addr"` AllowedPathsForShares []string `mapstructure:"allowed_paths_for_shares"` - DisableResharing bool `mapstructure:"disable_resharing"` } func (c *config) init() { @@ -68,7 +67,6 @@ type service struct { sm share.Manager gatewaySelector pool.Selectable[gateway.GatewayAPIClient] allowedPathsForShares []*regexp.Regexp - disableResharing bool } func getShareManager(c *config) (share.Manager, error) { @@ -129,16 +127,15 @@ func NewDefault(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error return nil, err } - return New(gatewaySelector, sm, allowedPathsForShares, c.DisableResharing), nil + return New(gatewaySelector, sm, allowedPathsForShares), nil } // New creates a new user share provider svc -func New(gatewaySelector pool.Selectable[gateway.GatewayAPIClient], sm share.Manager, allowedPathsForShares []*regexp.Regexp, disableResharing bool) rgrpc.Service { +func New(gatewaySelector pool.Selectable[gateway.GatewayAPIClient], sm share.Manager, allowedPathsForShares []*regexp.Regexp) rgrpc.Service { service := &service{ sm: sm, gatewaySelector: gatewaySelector, allowedPathsForShares: allowedPathsForShares, - disableResharing: disableResharing, } return service @@ -160,8 +157,8 @@ func (s *service) CreateShare(ctx context.Context, req *collaboration.CreateShar log := appctx.GetLogger(ctx) user := ctxpkg.ContextMustGetUser(ctx) - // when resharing is disabled grants must not allow grant permissions - if s.disableResharing && HasGrantPermissions(req.GetGrant().GetPermissions().GetPermissions()) { + // Grants must not allow grant permissions + if HasGrantPermissions(req.GetGrant().GetPermissions().GetPermissions()) { return &collaboration.CreateShareResponse{ Status: status.NewInvalidArg(ctx, "resharing not supported"), }, nil @@ -342,8 +339,8 @@ func (s *service) UpdateShare(ctx context.Context, req *collaboration.UpdateShar log := appctx.GetLogger(ctx) user := ctxpkg.ContextMustGetUser(ctx) - // when resharing is disabled grants must not allow grant permissions - if s.disableResharing && HasGrantPermissions(req.GetShare().GetPermissions().GetPermissions()) { + // Grants must not allow grant permissions + if HasGrantPermissions(req.GetShare().GetPermissions().GetPermissions()) { return &collaboration.UpdateShareResponse{ Status: status.NewInvalidArg(ctx, "resharing not supported"), }, nil diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/data/capabilities.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/data/capabilities.go index 369ca2317..82e2fdf2b 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/data/capabilities.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/data/capabilities.go @@ -209,7 +209,6 @@ type CapabilitiesDav struct { // CapabilitiesFilesSharing TODO document type CapabilitiesFilesSharing struct { APIEnabled ocsBool `json:"api_enabled" xml:"api_enabled" mapstructure:"api_enabled"` - Resharing ocsBool `json:"resharing" xml:"resharing"` GroupSharing ocsBool `json:"group_sharing" xml:"group_sharing" mapstructure:"group_sharing"` SharingRoles ocsBool `json:"sharing_roles" xml:"sharing_roles" mapstructure:"sharing_roles"` DenyAccess ocsBool `json:"deny_access" xml:"deny_access" mapstructure:"deny_access"` @@ -222,6 +221,8 @@ type CapabilitiesFilesSharing struct { Federation *CapabilitiesFilesSharingFederation `json:"federation" xml:"federation"` Public *CapabilitiesFilesSharingPublic `json:"public" xml:"public"` User *CapabilitiesFilesSharingUser `json:"user" xml:"user"` + // TODO: Remove next line once web defaults to resharing=false + Resharing ocsBool `json:"resharing" xml:"resharing"` } // CapabilitiesFilesSharingPublic TODO document diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go index 694273866..4a46ebaa1 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go @@ -69,8 +69,6 @@ import ( const ( storageIDPrefix string = "shared::" - - _resharingDefault bool = false ) var ( @@ -92,7 +90,6 @@ type Handler struct { userIdentifierCache *ttlcache.Cache statCache cache.StatCache deniable bool - resharing bool publicPasswordEnforced passwordEnforced passwordValidator password.Validator @@ -146,7 +143,6 @@ func (h *Handler) Init(c *config.Config) error { h.userIdentifierCache = ttlcache.NewCache() _ = h.userIdentifierCache.SetTTL(time.Second * time.Duration(c.UserIdentifierCacheTTL)) h.deniable = c.EnableDenials - h.resharing = resharing(c) h.publicPasswordEnforced = publicPwdEnforced(c) h.passwordValidator = passwordPolicies(c) @@ -292,6 +288,12 @@ func (h *Handler) CreateShare(w http.ResponseWriter, r *http.Request) { return } + // resharing is forbidden + if role.CS3ResourcePermissions().GetAddGrant() { + response.WriteOCSError(w, r, response.MetaBadRequest.StatusCode, "resharing not supported", nil) + return + } + var share *collaboration.Share if shareType == int(conversions.ShareTypeUser) { share, ocsErr = h.createUserShare(w, r, statRes.Info, role, val) @@ -320,7 +322,7 @@ func (h *Handler) CreateShare(w http.ResponseWriter, r *http.Request) { response.WriteOCSSuccess(w, r, s) case int(conversions.ShareTypePublicLink): // public links default to read only - _, _, ocsErr := h.extractPermissions(reqRole, reqPermissions, statRes.Info, conversions.NewViewerRole(h.resharing)) + _, _, ocsErr := h.extractPermissions(reqRole, reqPermissions, statRes.Info, conversions.NewViewerRole()) if ocsErr != nil && ocsErr.Error != conversions.ErrZeroPermission { response.WriteOCSError(w, r, http.StatusForbidden, "No share permission", nil) return @@ -339,7 +341,7 @@ func (h *Handler) CreateShare(w http.ResponseWriter, r *http.Request) { response.WriteOCSSuccess(w, r, s) case int(conversions.ShareTypeFederatedCloudShare): // federated shares default to read only - if role, val, err := h.extractPermissions(reqRole, reqPermissions, statRes.Info, conversions.NewViewerRole(h.resharing)); err == nil { + if role, val, err := h.extractPermissions(reqRole, reqPermissions, statRes.Info, conversions.NewViewerRole()); err == nil { h.createFederatedCloudShare(w, r, statRes.Info, role, val) } case int(conversions.ShareTypeSpaceMembershipUser), int(conversions.ShareTypeSpaceMembershipGroup): @@ -429,7 +431,7 @@ func (h *Handler) extractPermissions(reqRole string, reqPermissions string, ri * // the share role overrides the requested permissions if reqRole != "" { - role = conversions.RoleFromName(reqRole, h.resharing) + role = conversions.RoleFromName(reqRole) } // if the role is unknown - fall back to reqPermissions or defaultPermissions @@ -1685,10 +1687,3 @@ func sufficientPermissions(existing, requested *provider.ResourcePermissions, is rp := conversions.RoleFromResourcePermissions(requested, islink).OCSPermissions() return ep.Contain(rp) } - -func resharing(c *config.Config) bool { - if c != nil && c.Capabilities.Capabilities != nil && c.Capabilities.Capabilities.FilesSharing != nil { - return bool(c.Capabilities.Capabilities.FilesSharing.Resharing) - } - return _resharingDefault -} diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/sciencemesh/share.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/sciencemesh/share.go index af51c5e6b..c5bc78e56 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/sciencemesh/share.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/sciencemesh/share.go @@ -150,9 +150,9 @@ func (h *sharesHandler) CreateShare(w http.ResponseWriter, r *http.Request) { func getPermissionsByRole(role string) (*providerpb.ResourcePermissions, appprovider.ViewMode) { switch role { case "viewer": - return conversions.NewViewerRole(false).CS3ResourcePermissions(), appprovider.ViewMode_VIEW_MODE_READ_ONLY + return conversions.NewViewerRole().CS3ResourcePermissions(), appprovider.ViewMode_VIEW_MODE_READ_ONLY case "editor": - return conversions.NewEditorRole(false).CS3ResourcePermissions(), appprovider.ViewMode_VIEW_MODE_READ_WRITE + return conversions.NewEditorRole().CS3ResourcePermissions(), appprovider.ViewMode_VIEW_MODE_READ_WRITE } return nil, 0 } diff --git a/vendor/github.com/cs3org/reva/v2/pkg/cbox/utils/conversions.go b/vendor/github.com/cs3org/reva/v2/pkg/cbox/utils/conversions.go index a2cc7d181..b94b50b3b 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/cbox/utils/conversions.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/cbox/utils/conversions.go @@ -145,12 +145,12 @@ func SharePermToInt(p *provider.ResourcePermissions) int { func IntTosharePerm(p int, itemType string) *provider.ResourcePermissions { switch p { case 1: - return conversions.NewViewerRole(false).CS3ResourcePermissions() + return conversions.NewViewerRole().CS3ResourcePermissions() case 15: if itemType == "folder" { - return conversions.NewEditorRole(false).CS3ResourcePermissions() + return conversions.NewEditorRole().CS3ResourcePermissions() } - return conversions.NewFileEditorRole(false).CS3ResourcePermissions() + return conversions.NewFileEditorRole().CS3ResourcePermissions() case 4: return conversions.NewUploaderRole().CS3ResourcePermissions() default: diff --git a/vendor/github.com/cs3org/reva/v2/pkg/conversions/role.go b/vendor/github.com/cs3org/reva/v2/pkg/conversions/role.go index cbde91bff..29621c4aa 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/conversions/role.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/conversions/role.go @@ -141,20 +141,20 @@ func (r *Role) WebDAVPermissions(isDir, isShared, isMountpoint, isPublic bool) s } // RoleFromName creates a role from the name -func RoleFromName(name string, sharing bool) *Role { +func RoleFromName(name string) *Role { switch name { case RoleDenied: return NewDeniedRole() case RoleViewer: - return NewViewerRole(sharing) + return NewViewerRole() case RoleSpaceViewer: return NewSpaceViewerRole() case RoleEditor: - return NewEditorRole(sharing) + return NewEditorRole() case RoleSpaceEditor: return NewSpaceEditorRole() case RoleFileEditor: - return NewFileEditorRole(sharing) + return NewFileEditorRole() case RoleUploader: return NewUploaderRole() case RoleManager: @@ -183,15 +183,11 @@ func NewDeniedRole() *Role { } // NewViewerRole creates a viewer role. `sharing` indicates if sharing permission should be added -func NewViewerRole(sharing bool) *Role { +func NewViewerRole() *Role { p := PermissionRead - if sharing { - p |= PermissionShare - } return &Role{ Name: RoleViewer, cS3ResourcePermissions: &provider.ResourcePermissions{ - AddGrant: sharing, GetPath: true, GetQuota: true, InitiateFileDownload: true, @@ -221,15 +217,11 @@ func NewSpaceViewerRole() *Role { } // NewEditorRole creates an editor role. `sharing` indicates if sharing permission should be added -func NewEditorRole(sharing bool) *Role { +func NewEditorRole() *Role { p := PermissionRead | PermissionCreate | PermissionWrite | PermissionDelete - if sharing { - p |= PermissionShare - } return &Role{ Name: RoleEditor, cS3ResourcePermissions: &provider.ResourcePermissions{ - AddGrant: sharing, CreateContainer: true, Delete: true, GetPath: true, @@ -271,15 +263,11 @@ func NewSpaceEditorRole() *Role { } // NewFileEditorRole creates a file-editor role -func NewFileEditorRole(sharing bool) *Role { +func NewFileEditorRole() *Role { p := PermissionRead | PermissionWrite - if sharing { - p |= PermissionShare - } return &Role{ Name: RoleEditor, cS3ResourcePermissions: &provider.ResourcePermissions{ - AddGrant: sharing, GetPath: true, GetQuota: true, InitiateFileDownload: true, @@ -378,34 +366,30 @@ func NewManagerRole() *Role { // RoleFromOCSPermissions tries to map ocs permissions to a role // TODO: rethink using this. ocs permissions cannot be assigned 1:1 to roles func RoleFromOCSPermissions(p Permissions, ri *provider.ResourceInfo) *Role { - if p == PermissionInvalid { + switch { + // Invalid + case p == PermissionInvalid: return NewNoneRole() - } - - if p.Contain(PermissionRead) { - if p.Contain(PermissionWrite) && p.Contain(PermissionCreate) && p.Contain(PermissionDelete) { - if p.Contain(PermissionShare) { - return NewEditorRole(true) - } - - if isSpaceRoot(ri) { - return NewSpaceEditorRole() - } - } - - if p == PermissionRead && isSpaceRoot(ri) { + // Uploader + case p == PermissionCreate: + return NewUploaderRole() + // Viewer/SpaceViewer + case p == PermissionRead: + if isSpaceRoot(ri) { return NewSpaceViewerRole() } - - if p == PermissionRead|PermissionShare && !isSpaceRoot(ri) { - return NewViewerRole(true) + return NewViewerRole() + // Editor/SpaceEditor + case p.Contain(PermissionRead) && p.Contain(PermissionWrite) && p.Contain(PermissionCreate) && p.Contain(PermissionDelete) && !p.Contain(PermissionShare): + if isSpaceRoot(ri) { + return NewSpaceEditorRole() } + + return NewEditorRole() + // Custom + default: + return NewLegacyRoleFromOCSPermissions(p) } - if p == PermissionCreate { - return NewUploaderRole() - } - // legacy - return NewLegacyRoleFromOCSPermissions(p) } func isSpaceRoot(ri *provider.ResourceInfo) bool { diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/eosfs/eosfs.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/eosfs/eosfs.go index 50f9493f8..2d11ecdfa 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/eosfs/eosfs.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/eosfs/eosfs.go @@ -83,8 +83,6 @@ const LockTypeKey = "reva.lock.type" var hiddenReg = regexp.MustCompile(`\.sys\..#.`) -var _resharing = false - func (c *Config) init() { c.Namespace = path.Clean(c.Namespace) if !strings.HasPrefix(c.Namespace, "/") { @@ -2129,12 +2127,12 @@ func (fs *eosfs) permissionSet(ctx context.Context, eosFileInfo *eosclient.FileI // The role names should not be hardcoded any more as they will come from config in the future if publicShare, ok := u.Opaque.Map["public-share-role"]; ok { if string(publicShare.Value) == "editor" { - return conversions.NewEditorRole(_resharing).CS3ResourcePermissions() + return conversions.NewEditorRole().CS3ResourcePermissions() } else if string(publicShare.Value) == "uploader" { return conversions.NewUploaderRole().CS3ResourcePermissions() } // Default to viewer role - return conversions.NewViewerRole(_resharing).CS3ResourcePermissions() + return conversions.NewViewerRole().CS3ResourcePermissions() } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 3dfd253a3..e1b112c0d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -366,7 +366,7 @@ github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1 github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1 github.com/cs3org/go-cs3apis/cs3/tx/v1beta1 github.com/cs3org/go-cs3apis/cs3/types/v1beta1 -# github.com/cs3org/reva/v2 v2.19.2-0.20240328104440-9c04f2d8ab7e +# github.com/cs3org/reva/v2 v2.19.2-0.20240404085416-251ba8d12f6f ## explicit; go 1.21 github.com/cs3org/reva/v2/cmd/revad/internal/grace github.com/cs3org/reva/v2/cmd/revad/runtime