From 8b6c4eb426bf98b962a8bb5a02fecc77be2f0c50 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Mon, 6 Jan 2025 11:02:42 +0100 Subject: [PATCH 1/3] TASK: Remove obsolete legacy yaml policy for workspaces With the introduction of explicit user assignments for workspaces https://github.com/neos/neos-development-collection/pull/5146 and roles and the full evaluation of those via https://github.com/neos/neos-development-collection/pull/5298 we have replaced the previously still kept 8.3 yaml security configuration for workspaces. This decision was done as for security we can no longer use flows security framework which uses aop inside the content-repository library, and also we wanted to cleanup the user <-> workspace relation ship as well as the concept of internal vs shared workspaces. Following yaml roles were removed: - `Neos.ContentRepository:Administrator` - `Neos.ContentRepository:InternalWorkspaceAccess` Following yaml targets were removed: - `Neos.Neos:PublicWorkspaceAccess` - `Neos.Neos:OtherWorkspacesAccess` - `Neos.Neos:Backend.OtherUsersPersonalWorkspaceAccess` - `Neos.Neos:Backend.PublishOwnWorkspaceContent` - `Neos.Neos:Backend.DiscardOwnWorkspaceContent` - `Neos.Workspace.Ui:Backend.PublishAllToLiveWorkspace` Note that these targets were moved to the `Neos.Workspace.Ui:Backend` package via https://github.com/neos/neos-development-collection/pull/5118 in 9.0 but were removed now either way: - `Neos.Neos:Backend.Module.Management.Workspaces.ManageOwnWorkspaces` (`Neos.Workspace.Ui:Backend.Module.Management.Workspace.ManageOwnWorkspaces`) - `Neos.Neos:Backend.Module.Management.Workspaces.ManageInternalWorkspaces` (`Neos.Workspace.Ui:Backend.Module.Management.Workspace.ManageInternalWorkspaces`) - `Neos.Neos:Backend.Module.Management.Workspaces.ManageAllPrivateWorkspaces` (`Neos.Workspace.Ui:Backend.Module.Management.Workspace.ManageAllPrivateWorkspaces`) --- .../Configuration/Policy.yaml | 30 ---------------- Neos.Neos/Configuration/Policy.yaml | 22 ------------ Neos.Workspace.Ui/Configuration/Policy.yaml | 36 ------------------- .../Migrations/Code/Version20240603134000.php | 20 ----------- 4 files changed, 108 deletions(-) delete mode 100644 Neos.ContentRepository.NodeAccess/Configuration/Policy.yaml diff --git a/Neos.ContentRepository.NodeAccess/Configuration/Policy.yaml b/Neos.ContentRepository.NodeAccess/Configuration/Policy.yaml deleted file mode 100644 index d015bec6748..00000000000 --- a/Neos.ContentRepository.NodeAccess/Configuration/Policy.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# # -# Security policy for the ContentRepository package # -# # - -privilegeTargets: - 'Neos\Flow\Security\Authorization\Privilege\Method\MethodPrivilege': - 'Neos.Neos:PublicWorkspaceAccess': - label: Allowed to access the public workspace - matcher: 'method(Neos\ContentRepository\Domain\Service\Context->validateWorkspace()) && evaluate(this.workspace.publicWorkspace === true)' - - 'Neos.Neos:OtherWorkspacesAccess': - label: Allowed to access to other users workspaces - matcher: 'method(Neos\ContentRepository\Domain\Service\Context->validateWorkspace()) && evaluate(this.workspace.publicWorkspace === false) && evaluate(this.workspace.personalWorkspace === false)' - -roles: - 'Neos.Flow:Everybody': - privileges: - - privilegeTarget: 'Neos.Neos:PublicWorkspaceAccess' - permission: GRANT - - 'Neos.ContentRepository:InternalWorkspaceAccess': - abstract: TRUE - privileges: - - privilegeTarget: 'Neos.Neos:OtherWorkspacesAccess' - permission: GRANT - - 'Neos.ContentRepository:Administrator': - abstract: true - parentRoles: ['Neos.ContentRepository:InternalWorkspaceAccess'] - diff --git a/Neos.Neos/Configuration/Policy.yaml b/Neos.Neos/Configuration/Policy.yaml index c5f3beb3ca3..d8b19e088c9 100644 --- a/Neos.Neos/Configuration/Policy.yaml +++ b/Neos.Neos/Configuration/Policy.yaml @@ -47,23 +47,10 @@ privilegeTargets: label: Access to own personal workspace matcher: 'method(Neos\Neos\TypeConverter\NodeConverter->prepareContextProperties(workspaceName === current.userInformation.personalWorkspaceName))' - # No role should have this privilege assigned: - 'Neos.Neos:Backend.OtherUsersPersonalWorkspaceAccess': - label: Access to other users personal workspace - matcher: 'method(Neos\ContentRepository\Domain\Service\Context->validateWorkspace()) && evaluate(this.workspace.owner !== current.userInformation.backendUser, this.workspace.personalWorkspace === true)' - 'Neos.Neos:Backend.EditContent': label: General access to content editing matcher: 'method(Neos\Neos\Service\Controller\NodeController->(show|getPrimaryChildNode|getChildNodesForTree|filterChildNodesForTree|getChildNodes|getChildNodesFromParent|create|createAndRender|createNodeForTheTree|move|moveBefore|moveAfter|moveInto|moveAndRender|copy|copyBefore|copyAfter|copyInto|copyAndRender|update|updateAndRender|delete|searchPage|error)Action()) || method(Neos\Neos\Controller\Backend\ContentController->(uploadAsset|assetsWithMetadata|imageWithMetadata|createImageVariant|error)Action()) || method(Neos\Neos\Controller\Service\AssetProxiesController->(index|show|import|error)Action()) || method(Neos\Neos\Controller\Service\AssetsController->(index|show|error)Action()) || method(Neos\Neos\Controller\Service\NodesController->(index|show|create|error)Action())' - 'Neos.Neos:Backend.PublishOwnWorkspaceContent': - label: Allowed to publish own personal workspace - matcher: 'method(Neos\Neos\Service\Controller\WorkspaceController->(publishNode|publishNodes|error)Action()) || method(Neos\Neos\Service\Controller\WorkspaceController->publishAllAction(workspaceName = current.userInformation.personalWorkspaceName)) || method(Neos\Neos\Service\Controller\WorkspaceController->getWorkspaceWideUnpublishedNodesAction(workspace.name = current.userInformation.personalWorkspaceName))' - - 'Neos.Neos:Backend.DiscardOwnWorkspaceContent': - label: Allowed to discard changes in own workspace - matcher: 'method(Neos\Neos\Service\Controller\WorkspaceController->(discardNode|discardNodes|error)Action()) || method(Neos\Neos\Service\Controller\WorkspaceController->discardAllAction(workspace.name === current.userInformation.personalWorkspaceName))' - # # User management and user settings # @@ -173,7 +160,6 @@ roles: 'Neos.Neos:AbstractEditor': # This group is assigned conventionally for new shared workspaces as collaborator. See WorkspaceService::assignWorkspaceRole abstract: true - parentRoles: ['Neos.ContentRepository:Administrator'] privileges: - privilegeTarget: 'Neos.Neos:Backend.GeneralAccess' @@ -191,14 +177,6 @@ roles: privilegeTarget: 'Neos.Neos:Backend.EditContent' permission: GRANT - - - privilegeTarget: 'Neos.Neos:Backend.PublishOwnWorkspaceContent' - permission: GRANT - - - - privilegeTarget: 'Neos.Neos:Backend.DiscardOwnWorkspaceContent' - permission: GRANT - - privilegeTarget: 'Neos.Neos:Backend.ContentDimensions' permission: GRANT diff --git a/Neos.Workspace.Ui/Configuration/Policy.yaml b/Neos.Workspace.Ui/Configuration/Policy.yaml index cc57d46f5f7..0084e5775dc 100644 --- a/Neos.Workspace.Ui/Configuration/Policy.yaml +++ b/Neos.Workspace.Ui/Configuration/Policy.yaml @@ -2,58 +2,22 @@ privilegeTargets: 'Neos\Flow\Security\Authorization\Privilege\Method\MethodPrivilege': - 'Neos.Workspace.Ui:Backend.PublishAllToLiveWorkspace': - label: Allowed to publish to the live workspace - matcher: 'method(Neos\Workspace\Ui\Controller\WorkspaceController->publishWorkspaceAction(workspace.baseWorkspace.name === "live"))' - 'Neos.Workspace.Ui:Backend.CreateWorkspaces': label: Allowed to create a workspace matcher: 'method(Neos\Workspace\Ui\Controller\WorkspaceController->(create|new)Action())' - 'Neos.Workspace.Ui:Backend.Module.Management.Workspace.ManageOwnWorkspaces': - label: Allowed to manage own workspaces - matcher: 'method(Neos\Workspace\Ui\Controller\WorkspaceController->(publishWorkspace|discardWorkspace|edit|update|delete)Action(workspace.owner === current.userInformation.backendUser))' - - 'Neos.Workspace.Ui:Backend.Module.Management.Workspace.ManageInternalWorkspaces': - label: Manage internal workspaces - matcher: 'method(Neos\Workspace\Ui\Controller\WorkspaceController->(publishWorkspace|discardWorkspace|edit|update|delete)Action(workspace.owner === null))' - - 'Neos.Workspace.Ui:Backend.Module.Management.Workspace.ManageAllPrivateWorkspaces': - label: Manage all private workspaces - matcher: 'method(Neos\Workspace\Ui\Controller\WorkspaceController->(publishWorkspace|discardWorkspace|edit|update|delete)Action()) && evaluate(this.workspace.owner !== current.userInformation.backendUser, this.workspace.personalWorkspace === false)' - 'Neos\Neos\Security\Authorization\Privilege\ModulePrivilege': 'Neos.Workspace.Ui:Backend.Module.Management.Workspace': label: General access to the workspace module matcher: 'management/workspace' roles: - 'Neos.Neos:LivePublisher': - privileges: - - - privilegeTarget: 'Neos.Workspace.Ui:Backend.PublishAllToLiveWorkspace' - permission: GRANT - 'Neos.Neos:AbstractEditor': privileges: - privilegeTarget: 'Neos.Workspace.Ui:Backend.CreateWorkspaces' permission: GRANT - - - privilegeTarget: 'Neos.Workspace.Ui:Backend.Module.Management.Workspace.ManageOwnWorkspaces' - permission: GRANT - - privilegeTarget: 'Neos.Workspace.Ui:Backend.Module.Management.Workspace' permission: GRANT - - 'Neos.Neos:Administrator': - privileges: - - - privilegeTarget: 'Neos.Workspace.Ui:Backend.Module.Management.Workspace.ManageInternalWorkspaces' - permission: GRANT - - - - privilegeTarget: 'Neos.Workspace.Ui:Backend.Module.Management.Workspace.ManageAllPrivateWorkspaces' - permission: GRANT diff --git a/Neos.Workspace.Ui/Migrations/Code/Version20240603134000.php b/Neos.Workspace.Ui/Migrations/Code/Version20240603134000.php index 7599b1f78e2..476feea6fb3 100644 --- a/Neos.Workspace.Ui/Migrations/Code/Version20240603134000.php +++ b/Neos.Workspace.Ui/Migrations/Code/Version20240603134000.php @@ -26,31 +26,11 @@ public function getIdentifier(): string public function up(): void { - $this->searchAndReplace( - 'Neos.Neos:Backend.PublishAllToLiveWorkspace', - 'Neos.Workspace.Ui:Backend.PublishAllToLiveWorkspace', - ['yaml', 'html', 'php'] - ); $this->searchAndReplace( 'Neos.Neos:Backend.CreateWorkspaces', 'Neos.Workspace.Ui:Backend.CreateWorkspaces', ['yaml', 'html', 'php'] ); - $this->searchAndReplace( - 'Neos.Neos:Backend.Module.Management.Workspaces.ManageOwnWorkspaces', - 'Neos.Workspace.Ui:Backend.Module.Management.Workspace.ManageOwnWorkspaces', - ['yaml', 'html', 'php'] - ); - $this->searchAndReplace( - 'Neos.Neos:Backend.Module.Management.Workspaces.ManageInternalWorkspaces', - 'Neos.Workspace.Ui:Backend.Module.Management.Workspace.ManageInternalWorkspaces', - ['yaml', 'html', 'php'] - ); - $this->searchAndReplace( - 'Neos.Neos:Backend.Module.Management.Workspaces.ManageAllPrivateWorkspaces', - 'Neos.Workspace.Ui:Backend.Module.Management.Workspace.ManageAllPrivateWorkspaces', - ['yaml', 'html', 'php'] - ); $this->searchAndReplace( 'Neos.Neos:Backend.Module.Management.Workspaces', 'Neos.Workspace.Ui:Backend.Module.Management.Workspace', From a03eb24440ea0bc8a7d2a3c88aa33b0fb63a9283 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Mon, 6 Jan 2025 11:24:00 +0100 Subject: [PATCH 2/3] TASK: Properly re-remove obsolete legacy `userInformation.personalWorkspaceName` in policy for workspaces `current.userInformation.personalWorkspaceName` (`UserService::getPersonalWorkspaceName()`) was initially removed in c3f51e2e0c37706b2935fde28ffbaaec6be59b3b because with multiple content repositories we cannot find out the value: ```php public function getPersonalWorkspaceName(): ?string { $currentUser = $this->userDomainService->getCurrentUser(); $cr = 'default'; // TODO!!! $this->workspaceService->getPersonalWorkspaceForUser($cr, $currentUser); return $workspace->workspaceName->value; } ``` This is luckily no longer needed as the now called `NodeAddressToNodeConverter` (which we decided to keep in Neos 9.0: https://github.com/neos/neos-development-collection/issues/4873) Will handle this itself through the security in `ContentRepository::getContentSubgraph()` via https://github.com/neos/neos-development-collection/pull/5298 Additionally, this pr makes `UserService::getPersonalWorkspaceName()` throw and exception to ease upgrading as otherwise `NULL` will be evaluated. --- Neos.Neos/Classes/Service/UserService.php | 12 ++++++++++++ Neos.Neos/Configuration/Policy.yaml | 8 -------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Neos.Neos/Classes/Service/UserService.php b/Neos.Neos/Classes/Service/UserService.php index 5326ad93220..ff18f261fa1 100644 --- a/Neos.Neos/Classes/Service/UserService.php +++ b/Neos.Neos/Classes/Service/UserService.php @@ -59,6 +59,18 @@ public function getBackendUser() return $this->userDomainService->getCurrentUser(); } + /** + * 8.3 behaviour: Returns the name of the currently logged in user's personal workspace + * (even if that might not exist at that time). + * If no user is logged in this method returns null. + * + * @deprecated and not implemented with Neos 9.0 - can be removed any time, just for the 8.3 upgrade phase + */ + public function getPersonalWorkspaceName(): ?string + { + throw new \LogicException('`userInformation.personalWorkspaceName` was removed in Neos 9.0 see https://github.com/neos/neos-development-collection/pull/5418'); + } + /** * Returns the stored preferences of a user * diff --git a/Neos.Neos/Configuration/Policy.yaml b/Neos.Neos/Configuration/Policy.yaml index d8b19e088c9..1267021d09b 100644 --- a/Neos.Neos/Configuration/Policy.yaml +++ b/Neos.Neos/Configuration/Policy.yaml @@ -43,10 +43,6 @@ privilegeTargets: label: Access to content service APIs matcher: 'method(Neos\Neos\Controller\Backend\SchemaController->(nodeTypeSchema)Action()) || method(Neos\Neos\Controller\Backend\SettingsController->editPreviewAction())' - 'Neos.Neos:Backend.PersonalWorkspaceReadAccess.NodeConverter': - label: Access to own personal workspace - matcher: 'method(Neos\Neos\TypeConverter\NodeConverter->prepareContextProperties(workspaceName === current.userInformation.personalWorkspaceName))' - 'Neos.Neos:Backend.EditContent': label: General access to content editing matcher: 'method(Neos\Neos\Service\Controller\NodeController->(show|getPrimaryChildNode|getChildNodesForTree|filterChildNodesForTree|getChildNodes|getChildNodesFromParent|create|createAndRender|createNodeForTheTree|move|moveBefore|moveAfter|moveInto|moveAndRender|copy|copyBefore|copyAfter|copyInto|copyAndRender|update|updateAndRender|delete|searchPage|error)Action()) || method(Neos\Neos\Controller\Backend\ContentController->(uploadAsset|assetsWithMetadata|imageWithMetadata|createImageVariant|error)Action()) || method(Neos\Neos\Controller\Service\AssetProxiesController->(index|show|import|error)Action()) || method(Neos\Neos\Controller\Service\AssetsController->(index|show|error)Action()) || method(Neos\Neos\Controller\Service\NodesController->(index|show|create|error)Action())' @@ -169,10 +165,6 @@ roles: privilegeTarget: 'Neos.Neos:ContentPreview' permission: GRANT - - - privilegeTarget: 'Neos.Neos:Backend.PersonalWorkspaceReadAccess.NodeConverter' - permission: GRANT - - privilegeTarget: 'Neos.Neos:Backend.EditContent' permission: GRANT From 09f4c2af8f95e4054172ae12a8f0a5e3fcd49576 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:02:09 +0100 Subject: [PATCH 3/3] TASK: Remove policy for removed `Neos\Neos\Service\Controller\NodeController` This legacy service controller was removed see https://github.com/neos/neos-development-collection/issues/5423 But as identified here there is still a method privilege to be adjusted: https://github.com/neos/neos-development-collection/issues/4478#issuecomment-2575353900 --- Neos.Neos/Configuration/Policy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Neos.Neos/Configuration/Policy.yaml b/Neos.Neos/Configuration/Policy.yaml index 1267021d09b..63c71c160a9 100644 --- a/Neos.Neos/Configuration/Policy.yaml +++ b/Neos.Neos/Configuration/Policy.yaml @@ -45,7 +45,7 @@ privilegeTargets: 'Neos.Neos:Backend.EditContent': label: General access to content editing - matcher: 'method(Neos\Neos\Service\Controller\NodeController->(show|getPrimaryChildNode|getChildNodesForTree|filterChildNodesForTree|getChildNodes|getChildNodesFromParent|create|createAndRender|createNodeForTheTree|move|moveBefore|moveAfter|moveInto|moveAndRender|copy|copyBefore|copyAfter|copyInto|copyAndRender|update|updateAndRender|delete|searchPage|error)Action()) || method(Neos\Neos\Controller\Backend\ContentController->(uploadAsset|assetsWithMetadata|imageWithMetadata|createImageVariant|error)Action()) || method(Neos\Neos\Controller\Service\AssetProxiesController->(index|show|import|error)Action()) || method(Neos\Neos\Controller\Service\AssetsController->(index|show|error)Action()) || method(Neos\Neos\Controller\Service\NodesController->(index|show|create|error)Action())' + matcher: 'method(Neos\Neos\Controller\Backend\ContentController->(uploadAsset|assetsWithMetadata|imageWithMetadata|createImageVariant|error)Action()) || method(Neos\Neos\Controller\Service\AssetProxiesController->(index|show|import|error)Action()) || method(Neos\Neos\Controller\Service\AssetsController->(index|show|error)Action()) || method(Neos\Neos\Controller\Service\NodesController->(index|show|create|error)Action())' # # User management and user settings