web-base/Core/API/SettingsAPI.class.php

191 lines
6.1 KiB
PHP
Raw Normal View History

2020-06-25 16:54:58 +02:00
<?php
2022-11-18 18:06:46 +01:00
namespace Core\API {
2020-06-25 16:54:58 +02:00
2022-11-18 18:06:46 +01:00
use Core\Objects\Context;
2020-06-25 16:54:58 +02:00
2022-06-20 19:52:31 +02:00
abstract class SettingsAPI extends Request {
public function __construct(Context $context, bool $externalCall = false, array $params = array()) {
parent::__construct($context, $externalCall, $params);
}
2020-06-25 16:54:58 +02:00
}
}
2022-11-18 18:06:46 +01:00
namespace Core\API\Settings {
2020-06-25 16:54:58 +02:00
2022-11-18 18:06:46 +01:00
use Core\API\Parameter\Parameter;
use Core\API\Parameter\StringType;
use Core\API\SettingsAPI;
use Core\Configuration\Settings;
use Core\Driver\SQL\Column\Column;
use Core\Driver\SQL\Condition\CondBool;
use Core\Driver\SQL\Condition\CondIn;
use Core\Driver\SQL\Condition\CondNot;
use Core\Driver\SQL\Condition\CondRegex;
2023-01-16 21:47:23 +01:00
use Core\Driver\SQL\Query\Insert;
2022-11-18 18:06:46 +01:00
use Core\Driver\SQL\Strategy\UpdateStrategy;
use Core\Objects\Context;
2023-01-16 21:47:23 +01:00
use Core\Objects\DatabaseEntity\Group;
2020-06-25 16:54:58 +02:00
class Get extends SettingsAPI {
2022-06-20 19:52:31 +02:00
public function __construct(Context $context, bool $externalCall = false) {
parent::__construct($context, $externalCall, array(
2020-06-27 22:47:12 +02:00
'key' => new StringType('key', -1, true, NULL)
2020-06-25 16:54:58 +02:00
));
}
2022-02-21 13:01:03 +01:00
public function _execute(): bool {
2020-06-25 16:54:58 +02:00
$key = $this->getParam("key");
2022-06-20 19:52:31 +02:00
$sql = $this->context->getSQL();
2020-06-25 16:54:58 +02:00
2023-01-11 22:05:02 +01:00
$settings = Settings::getAll($sql, $key);
if ($settings !== null) {
2020-06-25 16:54:58 +02:00
$this->result["settings"] = $settings;
2023-01-11 22:05:02 +01:00
} else {
return $this->createError("Error fetching settings: " . $sql->getLastError());
2020-06-25 16:54:58 +02:00
}
return $this->success;
}
2023-01-16 21:47:23 +01:00
public static function getDefaultACL(Insert $insert): void {
$insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to fetch site settings");
}
2020-06-25 16:54:58 +02:00
}
class Set extends SettingsAPI {
2022-06-20 19:52:31 +02:00
public function __construct(Context $context, bool $externalCall = false) {
parent::__construct($context, $externalCall, array(
2020-06-25 16:54:58 +02:00
'settings' => new Parameter('settings', Parameter::TYPE_ARRAY)
));
}
2022-02-21 13:01:03 +01:00
public function _execute(): bool {
2020-06-25 16:54:58 +02:00
$values = $this->getParam("settings");
if (empty($values)) {
return $this->createError("No values given.");
}
$paramKey = new StringType('key', 32);
2020-06-26 19:31:31 +02:00
$paramValue = new StringType('value', 1024, true, NULL);
2020-06-25 16:54:58 +02:00
2022-06-20 19:52:31 +02:00
$sql = $this->context->getSQL();
2020-06-25 16:54:58 +02:00
$query = $sql->insert("Settings", array("name", "value"));
2020-06-26 19:31:31 +02:00
$keys = array();
$deleteKeys = array();
2020-06-25 16:54:58 +02:00
foreach($values as $key => $value) {
if (!$paramKey->parseParam($key)) {
$key = print_r($key, true);
return $this->createError("Invalid Type for key in parameter settings: '$key' (Required: " . $paramKey->getTypeName() . ")");
2020-06-26 19:31:31 +02:00
} else if(!is_null($value) && !$paramValue->parseParam($value)) {
2020-06-25 16:54:58 +02:00
$value = print_r($value, true);
return $this->createError("Invalid Type for value in parameter settings: '$value' (Required: " . $paramValue->getTypeName() . ")");
2020-06-26 19:31:31 +02:00
} else if(preg_match("/^[a-zA-Z_][a-zA-Z_0-9-]*$/", $paramKey->value) !== 1) {
return $this->createError("The property key should only contain alphanumeric characters, underscores and dashes");
2020-06-25 16:54:58 +02:00
} else {
2020-06-26 19:31:31 +02:00
if (!is_null($paramValue->value)) {
$query->addRow($paramKey->value, $paramValue->value);
} else {
$deleteKeys[] = $paramKey->value;
}
$keys[] = $paramKey->value;
2020-06-25 16:54:58 +02:00
}
}
2020-06-26 19:31:31 +02:00
if ($this->isExternalCall()) {
$column = $this->checkReadonly($keys);
if(!$this->success) {
return false;
} else if($column !== null) {
return $this->createError("Column '$column' is readonly.");
}
}
if (!empty($deleteKeys) && !$this->deleteKeys($keys)) {
return false;
}
if (count($deleteKeys) !== count($keys)) {
$query->onDuplicateKeyStrategy(new UpdateStrategy(
array("name"),
array("value" => new Column("value")))
);
$this->success = ($query->execute() !== FALSE);
$this->lastError = $sql->getLastError();
}
return $this->success;
}
private function checkReadonly(array $keys) {
2022-06-20 19:52:31 +02:00
$sql = $this->context->getSQL();
2020-06-26 19:31:31 +02:00
$res = $sql->select("name")
->from("Settings")
->where(new CondBool("readonly"))
2021-12-08 16:53:43 +01:00
->where(new CondIn(new Column("name"), $keys))
2022-06-08 18:37:08 +02:00
->first()
2020-06-26 19:31:31 +02:00
->execute();
$this->success = ($res !== FALSE);
$this->lastError = $sql->getLastError();
2022-06-08 18:37:08 +02:00
if ($this->success && $res !== null) {
return $res["name"];
2020-06-26 19:31:31 +02:00
}
return null;
}
2023-01-11 22:05:02 +01:00
private function deleteKeys(array $keys): bool {
2022-06-20 19:52:31 +02:00
$sql = $this->context->getSQL();
2020-06-26 19:31:31 +02:00
$res = $sql->delete("Settings")
2021-12-08 16:53:43 +01:00
->where(new CondIn(new Column("name"), $keys))
2020-06-26 19:31:31 +02:00
->execute();
2020-06-25 16:54:58 +02:00
2020-06-26 19:31:31 +02:00
$this->success = ($res !== FALSE);
2020-06-25 16:54:58 +02:00
$this->lastError = $sql->getLastError();
return $this->success;
}
2023-01-16 21:47:23 +01:00
public static function getDefaultACL(Insert $insert): void {
$insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to modify site settings");
}
2020-06-25 16:54:58 +02:00
}
2022-11-18 18:06:46 +01:00
class GenerateJWT extends SettingsAPI {
public function __construct(Context $context, bool $externalCall = false) {
parent::__construct($context, $externalCall, [
"type" => new StringType("type", 32, true, "HS512")
]);
}
protected function _execute(): bool {
$algorithm = $this->getParam("type");
if (!Settings::isJwtAlgorithmSupported($algorithm)) {
return $this->createError("Algorithm is not supported");
}
$settings = $this->context->getSettings();
if (!$settings->generateJwtKey($algorithm)) {
return $this->createError("Error generating JWT-Key: " . $settings->getLogger()->getLastMessage());
}
$saveRequest = $settings->saveJwtKey($this->context);
if (!$saveRequest->success()) {
return $this->createError("Error saving JWT-Key: " . $saveRequest->getLastError());
}
$this->result["jwt_public_key"] = $settings->getJwtPublicKey(false)?->getKeyMaterial();
return true;
}
2023-01-16 21:47:23 +01:00
public static function getDefaultACL(Insert $insert): void {
$insert->addRow(self::getEndpoint(), [Group::ADMIN], "Allows users to regenerate the JWT key. This invalidates all sessions");
}
2022-11-18 18:06:46 +01:00
}
2020-06-25 16:54:58 +02:00
}