Skip to content

Commit

Permalink
TASK: remove owner column in workspace management table, fix some per…
Browse files Browse the repository at this point in the history
…missions
  • Loading branch information
JamesAlias committed Oct 23, 2024
1 parent 64fa1b7 commit 916e510
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 46 deletions.
5 changes: 5 additions & 0 deletions Neos.Neos/Classes/Domain/Model/WorkspacePermissions.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,9 @@ public static function all(): self
{
return new self(true, true, true);
}

public static function none(): self
{
return new self(false, false, false);
}
}
19 changes: 15 additions & 4 deletions Neos.Neos/Classes/Domain/Service/WorkspaceService.php
Original file line number Diff line number Diff line change
Expand Up @@ -289,19 +289,30 @@ public function getWorkspacePermissionsForUser(ContentRepositoryId $contentRepos
} catch (NoSuchRoleException $e) {
throw new \RuntimeException(sprintf('Failed to determine roles for user "%s", check your package dependencies: %s', $user->getId()->value, $e->getMessage()), 1727084881, $e);
}

$userIsAdministrator = in_array('Neos.Neos:Administrator', $userRoles, true);

if ($userIsAdministrator) {
return WorkspacePermissions::all();
}

$workspaceMetadata = $this->loadWorkspaceMetadata($contentRepositoryId, $workspaceName);
if ($workspaceMetadata !== null && $workspaceMetadata->ownerUserId !== null && $workspaceMetadata->ownerUserId->equals($user->getId())) {
$userIsOwner = $workspaceMetadata !== null && $workspaceMetadata->ownerUserId !== null && $workspaceMetadata->ownerUserId->equals($user->getId());

if ($userIsOwner) {
return WorkspacePermissions::all();
}

$userWorkspaceRole = $this->loadWorkspaceRoleOfUser($contentRepositoryId, $workspaceName, $user->getId(), $userRoles);
$userIsAdministrator = in_array('Neos.Neos:Administrator', $userRoles, true);

if ($userWorkspaceRole === null) {
return WorkspacePermissions::create(false, false, $userIsAdministrator);
return WorkspacePermissions::none();
}

return WorkspacePermissions::create(
read: $userWorkspaceRole->isAtLeast(WorkspaceRole::COLLABORATOR),
write: $userWorkspaceRole->isAtLeast(WorkspaceRole::COLLABORATOR),
manage: $userIsAdministrator || $userWorkspaceRole->isAtLeast(WorkspaceRole::MANAGER),
manage: $userWorkspaceRole->isAtLeast(WorkspaceRole::MANAGER),
);
}

Expand Down
78 changes: 46 additions & 32 deletions Neos.Workspace.Ui/Classes/Controller/WorkspaceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
use Neos\Neos\Domain\Model\WorkspaceDescription;
use Neos\Neos\Domain\Model\WorkspaceRole;
use Neos\Neos\Domain\Model\WorkspaceRoleAssignment;
use Neos\Neos\Domain\Model\WorkspaceRoleSubjectType;
use Neos\Neos\Domain\Model\WorkspaceTitle;
use Neos\Neos\Domain\NodeLabel\NodeLabelGeneratorInterface;
use Neos\Neos\Domain\Repository\SiteRepository;
Expand Down Expand Up @@ -281,6 +282,7 @@ public function editAction(WorkspaceName $workspaceName): void
workspaceTitle: $workspaceMetadata->title,
workspaceDescription: $workspaceMetadata->description,
workspaceHasChanges: $this->computePendingChanges($workspace, $contentRepository)->total > 0,
baseWorkspaceName: $workspace->baseWorkspaceName,
baseWorkspaceOptions: $this->prepareBaseWorkspaceOptions($contentRepository, $workspaceName),
);

Expand Down Expand Up @@ -310,6 +312,12 @@ public function updateAction(
}

$workspace = $contentRepository->findWorkspaceByName($workspaceName);

$userCanManageWorkspace = $this->workspaceService->getWorkspacePermissionsForUser($contentRepositoryId, $workspaceName, $this->userService->getCurrentUser())->manage;
if (!$userCanManageWorkspace) {
$this->throwStatus(403);
}

