Skip to content

Instantly share code, notes, and snippets.

@Benjamin-K
Created December 5, 2022 16:42
Show Gist options
  • Save Benjamin-K/78c99f19a6dd9de8dfa276cdfdfa82f8 to your computer and use it in GitHub Desktop.
Save Benjamin-K/78c99f19a6dd9de8dfa276cdfdfa82f8 to your computer and use it in GitHub Desktop.
Neos: Add policy method to check if user is in workspace (instead of node)
<?php
// File: Classes/Aspects/NodePrivilegeContextAspect.php
declare(strict_types=1);
namespace Your\Package\Aspects;
use Neos\Flow\Annotations as Flow;
/**
* Add additional methods to NodePrivilegeContext
*
* @Flow\Introduce("class(Neos\ContentRepository\Security\Authorization\Privilege\Node\NodePrivilegeContext)", traitName="Your\Package\Security\Authorization\Privilege\Node\UserIsInWorkspaceTrait")
* @Flow\Aspect
*/
class NodePrivilegeContextAspect
{
}
<?php
// File: Classes/Security/Authorization/Privilege/Node/UserIsInWorkspaceTrait.php
declare(strict_types=1);
namespace Your\Package\Security\Authorization\Privilege\Node;
use Neos\ContentRepository\Domain\Model\Workspace;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Core\Bootstrap;
trait UserIsInWorkspaceTrait
{
/**
* @Flow\Inject
* @var \Your\Package\Service\UserService
*/
protected $_userService;
/**
* Matches if the current user is in one of the given target workspaces
*
* Example userIsInTargetWorkspace(['preview-svxg3']) matches if the current user has selected workspace "preview-svxg3" as target workspace
*
* @param string|array $workspaceNames An array of workspace names, e.g. ["live", "preview-svxg3"]
* @return boolean true if the current user is in one of the given $workspaceNames, otherwise false
*/
public function userIsInTargetWorkspace($workspaceNames): bool
{
if ($this->_userService === null) {
// As class properties are not properly loaded in a trait used for an aspect, we need to load it ourself
$this->_userService = Bootstrap::$staticObjectManager->get('Your\Package\Service\UserService');
}
if ($this->node === null) {
return true;
}
/** @var Workspace|null */
$baseWorkspace = $this->_userService->getCurrentUsersBaseWorkspace();
if ($baseWorkspace === null) {
// User is not logged in or has no base workspace
return true;
}
if (!is_array($workspaceNames)) {
$workspaceNames = [$workspaceNames];
}
return in_array($baseWorkspace->getName(), $workspaceNames);
}
}
<?php
// File: Classes/Service/UserService.php
declare(strict_types=1);
namespace Your\Package\Service;
use Neos\Flow\Annotations as Flow;
use Neos\ContentRepository\Domain\Model\Workspace;
/**
* @Flow\Scope("singleton")
* @api
*/
class UserService extends \Neos\Neos\Service\UserService
{
/**
* @var Workspace|false
*/
protected $baseWorkspace = false;
/**
* Get users base workspace and store it for faster future requests.
*
* @return ?Workspace
*/
public function getCurrentUsersBaseWorkspace(): ?Workspace
{
if ($this->baseWorkspace === false) {
$userWorkspaceName = $this->getPersonalWorkspaceName();
if ($userWorkspaceName === null) {
// User is not logged in
$this->baseWorkspace = null;
return null;
}
/** @var Workspace */
$userWorkspace = $this->workspaceRepository->findOneByName($userWorkspaceName, true, true);
if ($userWorkspace === null) {
$this->baseWorkspace = null;
return null;
}
$this->baseWorkspace = $userWorkspace->getBaseWorkspace();
}
return $this->baseWorkspace;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment