protected-resources-list/utils/server.php

166 lines
4.1 KiB
PHP

<?php
require_once __DIR__ . "/loader.php";
if (str_starts_with($_SERVER["REQUEST_URI"], "/assets")) {
$file = __DIR__ . $_SERVER["REQUEST_URI"];
if (!file_exists($file)) {
http_response_code(404);
echo "File not found: " . $_SERVER["REQUEST_URI"];
exit();
}
header("content-type: " . mime_content_type($file));
echo file_get_contents($file);
exit();
}
if (!str_starts_with($_SERVER["REQUEST_URI"], "/rpc")) {
http_response_code(302);
header("location: /assets/index.html");
exit();
}
$request = json_decode(@file_get_contents('php://input'), true);
try {
if ($request === null) {
throw new RuntimeException("Failed to parse JRPC");
}
foreach (["id", "jsonrpc", "method", "params"] as $param) {
if (!isset($request[$param])) {
throw new RuntimeException("Bad JRPC structure");
}
}
/*
* {"jsonrpc":"2.0","method":"auth","params":{},"id":1}
*/
@session_start();
class RPC
{
private Config $config;
public function __construct()
{
$this->config = new Config();
$this->config->read();
}
private function hash($what): string
{
return md5(sha1($what) . md5($what));
}
public function getConfig(): array
{
$this->checkAuth();
return $this->config->asArray();
}
public function restart_quagga()
{
return shell_exec("./zebracfg.php");
}
public function checkUpdates()
{
$this->checkAuth();
$data = str_replace("=","",@shell_exec("git --no-pager fetch --dry-run --porcelain --verbose 2>&1 | grep refs"));
$parts = explode(" ", trim($data));
if(count($parts) < 3){
return null;
}
return $parts[0] != $parts[1];
}
public function installUpdates()
{
return @shell_exec("git --no-pager pull --verbose 2>&1");
}
public function getNetworks(): array
{
$this->checkAuth();
return (new NetworkConfigReader())->getConfigs();
}
public function setConfig($config): bool
{
$this->config->fromArray($config);
$this->config->save();
return true;
}
private function checkAuth(): void
{
$auth = $_SESSION["auth"] ?? false;
if (!$auth) {
throw new RuntimeException("Unauthorized");
}
}
private function comparePassword($passwd): bool
{
$pass = $this->config["password"];
if ($pass["type"] == "plaintext") {
return $pass["data"] == $passwd;
} else if ($pass["type"] == "hash") {
return $this->hash($passwd) == $pass["data"];
}
return false;
}
public function logout(): void
{
$_SESSION["auth"] = false;
}
public function auth($params): bool
{
if (isset($params["password"])) {
if ($this->comparePassword($params["password"])) {
return $_SESSION["auth"] = true;
} else {
return false;
}
}
return $_SESSION["auth"] ?? false;
}
public function __invoke($method, $args)
{
$cls = new ReflectionClass(__CLASS__);
$method = $cls->getMethod($method);
if (!$method or !$method->isPublic()) {
throw new RuntimeException("Unable to find method");
}
return $method->invoke($this, $args);
}
}
$rpc = new RPC();
$response = $rpc($request["method"], $request["params"]);
header("content-type: application/json");
@session_write_close();
echo json_encode([
"jsonrpc" => "2.0",
"id" => $request["id"],
"result" => $response
]);
} catch (Exception $e) {
http_response_code(500);
echo $e->getMessage();
}