Skip to content

Commit

Permalink
TASK: Add security tests for workspace service
Browse files Browse the repository at this point in the history
assert that base workspace creation is only allowed for writing

and that managing (setting title and roles) is only allowed to managers
  • Loading branch information
mhsdesign committed Nov 15, 2024
1 parent efca124 commit 8768298
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Neos.Neos/Classes/Domain/Service/WorkspaceService.php
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ private function requireManagementWorkspacePermission(ContentRepositoryId $conte
$this->userService->getCurrentUser()?->getId()
);
if (!$workspacePermissions->manage) {
throw new AccessDenied(sprintf('The current user does not have manage permissions for workspace "%s" in content repository "%s"', $workspaceName->value, $contentRepositoryId->value), 1731654519);
throw new AccessDenied(sprintf('Managing workspace "%s" in "%s" was denied: %s', $workspaceName->value, $contentRepositoryId->value, $workspacePermissions->getReason()), 1731654519);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,21 @@ private function tryCatchingExceptions(\Closure $callback): mixed
}

/**
* @Then an exception of type :expectedShortExceptionName should be thrown with code :code
* @Then an exception of type :expectedShortExceptionName should be thrown with message:
* @Then an exception of type :expectedShortExceptionName should be thrown
*/
public function anExceptionShouldBeThrown(string $expectedShortExceptionName, PyStringNode $expectedExceptionMessage = null): void
public function anExceptionShouldBeThrown(string $expectedShortExceptionName, ?int $code = null, PyStringNode $expectedExceptionMessage = null): void
{
Assert::assertNotNull($this->lastCaughtException, 'Expected an exception but none was thrown');
$lastCaughtExceptionShortName = (new \ReflectionClass($this->lastCaughtException))->getShortName();
Assert::assertSame($expectedShortExceptionName, $lastCaughtExceptionShortName, sprintf('Actual exception: %s (%s): %s', get_debug_type($this->lastCaughtException), $this->lastCaughtException->getCode(), $this->lastCaughtException->getMessage()));
if ($expectedExceptionMessage !== null) {
Assert::assertSame($expectedExceptionMessage->getRaw(), $this->lastCaughtException->getMessage());
}
if ($code !== null) {
Assert::assertSame($code, $this->lastCaughtException->getCode());
}
$this->lastCaughtException = null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,35 @@ Feature: Workspace permission related features
| admin |
| editor |
| restricted_editor |
| owner |
| collaborator |
| uninvolved |

Scenario Outline: Creating a base workspace without WRITE 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

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

Examples:
| user |
| admin |
| editor |
| restricted_editor |
| uninvolved |

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

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

Examples:
| user |
| collaborator |
| owner |

Scenario Outline: Deleting a workspace without MANAGE permissions
Given I am authenticated as <user>
Expand All @@ -103,7 +132,43 @@ Feature: Workspace permission related features
| manager |
| owner |

Scenario Outline: Managing metadata and roles of a workspace without MANAGE permissions
Given I am authenticated as <user>
And the title of workspace "workspace" is set to "Some new workspace title"
Then an exception of type "AccessDenied" should be thrown with code 1731654519

And the description of workspace "workspace" is set to "Some new workspace description"
Then an exception of type "AccessDenied" should be thrown with code 1731654519

When the role COLLABORATOR is assigned to workspace "workspace" for group "Neos.Neos:AbstractEditor"
Then an exception of type "AccessDenied" should be thrown with code 1731654519

When the role for group "Neos.Neos:AbstractEditor" is unassigned from workspace "workspace"
Then an exception of type "AccessDenied" should be thrown with code 1731654519

Examples:
| user |
| collaborator |
| uninvolved |

Scenario Outline: Managing metadata and roles of a workspace with MANAGE permissions
Given I am authenticated as <user>
And the title of workspace "workspace" is set to "Some new workspace title"
And the description of workspace "workspace" is set to "Some new workspace description"
When the role COLLABORATOR is assigned to workspace "workspace" for group "Neos.Neos:AbstractEditor"
When the role for group "Neos.Neos:AbstractEditor" is unassigned from workspace "workspace"

Examples:
| user |
| admin |
| manager |
| owner |

Scenario Outline: Handling commands that require WRITE permissions on the workspace
When I am authenticated as "uninvolved"
And the command <command> is executed with payload '<command payload>' and exceptions are caught
Then the last command should have thrown an exception of type "AccessDenied" with code 1729086686

When I am authenticated as "editor"
And the command <command> is executed with payload '<command payload>' and exceptions are caught
Then the last command should have thrown an exception of type "AccessDenied" with code 1729086686
Expand All @@ -119,6 +184,10 @@ Feature: Workspace permission related features
When I am authenticated as "owner"
And the command <command> is executed with payload '<command payload>'

# todo test also collaborator, but cannot commands twice here:
# When I am authenticated as "collaborator"
# And the command <command> is executed with payload '<command payload>' and exceptions are caught

Examples:
| command | command payload |
| CreateNodeAggregateWithNode | {"nodeAggregateId":"a1b1","parentNodeAggregateId":"a1b","nodeTypeName":"Neos.Neos:Document"} |
Expand Down

0 comments on commit 8768298

Please sign in to comment.