Files
better_guestbook/api/api.php
T

168 lines
4.6 KiB
PHP
Executable File

<?php
$debug = true;
if ($debug) {
ini_set("display_errors", 1);
ini_set("display_startup_errors", 1);
error_reporting(E_ALL);
}
// API Main Library
class gbAPI {
private $db;
private function b64url_encode($data) {
return rtrim(strtr(base64_encode($data), "+/", "-_"), "=");
}
private function b64url_decode($data) {
return base64_decode(strtr($data, "-_", "+/"));
}
function __construct($authRequired) {
define("APP_PATH", __DIR__ . "/../");
if ($authRequired) {
if (!$this->checkAuth()) {
$status = 401;
$data = [
"error" => "unauthorized",
"error_text" => "Authentication failed."
];
$this->answer($status, $data);
}
}
}
function getConfig() {
return parse_ini_file(APP_PATH . ".env");
}
function generateCookieToken($username) {
$config = $this->getConfig();
// Generate Token
$payload = [
"user" => $username,
"auth" => true,
"exp" => time() + $config["COOKIE_TOKEN_LIFETIME"]
];
$string = $this->b64url_encode(json_encode($payload));
$secret = $config["COOKIE_TOKEN_SIGNATURE"];
$sig = hash_hmac("sha256", $string, $secret);
return $string . "." . $sig;
}
function generateAPIToken($username) {
$config = $this->getConfig();
// Generate Token
$payload = [
"user" => $username,
"auth" => true
];
$string = $this->b64url_encode(json_encode($payload));
$secret = $config["API_TOKEN_SIGNATURE"];
$sig = hash_hmac("sha256", $string, $secret);
return $string . "." . $sig;
}
function checkAuth() {
if (!isset($_SERVER["HTTP_X_API_KEY"]) && !isset($_COOKIE["auth_token"])) {
return false;
}elseif (isset($_COOKIE["auth_token"]) && isset($_COOKIE["username"])) {
// Check Token
$username = $_COOKIE["username"];
$expected = $this->generateCookieToken($username);
$given = $_COOKIE["auth_token"];
$result = hash_equals($expected, $given);
if ($result) {
$given_string = explode(".", $given);
$body = json_decode($this->b64url_decode($given_string[0]), true);
if ($body["exp"] > time()) {
return true;
}else{
return false;
}
}
}elseif (isset($_SERVER["HTTP_X_API_KEY"])) {
// Decode Token
$payload = json_decode($this->b64url_decode($_SERVER["HTTP_X_API_KEY"]), true);
$username = $payload["username"];
$given = $payload["auth_token"];
$expected = $this->generateAPIToken($username);
$result = hash_equals($expected, $given);
if ($result) {
return true;
}
}
return false;
}
function answer($status, $data = [], $error = false) {
http_response_code($status);
header("Content-Type: application/json; charset=UTF-8");
if ($error) {
$json = [];
$json["status"] = $status;
foreach ($data as $key => $value) {
$json[$key] = $value;
}
}else{
$json = [
"status" => $status,
"data" => $data
];
}
$return = json_encode($json);
die($return);
}
function dbCommand($command, $expectResult, $stmtArgsRequired = false, $stmtArgs = []) {
if (isset($this->db)) {
$db = $this->db;
}else{
$config = $this->getConfig();
$db_name = $config["DB_FILE"];
$db_path = APP_PATH . $db_name;
if (!is_file($db_path)) {
$api->answer(500, [
"error" => "database_not_found",
"error_display" => "The Database was not found."
], true);
}
$db = new PDO("sqlite:" . $db_path);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
$stmt = $db->prepare($command);
$stmt->execute($stmtArgs);
if ($expectResult) {
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $result;
}
}
function getSetting($key) {
$command = "SELECT name, value FROM settings WHERE name = :name";
$value = $this->dbCommand($command, true, true, [":name" => $key]);
return $value;
}
}