Skip to content
6 changes: 3 additions & 3 deletions formwork/src/Panel/Controllers/BackupController.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ final class BackupController extends AbstractController
*/
public function make(): JsonResponse|Response
{
if (!$this->hasPermission('backup.make')) {
if (!$this->hasPermission('panel.backup.make')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand All @@ -47,7 +47,7 @@ public function make(): JsonResponse|Response
*/
public function download(RouteParams $routeParams): Response
{
if (!$this->hasPermission('backup.download')) {
if (!$this->hasPermission('panel.backup.download')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand All @@ -68,7 +68,7 @@ public function download(RouteParams $routeParams): Response
*/
public function delete(RouteParams $routeParams): Response
{
if (!$this->hasPermission('backup.download')) {
if (!$this->hasPermission('panel.backup.download')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down
2 changes: 1 addition & 1 deletion formwork/src/Panel/Controllers/CacheController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ final class CacheController extends AbstractController
*/
public function clear(RouteParams $routeParams, AbstractCache $cache): JsonResponse|Response
{
if (!$this->hasPermission('cache.clear')) {
if (!$this->hasPermission('panel.cache.clear')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down
2 changes: 1 addition & 1 deletion formwork/src/Panel/Controllers/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ final class DashboardController extends AbstractController
*/
public function index(Statistics $statistics): Response
{
if (!$this->hasPermission('dashboard')) {
if (!$this->hasPermission('panel.dashboard')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down
12 changes: 6 additions & 6 deletions formwork/src/Panel/Controllers/FilesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ final class FilesController extends AbstractController
*/
public function index(): Response
{
if (!$this->hasPermission('files.index')) {
if (!$this->hasPermission('panel.files.index')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand All @@ -46,7 +46,7 @@ public function index(): Response
*/
public function upload(): Response
{
if (!$this->hasPermission('files.upload')) {
if (!$this->hasPermission('panel.files.upload')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down Expand Up @@ -87,7 +87,7 @@ public function upload(): Response
*/
public function edit(RouteParams $routeParams): Response
{
if (!$this->hasPermission('files.edit')) {
if (!$this->hasPermission('panel.files.edit')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down Expand Up @@ -139,7 +139,7 @@ public function edit(RouteParams $routeParams): Response
*/
public function delete(RouteParams $routeParams): JsonResponse|Response
{
if (!$this->hasPermission('files.delete')) {
if (!$this->hasPermission('panel.files.delete')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down Expand Up @@ -171,7 +171,7 @@ public function delete(RouteParams $routeParams): JsonResponse|Response
*/
public function rename(RouteParams $routeParams, FileFactory $fileFactory): JsonResponse|Response
{
if (!$this->hasPermission('files.rename')) {
if (!$this->hasPermission('panel.files.rename')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down Expand Up @@ -240,7 +240,7 @@ public function rename(RouteParams $routeParams, FileFactory $fileFactory): Json
*/
public function replace(RouteParams $routeParams): JsonResponse|Response
{
if (!$this->hasPermission('files.replace')) {
if (!$this->hasPermission('panel.files.replace')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down
6 changes: 3 additions & 3 deletions formwork/src/Panel/Controllers/OptionsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ final class OptionsController extends AbstractController
*/
public function index(): Response
{
if (!$this->hasPermission('options.site')) {
if (!$this->hasPermission('panel.options.site')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand All @@ -38,7 +38,7 @@ public function index(): Response
*/
public function systemOptions(Schemes $schemes): Response
{
if (!$this->hasPermission('options.system')) {
if (!$this->hasPermission('panel.options.system')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down Expand Up @@ -81,7 +81,7 @@ public function systemOptions(Schemes $schemes): Response
*/
public function siteOptions(Schemes $schemes): Response
{
if (!$this->hasPermission('options.site')) {
if (!$this->hasPermission('panel.options.site')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down
18 changes: 11 additions & 7 deletions formwork/src/Panel/Controllers/PagesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ final class PagesController extends AbstractController
*/
public function index(): Response
{
if (!$this->hasPermission('pages.index')) {
if (!$this->hasPermission('panel.pages.index')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand All @@ -52,7 +52,7 @@ public function index(): Response
'includeChildren' => true,
'class' => 'pages-tree-root',
'parent' => '.',
'orderable' => $this->panel->user()->permissions()->has('pages.reorder'),
'orderable' => $this->panel->user()->permissions()->has('panel.pages.reorder'),
'headers' => true,
]),
]));
Expand All @@ -63,7 +63,7 @@ public function index(): Response
*/
public function create(PageFactory $pageFactory): Response
{
if (!$this->hasPermission('pages.create')) {
if (!$this->hasPermission('panel.pages.create')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down Expand Up @@ -98,7 +98,7 @@ public function create(PageFactory $pageFactory): Response
*/
public function edit(RouteParams $routeParams): Response
{
if (!$this->hasPermission('pages.edit')) {
if (!$this->hasPermission('panel.pages.edit')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down Expand Up @@ -209,6 +209,10 @@ public function edit(RouteParams $routeParams): Response
*/
public function preview(RouteParams $routeParams): Response
{
if (!$this->hasPermission('panel.pages.preview')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

$page = $this->site->findPage($routeParams->get('page'));

if ($page === null) {
Expand Down Expand Up @@ -241,7 +245,7 @@ public function preview(RouteParams $routeParams): Response
*/
public function reorder(): JsonResponse|Response
{
if (!$this->hasPermission('pages.reorder')) {
if (!$this->hasPermission('panel.pages.reorder')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down Expand Up @@ -284,7 +288,7 @@ public function reorder(): JsonResponse|Response
*/
public function delete(RouteParams $routeParams): Response
{
if (!$this->hasPermission('pages.delete')) {
if (!$this->hasPermission('panel.pages.delete')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down Expand Up @@ -333,7 +337,7 @@ public function delete(RouteParams $routeParams): Response
*/
public function upload(RouteParams $routeParams): Response|JsonResponse
{
if (!$this->hasPermission('files.upload')) {
if (!$this->hasPermission('panel.files.upload')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down
2 changes: 1 addition & 1 deletion formwork/src/Panel/Controllers/StatisticsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ final class StatisticsController extends AbstractController
*/
public function index(Statistics $statistics): Response
{
if (!$this->hasPermission('statistics')) {
if (!$this->hasPermission('panel.statistics')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down
8 changes: 4 additions & 4 deletions formwork/src/Panel/Controllers/ToolsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ final class ToolsController extends AbstractController
*/
public function index(): Response
{
if (!$this->hasPermission('tools.backups')) {
if (!$this->hasPermission('panel.tools.backups')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand All @@ -36,7 +36,7 @@ public function index(): Response
*/
public function backups(): Response
{
if (!$this->hasPermission('tools.backups')) {
if (!$this->hasPermission('panel.tools.backups')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down Expand Up @@ -64,7 +64,7 @@ public function backups(): Response
*/
public function updates(): Response
{
if (!$this->hasPermission('tools.updates')) {
if (!$this->hasPermission('panel.tools.updates')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand All @@ -83,7 +83,7 @@ public function updates(): Response
*/
public function info(): Response
{
if (!$this->hasPermission('tools.info')) {
if (!$this->hasPermission('panel.tools.info')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down
4 changes: 2 additions & 2 deletions formwork/src/Panel/Controllers/UpdatesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ final class UpdatesController extends AbstractController
*/
public function check(Updater $updater): JsonResponse|Response
{
if (!$this->hasPermission('updates.check')) {
if (!$this->hasPermission('panel.updates.check')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand All @@ -45,7 +45,7 @@ public function check(Updater $updater): JsonResponse|Response
*/
public function update(Updater $updater, AbstractCache $cache): JsonResponse|Response
{
if (!$this->hasPermission('updates.update')) {
if (!$this->hasPermission('panel.updates.update')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down
18 changes: 12 additions & 6 deletions formwork/src/Panel/Controllers/UsersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ final class UsersController extends AbstractController
*/
public function index(): Response
{
if (!$this->hasPermission('users.index')) {
if (!$this->hasPermission('panel.users.index')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand All @@ -40,7 +40,7 @@ public function index(): Response
*/
public function create(): Response
{
if (!$this->hasPermission('users.create')) {
if (!$this->hasPermission('panel.users.create')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down Expand Up @@ -89,7 +89,7 @@ public function create(): Response
*/
public function delete(RouteParams $routeParams): Response
{
if (!$this->hasPermission('users.delete')) {
if (!$this->hasPermission('panel.users.delete')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down Expand Up @@ -129,7 +129,7 @@ public function delete(RouteParams $routeParams): Response
*/
public function deleteImage(RouteParams $routeParams): Response
{
if (!$this->hasPermission('users.deleteImage')) {
if (!$this->hasPermission('panel.users.deleteImage')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

Expand Down Expand Up @@ -164,6 +164,10 @@ public function deleteImage(RouteParams $routeParams): Response
*/
public function profile(RouteParams $routeParams): Response
{
if (!$this->hasPermission('panel.users.profile')) {
return $this->forward(ErrorsController::class, 'forbidden');
}

$scheme = $this->app->schemes()->get('users.user');

$fields = $scheme->fields();
Expand All @@ -177,8 +181,10 @@ public function profile(RouteParams $routeParams): Response

$fields->setModel($user);

// Disable password and/or role fields if they cannot be changed
$fields->get('password')->set('disabled', !$this->panel->user()->canChangePasswordOf($user));
// Hide password field if the user cannot change it
$fields->get('password')->set('visible', $this->panel->user()->canChangePasswordOf($user));

// Disable role field if it cannot be changed
$fields->get('role')->set('disabled', !$this->panel->user()->canChangeRoleOf($user));

if ($this->request->method() === RequestMethod::POST) {
Expand Down
4 changes: 2 additions & 2 deletions formwork/src/Panel/Navigation/NavigationItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ public function uri(): string
/**
* Get navigation item permissions
*/
public function permissions(): string
public function permissions(): ?string
{
return $this->data['permissions'] ?? '*';
return $this->data['permissions'];
}

/**
Expand Down
4 changes: 2 additions & 2 deletions formwork/src/Services/Loaders/UsersServiceLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ private function loadRoles(): void
$this->roleCollection = new RoleCollection();
foreach (FileSystem::listFiles($path = $this->config->get('system.users.paths.roles')) as $file) {
/**
* @var array{title: string, permissions: array<string, bool>}
* @var array{title: string, permissions?: array<string, bool>}
*/
$data = Yaml::parseFile(FileSystem::joinPaths($path, $file));
$id = FileSystem::name($file);
$permissions = new Permissions($data['permissions']);
$permissions = new Permissions($data['permissions'] ?? []);
$this->roleCollection->set($id, new Role($id, $data['title'], $permissions, $this->translations));
}
}
Expand Down
26 changes: 2 additions & 24 deletions formwork/src/Users/Permissions.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,24 @@

class Permissions
{
/**
* The permission values
*
* @var array<string, bool>
*/
protected array $permissions = [
'dashboard' => false,
'cache' => false,
'backup' => false,
'pages' => false,
'options' => false,
'updates' => false,
'users' => false,
];

/**
* @param array<string, bool> $permissions
*/
public function __construct(array $permissions)
{
$this->permissions = [...$this->permissions, ...$permissions];
}
public function __construct(protected array $permissions) {}

/**
* Return whether a permission is granted
*/
public function has(string $permission): bool
{
if ($permission === '*') {
return true;
}

if (array_key_exists($permission, $this->permissions)) {
return $this->permissions[$permission];
}

// If $permission is not found try with the upper level one (super permission),
// e.g. try with 'options' if 'options.updates' is not found

$superPermission = Str::before($permission, '.');
$superPermission = Str::beforeLast($permission, '.');

if ($superPermission !== $permission) {
return $this->has($superPermission);
Expand Down
Loading