Skip to content

Commit

Permalink
TASK: Allow workspace creation with only base workspace read privilege
Browse files Browse the repository at this point in the history
as change base workspace would allow either way to repoint the base
  • Loading branch information
mhsdesign committed Dec 6, 2024
1 parent 0257b28 commit d514e61
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ public function canExecuteCommand(CommandInterface $command): Privilege
if ($command instanceof CreateRootWorkspace) {
return Privilege::denied('Creation of root workspaces is currently only allowed with disabled authorization checks');
}
if ($command instanceof CreateWorkspace) {
$baseWorkspacePermissions = $this->getWorkspacePermissionsForCurrentUser($command->baseWorkspaceName);
if (!$baseWorkspacePermissions->read) {
return Privilege::denied(sprintf('Missing "read" permissions for base workspace "%s": %s', $command->baseWorkspaceName->value, $baseWorkspacePermissions->getReason()));
}
return Privilege::granted(sprintf('User has "read" permissions for base workspace "%s"', $command->baseWorkspaceName->value));
}
if ($command instanceof ChangeBaseWorkspace) {
$workspacePermissions = $this->getWorkspacePermissionsForCurrentUser($command->workspaceName);
if (!$workspacePermissions->manage) {
Expand All @@ -139,7 +146,6 @@ public function canExecuteCommand(CommandInterface $command): Privilege
PublishWorkspace::class,
PublishIndividualNodesFromWorkspace::class,
RebaseWorkspace::class => $this->requireWorkspaceWritePermission($command->workspaceName),
CreateWorkspace::class => $this->requireWorkspaceWritePermission($command->baseWorkspaceName),
DeleteWorkspace::class => $this->requireWorkspaceManagePermission($command->workspaceName),
default => Privilege::granted('Command not restricted'),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@
use Neos\Flow\Persistence\PersistenceManagerInterface;
use Neos\Flow\Security\AccountFactory;
use Neos\Flow\Security\Cryptography\HashService;
use Neos\Flow\Security\Policy\PolicyService;
use Neos\Neos\Domain\Model\User;
use Neos\Neos\Domain\Service\UserService;
use Neos\Neos\Security\Authorization\Privilege\ReadNodePrivilege;
use Neos\Party\Domain\Model\PersonName;
use Neos\Utility\ObjectAccess;

Expand Down Expand Up @@ -61,11 +59,14 @@ public function theNeosUserExists(string $username, string $id = null, string $f
public function theFollowingNeosUsersExist(TableNode $usersTable): void
{
foreach ($usersTable->getHash() as $userData) {
if (empty($userData['Roles'])) {
throw new \InvalidArgumentException('Please specify explicit roles for the Neos user, to avoid using any fallbacks.');
}
$this->createUser(
username: $userData['Username'],
firstName: $userData['First name'] ?? null,
lastName: $userData['Last name'] ?? null,
roleIdentifiers: !empty($userData['Roles']) ? explode(',', $userData['Roles']) : null,
roleIdentifiers: explode(',', $userData['Roles']),
id: $userData['Id'] ?? null,
);
}
Expand All @@ -81,6 +82,7 @@ private function createUser(string $username, string $firstName = null, string $

$accountFactory = $this->getObject(AccountFactory::class);

// todo either hack the global hash service or fix flow to avoid having to inline this code
// NOTE: We replace the original {@see HashService} by a "mock" for performance reasons (the default hashing strategy usually takes a while to create passwords)

/** @var HashService $originalHashService */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,15 @@ Feature: Workspace permission related features
And the following Neos users exist:
| Username | Roles |
| admin | Neos.Neos:Administrator |
# editors are Neos.Neos:LivePublisher
| editor | Neos.Neos:Editor |
| restricted_editor | Neos.Neos:RestrictedEditor |
| owner | Neos.Neos:Editor |
| manager | Neos.Neos:Editor |
| collaborator | Neos.Neos:Editor |
| restricted_editor | Neos.Neos:RestrictedEditor |
| uninvolved | Neos.Neos:Editor |
# neos user with out any editing roles
| simple_user | Neos.Neos:UserManager |

When content repository security is enabled

Expand All @@ -72,8 +75,9 @@ Feature: Workspace permission related features
| owner |
| collaborator |
| uninvolved |
| simple_user |

Scenario Outline: Creating a base workspace without WRITE permissions
Scenario Outline: Creating a nested workspace without READ permissions
Given I am authenticated as <user>
And the shared workspace "some-shared-workspace" is created with the target workspace "workspace"
Then an exception of type "AccessDenied" should be thrown with code 1729086686
Expand All @@ -87,8 +91,9 @@ Feature: Workspace permission related features
| editor |
| restricted_editor |
| uninvolved |
| simple_user |

Scenario Outline: Creating a base workspace with WRITE permissions
Scenario Outline: Creating a nested workspace with READ permissions
Given I am authenticated as <user>
And the shared workspace "some-shared-workspace" is created with the target workspace "workspace"

Expand All @@ -99,6 +104,33 @@ Feature: Workspace permission related features
| collaborator |
| owner |

Scenario Outline: Creating a workspace without READ permissions (on live)
Given I am authenticated as <user>
And the shared workspace "some-shared-workspace" is created with the target workspace "live"
Then an exception of type "AccessDenied" should be thrown with code 1729086686

And the personal workspace "some-other-personal-workspace" is created with the target workspace "live" for user <user>
Then an exception of type "AccessDenied" should be thrown with code 1729086686

Examples:
| user |
| restricted_editor |
| simple_user |

Scenario Outline: Creating a workspace with READ permissions (on live)
Given I am authenticated as <user>
And the shared workspace "some-shared-workspace" is created with the target workspace "live"

And the personal workspace "some-other-personal-workspace" is created with the target workspace "live" for user <user>

Examples:
| user |
| admin |
| editor |
| owner |
| collaborator |
| uninvolved |

Scenario Outline: Changing a base workspace without MANAGE permissions or READ permissions on the base workspace
Given I am authenticated as <user>
When the command ChangeBaseWorkspace is executed with payload and exceptions are caught:
Expand Down Expand Up @@ -136,6 +168,7 @@ Feature: Workspace permission related features
| user |
| collaborator |
| uninvolved |
| simple_user |

Scenario Outline: Deleting a workspace with MANAGE permissions
Given I am authenticated as <user>
Expand Down Expand Up @@ -247,5 +280,6 @@ Feature: Workspace permission related features
| PublishWorkspace | {} |
| PublishIndividualNodesFromWorkspace | {"nodesToPublish":[{"nodeAggregateId":"a1"}]} |
| RebaseWorkspace | {} |
# note, creating a core workspace will not grant permissions to it to the current user: Missing "read" permissions for base workspace "new-workspace"
| CreateWorkspace | {"workspaceName":"new-workspace","baseWorkspaceName":"workspace","newContentStreamId":"any"} |

0 comments on commit d514e61

Please sign in to comment.