From 73e2eb3d41c4534bd6024198f0848e3774ba5e09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Jedenastik?= Date: Tue, 9 May 2023 12:01:53 +0200 Subject: [PATCH 1/2] BUGFIX: MenuHelper uses content dimensions to get node for privilege check --- .../Classes/Controller/Backend/MenuHelper.php | 84 +++++++++++++------ 1 file changed, 59 insertions(+), 25 deletions(-) diff --git a/Neos.Neos/Classes/Controller/Backend/MenuHelper.php b/Neos.Neos/Classes/Controller/Backend/MenuHelper.php index 779337503c1..c03ecf39385 100644 --- a/Neos.Neos/Classes/Controller/Backend/MenuHelper.php +++ b/Neos.Neos/Classes/Controller/Backend/MenuHelper.php @@ -11,6 +11,7 @@ * source code. */ +use Neos\ContentRepository\Domain\Service\ContentDimensionCombinator; use Neos\ContentRepository\Security\Authorization\Privilege\Node\NodePrivilegeSubject; use Neos\Flow\Annotations as Flow; use Neos\Flow\Http\Exception; @@ -69,6 +70,12 @@ class MenuHelper */ protected $contextFactory; + /** + * @Flow\Inject + * @var ContentDimensionCombinator + */ + protected $contentDimensionCombinator; + /** * @param array $settings */ @@ -93,38 +100,65 @@ public function buildSiteList(ControllerContext $controllerContext): array return []; } - $context = $this->contextFactory->create(); + // generate ContentContext for all possible dimension combinations + $combinations = $this->contentDimensionCombinator->getAllAllowedCombinations(); + $contentContexts = []; + foreach ($combinations as $dimensionCombination) { + $contentContexts[] = $this->contextFactory->create([ + 'dimensions' => $dimensionCombination, + 'invisibleContentShown' => true, + 'inaccessibleContentShown' => true, + ]); + } + $domainsFound = false; $sites = []; foreach ($this->siteRepository->findOnline() as $site) { - $node = $context->getNode(\Neos\ContentRepository\Domain\Utility\NodePaths::addNodePathSegment(SiteService::SITES_ROOT_PATH, $site->getNodeName())); - if ($this->privilegeManager->isGranted(NodeTreePrivilege::class, new NodePrivilegeSubject($node))) { - $uri = null; - $active = false; - /** @var $site Site */ - if ($site->hasActiveDomains()) { - $activeHostPatterns = $site->getActiveDomains()->map(static function ($domain) { - return $domain->getHostname(); - })->toArray(); - - $active = in_array($requestUriHost, $activeHostPatterns, true); - - if ($active) { - $uri = $contentModule['uri']; - } else { - $uri = $controllerContext->getUriBuilder()->reset()->uriFor('switchSite', ['site' => $site], 'Backend\Backend', 'Neos.Neos'); - } + $granted = false; + foreach ($contentContexts as $context) { + // check if the site node exists in the context dimension + $node = $context->getNode(\Neos\ContentRepository\Domain\Utility\NodePaths::addNodePathSegment(SiteService::SITES_ROOT_PATH, $site->getNodeName())); + if (!$node) { + continue; + } - $domainsFound = true; + // if the node exists, check if the user is granted access to this node + if ($this->privilegeManager->isGranted(NodeTreePrivilege::class, new NodePrivilegeSubject($node))) { + $granted = true; + break; } + } - $sites[] = [ - 'name' => $site->getName(), - 'nodeName' => $site->getNodeName(), - 'uri' => $uri, - 'active' => $active - ]; + // if no siteNode is accessible ignore this site + if (!$granted) { + continue; + } + + $uri = null; + $active = false; + /** @var $site Site */ + if ($site->hasActiveDomains()) { + $activeHostPatterns = $site->getActiveDomains()->map(static function ($domain) { + return $domain->getHostname(); + })->toArray(); + + $active = in_array($requestUriHost, $activeHostPatterns, true); + + if ($active) { + $uri = $contentModule['uri']; + } else { + $uri = $controllerContext->getUriBuilder()->reset()->uriFor('switchSite', ['site' => $site], 'Backend\Backend', 'Neos.Neos'); + } + + $domainsFound = true; } + + $sites[] = [ + 'name' => $site->getName(), + 'nodeName' => $site->getNodeName(), + 'uri' => $uri, + 'active' => $active + ]; } if ($domainsFound === false) { From 8fae658eb52212e024abdaea0253fff0447468eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Jedenastik?= Date: Tue, 6 Feb 2024 12:21:54 +0100 Subject: [PATCH 2/2] TASK: MenuHelper uses NodeDataRepository::findByPathWithoutReduce instead of ContentDimensionCombinator --- .../Classes/Controller/Backend/MenuHelper.php | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/Neos.Neos/Classes/Controller/Backend/MenuHelper.php b/Neos.Neos/Classes/Controller/Backend/MenuHelper.php index c03ecf39385..54694d6f28c 100644 --- a/Neos.Neos/Classes/Controller/Backend/MenuHelper.php +++ b/Neos.Neos/Classes/Controller/Backend/MenuHelper.php @@ -11,14 +11,16 @@ * source code. */ -use Neos\ContentRepository\Domain\Service\ContentDimensionCombinator; +use Neos\ContentRepository\Domain\Factory\NodeFactory; +use Neos\ContentRepository\Domain\Repository\NodeDataRepository; +use Neos\ContentRepository\Domain\Repository\WorkspaceRepository; +use Neos\ContentRepository\Domain\Utility\NodePaths; use Neos\ContentRepository\Security\Authorization\Privilege\Node\NodePrivilegeSubject; use Neos\Flow\Annotations as Flow; use Neos\Flow\Http\Exception; use Neos\Flow\Mvc\Controller\ControllerContext; use Neos\Flow\Mvc\Routing\Exception\MissingActionNameException; use Neos\Flow\Security\Authorization\PrivilegeManagerInterface; -use Neos\Neos\Domain\Service\ContentContextFactory; use Neos\Neos\Domain\Service\SiteService; use Neos\Neos\Security\Authorization\Privilege\ModulePrivilege; use Neos\Neos\Security\Authorization\Privilege\ModulePrivilegeSubject; @@ -66,15 +68,21 @@ class MenuHelper /** * @Flow\Inject - * @var ContentContextFactory + * @var WorkspaceRepository */ - protected $contextFactory; + protected $workspaceRepository; /** * @Flow\Inject - * @var ContentDimensionCombinator + * @var NodeDataRepository */ - protected $contentDimensionCombinator; + protected $nodeDataRepository; + + /** + * @Flow\Inject + * @var NodeFactory + */ + protected $nodeFactory; /** * @param array $settings @@ -100,30 +108,22 @@ public function buildSiteList(ControllerContext $controllerContext): array return []; } - // generate ContentContext for all possible dimension combinations - $combinations = $this->contentDimensionCombinator->getAllAllowedCombinations(); - $contentContexts = []; - foreach ($combinations as $dimensionCombination) { - $contentContexts[] = $this->contextFactory->create([ - 'dimensions' => $dimensionCombination, - 'invisibleContentShown' => true, - 'inaccessibleContentShown' => true, - ]); - } + $liveWorkspace = $this->workspaceRepository->findByIdentifier('live'); $domainsFound = false; $sites = []; foreach ($this->siteRepository->findOnline() as $site) { $granted = false; - foreach ($contentContexts as $context) { - // check if the site node exists in the context dimension - $node = $context->getNode(\Neos\ContentRepository\Domain\Utility\NodePaths::addNodePathSegment(SiteService::SITES_ROOT_PATH, $site->getNodeName())); - if (!$node) { - continue; - } + + $siteNodePath = NodePaths::addNodePathSegment(SiteService::SITES_ROOT_PATH, $site->getNodeName()); + $siteNodesInAllDimensions = $this->nodeDataRepository->findByPathWithoutReduce($siteNodePath, $liveWorkspace); + + foreach ($siteNodesInAllDimensions as $siteNodeData) { + $siteNodeContext = $this->nodeFactory->createContextMatchingNodeData($siteNodeData); + $siteNode = $this->nodeFactory->createFromNodeData($siteNodeData, $siteNodeContext); // if the node exists, check if the user is granted access to this node - if ($this->privilegeManager->isGranted(NodeTreePrivilege::class, new NodePrivilegeSubject($node))) { + if ($this->privilegeManager->isGranted(NodeTreePrivilege::class, new NodePrivilegeSubject($siteNode))) { $granted = true; break; }