From ee638914a8199ea93ca7aedc13f0608c644a771d Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 27 Mar 2024 14:12:01 +0100 Subject: [PATCH] ApiPermission: added isCore column --- Core/API/ApiKeyAPI.class.php | 8 ++-- Core/API/DatabaseAPI.class.php | 4 +- Core/API/GroupsAPI.class.php | 14 +++---- Core/API/LogsAPI.class.php | 2 +- Core/API/MailAPI.class.php | 2 +- Core/API/PermissionAPI.class.php | 39 ++++++++++++------- Core/API/RoutesAPI.class.php | 16 ++++---- Core/API/SettingsAPI.class.php | 4 +- Core/API/Stats.class.php | 2 +- Core/API/UserAPI.class.php | 12 +++--- Core/API/VisitorsAPI.class.php | 2 +- Core/Configuration/CreateDatabase.class.php | 5 ++- Core/Documents/Install.class.php | 19 +++++---- Core/Objects/Context.class.php | 7 +++- cli.php | 14 ++++--- .../src/views/access-control-list.js | 8 ++-- react/admin-panel/src/views/overview.js | 2 - 17 files changed, 89 insertions(+), 71 deletions(-) diff --git a/Core/API/ApiKeyAPI.class.php b/Core/API/ApiKeyAPI.class.php index e90a356..c87f98b 100644 --- a/Core/API/ApiKeyAPI.class.php +++ b/Core/API/ApiKeyAPI.class.php @@ -62,7 +62,7 @@ namespace Core\API\ApiKey { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [], "Allows users to create new API-Keys"); + $insert->addRow(self::getEndpoint(), [], "Allows users to create new API-Keys", true); } } @@ -109,7 +109,7 @@ namespace Core\API\ApiKey { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [], "Allows users to fetch new API-Key"); + $insert->addRow(self::getEndpoint(), [], "Allows users to fetch new API-Keys", true); } } @@ -137,7 +137,7 @@ namespace Core\API\ApiKey { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [], "Allows users to refresh API-Key"); + $insert->addRow(self::getEndpoint(), [], "Allows users to refresh API-Keys", true); } } @@ -162,7 +162,7 @@ namespace Core\API\ApiKey { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [], "Allows users to revoke API-Key"); + $insert->addRow(self::getEndpoint(), [], "Allows users to revoke API-Keys", true); } } } \ No newline at end of file diff --git a/Core/API/DatabaseAPI.class.php b/Core/API/DatabaseAPI.class.php index 2df952c..d38901c 100644 --- a/Core/API/DatabaseAPI.class.php +++ b/Core/API/DatabaseAPI.class.php @@ -33,7 +33,7 @@ namespace Core\API\Database { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to view the database status"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to view the database status", true); } } @@ -106,7 +106,7 @@ namespace Core\API\Database { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to migrate the database structure"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to migrate the database structure", true); } } } \ No newline at end of file diff --git a/Core/API/GroupsAPI.class.php b/Core/API/GroupsAPI.class.php index d5b4c8f..23c5f67 100644 --- a/Core/API/GroupsAPI.class.php +++ b/Core/API/GroupsAPI.class.php @@ -85,7 +85,7 @@ namespace Core\API\Groups { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to fetch available groups"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to fetch available groups", true); } } @@ -112,7 +112,7 @@ namespace Core\API\Groups { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to get details about a group"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to get details about a group", true); } } @@ -151,7 +151,7 @@ namespace Core\API\Groups { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to fetch members of a group"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to fetch members of a group", true); } } @@ -195,7 +195,7 @@ namespace Core\API\Groups { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to create a new group"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to create a new group", true); } } @@ -226,7 +226,7 @@ namespace Core\API\Groups { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to delete a group"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to delete a group", true); } } @@ -268,7 +268,7 @@ namespace Core\API\Groups { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to add members to a group"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to add members to a group", true); } } @@ -310,7 +310,7 @@ namespace Core\API\Groups { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to remove members from a group"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to remove members from a group", true); } } } \ No newline at end of file diff --git a/Core/API/LogsAPI.class.php b/Core/API/LogsAPI.class.php index 3e40887..cd54eb3 100644 --- a/Core/API/LogsAPI.class.php +++ b/Core/API/LogsAPI.class.php @@ -135,7 +135,7 @@ namespace Core\API\Logs { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to fetch system logs"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to fetch system logs", true); } } diff --git a/Core/API/MailAPI.class.php b/Core/API/MailAPI.class.php index f36061a..6d9cc31 100644 --- a/Core/API/MailAPI.class.php +++ b/Core/API/MailAPI.class.php @@ -82,7 +82,7 @@ namespace Core\API\Mail { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to send a test email to verify configuration"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to send a test email to verify configuration", true); } } diff --git a/Core/API/PermissionAPI.class.php b/Core/API/PermissionAPI.class.php index 04856a3..c51dc96 100644 --- a/Core/API/PermissionAPI.class.php +++ b/Core/API/PermissionAPI.class.php @@ -109,7 +109,7 @@ namespace Core\API\Permission { } $sql = $this->context->getSQL(); - $res = $sql->select("method", "groups", "description") + $res = $sql->select("method", "groups", "description", "isCore") ->from("ApiPermission") ->execute(); @@ -117,16 +117,18 @@ namespace Core\API\Permission { $this->lastError = $sql->getLastError(); if ($this->success) { - $permissions = array(); + $permissions = []; foreach ($res as $row) { $method = $row["method"]; $description = $row["description"]; $groups = json_decode($row["groups"]); - $permissions[] = array( + $isCore = $row["isCore"]; + $permissions[] = [ "method" => $method, "groups" => $groups, - "description" => $description - ); + "description" => $description, + "isCore" => $isCore + ]; } $this->result["permissions"] = $permissions; $this->result["groups"] = $this->groups; @@ -136,7 +138,7 @@ namespace Core\API\Permission { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to fetch API permissions"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to fetch API permissions", true); } } @@ -158,29 +160,37 @@ namespace Core\API\Permission { $sql = $this->context->getSQL(); $methodParam = new StringType('method', 32); $groupsParam = new Parameter('groups', Parameter::TYPE_ARRAY); + $descriptionParam = new StringType('method', 128); - $updateQuery = $sql->insert("ApiPermission", array("method", "groups")) - ->onDuplicateKeyStrategy(new UpdateStrategy(array("method"), array("groups" => new Column("groups")))); + $updateQuery = $sql->insert("ApiPermission", ["method", "groups", "description"]) + ->onDuplicateKeyStrategy(new UpdateStrategy(["method"], [ + "groups" => new Column("groups"), + "description" => new Column("description") + ])); $insertedMethods = array(); foreach ($permissions as $permission) { if (!is_array($permission)) { return $this->createError("Invalid data type found in parameter: permissions, expected: object"); - } else if (!isset($permission["method"]) || !array_key_exists("groups", $permission)) { - return $this->createError("Invalid object found in parameter: permissions, expected keys 'method' and 'groups'"); + } else if (!isset($permission["method"]) || !isset($permission["description"]) || !array_key_exists("groups", $permission)) { + return $this->createError("Invalid object found in parameter: permissions, expected keys: 'method', 'groups', 'description'"); } else if (!$methodParam->parseParam($permission["method"])) { $expectedType = $methodParam->getTypeName(); return $this->createError("Invalid data type found for attribute 'method', expected: $expectedType"); } else if (!$groupsParam->parseParam($permission["groups"])) { $expectedType = $groupsParam->getTypeName(); return $this->createError("Invalid data type found for attribute 'groups', expected: $expectedType"); + } else if (!$descriptionParam->parseParam($permission["description"])) { + $expectedType = $descriptionParam->getTypeName(); + return $this->createError("Invalid data type found for attribute 'description', expected: $expectedType"); } else if (empty(trim($methodParam->value))) { return $this->createError("Method cannot be empty."); } else { $method = $methodParam->value; $groups = $groupsParam->value; - $updateQuery->addRow($method, $groups); + $description = $descriptionParam->value; + $updateQuery->addRow($method, $groups, $description); $insertedMethods[] = $method; } } @@ -205,8 +215,11 @@ namespace Core\API\Permission { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], - "Allows users to modify API permissions. This is restricted to the administrator and cannot be changed"); + $insert->addRow( + self::getEndpoint(), [Group::ADMIN], + "Allows users to modify API permissions. This is restricted to the administrator and cannot be changed", + true + ); } } } \ No newline at end of file diff --git a/Core/API/RoutesAPI.class.php b/Core/API/RoutesAPI.class.php index 49587b8..6a00413 100644 --- a/Core/API/RoutesAPI.class.php +++ b/Core/API/RoutesAPI.class.php @@ -105,7 +105,7 @@ namespace Core\API\Routes { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to fetch site routing"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to fetch site routing", true); } } @@ -210,7 +210,7 @@ namespace Core\API\Routes { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to save the site routing"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to save the site routing", true); } } @@ -248,7 +248,7 @@ namespace Core\API\Routes { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to add new routes"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to add new routes", true); } } @@ -306,7 +306,7 @@ namespace Core\API\Routes { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to update existing routes"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to update existing routes", true); } } @@ -335,7 +335,7 @@ namespace Core\API\Routes { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to remove routes"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to remove routes", true); } } @@ -353,7 +353,7 @@ namespace Core\API\Routes { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to enable a route"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to enable a route", true); } } @@ -371,7 +371,7 @@ namespace Core\API\Routes { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to disable a route"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to disable a route", true); } } @@ -416,7 +416,7 @@ namespace Core\API\Routes { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to regenerate the routing cache"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to regenerate the routing cache", true); } } } diff --git a/Core/API/SettingsAPI.class.php b/Core/API/SettingsAPI.class.php index 0f058ec..40f3d26 100644 --- a/Core/API/SettingsAPI.class.php +++ b/Core/API/SettingsAPI.class.php @@ -50,7 +50,7 @@ namespace Core\API\Settings { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to fetch site settings"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to fetch site settings", true); } } @@ -152,7 +152,7 @@ namespace Core\API\Settings { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to modify site settings"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to modify site settings", true); } } } \ No newline at end of file diff --git a/Core/API/Stats.class.php b/Core/API/Stats.class.php index ade02dd..e8be77a 100644 --- a/Core/API/Stats.class.php +++ b/Core/API/Stats.class.php @@ -99,6 +99,6 @@ class Stats extends Request { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to view site statistics"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to view site statistics", true); } } \ No newline at end of file diff --git a/Core/API/UserAPI.class.php b/Core/API/UserAPI.class.php index edf2467..0a2aee3 100644 --- a/Core/API/UserAPI.class.php +++ b/Core/API/UserAPI.class.php @@ -211,7 +211,7 @@ namespace Core\API\User { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to create new users"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to create new users", true); } } @@ -273,7 +273,7 @@ namespace Core\API\User { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to fetch all users"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to fetch all users", true); } } @@ -316,7 +316,7 @@ namespace Core\API\User { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to get details about a user"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to get details about a user", true); } } @@ -438,7 +438,7 @@ namespace Core\API\User { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to invite new users"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to invite new users", true); } } @@ -853,7 +853,7 @@ namespace Core\API\User { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to modify other user's details"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to modify other user's details", true); } } @@ -890,7 +890,7 @@ namespace Core\API\User { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to delete other users"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to delete other users", true); } } diff --git a/Core/API/VisitorsAPI.class.php b/Core/API/VisitorsAPI.class.php index e103f04..fd7b1f1 100644 --- a/Core/API/VisitorsAPI.class.php +++ b/Core/API/VisitorsAPI.class.php @@ -116,7 +116,7 @@ namespace Core\API\Visitors { } public static function getDefaultACL(Insert $insert): void { - $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to view visitor statistics"); + $insert->addRow(self::getEndpoint(), [Group::ADMIN, Group::SUPPORT], "Allows users to view visitor statistics", true); } } } \ No newline at end of file diff --git a/Core/Configuration/CreateDatabase.class.php b/Core/Configuration/CreateDatabase.class.php index da08dc4..0bc5d7e 100644 --- a/Core/Configuration/CreateDatabase.class.php +++ b/Core/Configuration/CreateDatabase.class.php @@ -38,7 +38,8 @@ class CreateDatabase extends DatabaseScript { ->addString("method", 32) ->addJson("groups", true, '[]') ->addString("description", 128, false, "") - ->primaryKey("method"); + ->primaryKey("method") + ->addBool("isCore", false); self::loadDefaultACL($queries, $sql); self::loadPatches($queries, $sql); @@ -121,7 +122,7 @@ class CreateDatabase extends DatabaseScript { } public static function loadDefaultACL(array &$queries, SQL $sql) { - $query = $sql->insert("ApiPermission", ["method", "groups", "description"]); + $query = $sql->insert("ApiPermission", ["method", "groups", "description", "isCore"]); foreach (Request::getApiEndpoints() as $reflectionClass) { $method = $reflectionClass->getName() . "::getDefaultACL"; diff --git a/Core/Documents/Install.class.php b/Core/Documents/Install.class.php index 9037368..b3c6bec 100644 --- a/Core/Documents/Install.class.php +++ b/Core/Documents/Install.class.php @@ -20,8 +20,6 @@ namespace Documents\Install { use Core\Configuration\Configuration; use Core\Configuration\CreateDatabase; use Core\Driver\SQL\Expression\Count; - use Core\Driver\SQL\Query\Commit; - use Core\Driver\SQL\Query\StartTransaction; use Core\Driver\SQL\SQL; use Core\Elements\Body; use Core\Elements\Head; @@ -363,22 +361,23 @@ namespace Documents\Install { $msg = ""; $success = true; $queries = CreateDatabase::createQueries($sql); - array_unshift($queries, new StartTransaction($sql)); - $queries[] = new Commit($sql); - foreach ($queries as $query) { - try { + try { + $sql->startTransaction(); + foreach ($queries as $query) { if (!$query->execute()) { $msg = "Error creating tables: " . $sql->getLastError(); $success = false; } - } finally { + if (!$success) { - $sql->rollback(); + break; } } - + } finally { if (!$success) { - break; + $sql->rollback(); + } else { + $sql->commit(); } } diff --git a/Core/Objects/Context.class.php b/Core/Objects/Context.class.php index f07e6a4..346196a 100644 --- a/Core/Objects/Context.class.php +++ b/Core/Objects/Context.class.php @@ -104,8 +104,11 @@ class Context { } public function parseCookies(): void { - if (isset($_COOKIE['session']) && is_string($_COOKIE['session']) && !empty($_COOKIE['session'])) { - $this->loadSession($_COOKIE['session']); + + if ($this->sql) { + if (isset($_COOKIE['session']) && is_string($_COOKIE['session']) && !empty($_COOKIE['session'])) { + $this->loadSession($_COOKIE['session']); + } } // set language by priority: 1. GET parameter, 2. cookie, 3. user's settings diff --git a/cli.php b/cli.php index d76cf84..4866be6 100644 --- a/cli.php +++ b/cli.php @@ -45,11 +45,13 @@ if (!$context->isCLI()) { $dockerYaml = null; $database = $context->getConfig()->getDatabase(); -if ($database->getProperty("isDocker", false) && !is_file("/.dockerenv")) { - if (function_exists("yaml_parse")) { - $dockerYaml = yaml_parse(file_get_contents("./docker-compose.yml")); - } else { - _exit("yaml_parse not found but required for docker file parsing."); +if ($database !== null) { + if ($database->getProperty("isDocker", false) && !is_file("/.dockerenv")) { + if (function_exists("yaml_parse")) { + $dockerYaml = yaml_parse(file_get_contents("./docker-compose.yml")); + } else { + _exit("yaml_parse not found but required for docker file parsing."); + } } } @@ -819,7 +821,7 @@ if (count($argv) < 2) { if (array_key_exists($command, $registeredCommands)) { // TODO: do we need this? - if ($database->getProperty("isDocker", false) && !is_file("/.dockerenv")) { + if ($database !== null && $database->getProperty("isDocker", false) && !is_file("/.dockerenv")) { $requiresDocker = in_array($argv[2] ?? null, $registeredCommands[$command]["requiresDocker"] ?? []); if ($requiresDocker) { $containerName = $dockerYaml["services"]["php"]["container_name"]; diff --git a/react/admin-panel/src/views/access-control-list.js b/react/admin-panel/src/views/access-control-list.js index 7006e75..bad7690 100644 --- a/react/admin-panel/src/views/access-control-list.js +++ b/react/admin-panel/src/views/access-control-list.js @@ -3,12 +3,12 @@ import {LocaleContext} from "shared/locale"; import {Link, useNavigate} from "react-router-dom"; import {Button, Checkbox, TextField, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow} from "@material-ui/core"; import {Add, Refresh} from "@material-ui/icons"; +import {USER_GROUP_ADMIN} from "shared/constants"; export default function AccessControlList(props) { // meta - const showDialog = props.showDialog; const {translate: L, requestModules, currentLocale} = useContext(LocaleContext); const navigate = useNavigate(); @@ -74,7 +74,8 @@ export default function AccessControlList(props) { {permission.description} {groups.map(group => - + )} ); @@ -118,7 +119,8 @@ export default function AccessControlList(props) { - diff --git a/react/admin-panel/src/views/overview.js b/react/admin-panel/src/views/overview.js index 569116b..9989750 100644 --- a/react/admin-panel/src/views/overview.js +++ b/react/admin-panel/src/views/overview.js @@ -68,8 +68,6 @@ export default function Overview(props) { } */ - console.log(stats); - return <>