diff --git a/Neos.Neos/Classes/Command/WorkspaceCommandController.php b/Neos.Neos/Classes/Command/WorkspaceCommandController.php index a066a36452d..b55b5833658 100644 --- a/Neos.Neos/Classes/Command/WorkspaceCommandController.php +++ b/Neos.Neos/Classes/Command/WorkspaceCommandController.php @@ -302,9 +302,11 @@ public function assignRoleCommand(string $workspace, string $subject, string $ro $this->workspaceService->assignWorkspaceRole( $contentRepositoryId, $workspaceName, - $subjectType, - $roleSubject, - $workspaceRole, + WorkspaceRoleAssignment::create( + $subjectType, + $roleSubject, + $workspaceRole + ) ); $this->outputLine('Assigned role "%s" to subject "%s" for workspace "%s"', [$workspaceRole->value, $roleSubject->value, $workspaceName->value]); } diff --git a/Neos.Neos/Classes/Domain/Model/WorkspaceRoleAssignment.php b/Neos.Neos/Classes/Domain/Model/WorkspaceRoleAssignment.php index ba6e6370138..fd7d5a7896f 100644 --- a/Neos.Neos/Classes/Domain/Model/WorkspaceRoleAssignment.php +++ b/Neos.Neos/Classes/Domain/Model/WorkspaceRoleAssignment.php @@ -14,10 +14,36 @@ #[Flow\Proxy(false)] final readonly class WorkspaceRoleAssignment { - public function __construct( + private function __construct( public WorkspaceRoleSubjectType $subjectType, public WorkspaceRoleSubject $subject, public WorkspaceRole $role, ) { } + + public static function create( + WorkspaceRoleSubjectType $subjectType, + WorkspaceRoleSubject $subject, + WorkspaceRole $role, + ): self { + return new self($subjectType, $subject, $role); + } + + public static function createForUser(UserId $userId, WorkspaceRole $role): self + { + return new self( + WorkspaceRoleSubjectType::USER, + WorkspaceRoleSubject::fromString($userId->value), + $role + ); + } + + public static function createForGroup(string $flowRoleIdentifier, WorkspaceRole $role): self + { + return new self( + WorkspaceRoleSubjectType::GROUP, + WorkspaceRoleSubject::fromString($flowRoleIdentifier), + $role + ); + } } diff --git a/Neos.Neos/Classes/Domain/Service/WorkspaceService.php b/Neos.Neos/Classes/Domain/Service/WorkspaceService.php index 19cbd5faac1..5f854bc2689 100644 --- a/Neos.Neos/Classes/Domain/Service/WorkspaceService.php +++ b/Neos.Neos/Classes/Domain/Service/WorkspaceService.php @@ -151,6 +151,7 @@ public function createSharedWorkspace(ContentRepositoryId $contentRepositoryId, /** * Create a new, personal, workspace for the specified user if none exists yet + * @internal experimental api, until actually used by the Neos.Ui */ public function createPersonalWorkspaceForUserIfMissing(ContentRepositoryId $contentRepositoryId, User $user): void { @@ -176,21 +177,21 @@ public function createPersonalWorkspaceForUserIfMissing(ContentRepositoryId $con * Without explicit workspace roles, only administrators can change the corresponding workspace. * With this method, the subject (i.e. a Neos user or group represented by a Flow role identifier) can be granted a {@see WorkspaceRole} for the specified workspace */ - public function assignWorkspaceRole(ContentRepositoryId $contentRepositoryId, WorkspaceName $workspaceName, WorkspaceRoleSubjectType $subjectType, WorkspaceRoleSubject $subject, WorkspaceRole $role): void + public function assignWorkspaceRole(ContentRepositoryId $contentRepositoryId, WorkspaceName $workspaceName, WorkspaceRoleAssignment $assignment): void { $this->requireWorkspace($contentRepositoryId, $workspaceName); try { $this->dbal->insert(self::TABLE_NAME_WORKSPACE_ROLE, [ 'content_repository_id' => $contentRepositoryId->value, 'workspace_name' => $workspaceName->value, - 'subject_type' => $subjectType->value, - 'subject' => $subject->value, - 'role' => $role->value, + 'subject_type' => $assignment->subjectType->value, + 'subject' => $assignment->subject->value, + 'role' => $assignment->role->value, ]); } catch (UniqueConstraintViolationException $e) { - throw new \RuntimeException(sprintf('Failed to assign role for workspace "%s" to subject "%s" (Content Repository "%s"): There is already a role assigned for that user/group, please unassign that first', $workspaceName->value, $subject->value, $contentRepositoryId->value), 1728476154, $e); + throw new \RuntimeException(sprintf('Failed to assign role for workspace "%s" to subject "%s" (Content Repository "%s"): There is already a role assigned for that user/group, please unassign that first', $workspaceName->value, $assignment->subject->value, $contentRepositoryId->value), 1728476154, $e); } catch (DbalException $e) { - throw new \RuntimeException(sprintf('Failed to assign role for workspace "%s" to subject "%s" (Content Repository "%s"): %s', $workspaceName->value, $subject->value, $contentRepositoryId->value, $e->getMessage()), 1728396138, $e); + throw new \RuntimeException(sprintf('Failed to assign role for workspace "%s" to subject "%s" (Content Repository "%s"): %s', $workspaceName->value, $assignment->subject->value, $contentRepositoryId->value, $e->getMessage()), 1728396138, $e); } } @@ -243,7 +244,7 @@ public function getWorkspaceRoleAssignments(ContentRepositoryId $contentReposito throw new \RuntimeException(sprintf('Failed to fetch workspace role assignments for workspace "%s" (Content Repository "%s"): %s', $workspaceName->value, $contentRepositoryId->value, $e->getMessage()), 1728474440, $e); } return WorkspaceRoleAssignments::fromArray( - array_map(static fn (array $row) => new WorkspaceRoleAssignment( + array_map(static fn (array $row) => WorkspaceRoleAssignment::create( WorkspaceRoleSubjectType::from($row['subject_type']), WorkspaceRoleSubject::fromString($row['subject']), WorkspaceRole::from($row['role']), diff --git a/Neos.Neos/Tests/Behavior/Features/Bootstrap/WorkspaceServiceTrait.php b/Neos.Neos/Tests/Behavior/Features/Bootstrap/WorkspaceServiceTrait.php index fa7c30b70c3..0570d6ee3b9 100644 --- a/Neos.Neos/Tests/Behavior/Features/Bootstrap/WorkspaceServiceTrait.php +++ b/Neos.Neos/Tests/Behavior/Features/Bootstrap/WorkspaceServiceTrait.php @@ -165,9 +165,11 @@ public function theRoleIsAssignedToWorkspaceForGroupOrUser(string $role, string $this->tryCatchingExceptions(fn () => $this->getObject(WorkspaceService::class)->assignWorkspaceRole( $this->currentContentRepository->id, WorkspaceName::fromString($workspaceName), - $groupName !== null ? WorkspaceRoleSubjectType::GROUP : WorkspaceRoleSubjectType::USER, - WorkspaceRoleSubject::fromString($groupName ?? $username), - WorkspaceRole::from($role) + WorkspaceRoleAssignment::create( + $groupName !== null ? WorkspaceRoleSubjectType::GROUP : WorkspaceRoleSubjectType::USER, + WorkspaceRoleSubject::fromString($groupName ?? $username), + WorkspaceRole::from($role) + ) )); } diff --git a/Neos.Workspace.Ui/Classes/Controller/WorkspaceController.php b/Neos.Workspace.Ui/Classes/Controller/WorkspaceController.php index 5f4588cfb7f..c5710e14cfb 100644 --- a/Neos.Workspace.Ui/Classes/Controller/WorkspaceController.php +++ b/Neos.Workspace.Ui/Classes/Controller/WorkspaceController.php @@ -52,8 +52,7 @@ use Neos\Neos\Domain\Model\WorkspaceClassification; use Neos\Neos\Domain\Model\WorkspaceDescription; use Neos\Neos\Domain\Model\WorkspaceRole; -use Neos\Neos\Domain\Model\WorkspaceRoleSubject; -use Neos\Neos\Domain\Model\WorkspaceRoleSubjectType; +use Neos\Neos\Domain\Model\WorkspaceRoleAssignment; use Neos\Neos\Domain\Model\WorkspaceTitle; use Neos\Neos\Domain\Repository\SiteRepository; use Neos\Neos\Domain\Service\NodeTypeNameFactory; @@ -227,16 +226,18 @@ public function createAction( $this->workspaceService->assignWorkspaceRole( $contentRepositoryId, $workspaceName, - WorkspaceRoleSubjectType::USER, - WorkspaceRoleSubject::fromString($currentUser->getId()->value), - WorkspaceRole::MANAGER, + WorkspaceRoleAssignment::createForUser( + $currentUser->getId(), + WorkspaceRole::MANAGER, + ) ); $this->workspaceService->assignWorkspaceRole( $contentRepositoryId, $workspaceName, - WorkspaceRoleSubjectType::GROUP, - WorkspaceRoleSubject::fromString('Neos.Neos:AbstractEditor'), - WorkspaceRole::COLLABORATOR, + WorkspaceRoleAssignment::createForGroup( + 'Neos.Neos:AbstractEditor', + WorkspaceRole::COLLABORATOR, + ) ); $this->addFlashMessage($this->getModuleLabel('workspaces.workspaceHasBeenCreated', [$title->value])); $this->redirect('index');