if ($workspace === null) {
$this->addFlashMessage(
$this->getModuleLabel('workspaces.workspaceDoesNotExist'),
Expand Down Expand Up @@ -1129,34 +1137,11 @@ public function getModuleLabel(string $id, array $arguments = [], mixed $quantit

protected function getUserWorkspace(ContentRepository $contentRepository): Workspace
{
/*
$items = [];
$allWorkspaces = $contentRepository->findWorkspaces();
foreach ($allWorkspaces as $workspace) {
$workspaceMetadata = $this->workspaceService->getWorkspaceMetadata($contentRepositoryId, $workspace->workspaceName);
$permissions = $this->workspaceService->getWorkspacePermissionsForUser($contentRepositoryId, $workspace->workspaceName, $currentUser);
if (!$permissions->read) {
continue;
}
$items[] = new WorkspaceListItem(
name: $workspace->workspaceName->value,
classification: $workspaceMetadata->classification->name,
title: $workspaceMetadata->title->value,
description: $workspaceMetadata->description->value,
baseWorkspaceName: $workspace->baseWorkspaceName?->value,
pendingChanges: $this->computePendingChanges($workspace, $contentRepository),
hasDependantWorkspaces: !$allWorkspaces->getDependantWorkspaces($workspace->workspaceName)->isEmpty(),
permissions: $permissions,
);
}
*/

$currentUser = $this->userService->getCurrentUser();
if ($currentUser === null) {
throw new \RuntimeException('No user is authenticated', 1729505338);
}
$userWorkspace = $this->workspaceService->getPersonalWorkspaceForUser($contentRepository->id, $currentUser->getId());
return $userWorkspace;
return $this->workspaceService->getPersonalWorkspaceForUser($contentRepository->id, $currentUser->getId());
}

protected function getWorkspaceListItems(
Expand All @@ -1172,6 +1157,9 @@ protected function getWorkspaceListItems(

$allWorkspaces = $contentRepository->findWorkspaces();

$userWorkspaceOwner = $this->userService->findUserById($userWorkspaceMetadata->ownerUserId);

// add user workspace first
$workspaceListItems = [];
$workspaceListItems[$userWorkspace->workspaceName->value] = new WorkspaceListItem(
$userWorkspace->workspaceName->value,
Expand All @@ -1182,12 +1170,11 @@ protected function getWorkspaceListItems(
$userWorkspace->baseWorkspaceName?->value,
$this->computePendingChanges($userWorkspace, $contentRepository),
!$allWorkspaces->getDependantWorkspaces($userWorkspace->workspaceName)->isEmpty(),
$userWorkspaceMetadata->ownerUserId ? $this->userService->findUserById(
UserId::fromString($userWorkspaceMetadata->ownerUserId->value)
)?->getLabel() : null,
$userWorkspaceOwner?->getLabel(),
$userWorkspacesPermissions,
);

// add other, accessible workspaces
foreach ($allWorkspaces as $workspace) {
$workspaceMetadata = $this->workspaceService->getWorkspaceMetadata($contentRepository->id, $workspace->workspaceName);
$workspacesPermissions = $this->workspaceService->getWorkspacePermissionsForUser(
Expand All @@ -1196,7 +1183,36 @@ protected function getWorkspaceListItems(
$this->userService->getCurrentUser()
);

// TODO: check permissions (read?, admin?)
if ($workspacesPermissions->read === false) {
continue;
}

$workspaceOwner = $workspaceMetadata->ownerUserId
? $this->userService->findUserById($workspaceMetadata->ownerUserId)
: null;

$workspaceRoleAssignments = $this->workspaceService->getWorkspaceRoleAssignments($contentRepository->id, $workspace->workspaceName);

/**
* Managing users of the workspace excluding the owner
* @var array<string> $workspaceManagerUsers
*/
$workspaceManagerUsers = [];
$workspaceManagerGroups = [];

foreach ($workspaceRoleAssignments as $roleAssignment) {
if ($roleAssignment->role === WorkspaceRole::MANAGER) {
if ($roleAssignment->subjectType == WorkspaceRoleSubjectType::USER) {
$userId = UserId::fromString($roleAssignment->subject->value);

$workspaceManagerUsers[] = $this->userService
->findUserById($userId)
->getLabel();
} elseif ($roleAssignment->subjectType == WorkspaceRoleSubjectType::GROUP) {
$workspaceManagerGroups[] = $roleAssignment->subject->value;
}
}
}

$workspaceListItems[$workspace->workspaceName->value] = new WorkspaceListItem(
$workspace->workspaceName->value,
Expand All @@ -1207,10 +1223,8 @@ protected function getWorkspaceListItems(
$workspace->baseWorkspaceName?->value,
$this->computePendingChanges($workspace, $contentRepository),
!$allWorkspaces->getDependantWorkspaces($workspace->workspaceName)->isEmpty(),
$workspaceMetadata->ownerUserId ? $this->userService->findUserById(
UserId::fromString($workspaceMetadata->ownerUserId->value)
)?->getLabel() : null,
$workspacesPermissions, // todo manage always true????
$workspaceOwner?->getLabel(),
$workspacesPermissions,
);
}
return WorkspaceListItems::fromArray($workspaceListItems);
Expand Down
9 changes: 5 additions & 4 deletions Neos.Workspace.Ui/Classes/ViewModel/EditWorkspaceFormData.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,16 @@
final readonly class EditWorkspaceFormData
{
public function __construct(
public WorkspaceName $workspaceName,
public WorkspaceTitle $workspaceTitle,
public WorkspaceName $workspaceName,
public WorkspaceTitle $workspaceTitle,
public WorkspaceDescription $workspaceDescription,
public bool $workspaceHasChanges,
public bool $workspaceHasChanges,
public WorkspaceName $baseWorkspaceName,
/**
* Options for the baseWorkspace selector where the key is the workspace name and the value is the workspace title.
* @var array<string, string>
*/
public array $baseWorkspaceOptions,
public array $baseWorkspaceOptions,
)
{
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
prototype(Neos.Workspace.Ui:Component.Modal.Edit) < prototype(Neos.Fusion:Component) {
workspaceHasChanges = false
baseWorkspaceName = ''
/// array<string, string>
baseWorkspaceOptions = ${[]}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ prototype(Neos.Workspace.Ui:Component.WorkspaceTable) < prototype(Neos.Fusion:Co
</button>
</th>
<th>{private.i18n.id('workspaces.workspace.description')}</th>
<th>{private.i18n.id('workspaces.workspace.owner')}</th>
<th>
<button type="button" class="icon-button">
{private.i18n.id('workspaces.workspace.lastModified')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ prototype(Neos.Workspace.Ui:Component.WorkspaceTableRow) < prototype(Neos.Fusion
userWorkspaceName = null
/// Neos\Workspace\Ui\ViewModel\WorkspaceListItem
workspaceListItem = ${[]}
/// boolean todo unused!!!
canManage = false
/// integer
level = 0

Expand Down Expand Up @@ -96,7 +94,6 @@ prototype(Neos.Workspace.Ui:Component.WorkspaceTableRow) < prototype(Neos.Fusion
<td class="workspace-description-column">
{props.workspaceListItem.description || '﹘'}
</td>
<td>{props.workspaceListItem.owner || '﹘'}</td>
<td>﹘</td>
<td>{private.i18n.id('workspaces.workspace.status.' + props.workspaceListItem.status).translate()}</td>
<td>
Expand Down Expand Up @@ -133,13 +130,13 @@ prototype(Neos.Workspace.Ui:Component.WorkspaceTableRow) < prototype(Neos.Fusion
attributes.hx-target='#popover-container'
attributes.hx-swap='innerHTML'
attributes.hx-on--after-request={'document.getElementById("' + private.editWorkspacePopoverId + '").showPopover()'}
@if={!props.canManage || props.workspaceListItem.pendingChanges == null}
attributes.disabled={props.workspaceListItem.permissions.manage == false}
/>
<Neos.Workspace.Ui:Component.Button
isDanger
title={private.i18n.id('workspaces.deleteWorkspace').arguments([props.workspaceListItem.title])}
icon="trash-alt icon-white"
disabled={props.workspaceListItem.pendingChanges.total > 0}
attributes.disabled={props.workspaceListItem.pendingChanges.total > 0 || props.workspaceListItem.permissions.manage == false}
attributes.hx-get={private.deleteWorkspaceUri}
attributes.hx-target='#popover-container'
attributes.hx-swap='innerHTML'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Neos.Workspace.Ui.WorkspaceController.edit = Neos.Fusion:Component {
workspaceDescription={props.editWorkspaceFormData.workspaceDescription.value}

workspaceHasChanges={props.editWorkspaceFormData.workspaceHasChanges}
baseWorkspaceName={props.editWorkspaceFormData.baseWorkspaceName.value}
baseWorkspaceOptions={props.editWorkspaceFormData.baseWorkspaceOptions}
/>
`
Expand Down

0 comments on commit 916e510

Please sign in to comment.