diff --git a/go.mod b/go.mod index b2f7540fa4..cfca2e8e83 100644 --- a/go.mod +++ b/go.mod @@ -64,7 +64,7 @@ require ( github.com/open-policy-agent/opa v1.15.2 github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d - github.com/opencloud-eu/reva/v2 v2.46.3-0.20260610093751-a33d8108dd91 + github.com/opencloud-eu/reva/v2 v2.46.3-0.20260611095012-6617969b3720 github.com/opensearch-project/opensearch-go/v4 v4.6.0 github.com/orcaman/concurrent-map v1.0.0 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index 9d30b7b4cc..e39c8fddf7 100644 --- a/go.sum +++ b/go.sum @@ -948,8 +948,8 @@ github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 h1:W1ms+l github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89/go.mod h1:vigJkNss1N2QEceCuNw/ullDehncuJNFB6mEnzfq9UI= 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.46.3-0.20260610093751-a33d8108dd91 h1:A/a0d9UNclpNBWGp2NUDWF+qO+U/u38EBH4CIk2dqIE= -github.com/opencloud-eu/reva/v2 v2.46.3-0.20260610093751-a33d8108dd91/go.mod h1:RoFQt+u7edxwzHr1IZ2Y6VaDinMiRPQupAvMBy3WVmE= +github.com/opencloud-eu/reva/v2 v2.46.3-0.20260611095012-6617969b3720 h1:UHJDrOoU9hoVFg0hgKmNIMp0hFEb/reiDYthVHlX5g8= +github.com/opencloud-eu/reva/v2 v2.46.3-0.20260611095012-6617969b3720/go.mod h1:RoFQt+u7edxwzHr1IZ2Y6VaDinMiRPQupAvMBy3WVmE= 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= diff --git a/services/graph/pkg/unifiedrole/conversion.go b/services/graph/pkg/unifiedrole/conversion.go index 457cb5db0f..92dbcf5030 100644 --- a/services/graph/pkg/unifiedrole/conversion.go +++ b/services/graph/pkg/unifiedrole/conversion.go @@ -4,8 +4,8 @@ import ( "strings" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" - "github.com/opencloud-eu/reva/v2/pkg/conversions" libregraph "github.com/opencloud-eu/libre-graph-api-go" + "github.com/opencloud-eu/reva/v2/pkg/conversions" ) // PermissionsToCS3ResourcePermissions converts the provided libregraph UnifiedRolePermissions to a cs3 ResourcePermissions @@ -204,12 +204,16 @@ func cs3RoleToDisplayName(role *conversions.Role) string { switch role.Name { case conversions.RoleViewer: return _viewerUnifiedRoleDisplayName + case conversions.RoleViewerWithVersions: + return _viewerWithVersionsUnifiedRoleDisplayName case conversions.RoleViewerListGrants: return _viewerListGrantsUnifiedRoleDisplayName case conversions.RoleSpaceViewer: return _spaceViewerUnifiedRoleDisplayName case conversions.RoleEditor: return _editorUnifiedRoleDisplayName + case conversions.RoleEditorWithVersions: + return _editorWithVersionsUnifiedRoleDisplayName case conversions.RoleEditorListGrants: return _editorListGrantsUnifiedRoleDisplayName case conversions.RoleSpaceEditor: @@ -218,6 +222,8 @@ func cs3RoleToDisplayName(role *conversions.Role) string { return _spaceEditorWithoutVersionsUnifiedRoleDisplayName case conversions.RoleFileEditor: return _fileEditorUnifiedRoleDisplayName + case conversions.RoleFileEditorWithVersions: + return _fileEditorWithVersionsUnifiedRoleDisplayName case conversions.RoleFileEditorListGrants: return _fileEditorListGrantsUnifiedRoleDisplayName case conversions.RoleEditorLite: diff --git a/services/graph/pkg/unifiedrole/conversion_test.go b/services/graph/pkg/unifiedrole/conversion_test.go index 3591b88a36..6ba6888078 100644 --- a/services/graph/pkg/unifiedrole/conversion_test.go +++ b/services/graph/pkg/unifiedrole/conversion_test.go @@ -6,8 +6,8 @@ import ( provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" . "github.com/onsi/gomega" "github.com/onsi/gomega/types" - cs3Conversions "github.com/opencloud-eu/reva/v2/pkg/conversions" libregraph "github.com/opencloud-eu/libre-graph-api-go" + cs3Conversions "github.com/opencloud-eu/reva/v2/pkg/conversions" "github.com/opencloud-eu/opencloud/pkg/conversions" "github.com/opencloud-eu/opencloud/services/graph/pkg/unifiedrole" @@ -19,16 +19,19 @@ func TestPermissionsToCS3ResourcePermissions(t *testing.T) { unifiedRoleDefinition *libregraph.UnifiedRoleDefinition match bool }{ - cs3Conversions.RoleViewer: {cs3Conversions.NewViewerRole(), unifiedrole.RoleViewer, true}, - cs3Conversions.RoleViewerListGrants: {cs3Conversions.NewViewerListGrantsRole(), unifiedrole.RoleViewerListGrants, true}, - cs3Conversions.RoleEditor: {cs3Conversions.NewEditorRole(), unifiedrole.RoleEditor, true}, - cs3Conversions.RoleEditorListGrants: {cs3Conversions.NewEditorListGrantsRole(), unifiedrole.RoleEditorListGrants, true}, - cs3Conversions.RoleFileEditor: {cs3Conversions.NewFileEditorRole(), unifiedrole.RoleFileEditor, true}, - cs3Conversions.RoleFileEditorListGrants: {cs3Conversions.NewFileEditorListGrantsRole(), unifiedrole.RoleFileEditorListGrants, true}, - cs3Conversions.RoleManager: {cs3Conversions.NewManagerRole(), unifiedrole.RoleManager, true}, - cs3Conversions.RoleSecureViewer: {cs3Conversions.NewSecureViewerRole(), unifiedrole.RoleSecureViewer, true}, - cs3Conversions.RoleDenied: {cs3Conversions.NewDeniedRole(), unifiedrole.RoleDenied, true}, - "no match": {cs3Conversions.NewFileEditorRole(), unifiedrole.RoleManager, false}, + cs3Conversions.RoleViewer: {cs3Conversions.NewViewerRole(), unifiedrole.RoleViewer, true}, + cs3Conversions.RoleViewerWithVersions: {cs3Conversions.NewViewerWithVersionsRole(), unifiedrole.RoleViewerWithVersions, true}, + cs3Conversions.RoleViewerListGrants: {cs3Conversions.NewViewerListGrantsRole(), unifiedrole.RoleViewerListGrants, true}, + cs3Conversions.RoleEditor: {cs3Conversions.NewEditorRole(), unifiedrole.RoleEditor, true}, + cs3Conversions.RoleEditorWithVersions: {cs3Conversions.NewEditorWithVersionsRole(), unifiedrole.RoleEditorWithVersions, true}, + cs3Conversions.RoleEditorListGrants: {cs3Conversions.NewEditorListGrantsRole(), unifiedrole.RoleEditorListGrants, true}, + cs3Conversions.RoleFileEditor: {cs3Conversions.NewFileEditorRole(), unifiedrole.RoleFileEditor, true}, + cs3Conversions.RoleFileEditorWithVersions: {cs3Conversions.NewFileEditorWithVersionsRole(), unifiedrole.RoleFileEditorWithVersions, true}, + cs3Conversions.RoleFileEditorListGrants: {cs3Conversions.NewFileEditorListGrantsRole(), unifiedrole.RoleFileEditorListGrants, true}, + cs3Conversions.RoleManager: {cs3Conversions.NewManagerRole(), unifiedrole.RoleManager, true}, + cs3Conversions.RoleSecureViewer: {cs3Conversions.NewSecureViewerRole(), unifiedrole.RoleSecureViewer, true}, + cs3Conversions.RoleDenied: {cs3Conversions.NewDeniedRole(), unifiedrole.RoleDenied, true}, + "no match": {cs3Conversions.NewFileEditorRole(), unifiedrole.RoleManager, false}, } for name, tc := range tests { @@ -58,17 +61,21 @@ func TestCS3ResourcePermissionsToRole(t *testing.T) { unifiedRoleDefinition *libregraph.UnifiedRoleDefinition constraints string }{ - cs3Conversions.RoleViewer + "1": {cs3Conversions.NewViewerRole().CS3ResourcePermissions(), unifiedrole.RoleViewer, unifiedrole.UnifiedRoleConditionFile}, - cs3Conversions.RoleViewer + "2": {cs3Conversions.NewViewerRole().CS3ResourcePermissions(), unifiedrole.RoleViewer, unifiedrole.UnifiedRoleConditionFolder}, - cs3Conversions.RoleEditor: {cs3Conversions.NewEditorRole().CS3ResourcePermissions(), unifiedrole.RoleEditor, unifiedrole.UnifiedRoleConditionFolder}, - cs3Conversions.RoleFileEditor: {cs3Conversions.NewFileEditorRole().CS3ResourcePermissions(), unifiedrole.RoleFileEditor, unifiedrole.UnifiedRoleConditionFile}, - cs3Conversions.RoleManager: {cs3Conversions.NewManagerRole().CS3ResourcePermissions(), unifiedrole.RoleManager, unifiedrole.UnifiedRoleConditionDrive}, - cs3Conversions.RoleSpaceViewer: {cs3Conversions.NewSpaceViewerRole().CS3ResourcePermissions(), unifiedrole.RoleSpaceViewer, unifiedrole.UnifiedRoleConditionDrive}, - cs3Conversions.RoleSpaceEditor: {cs3Conversions.NewSpaceEditorRole().CS3ResourcePermissions(), unifiedrole.RoleSpaceEditor, unifiedrole.UnifiedRoleConditionDrive}, - cs3Conversions.RoleSecureViewer + "1": {cs3Conversions.NewSecureViewerRole().CS3ResourcePermissions(), unifiedrole.RoleSecureViewer, unifiedrole.UnifiedRoleConditionFile}, - cs3Conversions.RoleSecureViewer + "2": {cs3Conversions.NewSecureViewerRole().CS3ResourcePermissions(), unifiedrole.RoleSecureViewer, unifiedrole.UnifiedRoleConditionFolder}, - cs3Conversions.RoleDenied: {cs3Conversions.NewDeniedRole().CS3ResourcePermissions(), unifiedrole.RoleDenied, unifiedrole.UnifiedRoleConditionFolder}, - "custom 1": {&provider.ResourcePermissions{GetPath: true}, nil, unifiedrole.UnifiedRoleConditionFolder}, + cs3Conversions.RoleViewer + "1": {cs3Conversions.NewViewerRole().CS3ResourcePermissions(), unifiedrole.RoleViewer, unifiedrole.UnifiedRoleConditionFile}, + cs3Conversions.RoleViewer + "2": {cs3Conversions.NewViewerRole().CS3ResourcePermissions(), unifiedrole.RoleViewer, unifiedrole.UnifiedRoleConditionFolder}, + cs3Conversions.RoleViewerWithVersions + "1": {cs3Conversions.NewViewerWithVersionsRole().CS3ResourcePermissions(), unifiedrole.RoleViewerWithVersions, unifiedrole.UnifiedRoleConditionFile}, + cs3Conversions.RoleViewerWithVersions + "2": {cs3Conversions.NewViewerWithVersionsRole().CS3ResourcePermissions(), unifiedrole.RoleViewerWithVersions, unifiedrole.UnifiedRoleConditionFolder}, + cs3Conversions.RoleEditor: {cs3Conversions.NewEditorRole().CS3ResourcePermissions(), unifiedrole.RoleEditor, unifiedrole.UnifiedRoleConditionFolder}, + cs3Conversions.RoleEditorWithVersions: {cs3Conversions.NewEditorWithVersionsRole().CS3ResourcePermissions(), unifiedrole.RoleEditorWithVersions, unifiedrole.UnifiedRoleConditionFolder}, + cs3Conversions.RoleFileEditor: {cs3Conversions.NewFileEditorRole().CS3ResourcePermissions(), unifiedrole.RoleFileEditor, unifiedrole.UnifiedRoleConditionFile}, + cs3Conversions.RoleFileEditorWithVersions: {cs3Conversions.NewFileEditorWithVersionsRole().CS3ResourcePermissions(), unifiedrole.RoleFileEditorWithVersions, unifiedrole.UnifiedRoleConditionFile}, + cs3Conversions.RoleManager: {cs3Conversions.NewManagerRole().CS3ResourcePermissions(), unifiedrole.RoleManager, unifiedrole.UnifiedRoleConditionDrive}, + cs3Conversions.RoleSpaceViewer: {cs3Conversions.NewSpaceViewerRole().CS3ResourcePermissions(), unifiedrole.RoleSpaceViewer, unifiedrole.UnifiedRoleConditionDrive}, + cs3Conversions.RoleSpaceEditor: {cs3Conversions.NewSpaceEditorRole().CS3ResourcePermissions(), unifiedrole.RoleSpaceEditor, unifiedrole.UnifiedRoleConditionDrive}, + cs3Conversions.RoleSecureViewer + "1": {cs3Conversions.NewSecureViewerRole().CS3ResourcePermissions(), unifiedrole.RoleSecureViewer, unifiedrole.UnifiedRoleConditionFile}, + cs3Conversions.RoleSecureViewer + "2": {cs3Conversions.NewSecureViewerRole().CS3ResourcePermissions(), unifiedrole.RoleSecureViewer, unifiedrole.UnifiedRoleConditionFolder}, + cs3Conversions.RoleDenied: {cs3Conversions.NewDeniedRole().CS3ResourcePermissions(), unifiedrole.RoleDenied, unifiedrole.UnifiedRoleConditionFolder}, + "custom 1": {&provider.ResourcePermissions{GetPath: true}, nil, unifiedrole.UnifiedRoleConditionFolder}, } for name, tc := range tests { diff --git a/services/graph/pkg/unifiedrole/export_test.go b/services/graph/pkg/unifiedrole/export_test.go index bca190a00a..0ef80b3be4 100644 --- a/services/graph/pkg/unifiedrole/export_test.go +++ b/services/graph/pkg/unifiedrole/export_test.go @@ -2,13 +2,16 @@ package unifiedrole var ( RoleViewer = roleViewer + RoleViewerWithVersions = roleViewerWithVersions RoleViewerListGrants = roleViewerListGrants RoleSpaceViewer = roleSpaceViewer RoleEditor = roleEditor + RoleEditorWithVersions = roleEditorWithVersions RoleEditorListGrants = roleEditorListGrants RoleSpaceEditor = roleSpaceEditor RoleSpaceEditorWithoutVersions = roleSpaceEditorWithoutVersions RoleFileEditor = roleFileEditor + RoleFileEditorWithVersions = roleFileEditorWithVersions RoleFileEditorListGrants = roleFileEditorListGrants RoleEditorLite = roleEditorLite RoleManager = roleManager diff --git a/services/graph/pkg/unifiedrole/roles.go b/services/graph/pkg/unifiedrole/roles.go index 5b866e70ef..7e4e1b95aa 100644 --- a/services/graph/pkg/unifiedrole/roles.go +++ b/services/graph/pkg/unifiedrole/roles.go @@ -16,12 +16,16 @@ import ( const ( // UnifiedRoleViewerID Unified role viewer id. UnifiedRoleViewerID = "b1e2218d-eef8-4d4c-b82d-0f1a1b48f3b5" + // UnifiedRoleViewerWithVersionsID Unified role viewer with versions id. + UnifiedRoleViewerWithVersionsID = "d1e2218d-eef8-4d4c-b82d-0f1a1b48f3b5" // UnifiedRoleViewerListGrantsID Unified role viewer id. UnifiedRoleViewerListGrantsID = "d5041006-ebb3-4b4a-b6a4-7c180ecfb17d" // UnifiedRoleSpaceViewerID Unified role space viewer id. UnifiedRoleSpaceViewerID = "a8d5fe5e-96e3-418d-825b-534dbdf22b99" // UnifiedRoleEditorID Unified role editor id. UnifiedRoleEditorID = "fb6c3e19-e378-47e5-b277-9732f9de6e21" + // UnifiedRoleEditorWithVersionsID + UnifiedRoleEditorWithVersionsID = "b8c6e1c9-5d2a-4f0e-9c3b-1a2b3c4d5e6f" // UnifiedRoleEditorListGrantsID Unified role editor id. UnifiedRoleEditorListGrantsID = "e8ea8b21-abd4-45d2-b893-8d1546378e9e" // UnifiedRoleSpaceEditorID Unified role space editor id. @@ -30,6 +34,8 @@ const ( UnifiedRoleSpaceEditorWithoutVersionsID = "3284f2d5-0070-4ad8-ac40-c247f7c1fb27" // UnifiedRoleFileEditorID Unified role file editor id. UnifiedRoleFileEditorID = "2d00ce52-1fc2-4dbc-8b95-a73b73395f5a" + // UnifiedRoleFileEditorWithVersionsID Unified role file editor id. + UnifiedRoleFileEditorWithVersionsID = "3d00ce52-1fc2-4dbc-8b95-a73b73395f5a" // UnifiedRoleFileEditorListGrantsID Unified role file editor id. UnifiedRoleFileEditorListGrantsID = "c1235aea-d106-42db-8458-7d5610fb0a67" // UnifiedRoleEditorLiteID Unified role editor-lite id. @@ -95,7 +101,13 @@ var ( _viewerUnifiedRoleDescription = l10n.Template("View and download.") // UnifiedRole Viewer, Role DisplayName (resolves directly) - _viewerUnifiedRoleDisplayName = l10n.Template("Can view") + _viewerUnifiedRoleDisplayName = l10n.Template("Can view without versions") + + // UnifiedRole ViewerWithVersions, Role Description (resolves directly) + _viewerWithVersionsUnifiedRoleDescription = l10n.Template("View and download including the history.") + + // UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly) + _viewerWithVersionsUnifiedRoleDisplayName = l10n.Template("Can view") // UnifiedRole ViewerListGrants, Role Description (resolves directly) _viewerListGrantsUnifiedRoleDescription = l10n.Template("View, download and show all invited people.") @@ -113,7 +125,13 @@ var ( _editorUnifiedRoleDescription = l10n.Template("View, download, upload, edit, add and delete.") // UnifiedRole Editor, Role DisplayName (resolves directly) - _editorUnifiedRoleDisplayName = l10n.Template("Can edit") + _editorUnifiedRoleDisplayName = l10n.Template("Can edit without history") + + // UnifiedRole Editor, Role Description (resolves directly) + _editorWithVersionsUnifiedRoleDescription = l10n.Template("View, download, upload, edit, add and delete including the history.") + + // UnifiedRole Editor, Role DisplayName (resolves directly) + _editorWithVersionsUnifiedRoleDisplayName = l10n.Template("Can edit") // UnifiedRoleListGrants Editor, Role Description (resolves directly) _editorListGrantsUnifiedRoleDescription = l10n.Template("View, download, upload, edit, add, delete and show all invited people.") @@ -137,11 +155,17 @@ var ( _fileEditorUnifiedRoleDescription = l10n.Template("View, download and edit.") // UnifiedRole FileEditor, Role DisplayName (resolves directly) - _fileEditorUnifiedRoleDisplayName = l10n.Template("Can edit") + _fileEditorUnifiedRoleDisplayName = l10n.Template("Can edit without history") // UnifiedRole FileEditorListGrants, Role Description (resolves directly) _fileEditorListGrantsUnifiedRoleDescription = l10n.Template("View, download, edit and show all invited people.") + // UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly) + _fileEditorWithVersionsUnifiedRoleDisplayName = l10n.Template("Can edit") + + // UnifiedRole FileEditorWithVErsions, Role Description (resolves directly) + _fileEditorWithVersionsUnifiedRoleDescription = l10n.Template("View, download and edit including the history.") + // UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly) _fileEditorListGrantsUnifiedRoleDisplayName = l10n.Template("Can edit") @@ -187,13 +211,16 @@ var ( // buildInRoles contains the built-in roles. buildInRoles = []*libregraph.UnifiedRoleDefinition{ roleViewer, + roleViewerWithVersions, roleViewerListGrants, roleSpaceViewer, roleEditor, roleEditorListGrants, + roleEditorWithVersions, roleSpaceEditor, roleSpaceEditorWithoutVersions, roleFileEditor, + roleFileEditorWithVersions, roleFileEditorListGrants, roleEditorLite, roleManager, @@ -230,6 +257,35 @@ var ( } }() + // roleViewerWithVersions creates a viewer role. + roleViewerWithVersions = func() *libregraph.UnifiedRoleDefinition { + r := conversions.NewViewerWithVersionsRole() + return &libregraph.UnifiedRoleDefinition{ + Id: proto.String(UnifiedRoleViewerWithVersionsID), + Description: proto.String(_viewerWithVersionsUnifiedRoleDescription), + DisplayName: proto.String(cs3RoleToDisplayName(r)), + RolePermissions: []libregraph.UnifiedRolePermission{ + { + AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()), + Condition: proto.String(UnifiedRoleConditionFile), + }, + { + AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()), + Condition: proto.String(UnifiedRoleConditionFolder), + }, + { + AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()), + Condition: proto.String(UnifiedRoleConditionFileFederatedUser), + }, + { + AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()), + Condition: proto.String(UnifiedRoleConditionFolderFederatedUser), + }, + }, + LibreGraphWeight: proto.Int32(11), + } + }() + // roleSecureViewer creates a secure viewer role roleSecureViewer = func() *libregraph.UnifiedRoleDefinition { r := conversions.NewSecureViewerRole() @@ -356,6 +412,26 @@ var ( } }() + roleEditorWithVersions = func() *libregraph.UnifiedRoleDefinition { + r := conversions.NewEditorWithVersionsRole() + return &libregraph.UnifiedRoleDefinition{ + Id: proto.String(UnifiedRoleEditorWithVersionsID), + Description: proto.String(_editorWithVersionsUnifiedRoleDescription), + DisplayName: proto.String(cs3RoleToDisplayName(r)), + RolePermissions: []libregraph.UnifiedRolePermission{ + { + AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()), + Condition: proto.String(UnifiedRoleConditionFolder), + }, + { + AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()), + Condition: proto.String(UnifiedRoleConditionFolderFederatedUser), + }, + }, + LibreGraphWeight: proto.Int32(71), + } + }() + // roleSpaceEditorWithoutVersions creates an editor without versions role roleSpaceEditorWithoutVersions = func() *libregraph.UnifiedRoleDefinition { r := conversions.NewSpaceEditorWithoutVersionsRole() @@ -411,6 +487,27 @@ var ( } }() + // roleFileEditorWithVersions creates a file-editor role + roleFileEditorWithVersions = func() *libregraph.UnifiedRoleDefinition { + r := conversions.NewFileEditorWithVersionsRole() + return &libregraph.UnifiedRoleDefinition{ + Id: proto.String(UnifiedRoleFileEditorWithVersionsID), + Description: proto.String(_fileEditorWithVersionsUnifiedRoleDescription), + DisplayName: proto.String(cs3RoleToDisplayName(r)), + RolePermissions: []libregraph.UnifiedRolePermission{ + { + AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()), + Condition: proto.String(UnifiedRoleConditionFile), + }, + { + AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()), + Condition: proto.String(UnifiedRoleConditionFileFederatedUser), + }, + }, + LibreGraphWeight: proto.Int32(101), + } + }() + // roleFileEditorListGrants creates a file-editor role roleFileEditorListGrants = func() *libregraph.UnifiedRoleDefinition { r := conversions.NewFileEditorListGrantsRole() diff --git a/services/graph/pkg/unifiedrole/roles_test.go b/services/graph/pkg/unifiedrole/roles_test.go index aae4733a4a..a286ed945a 100644 --- a/services/graph/pkg/unifiedrole/roles_test.go +++ b/services/graph/pkg/unifiedrole/roles_test.go @@ -25,6 +25,18 @@ func TestGetDefinition(t *testing.T) { ids: []string{unifiedrole.UnifiedRoleViewerID, unifiedrole.UnifiedRoleEditorID}, unifiedRoleDefinition: unifiedrole.RoleViewer, }, + "pass viewer-with-versions": { + ids: []string{unifiedrole.UnifiedRoleViewerWithVersionsID}, + unifiedRoleDefinition: unifiedrole.RoleViewerWithVersions, + }, + "pass editor-with-versions": { + ids: []string{unifiedrole.UnifiedRoleEditorWithVersionsID}, + unifiedRoleDefinition: unifiedrole.RoleEditorWithVersions, + }, + "pass file-editor-with-versions": { + ids: []string{unifiedrole.UnifiedRoleFileEditorWithVersionsID}, + unifiedRoleDefinition: unifiedrole.RoleFileEditorWithVersions, + }, "fail unknown": { ids: []string{"unknown"}, expectError: unifiedrole.ErrUnknownRole, @@ -162,9 +174,11 @@ func TestGetRolesByPermissions(t *testing.T) { constraints: unifiedrole.UnifiedRoleConditionFile, unifiedRoleDefinition: []*libregraph.UnifiedRoleDefinition{ unifiedrole.RoleViewer, + unifiedrole.RoleViewerWithVersions, unifiedrole.RoleSecureViewer, unifiedrole.RoleViewerListGrants, unifiedrole.RoleFileEditor, + unifiedrole.RoleFileEditorWithVersions, unifiedrole.RoleFileEditorListGrants, }, }, @@ -173,11 +187,13 @@ func TestGetRolesByPermissions(t *testing.T) { constraints: unifiedrole.UnifiedRoleConditionFolder, unifiedRoleDefinition: []*libregraph.UnifiedRoleDefinition{ unifiedrole.RoleViewer, + unifiedrole.RoleViewerWithVersions, unifiedrole.RoleSecureViewer, unifiedrole.RoleViewerListGrants, unifiedrole.RoleEditorLite, unifiedrole.RoleEditor, unifiedrole.RoleEditorListGrants, + unifiedrole.RoleEditorWithVersions, unifiedrole.RoleDenied, }, }, diff --git a/services/web/pkg/theme/theme.go b/services/web/pkg/theme/theme.go index 56f190d04e..099845fc0a 100644 --- a/services/web/pkg/theme/theme.go +++ b/services/web/pkg/theme/theme.go @@ -21,6 +21,10 @@ var themeDefaults = KV{ "name": "UnifiedRoleViewer", "iconName": "eye", }, + unifiedrole.UnifiedRoleViewerWithVersionsID: KV{ + "name": "UnifiedRoleViewerWithVersions", + "iconName": "eye", + }, unifiedrole.UnifiedRoleViewerListGrantsID: KV{ "name": "UnifiedRoleViewerListGrants", "iconName": "eye", @@ -33,6 +37,10 @@ var themeDefaults = KV{ "label": "UnifiedRoleFileEditor", "iconName": "pencil", }, + unifiedrole.UnifiedRoleFileEditorWithVersionsID: KV{ + "label": "UnifiedRoleFileEditorWithVersions", + "iconName": "pencil", + }, unifiedrole.UnifiedRoleFileEditorListGrantsID: KV{ "label": "UnifiedRoleFileEditorListGrants", "iconName": "pencil", @@ -41,6 +49,10 @@ var themeDefaults = KV{ "label": "UnifiedRoleEditor", "iconName": "pencil", }, + unifiedrole.UnifiedRoleEditorWithVersionsID: KV{ + "label": "UnifiedRoleEditorWithVersions", + "iconName": "pencil", + }, unifiedrole.UnifiedRoleEditorListGrantsID: KV{ "label": "UnifiedRoleEditorListGrants", "iconName": "pencil", diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/conversions/role.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/conversions/role.go index 508b091c4e..239387426d 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/conversions/role.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/conversions/role.go @@ -37,12 +37,16 @@ type Role struct { const ( // RoleViewer grants non-editor role on a resource. RoleViewer = "viewer" + // RoleViewerWithVersions grants non-editor role on a resource including list versions. + RoleViewerWithVersions = "viewer-with-versions" // RoleViewerListGrants grants non-editor role on a resource. RoleViewerListGrants = "viewer-list-grants" // RoleSpaceViewer grants non-editor role on a space. RoleSpaceViewer = "spaceviewer" // RoleEditor grants editor permission on a resource, including folders. RoleEditor = "editor" + // RoleEditorWithVersions grants editor permission on a resource, including folders and list/restore versions + RoleEditorWithVersions = "editor-with-versions" // RoleEditorListGrants grants editor permission on a resource, including folders. RoleEditorListGrants = "editor-list-grants" // RoleSpaceEditor grants editor permission on a space. @@ -51,6 +55,8 @@ const ( RoleSpaceEditorWithoutVersions = "spaceeditor-without-versions" // RoleFileEditor grants editor permission on a single file. RoleFileEditor = "file-editor" + // RoleFileEditorWithVersions grants editor permission on a single file, including list/restore versions. + RoleFileEditorWithVersions = "file-editor-with-versions" // RoleFileEditorListGrants grants editor permission on a single file. RoleFileEditorListGrants = "file-editor-list-grants" // RoleCoowner grants co-owner permissions on a resource. @@ -163,18 +169,24 @@ func RoleFromName(name string) *Role { return NewDeniedRole() case RoleViewer: return NewViewerRole() + case RoleViewerWithVersions: + return NewViewerWithVersionsRole() case RoleViewerListGrants: return NewViewerListGrantsRole() case RoleSpaceViewer: return NewSpaceViewerRole() case RoleEditor: return NewEditorRole() + case RoleEditorWithVersions: + return NewEditorWithVersionsRole() case RoleEditorListGrants: return NewEditorListGrantsRole() case RoleSpaceEditor: return NewSpaceEditorRole() case RoleFileEditor: return NewFileEditorRole() + case RoleFileEditorWithVersions: + return NewFileEditorWithVersionsRole() case RoleFileEditorListGrants: return NewFileEditorListGrantsRole() case RoleUploader: @@ -225,6 +237,14 @@ func NewViewerRole() *Role { } } +// NewViewerWithVersionsRole creates a viewer role which enables listing of file versions +func NewViewerWithVersionsRole() *Role { + role := NewViewerRole() + role.Name = RoleViewerWithVersions + role.cS3ResourcePermissions.ListFileVersions = true + return role +} + // NewViewerListGrantsRole creates a viewer role. `sharing` indicates if sharing permission should be added func NewViewerListGrantsRole() *Role { role := NewViewerRole() @@ -278,6 +298,15 @@ func NewEditorListGrantsRole() *Role { return role } +// NewEditorWithVersionsRole creates an editor role including list/restore versions. `sharing` indicates if sharing permission should be added +func NewEditorWithVersionsRole() *Role { + role := NewEditorRole() + role.Name = RoleEditorWithVersions + role.cS3ResourcePermissions.ListFileVersions = true + role.cS3ResourcePermissions.RestoreFileVersion = true + return role +} + // NewSpaceEditorRole creates an editor role func NewSpaceEditorRole() *Role { return &Role{ @@ -350,6 +379,15 @@ func NewFileEditorListGrantsRole() *Role { return role } +// NewFileEditorWithVersionsRole creates a file-editor role including list/restore versions +func NewFileEditorWithVersionsRole() *Role { + role := NewFileEditorRole() + role.Name = RoleFileEditorWithVersions + role.cS3ResourcePermissions.ListFileVersions = true + role.cS3ResourcePermissions.RestoreFileVersion = true + return role +} + // NewCoownerRole creates a coowner role. func NewCoownerRole() *Role { return &Role{ diff --git a/vendor/modules.txt b/vendor/modules.txt index ab6c6a5a87..b38f22cb42 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1360,7 +1360,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.46.3-0.20260610093751-a33d8108dd91 +# github.com/opencloud-eu/reva/v2 v2.46.3-0.20260611095012-6617969b3720 ## explicit; go 1.25.0 github.com/opencloud-eu/reva/v2/cmd/revad/internal/grace github.com/opencloud-eu/reva/v2/cmd/revad/runtime