* @link https://getkirby.com * @copyright Bastian Allgeier * @license https://getkirby.com/license */ class Permissions { public static array $extendedActions = []; protected array $actions = [ 'access' => [ 'account' => true, 'languages' => true, 'panel' => true, 'site' => true, 'system' => true, 'users' => true, ], 'files' => [ 'access' => true, 'changeName' => true, 'changeTemplate' => true, 'create' => true, 'delete' => true, 'list' => true, 'read' => true, 'replace' => true, 'update' => true ], 'languages' => [ 'create' => true, 'delete' => true ], 'pages' => [ 'access' => true, 'changeSlug' => true, 'changeStatus' => true, 'changeTemplate' => true, 'changeTitle' => true, 'create' => true, 'delete' => true, 'duplicate' => true, 'list' => true, 'move' => true, 'preview' => true, 'read' => true, 'sort' => true, 'update' => true ], 'site' => [ 'changeTitle' => true, 'update' => true ], 'users' => [ 'changeEmail' => true, 'changeLanguage' => true, 'changeName' => true, 'changePassword' => true, 'changeRole' => true, 'create' => true, 'delete' => true, 'update' => true ], 'user' => [ 'changeEmail' => true, 'changeLanguage' => true, 'changeName' => true, 'changePassword' => true, 'changeRole' => true, 'delete' => true, 'update' => true ] ]; /** * Permissions constructor * * @throws \Kirby\Exception\InvalidArgumentException */ public function __construct(array|bool|null $settings = []) { // dynamically register the extended actions foreach (static::$extendedActions as $key => $actions) { if (isset($this->actions[$key]) === true) { throw new InvalidArgumentException('The action ' . $key . ' is already a core action'); } $this->actions[$key] = $actions; } if (is_array($settings) === true) { return $this->setCategories($settings); } if (is_bool($settings) === true) { return $this->setAll($settings); } } public function for(string $category = null, string $action = null): bool { if ($action === null) { if ($this->hasCategory($category) === false) { return false; } return $this->actions[$category]; } if ($this->hasAction($category, $action) === false) { return false; } return $this->actions[$category][$action]; } protected function hasAction(string $category, string $action): bool { return $this->hasCategory($category) === true && array_key_exists($action, $this->actions[$category]) === true; } protected function hasCategory(string $category): bool { return array_key_exists($category, $this->actions) === true; } /** * @return $this */ protected function setAction( string $category, string $action, $setting ): static { // wildcard to overwrite the entire category if ($action === '*') { return $this->setCategory($category, $setting); } $this->actions[$category][$action] = $setting; return $this; } /** * @return $this */ protected function setAll(bool $setting): static { foreach ($this->actions as $categoryName => $actions) { $this->setCategory($categoryName, $setting); } return $this; } /** * @return $this */ protected function setCategories(array $settings): static { foreach ($settings as $categoryName => $categoryActions) { if (is_bool($categoryActions) === true) { $this->setCategory($categoryName, $categoryActions); } if (is_array($categoryActions) === true) { foreach ($categoryActions as $actionName => $actionSetting) { $this->setAction($categoryName, $actionName, $actionSetting); } } } return $this; } /** * @return $this * @throws \Kirby\Exception\InvalidArgumentException */ protected function setCategory(string $category, bool $setting): static { if ($this->hasCategory($category) === false) { throw new InvalidArgumentException('Invalid permissions category'); } foreach ($this->actions[$category] as $actionName => $actionSetting) { $this->actions[$category][$actionName] = $setting; } return $this; } public function toArray(): array { return $this->actions; } }