some fixes

This commit is contained in:
Roman 2021-04-07 00:03:14 +02:00
parent 43f4407269
commit af27b7c302
4 changed files with 176 additions and 50 deletions

204
cli.php

@ -3,75 +3,79 @@
include_once 'core/core.php'; include_once 'core/core.php';
include_once 'core/constants.php'; include_once 'core/constants.php';
use Configuration\Configuration;
use Configuration\DatabaseScript; use Configuration\DatabaseScript;
use Driver\SQL\SQL;
use Objects\ConnectionData; use Objects\ConnectionData;
use Objects\User;
function printLine(string $line = "") {
echo $line . PHP_EOL;
}
function _exit(string $line = "") {
printLine($line);
die();
}
if (php_sapi_name() !== "cli") { if (php_sapi_name() !== "cli") {
die(); _exit("Can only be executed via CLI");
} }
function getDatabaseConfig(): ConnectionData { function getDatabaseConfig(): ConnectionData {
$configClass = "\\Configuration\\Database"; $configClass = "\\Configuration\\Database";
$file = getClassPath($configClass); $file = getClassPath($configClass);
if (!file_exists($file) || !is_readable($file)) { if (!file_exists($file) || !is_readable($file)) {
die("Database configuration does not exist or is not readable\n"); _exit("Database configuration does not exist or is not readable");
} }
include_once $file; include_once $file;
return new $configClass(); return new $configClass();
} }
function connectDatabase() { function getUser(): User {
$config = getDatabaseConfig(); $config = new Configuration();
$db = SQL::createConnection($config); $user = new User($config);
if (!($db instanceof SQL) || !$db->isConnected()) { if (!$user->getSQL() || !$user->getSQL()->isConnected()) {
if ($db instanceof SQL) { _exit("Could not establish database connection");
die($db->getLastError() . "\n");
} else {
$msg = (is_string($db) ? $db : "Unknown Error");
die("Database error: $msg\n");
}
} }
return $db; return $user;
} }
function printHelp() { function printHelp() {
// TODO: help // TODO: help
} }
function handleDatabase($argv) { function handleDatabase(array $argv) {
$action = $argv[2] ?? ""; $action = $argv[2] ?? "";
if ($action === "migrate") { if ($action === "migrate") {
$class = $argv[3] ?? null; $class = $argv[3] ?? null;
if (!$class) { if (!$class) {
die("Usage: cli.php db migrate <class name>\n"); _exit("Usage: cli.php db migrate <class name>");
} }
$class = str_replace('/', '\\', $class); $class = str_replace('/', '\\', $class);
$className = "\\Configuration\\$class"; $className = "\\Configuration\\$class";
$classPath = getClassPath($className); $classPath = getClassPath($className);
if (!file_exists($classPath) || !is_readable($classPath)) { if (!file_exists($classPath) || !is_readable($classPath)) {
die("Database script file does not exist or is not readable\n"); _exit("Database script file does not exist or is not readable");
} }
include_once $classPath; include_once $classPath;
$obj = new $className(); $obj = new $className();
if (!($obj instanceof DatabaseScript)) { if (!($obj instanceof DatabaseScript)) {
die("Not a database script\n"); _exit("Not a database script");
} }
$db = connectDatabase(); $user = getUser();
$queries = $obj->createQueries($db); $sql = $user->getSQL();
$queries = $obj->createQueries($sql);
foreach ($queries as $query) { foreach ($queries as $query) {
if (!$query->execute($db)) { if (!$query->execute($sql)) {
die($db->getLastError()); _exit($sql->getLastError());
} }
} }
$db->close();
} else if ($action === "export" || $action === "import") { } else if ($action === "export" || $action === "import") {
// database config // database config
@ -94,11 +98,11 @@ function handleDatabase($argv) {
if ($action === "import") { if ($action === "import") {
$file = $argv[3] ?? null; $file = $argv[3] ?? null;
if (!$file) { if (!$file) {
die("Usage: cli.php db import <path>\n"); _exit("Usage: cli.php db import <path>");
} }
if (!file_exists($file) || !is_readable($file)) { if (!file_exists($file) || !is_readable($file)) {
die("File not found or not readable\n"); _exit("File not found or not readable");
} }
$inputData = file_get_contents($file); $inputData = file_get_contents($file);
@ -116,8 +120,6 @@ function handleDatabase($argv) {
} else if ($action === "import") { } else if ($action === "import") {
$command_bin = "mysql"; $command_bin = "mysql";
$descriptorSpec[0] = ["pipe", "r"]; $descriptorSpec[0] = ["pipe", "r"];
} else {
die("Unsupported action\n");
} }
} else if ($dbType === "postgres") { } else if ($dbType === "postgres") {
@ -132,12 +134,10 @@ function handleDatabase($argv) {
} else if ($action === "import") { } else if ($action === "import") {
$command_bin = "/usr/bin/psql"; $command_bin = "/usr/bin/psql";
$descriptorSpec[0] = ["pipe", "r"]; $descriptorSpec[0] = ["pipe", "r"];
} else {
die("Unsupported action\n");
} }
} else { } else {
die("Unsupported database type\n"); _exit("Unsupported database type");
} }
if ($database) { if ($database) {
@ -156,36 +156,155 @@ function handleDatabase($argv) {
proc_close($process); proc_close($process);
} }
} else { } else {
die("Usage: cli.php db <migrate|import|export> [options...]"); _exit("Usage: cli.php db <migrate|import|export> [options...]");
} }
} }
function onMaintenance($argv) { function onMaintenance(array $argv) {
$action = $argv[2] ?? "status"; $action = $argv[2] ?? "status";
$maintenanceFile = "MAINTENANCE"; $maintenanceFile = "MAINTENANCE";
$isMaintenanceEnabled = file_exists($maintenanceFile); $isMaintenanceEnabled = file_exists($maintenanceFile);
if ($action === "status") { if ($action === "status") {
die("Maintenance: " . ($isMaintenanceEnabled ? "on" : "off") . "\n"); _exit("Maintenance: " . ($isMaintenanceEnabled ? "on" : "off"));
} else if ($action === "on") { } else if ($action === "on") {
$file = fopen($maintenanceFile, 'w') or die("Unable to create maintenance file\n"); $file = fopen($maintenanceFile, 'w') or _exit("Unable to create maintenance file");
fclose($file); fclose($file);
die("Maintenance enabled\n"); _exit("Maintenance enabled");
} else if ($action === "off") { } else if ($action === "off") {
if (file_exists($maintenanceFile)) { if (file_exists($maintenanceFile)) {
if (!unlink($maintenanceFile)) { if (!unlink($maintenanceFile)) {
die("Unable to delete maintenance file\n"); _exit("Unable to delete maintenance file");
} }
} }
die("Maintenance disabled\n"); _exit("Maintenance disabled");
} else { } else {
die("Usage: cli.php maintenance <status|on|off>\n"); _exit("Usage: cli.php maintenance <status|on|off>");
}
}
function printTable(array $head, array $body) {
$columns = [];
foreach ($head as $key) {
$columns[$key] = strlen($key);
}
foreach ($body as $row) {
foreach ($head as $key) {
$value = $row[$key] ?? "";
$length = strlen($value);
$columns[$key] = max($columns[$key], $length);
}
}
// print table
foreach ($head as $key) {
echo str_pad($key, $columns[$key]) . ' ';
}
printLine();
foreach ($body as $row) {
foreach ($head as $key) {
echo str_pad($row[$key] ?? "", $columns[$key]) . ' ';
}
printLine();
}
}
// TODO: add missing api functions (should be all internal only i guess)
function onRoutes(array $argv) {
$user = getUser();
$action = $argv[2] ?? "list";
if ($action === "list") {
$req = new Api\Routes\Fetch($user);
$success = $req->execute();
if (!$success) {
_exit("Error fetching routes: " . $req->getLastError());
} else {
$routes = $req->getResult()["routes"];
$head = ["uid", "request", "action", "target", "extra", "active"];
// strict boolean
foreach ($routes as &$route) {
$route["active"] = $route["active"] ? "true" : "false";
}
printTable($head, $routes);
}
} else if ($action === "add") {
if (count($argv) < 6) {
_exit("Usage: cli.php routes add <request> <action> <target> [extra]");
}
$params = array(
"request" => $argv[3],
"action" => $argv[4],
"target" => $argv[5],
"extra" => $argv[6] ?? ""
);
/*
$req = new Api\Routes\Add($user);
$success = $req->execute($params);
if (!$success) {
_exit($req->getLastError());
} else {
_exit("Route added successfully");
}*/
} else if (in_array($action, ["remove","modify","enable","disable"])) {
$uid = $argv[3] ?? null;
if ($uid === null || ($action === "modify" && count($argv) < 7)) {
if ($action === "modify") {
_exit("Usage: cli.php routes $action <uid> <request> <action> <target> [extra]");
} else {
_exit("Usage: cli.php routes $action <uid>");
}
}
$params = ["uid" => $uid];
if ($action === "remove") {
$input = null;
do {
if ($input === "n") {
die();
}
echo "Remove route #$uid? (y|n): ";
} while(($input = trim(fgets(STDIN))) !== "y");
// $req = new Api\Routes\Remove($user);
} else if ($action === "enable") {
// $req = new Api\Routes\Enable($user);
} else if ($action === "disable") {
// $req = new Api\Routes\Disable($user);
} else if ($action === "modify") {
// $req = new Api\Routes\Update($user);
$params["request"] = $argv[4];
$params["action"] = $argv[5];
$params["target"] = $argv[6];
$params["extra"] = $argv[7] ?? "";
} else {
_exit("Unsupported action");
}
/*
$success = $req->execute($params);
if (!$success) {
_exit($req->getLastError());
} else {
_exit("Route updated successfully");
}
*/
} else {
_exit("Usage: cli.php routes <list|enable|disable|add|remove|modify> [options...]");
} }
} }
$argv = $_SERVER['argv']; $argv = $_SERVER['argv'];
if (count($argv) < 2) { if (count($argv) < 2) {
die("Usage: cli.php <db|routes|settings|maintenance> [options...]\n"); _exit("Usage: cli.php <db|routes|settings|maintenance> [options...]");
} }
$command = $argv[1]; $command = $argv[1];
@ -197,13 +316,14 @@ switch ($command) {
handleDatabase($argv); handleDatabase($argv);
break; break;
case 'routes': case 'routes':
// TODO: routes onRoutes($argv);
break; break;
case 'maintenance': case 'maintenance':
onMaintenance($argv); onMaintenance($argv);
break; break;
default: default:
echo "Unknown command '$command'\n\n"; printLine("Unknown command '$command'");
printLine();
printHelp(); printHelp();
exit; exit;
} }

