From bd650ec5673906131f6d2ac141ff9a1c7a364fd8 Mon Sep 17 00:00:00 2001 From: flash Date: Wed, 27 May 2026 19:24:46 +0200 Subject: [PATCH] feat: add EditorLitePlus role for editing without delete Add a new sharing role "EditorLitePlus" that grants all editor permissions (view, download, upload, edit, add, move) except delete. This role fills a gap between EditorLite (upload only) and Editor (full edit including delete) for use cases where users need to work with documents but should not be able to delete them, e.g. shared project folders or document management scenarios. Permissions: Read, Write, Create, Move. Explicitly excluded: Delete, PurgeRecycle, ListRecycle, RestoreRecycleItem. --- services/graph/pkg/unifiedrole/conversion.go | 2 ++ services/graph/pkg/unifiedrole/roles.go | 27 +++++++++++++++++++ .../reva/v2/pkg/conversions/role.go | 21 +++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/services/graph/pkg/unifiedrole/conversion.go b/services/graph/pkg/unifiedrole/conversion.go index 457cb5db0f..152bb6a89c 100644 --- a/services/graph/pkg/unifiedrole/conversion.go +++ b/services/graph/pkg/unifiedrole/conversion.go @@ -220,6 +220,8 @@ func cs3RoleToDisplayName(role *conversions.Role) string { return _fileEditorUnifiedRoleDisplayName case conversions.RoleFileEditorListGrants: return _fileEditorListGrantsUnifiedRoleDisplayName + case conversions.RoleEditorLitePlus: + return _editorLitePlusUnifiedRoleDisplayName case conversions.RoleEditorLite: return _editorLiteUnifiedRoleDisplayName case conversions.RoleManager: diff --git a/services/graph/pkg/unifiedrole/roles.go b/services/graph/pkg/unifiedrole/roles.go index 5b866e70ef..4f59b873ed 100644 --- a/services/graph/pkg/unifiedrole/roles.go +++ b/services/graph/pkg/unifiedrole/roles.go @@ -32,6 +32,8 @@ const ( UnifiedRoleFileEditorID = "2d00ce52-1fc2-4dbc-8b95-a73b73395f5a" // UnifiedRoleFileEditorListGrantsID Unified role file editor id. UnifiedRoleFileEditorListGrantsID = "c1235aea-d106-42db-8458-7d5610fb0a67" + // UnifiedRoleEditorLitePlusID Unified role editor-lite-plus id. + UnifiedRoleEditorLitePlusID = "48d8a2b0-d7c2-4b63-a0b5-2e3f5c9e8d1a" // UnifiedRoleEditorLiteID Unified role editor-lite id. UnifiedRoleEditorLiteID = "1c996275-f1c9-4e71-abdf-a42f6495e960" // UnifiedRoleManagerID Unified role manager id. @@ -145,6 +147,12 @@ var ( // UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly) _fileEditorListGrantsUnifiedRoleDisplayName = l10n.Template("Can edit") + // UnifiedRole EditorLitePlus, Role Description (resolves directly) + _editorLightUnifiedRoleDescription = l10n.Template("View, download, upload, edit and add. No delete.") + + // UnifiedRole EditorLitePlus, Role DisplayName (resolves directly) + _editorLightUnifiedRoleDisplayName = l10n.Template("Can edit (no delete)") + // UnifiedRole EditorLite, Role Description (resolves directly) _editorLiteUnifiedRoleDescription = l10n.Template("View, download and upload.") @@ -179,6 +187,7 @@ var ( UnifiedRoleSpaceEditorWithoutVersionsID: conversions.RoleSpaceEditorWithoutVersions, UnifiedRoleEditorID: conversions.RoleEditor, UnifiedRoleFileEditorID: conversions.RoleFileEditor, + UnifiedRoleEditorLitePlusID: conversions.RoleEditorLitePlus, UnifiedRoleEditorLiteID: conversions.RoleEditorLite, UnifiedRoleManagerID: conversions.RoleManager, UnifiedRoleSecureViewerID: conversions.RoleSecureViewer, @@ -195,6 +204,7 @@ var ( roleSpaceEditorWithoutVersions, roleFileEditor, roleFileEditorListGrants, + roleEditorLitePlus, roleEditorLite, roleManager, roleSecureViewer, @@ -314,6 +324,23 @@ var ( } }() + // roleEditorLitePlus creates an editor role without delete permission. + roleEditorLitePlus = func() *libregraph.UnifiedRoleDefinition { + r := conversions.NewEditorLitePlusRole() + return &libregraph.UnifiedRoleDefinition{ + Id: proto.String(UnifiedRoleEditorLitePlusID), + Description: proto.String(_editorLitePlusUnifiedRoleDescription), + DisplayName: proto.String(cs3RoleToDisplayName(r)), + RolePermissions: []libregraph.UnifiedRolePermission{ + { + AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()), + Condition: proto.String(UnifiedRoleConditionFolder), + }, + }, + LibreGraphWeight: proto.Int32(55), + } + }() + // roleEditor creates an editor role. roleEditor = func() *libregraph.UnifiedRoleDefinition { r := conversions.NewEditorRole() 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..3bdb07a076 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 @@ -55,6 +55,8 @@ const ( RoleFileEditorListGrants = "file-editor-list-grants" // RoleCoowner grants co-owner permissions on a resource. RoleCoowner = "coowner" + // RoleEditorLitePlus grants editor permission without delete on a resource. + RoleEditorLitePlus = "editor-lite-plus" // RoleEditorLite grants permission to upload and download to a resource. RoleEditorLite = "editor-lite" // RoleUploader grants uploader permission to upload onto a resource (no download). @@ -271,6 +273,25 @@ func NewEditorRole() *Role { } } +// NewEditorLitePlusRole creates an editor role without delete permission. +// Users can view, download, upload, edit, add and move but not delete. +func NewEditorLitePlusRole() *Role { + return &Role{ + Name: RoleEditorLitePlus, + cS3ResourcePermissions: &provider.ResourcePermissions{ + CreateContainer: true, + GetPath: true, + GetQuota: true, + InitiateFileDownload: true, + InitiateFileUpload: true, + ListContainer: true, + Move: true, + Stat: true, + }, + ocsPermissions: PermissionRead | PermissionCreate | PermissionWrite, + } +} + // NewEditorListGrantsRole creates an editor role. `sharing` indicates if sharing permission should be added func NewEditorListGrantsRole() *Role { role := NewEditorRole()