mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-08-02 10:53:39 -04:00
* feat: add space viewer with versions role * fix after review --------- Co-authored-by: v.scharf <v.scharf@opencloud.eu>
711 lines
30 KiB
Go
711 lines
30 KiB
Go
package unifiedrole
|
|
|
|
import (
|
|
"cmp"
|
|
"slices"
|
|
"strings"
|
|
|
|
libregraph "github.com/opencloud-eu/libre-graph-api-go"
|
|
"google.golang.org/protobuf/proto"
|
|
|
|
"github.com/opencloud-eu/reva/v2/pkg/conversions"
|
|
|
|
"github.com/opencloud-eu/opencloud/pkg/l10n"
|
|
graphl10n "github.com/opencloud-eu/opencloud/services/graph/pkg/l10n"
|
|
)
|
|
|
|
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"
|
|
// UnifiedRoleSpaceViewerWithVersionsID
|
|
UnifiedRoleSpaceViewerWithVersionsID = "3de465fc-6e17-4839-8b8a-a77cc497878b"
|
|
// 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.
|
|
UnifiedRoleSpaceEditorID = "58c63c02-1d89-4572-916a-870abc5a1b7d"
|
|
// UnifiedRoleSpaceEditorWithoutVersionsID Unified role space editor without list/restore versions id.
|
|
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.
|
|
UnifiedRoleEditorLiteID = "1c996275-f1c9-4e71-abdf-a42f6495e960"
|
|
// UnifiedRoleManagerID Unified role manager id.
|
|
UnifiedRoleManagerID = "312c0871-5ef7-4b3a-85b6-0e4074c64049"
|
|
// UnifiedRoleSecureViewerID Unified role secure viewer id.
|
|
UnifiedRoleSecureViewerID = "aa97fe03-7980-45ac-9e50-b325749fd7e6"
|
|
// UnifiedRoleDeniedID Unified role to deny all access.
|
|
UnifiedRoleDeniedID = "63e64e19-8d43-42ec-a738-2b6af2610efa"
|
|
|
|
// Wile the below conditions follow the SDDL syntax, they are not parsed anywhere. We use them as strings to
|
|
// represent the constraints that a role definition applies to. For the actual syntax, see the SDDL documentation
|
|
// at https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-definition-language-for-conditional-aces-#conditional-expressions
|
|
|
|
// Some roles apply to a specific type of resource, for example, a role that applies to a file or a folder.
|
|
// @Resource is the placeholder for the resource that the role is applied to
|
|
// .Root, .Folder and .File are facets of the driveItem resource that indicate the type of the resource if they are present.
|
|
|
|
// UnifiedRoleConditionDrive defines constraint that matches a Driveroot/Spaceroot
|
|
UnifiedRoleConditionDrive = "exists @Resource.Root"
|
|
// UnifiedRoleConditionFolder defines constraints that matches a DriveItem representing a Folder
|
|
UnifiedRoleConditionFolder = "exists @Resource.Folder"
|
|
// UnifiedRoleConditionFile defines a constraint that matches a DriveItem representing a File
|
|
UnifiedRoleConditionFile = "exists @Resource.File"
|
|
|
|
// Some roles apply to a specific type of user, for example, a role that applies to a federated user.
|
|
// @Subject is the placeholder for the subject that the role is applied to. For sharing roles this is the user that the resource is shared with.
|
|
// .UserType is the type of the user: 'Member' for a member of the organization, 'Guest' for a guest user, 'Federated' for a federated user.
|
|
|
|
// UnifiedRoleConditionFederatedUser defines a constraint that matches a federated user
|
|
UnifiedRoleConditionFederatedUser = "@Subject.UserType==\"Federated\""
|
|
|
|
// For federated sharing we need roles that combine the constraints for the resource and the user.
|
|
// UnifiedRoleConditionFileFederatedUser defines a constraint that matches a File and a federated user
|
|
UnifiedRoleConditionFileFederatedUser = UnifiedRoleConditionFile + " && " + UnifiedRoleConditionFederatedUser
|
|
// UnifiedRoleConditionFolderFederatedUser defines a constraint that matches a Folder and a federated user
|
|
UnifiedRoleConditionFolderFederatedUser = UnifiedRoleConditionFolder + " && " + UnifiedRoleConditionFederatedUser
|
|
|
|
DriveItemPermissionsCreate = "libre.graph/driveItem/permissions/create"
|
|
DriveItemChildrenCreate = "libre.graph/driveItem/children/create"
|
|
DriveItemStandardDelete = "libre.graph/driveItem/standard/delete"
|
|
DriveItemPathRead = "libre.graph/driveItem/path/read"
|
|
DriveItemQuotaRead = "libre.graph/driveItem/quota/read"
|
|
DriveItemContentRead = "libre.graph/driveItem/content/read"
|
|
DriveItemUploadCreate = "libre.graph/driveItem/upload/create"
|
|
DriveItemPermissionsRead = "libre.graph/driveItem/permissions/read"
|
|
DriveItemChildrenRead = "libre.graph/driveItem/children/read"
|
|
DriveItemVersionsRead = "libre.graph/driveItem/versions/read"
|
|
DriveItemDeletedRead = "libre.graph/driveItem/deleted/read"
|
|
DriveItemPathUpdate = "libre.graph/driveItem/path/update"
|
|
DriveItemPermissionsDelete = "libre.graph/driveItem/permissions/delete"
|
|
DriveItemDeletedDelete = "libre.graph/driveItem/deleted/delete"
|
|
DriveItemVersionsUpdate = "libre.graph/driveItem/versions/update"
|
|
DriveItemDeletedUpdate = "libre.graph/driveItem/deleted/update"
|
|
DriveItemBasicRead = "libre.graph/driveItem/basic/read"
|
|
DriveItemPermissionsUpdate = "libre.graph/driveItem/permissions/update"
|
|
DriveItemPermissionsDeny = "libre.graph/driveItem/permissions/deny"
|
|
)
|
|
|
|
var (
|
|
// UnifiedRole Viewer, Role Description (resolves directly)
|
|
_viewerUnifiedRoleDescription = l10n.Template("View and download.")
|
|
|
|
// UnifiedRole Viewer, Role DisplayName (resolves directly)
|
|
_viewerUnifiedRoleDisplayName = l10n.Template("Can view")
|
|
|
|
// 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.")
|
|
|
|
// UnifiedRole Viewer, Role DisplayName (resolves directly)
|
|
_viewerListGrantsUnifiedRoleDisplayName = l10n.Template("Can view")
|
|
|
|
// UnifiedRole SpaceViewer, Role Description (resolves directly)
|
|
_spaceViewerUnifiedRoleDescription = l10n.Template("View and download.")
|
|
|
|
// UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
|
|
_spaceViewerUnifiedRoleDisplayName = l10n.Template("Can view")
|
|
|
|
// UnifiedRole SpaceViewer, Role Description (resolves directly)
|
|
_spaceViewerWithVersionsUnifiedRoleDescription = l10n.Template("View and download including the history.")
|
|
|
|
// UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
|
|
_spaceViewerWithVersionsUnifiedRoleDisplayName = l10n.Template("Can view")
|
|
|
|
// UnifiedRole Editor, Role Description (resolves directly)
|
|
_editorUnifiedRoleDescription = l10n.Template("View, download, upload, edit, add and delete.")
|
|
|
|
// UnifiedRole Editor, Role DisplayName (resolves directly)
|
|
_editorUnifiedRoleDisplayName = l10n.Template("Can edit")
|
|
|
|
// 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.")
|
|
|
|
// UnifiedRole EditorListGrants, Role DisplayName (resolves directly)
|
|
_editorListGrantsUnifiedRoleDisplayName = l10n.Template("Can edit")
|
|
|
|
// UnifiedRole SpaseEditor, Role Description (resolves directly)
|
|
_spaceEditorUnifiedRoleDescription = l10n.Template("View, download, upload, edit, add, delete including the history.")
|
|
|
|
// UnifiedRole SpaseEditor, Role DisplayName (resolves directly)
|
|
_spaceEditorUnifiedRoleDisplayName = l10n.Template("Can edit")
|
|
|
|
// UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves directly)
|
|
_spaceEditorWithoutVersionsUnifiedRoleDescription = l10n.Template("View, download, upload, edit, add and delete.")
|
|
|
|
// UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves directly)
|
|
_spaceEditorWithoutVersionsUnifiedRoleDisplayName = l10n.Template("Can edit without versions")
|
|
|
|
// UnifiedRole FileEditor, Role Description (resolves directly)
|
|
_fileEditorUnifiedRoleDescription = l10n.Template("View, download and edit.")
|
|
|
|
// UnifiedRole FileEditor, Role DisplayName (resolves directly)
|
|
_fileEditorUnifiedRoleDisplayName = l10n.Template("Can edit")
|
|
|
|
// 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")
|
|
|
|
// UnifiedRole EditorLite, Role Description (resolves directly)
|
|
_editorLiteUnifiedRoleDescription = l10n.Template("View, download and upload.")
|
|
|
|
// UnifiedRole EditorLite, Role DisplayName (resolves directly)
|
|
_editorLiteUnifiedRoleDisplayName = l10n.Template("Can upload")
|
|
|
|
// UnifiedRole Manager, Role Description (resolves directly)
|
|
_managerUnifiedRoleDescription = l10n.Template("View, download, upload, edit, add, delete and manage members.")
|
|
|
|
// UnifiedRole Manager, Role DisplayName (resolves directly)
|
|
_managerUnifiedRoleDisplayName = l10n.Template("Can manage")
|
|
|
|
// UnifiedRole SecureViewer, Role Description (resolves directly)
|
|
_secureViewerUnifiedRoleDescription = l10n.Template("View only documents, images and PDFs. Watermarks will be applied.")
|
|
|
|
// UnifiedRole SecureViewer, Role DisplayName (resolves directly)
|
|
_secureViewerUnifiedRoleDisplayName = l10n.Template("Can view (secure)")
|
|
|
|
// UnifiedRole FullDenial, Role Description (resolves directly)
|
|
_deniedUnifiedRoleDescription = l10n.Template("Deny all access.")
|
|
|
|
// UnifiedRole FullDenial, Role DisplayName (resolves directly)
|
|
_deniedUnifiedRoleDisplayName = l10n.Template("Cannot access")
|
|
|
|
// legacyNames contains the legacy role names.
|
|
legacyNames = map[string]string{
|
|
UnifiedRoleViewerID: conversions.RoleViewer,
|
|
// one V1 api the "spaceviewer" role was call "viewer" and the "spaceeditor" was "editor",
|
|
// we need to stay compatible with that
|
|
UnifiedRoleSpaceViewerID: "viewer",
|
|
UnifiedRoleSpaceEditorID: "editor",
|
|
UnifiedRoleSpaceEditorWithoutVersionsID: conversions.RoleSpaceEditorWithoutVersions,
|
|
UnifiedRoleEditorID: conversions.RoleEditor,
|
|
UnifiedRoleFileEditorID: conversions.RoleFileEditor,
|
|
UnifiedRoleEditorLiteID: conversions.RoleEditorLite,
|
|
UnifiedRoleManagerID: conversions.RoleManager,
|
|
UnifiedRoleSecureViewerID: conversions.RoleSecureViewer,
|
|
}
|
|
|
|
// buildInRoles contains the built-in roles.
|
|
buildInRoles = []*libregraph.UnifiedRoleDefinition{
|
|
roleViewer,
|
|
roleViewerWithVersions,
|
|
roleViewerListGrants,
|
|
roleSpaceViewer,
|
|
roleSpaceViewerWithVersions,
|
|
roleEditor,
|
|
roleEditorListGrants,
|
|
roleEditorWithVersions,
|
|
roleSpaceEditorWithVersions,
|
|
roleSpaceEditor,
|
|
roleFileEditor,
|
|
roleFileEditorWithVersions,
|
|
roleFileEditorListGrants,
|
|
roleEditorLite,
|
|
roleManager,
|
|
roleSecureViewer,
|
|
roleDenied,
|
|
}
|
|
|
|
// roleViewer creates a viewer role.
|
|
roleViewer = func() *libregraph.UnifiedRoleDefinition {
|
|
r := conversions.NewViewerRole()
|
|
return &libregraph.UnifiedRoleDefinition{
|
|
Id: proto.String(UnifiedRoleViewerID),
|
|
Description: proto.String(_viewerUnifiedRoleDescription),
|
|
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(10),
|
|
}
|
|
}()
|
|
|
|
// 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),
|
|
},
|
|
},
|
|
LibreGraphWeight: proto.Int32(11),
|
|
}
|
|
}()
|
|
|
|
// roleSecureViewer creates a secure viewer role
|
|
roleSecureViewer = func() *libregraph.UnifiedRoleDefinition {
|
|
r := conversions.NewSecureViewerRole()
|
|
return &libregraph.UnifiedRoleDefinition{
|
|
Id: proto.String(UnifiedRoleSecureViewerID),
|
|
Description: proto.String(_secureViewerUnifiedRoleDescription),
|
|
DisplayName: proto.String(cs3RoleToDisplayName(r)),
|
|
RolePermissions: []libregraph.UnifiedRolePermission{
|
|
{
|
|
AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()),
|
|
Condition: proto.String(UnifiedRoleConditionFile),
|
|
},
|
|
{
|
|
AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()),
|
|
Condition: proto.String(UnifiedRoleConditionFolder),
|
|
},
|
|
},
|
|
LibreGraphWeight: proto.Int32(20),
|
|
}
|
|
}()
|
|
|
|
// roleViewerListGrants creates a viewer role.
|
|
roleViewerListGrants = func() *libregraph.UnifiedRoleDefinition {
|
|
r := conversions.NewViewerListGrantsRole()
|
|
return &libregraph.UnifiedRoleDefinition{
|
|
Id: proto.String(UnifiedRoleViewerListGrantsID),
|
|
Description: proto.String(_viewerListGrantsUnifiedRoleDescription),
|
|
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(30),
|
|
}
|
|
}()
|
|
|
|
// roleSpaceViewer creates a spaceviewer role
|
|
roleSpaceViewer = func() *libregraph.UnifiedRoleDefinition {
|
|
r := conversions.NewSpaceViewerRole()
|
|
return &libregraph.UnifiedRoleDefinition{
|
|
Id: proto.String(UnifiedRoleSpaceViewerID),
|
|
Description: proto.String(_spaceViewerUnifiedRoleDescription),
|
|
DisplayName: proto.String(cs3RoleToDisplayName(r)),
|
|
RolePermissions: []libregraph.UnifiedRolePermission{
|
|
{
|
|
AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()),
|
|
Condition: proto.String(UnifiedRoleConditionDrive),
|
|
},
|
|
},
|
|
LibreGraphWeight: proto.Int32(40),
|
|
}
|
|
}()
|
|
|
|
// roleSpaceViewer creates a spaceviewer role
|
|
roleSpaceViewerWithVersions = func() *libregraph.UnifiedRoleDefinition {
|
|
r := conversions.NewSpaceViewerWithVersionsRole()
|
|
return &libregraph.UnifiedRoleDefinition{
|
|
Id: proto.String(UnifiedRoleSpaceViewerWithVersionsID),
|
|
Description: proto.String(_spaceViewerWithVersionsUnifiedRoleDescription),
|
|
DisplayName: proto.String(cs3RoleToDisplayName(r)),
|
|
RolePermissions: []libregraph.UnifiedRolePermission{
|
|
{
|
|
AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()),
|
|
Condition: proto.String(UnifiedRoleConditionDrive),
|
|
},
|
|
},
|
|
LibreGraphWeight: proto.Int32(40),
|
|
}
|
|
}()
|
|
|
|
// roleEditorLite creates an editor-lite role
|
|
roleEditorLite = func() *libregraph.UnifiedRoleDefinition {
|
|
r := conversions.NewEditorLiteRole()
|
|
return &libregraph.UnifiedRoleDefinition{
|
|
Id: proto.String(UnifiedRoleEditorLiteID),
|
|
Description: proto.String(_editorLiteUnifiedRoleDescription),
|
|
DisplayName: proto.String(cs3RoleToDisplayName(r)),
|
|
RolePermissions: []libregraph.UnifiedRolePermission{
|
|
{
|
|
AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()),
|
|
Condition: proto.String(UnifiedRoleConditionFolder),
|
|
},
|
|
},
|
|
LibreGraphWeight: proto.Int32(50),
|
|
}
|
|
}()
|
|
|
|
// roleEditor creates an editor role.
|
|
roleEditor = func() *libregraph.UnifiedRoleDefinition {
|
|
r := conversions.NewEditorRole()
|
|
return &libregraph.UnifiedRoleDefinition{
|
|
Id: proto.String(UnifiedRoleEditorID),
|
|
Description: proto.String(_editorUnifiedRoleDescription),
|
|
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(60),
|
|
}
|
|
}()
|
|
|
|
// roleEditorListGrants creates an editor role.
|
|
roleEditorListGrants = func() *libregraph.UnifiedRoleDefinition {
|
|
r := conversions.NewEditorListGrantsRole()
|
|
return &libregraph.UnifiedRoleDefinition{
|
|
Id: proto.String(UnifiedRoleEditorListGrantsID),
|
|
Description: proto.String(_editorListGrantsUnifiedRoleDescription),
|
|
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(70),
|
|
}
|
|
}()
|
|
|
|
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),
|
|
},
|
|
},
|
|
LibreGraphWeight: proto.Int32(71),
|
|
}
|
|
}()
|
|
|
|
// roleSpaceEditor creates an editor without versions role
|
|
roleSpaceEditor = func() *libregraph.UnifiedRoleDefinition {
|
|
r := conversions.NewSpaceEditorWithoutVersionsRole()
|
|
return &libregraph.UnifiedRoleDefinition{
|
|
Id: proto.String(UnifiedRoleSpaceEditorWithoutVersionsID),
|
|
Description: proto.String(_spaceEditorWithoutVersionsUnifiedRoleDescription),
|
|
DisplayName: proto.String(cs3RoleToDisplayName(r)),
|
|
RolePermissions: []libregraph.UnifiedRolePermission{
|
|
{
|
|
AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()),
|
|
Condition: proto.String(UnifiedRoleConditionDrive),
|
|
},
|
|
},
|
|
LibreGraphWeight: proto.Int32(80),
|
|
}
|
|
}()
|
|
|
|
// roleSpaceEditorWithVersions creates an editor role
|
|
roleSpaceEditorWithVersions = func() *libregraph.UnifiedRoleDefinition {
|
|
r := conversions.NewSpaceEditorRole()
|
|
return &libregraph.UnifiedRoleDefinition{
|
|
Id: proto.String(UnifiedRoleSpaceEditorID),
|
|
Description: proto.String(_spaceEditorUnifiedRoleDescription),
|
|
DisplayName: proto.String(cs3RoleToDisplayName(r)),
|
|
RolePermissions: []libregraph.UnifiedRolePermission{
|
|
{
|
|
AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()),
|
|
Condition: proto.String(UnifiedRoleConditionDrive),
|
|
},
|
|
},
|
|
LibreGraphWeight: proto.Int32(90),
|
|
}
|
|
}()
|
|
|
|
// roleFileEditor creates a file-editor role
|
|
roleFileEditor = func() *libregraph.UnifiedRoleDefinition {
|
|
r := conversions.NewFileEditorRole()
|
|
return &libregraph.UnifiedRoleDefinition{
|
|
Id: proto.String(UnifiedRoleFileEditorID),
|
|
Description: proto.String(_fileEditorUnifiedRoleDescription),
|
|
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(100),
|
|
}
|
|
}()
|
|
|
|
// 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),
|
|
},
|
|
},
|
|
LibreGraphWeight: proto.Int32(101),
|
|
}
|
|
}()
|
|
|
|
// roleFileEditorListGrants creates a file-editor role
|
|
roleFileEditorListGrants = func() *libregraph.UnifiedRoleDefinition {
|
|
r := conversions.NewFileEditorListGrantsRole()
|
|
return &libregraph.UnifiedRoleDefinition{
|
|
Id: proto.String(UnifiedRoleFileEditorListGrantsID),
|
|
Description: proto.String(_fileEditorListGrantsUnifiedRoleDescription),
|
|
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(110),
|
|
}
|
|
}()
|
|
|
|
// roleManager creates a manager role
|
|
roleManager = func() *libregraph.UnifiedRoleDefinition {
|
|
r := conversions.NewManagerRole()
|
|
return &libregraph.UnifiedRoleDefinition{
|
|
Id: proto.String(UnifiedRoleManagerID),
|
|
Description: proto.String(_managerUnifiedRoleDescription),
|
|
DisplayName: proto.String(cs3RoleToDisplayName(r)),
|
|
RolePermissions: []libregraph.UnifiedRolePermission{
|
|
{
|
|
AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()),
|
|
Condition: proto.String(UnifiedRoleConditionDrive),
|
|
},
|
|
},
|
|
LibreGraphWeight: proto.Int32(120),
|
|
}
|
|
}()
|
|
|
|
// roleDenied creates a secure viewer role
|
|
roleDenied = func() *libregraph.UnifiedRoleDefinition {
|
|
r := conversions.NewDeniedRole()
|
|
return &libregraph.UnifiedRoleDefinition{
|
|
Id: proto.String(UnifiedRoleDeniedID),
|
|
Description: proto.String(_deniedUnifiedRoleDescription),
|
|
DisplayName: proto.String(cs3RoleToDisplayName(r)),
|
|
RolePermissions: []libregraph.UnifiedRolePermission{
|
|
{
|
|
AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()),
|
|
Condition: proto.String(UnifiedRoleConditionFolder),
|
|
},
|
|
},
|
|
LibreGraphWeight: proto.Int32(200),
|
|
}
|
|
}()
|
|
)
|
|
|
|
// GetRoles returns a role filter that matches the provided resources
|
|
func GetRoles(f RoleFilter) []*libregraph.UnifiedRoleDefinition {
|
|
return filterRoles(buildInRoles, f)
|
|
}
|
|
|
|
// GetRole returns a role filter that matches the provided resources
|
|
func GetRole(f RoleFilter) (*libregraph.UnifiedRoleDefinition, error) {
|
|
roles := filterRoles(buildInRoles, f)
|
|
if len(roles) == 0 {
|
|
return nil, ErrUnknownRole
|
|
}
|
|
|
|
return roles[0], nil
|
|
}
|
|
|
|
// GetRolesByPermissions returns a list of role definitions
|
|
// that match the provided actions and constraints
|
|
func GetRolesByPermissions(roleSet []*libregraph.UnifiedRoleDefinition, actions []string, constraints string, listFederatedRoles, descending bool) []*libregraph.UnifiedRoleDefinition {
|
|
roles := make([]*libregraph.UnifiedRoleDefinition, 0, len(roleSet))
|
|
|
|
for _, role := range roleSet {
|
|
var match bool
|
|
|
|
for _, permission := range role.GetRolePermissions() {
|
|
// this is a dirty comparison because we are not really parsing the SDDL, but as long as we && the conditions we are good
|
|
isFederatedRole := strings.Contains(permission.GetCondition(), UnifiedRoleConditionFederatedUser)
|
|
switch {
|
|
case !strings.Contains(permission.GetCondition(), constraints):
|
|
continue
|
|
case listFederatedRoles && !isFederatedRole:
|
|
continue
|
|
case !listFederatedRoles && isFederatedRole:
|
|
continue
|
|
}
|
|
|
|
for i, action := range permission.GetAllowedResourceActions() {
|
|
if !slices.Contains(actions, action) {
|
|
break
|
|
}
|
|
if i == len(permission.GetAllowedResourceActions())-1 {
|
|
match = true
|
|
}
|
|
}
|
|
if role.GetId() == UnifiedRoleDeniedID && slices.Contains(actions, DriveItemPermissionsDeny) {
|
|
match = true
|
|
}
|
|
if match {
|
|
break
|
|
}
|
|
}
|
|
|
|
if match {
|
|
roles = append(roles, role)
|
|
}
|
|
|
|
}
|
|
|
|
return weightRoles(roles, constraints, descending)
|
|
}
|
|
|
|
// GetLegacyRoleName returns the legacy role name for the provided role
|
|
func GetLegacyRoleName(role libregraph.UnifiedRoleDefinition) string {
|
|
return legacyNames[role.GetId()]
|
|
}
|
|
|
|
// weightRoles sorts the provided role definitions by the number of LibreGraphWeight,
|
|
// descending - false - sorts the roles from least to most permissions
|
|
// descending - true - sorts the roles from most to least permissions
|
|
func weightRoles(roleSet []*libregraph.UnifiedRoleDefinition, constraints string, descending bool) []*libregraph.UnifiedRoleDefinition {
|
|
slices.SortFunc(roleSet, func(a, b *libregraph.UnifiedRoleDefinition) int {
|
|
if descending {
|
|
return cmp.Compare(b.GetLibreGraphWeight(), a.GetLibreGraphWeight())
|
|
}
|
|
return cmp.Compare(a.GetLibreGraphWeight(), b.GetLibreGraphWeight())
|
|
})
|
|
|
|
return roleSet
|
|
}
|
|
|
|
// cloneRole returns a shallow struct copy of r with independent allocations for
|
|
// the Description and DisplayName pointer fields — the only fields mutated by
|
|
// TranslateEntity. All other fields (Id, LibreGraphWeight, RolePermissions) are
|
|
// either read-only or stripped before rendering, so sharing their values is safe.
|
|
func cloneRole(r *libregraph.UnifiedRoleDefinition) libregraph.UnifiedRoleDefinition {
|
|
c := *r
|
|
if r.Description != nil {
|
|
s := *r.Description
|
|
c.Description = &s
|
|
}
|
|
if r.DisplayName != nil {
|
|
s := *r.DisplayName
|
|
c.DisplayName = &s
|
|
}
|
|
return c
|
|
}
|
|
|
|
// LocalizeRole returns a translated, independent copy of a single role definition.
|
|
// The global buildInRoles singleton is never modified.
|
|
func LocalizeRole(r *libregraph.UnifiedRoleDefinition, locale string) libregraph.UnifiedRoleDefinition {
|
|
c := cloneRole(r)
|
|
if locale != "" && locale != "en" {
|
|
_ = graphl10n.TranslateEntity(locale, "en", &c,
|
|
l10n.TranslateField("Description"),
|
|
l10n.TranslateField("DisplayName"),
|
|
)
|
|
}
|
|
return c
|
|
}
|
|
|
|
// LocalizeRoles returns a translated, independent copy of each role definition.
|
|
// The global buildInRoles singleton is never modified.
|
|
func LocalizeRoles(roles []*libregraph.UnifiedRoleDefinition, locale string) []libregraph.UnifiedRoleDefinition {
|
|
out := make([]libregraph.UnifiedRoleDefinition, len(roles))
|
|
for i, r := range roles {
|
|
out[i] = LocalizeRole(r, locale)
|
|
}
|
|
return out
|
|
}
|
|
|
|
// GetAllowedResourceActions returns the allowed resource actions for the provided role by condition
|
|
func GetAllowedResourceActions(role *libregraph.UnifiedRoleDefinition, condition string) []string {
|
|
if role == nil {
|
|
return []string{}
|
|
}
|
|
|
|
for _, p := range role.GetRolePermissions() {
|
|
if p.GetCondition() == condition {
|
|
return p.GetAllowedResourceActions()
|
|
}
|
|
}
|
|
|
|
return []string{}
|
|
}
|