diff --git a/Classes/Application/ReloadNodes/ReloadNodesQueryHandler.php b/Classes/Application/ReloadNodes/ReloadNodesQueryHandler.php index 2b05c6903d..b43606c7f6 100644 --- a/Classes/Application/ReloadNodes/ReloadNodesQueryHandler.php +++ b/Classes/Application/ReloadNodes/ReloadNodesQueryHandler.php @@ -18,7 +18,6 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindChildNodesFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\NodeType\NodeTypeCriteria; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; -use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; @@ -51,10 +50,7 @@ public function handle(ReloadNodesQuery $query, ActionRequest $actionRequest): R { $contentRepository = $this->contentRepositoryRegistry ->get($query->contentRepositoryId); - $subgraph = $contentRepository->getContentGraph($query->workspaceName)->getSubgraph( - $query->dimensionSpacePoint, - VisibilityConstraints::withoutRestrictions() - ); + $subgraph = $contentRepository->getContentSubgraph($query->workspaceName, $query->dimensionSpacePoint); $baseNodeTypeConstraints = NodeTypeCriteria::fromFilterString($this->baseNodeType); $documentNode = $subgraph->findNodeById($query->documentId); diff --git a/Classes/ContentRepository/Service/NeosUiNodeService.php b/Classes/ContentRepository/Service/NeosUiNodeService.php index 07d0b8ee35..63fdad72e5 100644 --- a/Classes/ContentRepository/Service/NeosUiNodeService.php +++ b/Classes/ContentRepository/Service/NeosUiNodeService.php @@ -13,7 +13,6 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\Node; -use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; @@ -32,10 +31,7 @@ public function findNodeBySerializedNodeAddress(string $serializedNodeAddress): $nodeAddress = NodeAddress::fromJsonString($serializedNodeAddress); $contentRepository = $this->contentRepositoryRegistry->get($nodeAddress->contentRepositoryId); - $subgraph = $contentRepository->getContentGraph($nodeAddress->workspaceName)->getSubgraph( - $nodeAddress->dimensionSpacePoint, - VisibilityConstraints::withoutRestrictions() - ); + $subgraph = $contentRepository->getContentSubgraph($nodeAddress->workspaceName, $nodeAddress->dimensionSpacePoint); return $subgraph->findNodeById($nodeAddress->aggregateId); } } diff --git a/Classes/ContentRepository/Service/WorkspaceService.php b/Classes/ContentRepository/Service/WorkspaceService.php index d1b9834a3c..94a57d78f5 100644 --- a/Classes/ContentRepository/Service/WorkspaceService.php +++ b/Classes/ContentRepository/Service/WorkspaceService.php @@ -14,7 +14,6 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindClosestNodeFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; -use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; @@ -92,9 +91,9 @@ public function getPublishableNodeInfo(WorkspaceName $workspaceName, ContentRepo } foreach ($originDimensionSpacePoints as $originDimensionSpacePoint) { - $subgraph = $contentGraph->getSubgraph( + $subgraph = $contentRepository->getContentSubgraph( + $workspaceName, $originDimensionSpacePoint->toDimensionSpacePoint(), - VisibilityConstraints::withoutRestrictions() ); $node = $subgraph->findNodeById($change->nodeAggregateId); if ($node instanceof Node) { diff --git a/Classes/Controller/BackendController.php b/Classes/Controller/BackendController.php index 930035d88f..426c6c1be6 100644 --- a/Classes/Controller/BackendController.php +++ b/Classes/Controller/BackendController.php @@ -13,8 +13,6 @@ */ use Neos\ContentRepository\Core\Feature\SubtreeTagging\Dto\SubtreeTag; -use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; -use Neos\ContentRepository\Core\SharedModel\Exception\WorkspaceDoesNotExist; use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; @@ -151,9 +149,9 @@ public function indexAction(string $node = null) $rootDimensionSpacePoints = $contentRepository->getVariationGraph()->getRootGeneralizations(); $arbitraryRootDimensionSpacePoint = array_shift($rootDimensionSpacePoints); - $subgraph = $contentGraph->getSubgraph( - $nodeAddress ? $nodeAddress->dimensionSpacePoint : $arbitraryRootDimensionSpacePoint, - VisibilityConstraints::withoutRestrictions() + $subgraph = $contentRepository->getContentSubgraph( + $workspace->workspaceName, + $nodeAddress->dimensionSpacePoint ?? $arbitraryRootDimensionSpacePoint, ); // we assume that the ROOT node is always stored in the CR as "physical" node; so it is safe @@ -222,9 +220,9 @@ public function redirectToAction(string $node): void $contentRepository = $this->contentRepositoryRegistry->get($nodeAddress->contentRepositoryId); - $nodeInstance = $contentRepository->getContentGraph($nodeAddress->workspaceName)->getSubgraph( - $nodeAddress->dimensionSpacePoint, - VisibilityConstraints::withoutRestrictions() + $nodeInstance = $contentRepository->getContentSubgraph( + $nodeAddress->workspaceName, + $nodeAddress->dimensionSpacePoint )->findNodeById($nodeAddress->aggregateId); $workspace = $contentRepository->findWorkspaceByName($nodeAddress->workspaceName); diff --git a/Classes/Controller/BackendServiceController.php b/Classes/Controller/BackendServiceController.php index c77cb7d799..e4669b003a 100644 --- a/Classes/Controller/BackendServiceController.php +++ b/Classes/Controller/BackendServiceController.php @@ -17,7 +17,6 @@ use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint; use Neos\ContentRepository\Core\Feature\WorkspaceModification\Exception\WorkspaceIsNotEmptyException; use Neos\ContentRepository\Core\Feature\WorkspaceRebase\Dto\RebaseErrorHandlingStrategy; -use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; @@ -34,6 +33,7 @@ use Neos\Neos\Domain\Service\WorkspacePublishingService; use Neos\Neos\Domain\Service\WorkspaceService; use Neos\Neos\FrontendRouting\SiteDetection\SiteDetectionResult; +use Neos\Neos\Security\Authorization\ContentRepositoryAuthorizationService; use Neos\Neos\Service\UserService; use Neos\Neos\Ui\Application\ChangeTargetWorkspace; use Neos\Neos\Ui\Application\DiscardAllChanges; @@ -176,6 +176,12 @@ class BackendServiceController extends ActionController */ protected $throwableStorage2; + /** + * @Flow\Inject + * @var ContentRepositoryAuthorizationService + */ + protected $contentRepositoryAuthorizationService; + /** * Set the controller context on the feedback collection after the controller * has been initialized @@ -448,11 +454,10 @@ public function changeBaseWorkspaceAction(string $targetWorkspaceName, string $d } $contentRepository = $this->contentRepositoryRegistry->get($documentNodeAddress->contentRepositoryId); - $subgraph = $contentRepository->getContentGraph($userWorkspace->workspaceName) - ->getSubgraph( - $command->documentNode->dimensionSpacePoint, - VisibilityConstraints::withoutRestrictions() - ); + $subgraph = $contentRepository->getContentSubgraph( + $userWorkspace->workspaceName, + $command->documentNode->dimensionSpacePoint, + ); $documentNodeInstance = $subgraph->findNodeById($command->documentNode->aggregateId); assert($documentNodeInstance !== null); @@ -576,9 +581,9 @@ public function getAdditionalNodeMetadataAction(array $nodes): void foreach ($nodes as $nodeAddressString) { $nodeAddress = NodeAddress::fromJsonString($nodeAddressString); $contentRepository = $this->contentRepositoryRegistry->get($nodeAddress->contentRepositoryId); - $subgraph = $contentRepository->getContentGraph($nodeAddress->workspaceName)->getSubgraph( + $subgraph = $contentRepository->getContentSubgraph( + $nodeAddress->workspaceName, $nodeAddress->dimensionSpacePoint, - VisibilityConstraints::withoutRestrictions() ); $node = $subgraph->findNodeById($nodeAddress->aggregateId); @@ -587,13 +592,13 @@ public function getAdditionalNodeMetadataAction(array $nodes): void return $this->getCurrentDimensionPresetIdentifiersForNode($node); }, $node->getOtherNodeVariants())));*/ if (!is_null($node)) { + $nodePrivileges = $this->contentRepositoryAuthorizationService->getNodePermissions($node, $this->securityContext->getRoles()); $result[$nodeAddress->toJson()] = [ - // todo reimplement nodePolicyService 'policy' => [ - 'disallowedNodeTypes' => [], - 'canRemove' => true, - 'canEdit' => true, - 'disallowedProperties' => [] + 'disallowedNodeTypes' => [], // not implemented for Neos 9.0 + 'canRemove' => $nodePrivileges->edit, + 'canEdit' => $nodePrivileges->edit, + 'disallowedProperties' => [] // not implemented for Neos 9.0 ] //'dimensions' => $this->getCurrentDimensionPresetIdentifiersForNode($node), //'otherNodeVariants' => $otherNodeVariants @@ -604,43 +609,6 @@ public function getAdditionalNodeMetadataAction(array $nodes): void $this->view->assign('value', $result); } - /** - * @throws \Neos\Flow\Mvc\Exception\NoSuchArgumentException - */ - public function initializeGetPolicyInformationAction(): void - { - $this->arguments->getArgument('nodes')->getPropertyMappingConfiguration()->allowAllProperties(); - } - - /** - * @phpstan-param list $nodes - */ - public function getPolicyInformationAction(array $nodes): void - { - $result = []; - foreach ($nodes as $nodeAddress) { - $contentRepository = $this->contentRepositoryRegistry->get($nodeAddress->contentRepositoryId); - $subgraph = $contentRepository->getContentGraph($nodeAddress->workspaceName)->getSubgraph( - $nodeAddress->dimensionSpacePoint, - VisibilityConstraints::withoutRestrictions() - ); - $node = $subgraph->findNodeById($nodeAddress->aggregateId); - if (!is_null($node)) { - $result[$nodeAddress->toJson()] = [ - // todo reimplement nodePolicyService - 'policy' => [ - 'disallowedNodeTypes' => [], - 'canRemove' => true, - 'canEdit' => true, - 'disallowedProperties' => [] - ] - ]; - } - } - - $this->view->assign('value', $result); - } - /** * Build and execute a flow query chain * @@ -701,9 +669,9 @@ public function generateUriPathSegmentAction(string $contextNode, string $text): { $contextNodeAddress = NodeAddress::fromJsonString($contextNode); $contentRepository = $this->contentRepositoryRegistry->get($contextNodeAddress->contentRepositoryId); - $subgraph = $contentRepository->getContentGraph($contextNodeAddress->workspaceName)->getSubgraph( + $subgraph = $contentRepository->getContentSubgraph( + $contextNodeAddress->workspaceName, $contextNodeAddress->dimensionSpacePoint, - VisibilityConstraints::withoutRestrictions() ); $contextNode = $subgraph->findNodeById($contextNodeAddress->aggregateId); diff --git a/Classes/Domain/Model/Changes/CopyAfter.php b/Classes/Domain/Model/Changes/CopyAfter.php index 30d3dfc638..5396ee4175 100644 --- a/Classes/Domain/Model/Changes/CopyAfter.php +++ b/Classes/Domain/Model/Changes/CopyAfter.php @@ -14,7 +14,6 @@ use Neos\ContentRepository\Core\DimensionSpace\OriginDimensionSpacePoint; use Neos\ContentRepository\Core\Feature\NodeDuplication\Command\CopyNodesRecursively; -use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; /** * @internal These objects internally reflect possible operations made by the Neos.Ui. @@ -64,9 +63,9 @@ public function apply(): void $contentRepository = $this->contentRepositoryRegistry->get($subject->contentRepositoryId); $command = CopyNodesRecursively::createFromSubgraphAndStartNode( - $contentRepository->getContentGraph($subject->workspaceName)->getSubgraph( + $contentRepository->getContentSubgraph( + $subject->workspaceName, $subject->dimensionSpacePoint, - VisibilityConstraints::withoutRestrictions() ), $subject->workspaceName, $subject, diff --git a/Classes/Fusion/Helper/WorkspaceHelper.php b/Classes/Fusion/Helper/WorkspaceHelper.php index a3b316ff22..63ad825d21 100644 --- a/Classes/Fusion/Helper/WorkspaceHelper.php +++ b/Classes/Fusion/Helper/WorkspaceHelper.php @@ -18,6 +18,7 @@ use Neos\Flow\Security\Context; use Neos\Neos\Domain\Service\UserService; use Neos\Neos\Domain\Service\WorkspaceService; +use Neos\Neos\Security\Authorization\ContentRepositoryAuthorizationService; use Neos\Neos\Ui\ContentRepository\Service\WorkspaceService as UiWorkspaceService; /** @@ -55,6 +56,12 @@ class WorkspaceHelper implements ProtectedContextAwareInterface */ protected $workspaceService; + /** + * @Flow\Inject + * @var ContentRepositoryAuthorizationService + */ + protected $contentRepositoryAuthorizationService; + /** * @return array */ @@ -66,7 +73,7 @@ public function getPersonalWorkspace(ContentRepositoryId $contentRepositoryId): } $contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId); $personalWorkspace = $this->workspaceService->getPersonalWorkspaceForUser($contentRepositoryId, $currentUser->getId()); - $personalWorkspacePermissions = $this->workspaceService->getWorkspacePermissionsForUser($contentRepositoryId, $personalWorkspace->workspaceName, $currentUser); + $personalWorkspacePermissions = $this->contentRepositoryAuthorizationService->getWorkspacePermissions($contentRepositoryId, $personalWorkspace->workspaceName, $this->securityContext->getRoles(), $currentUser->getId()); $publishableNodes = $this->uiWorkspaceService->getPublishableNodeInfo($personalWorkspace->workspaceName, $contentRepository->id); return [ 'name' => $personalWorkspace->workspaceName->value, diff --git a/Classes/Infrastructure/Configuration/ConfigurationProvider.php b/Classes/Infrastructure/Configuration/ConfigurationProvider.php index 15e1752c2c..68ccdb3af2 100644 --- a/Classes/Infrastructure/Configuration/ConfigurationProvider.php +++ b/Classes/Infrastructure/Configuration/ConfigurationProvider.php @@ -18,8 +18,10 @@ use Neos\Flow\Annotations as Flow; use Neos\Flow\Configuration\ConfigurationManager; use Neos\Flow\Mvc\Routing\UriBuilder; +use Neos\Flow\Security\Context as SecurityContext; use Neos\Neos\Domain\Model\WorkspaceClassification; use Neos\Neos\Domain\Service\WorkspaceService; +use Neos\Neos\Security\Authorization\ContentRepositoryAuthorizationService; use Neos\Neos\Service\UserService; use Neos\Neos\Ui\Domain\InitialData\CacheConfigurationVersionProviderInterface; use Neos\Neos\Ui\Domain\InitialData\ConfigurationProviderInterface; @@ -33,12 +35,18 @@ final class ConfigurationProvider implements ConfigurationProviderInterface #[Flow\Inject] protected UserService $userService; + #[Flow\Inject] + protected SecurityContext $securityContext; + #[Flow\Inject] protected ConfigurationManager $configurationManager; #[Flow\Inject] protected WorkspaceService $workspaceService; + #[Flow\Inject] + protected ContentRepositoryAuthorizationService $contentRepositoryAuthorizationService; + #[Flow\Inject] protected CacheConfigurationVersionProviderInterface $cacheConfigurationVersionProvider; @@ -93,17 +101,13 @@ public function getConfiguration( */ private function getAllowedTargetWorkspaces(ContentRepository $contentRepository): array { - $backendUser = $this->userService->getBackendUser(); - if ($backendUser === null) { - return []; - } $result = []; foreach ($contentRepository->findWorkspaces() as $workspace) { $workspaceMetadata = $this->workspaceService->getWorkspaceMetadata($contentRepository->id, $workspace->workspaceName); if (!in_array($workspaceMetadata->classification, [WorkspaceClassification::ROOT, WorkspaceClassification::SHARED], true)) { continue; } - $workspacePermissions = $this->workspaceService->getWorkspacePermissionsForUser($contentRepository->id, $workspace->workspaceName, $backendUser); + $workspacePermissions = $this->contentRepositoryAuthorizationService->getWorkspacePermissions($contentRepository->id, $workspace->workspaceName, $this->securityContext->getRoles(), $this->userService->getBackendUser()?->getId()); if ($workspacePermissions->read === false) { continue; } diff --git a/Classes/Infrastructure/ContentRepository/ConflictsFactory.php b/Classes/Infrastructure/ContentRepository/ConflictsFactory.php index a9268c8e8d..214e7bcd1c 100644 --- a/Classes/Infrastructure/ContentRepository/ConflictsFactory.php +++ b/Classes/Infrastructure/ContentRepository/ConflictsFactory.php @@ -35,7 +35,6 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindClosestNodeFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\ContentGraph\NodeAggregate; -use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; use Neos\ContentRepository\Core\SharedModel\Exception\NodeAggregateCurrentlyDoesNotExist; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Workspace\Workspace; @@ -188,12 +187,10 @@ private function acquireSubgraph( return null; } - return $this->contentRepository - ->getContentGraph($this->workspace->workspaceName) - ->getSubgraph( - $dimensionSpacePoint, - VisibilityConstraints::withoutRestrictions() - ); + return $this->contentRepository->getContentSubgraph( + $this->workspace->workspaceName, + $dimensionSpacePoint, + ); } private function extractValidDimensionSpacePointFromNodeAggregate(