@ -111,13 +111,15 @@ class Request {
return false; return false;
} }
if (!in_array($_SERVER['REQUEST_METHOD'], $this->allowedMethods)) {
$this->lastError = 'This method is not allowed';
header('HTTP 1.1 405 Method Not Allowed');
return false;
}
if ($this->externalCall) { if ($this->externalCall) {
// check the request method
if (!in_array($_SERVER['REQUEST_METHOD'], $this->allowedMethods)) {
$this->lastError = 'This method is not allowed';
header('HTTP 1.1 405 Method Not Allowed');
return false;
}
$apiKeyAuthorized = false; $apiKeyAuthorized = false;
// Logged in or api key authorized? // Logged in or api key authorized?

@ -33,7 +33,7 @@ class Settings {
} }
public static function loadDefaults(): Settings { public static function loadDefaults(): Settings {
$hostname = $_SERVER["SERVER_NAME"]; $hostname = $_SERVER["SERVER_NAME"] ?? "localhost";
$protocol = getProtocol(); $protocol = getProtocol();
$jwt = generateRandomString(32); $jwt = generateRandomString(32);

@ -14,7 +14,11 @@ spl_autoload_register(function($class) {
function getProtocol(): string { function getProtocol(): string {
return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https" : "http"; $isSecure = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ||
(!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') ||
(!empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on');
return $isSecure ? 'https' : 'http';
} }
function generateRandomString($length): string { function generateRandomString($length): string {