mirror of
https://github.com/sigmasternchen/useful-api.org
synced 2025-03-15 07:58:55 +00:00
feat: Add basic logging for rate limiting
This commit is contained in:
parent
275eddf025
commit
8255421d0e
9 changed files with 139 additions and 7 deletions
5
context.php
Normal file
5
context.php
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
const DB_CONNECTION = "DB_CONNECTION";
|
||||||
|
const REPOSITORIES = "REPOSITORIES";
|
||||||
|
const RENDERER = "RENDERER";
|
|
@ -1,6 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once(ROOT . "/middleware/renderer.php");
|
require_once(ROOT . "/middleware/renderer.php");
|
||||||
|
require_once(ROOT . "/middleware/log.php");
|
||||||
|
|
||||||
function fromController(string $path) {
|
function fromController(string $path) {
|
||||||
return function(array $context) use ($path) {
|
return function(array $context) use ($path) {
|
||||||
|
@ -12,8 +13,29 @@ return function(Router $router) {
|
||||||
$router->addRoute(GET, "/", fromController("/GET"));
|
$router->addRoute(GET, "/", fromController("/GET"));
|
||||||
$router->addRoute(GET, "/test", useRenderer(fromController("/test/GET")));
|
$router->addRoute(GET, "/test", useRenderer(fromController("/test/GET")));
|
||||||
|
|
||||||
$router->addRoute(GET, "/ipaddress", useRenderer(fromController("/ipaddress/GET")));
|
$router->addRoute(GET, "/ipaddress",
|
||||||
$router->addRoute(GET, "/whois", useRenderer(fromController("/whois/GET")));
|
useLog(
|
||||||
|
useRenderer(
|
||||||
|
fromController("/ipaddress/GET")
|
||||||
|
),
|
||||||
|
"ipaddress"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$router->addRoute(GET, "/whois",
|
||||||
|
useLog(
|
||||||
|
useRenderer(
|
||||||
|
fromController("/whois/GET")
|
||||||
|
),
|
||||||
|
"whois"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
$router->addRoute(GET, "/punycode", useRenderer(fromController("/punycode/GET")));
|
$router->addRoute(GET, "/punycode",
|
||||||
|
useLog(
|
||||||
|
useRenderer(
|
||||||
|
fromController("/punycode/GET")
|
||||||
|
),
|
||||||
|
"punycode"
|
||||||
|
)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
13
core.php
13
core.php
|
@ -10,9 +10,16 @@ if (MAINTENANCE_MODE) {
|
||||||
$connection = require_once(ROOT . "/persistence/connection.php");
|
$connection = require_once(ROOT . "/persistence/connection.php");
|
||||||
(require(ROOT . "/persistence/migrate.php"))($connection);
|
(require(ROOT . "/persistence/migrate.php"))($connection);
|
||||||
|
|
||||||
|
$repositories = (require_once(ROOT . "/persistence/Repositories.php"))($connection);
|
||||||
|
|
||||||
$router = require(ROOT . "/router/Router.php");
|
$router = require(ROOT . "/router/Router.php");
|
||||||
(require(ROOT . "/controllers/routes.php"))($router);
|
(require(ROOT . "/controllers/routes.php"))($router);
|
||||||
$router->execute([
|
|
||||||
"DB_CONNECTION" => $connection,
|
require_once(ROOT . "/context.php");
|
||||||
]);
|
$context = [
|
||||||
|
DB_CONNECTION => $connection,
|
||||||
|
REPOSITORIES => $repositories,
|
||||||
|
];
|
||||||
|
|
||||||
|
$router->execute($context);
|
||||||
}
|
}
|
||||||
|
|
20
middleware/log.php
Normal file
20
middleware/log.php
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once(ROOT . "/persistence/models/LogEntry.php");
|
||||||
|
|
||||||
|
function useLog($handler, string $endpoint) {
|
||||||
|
return function (array $context) use ($handler, $endpoint) {
|
||||||
|
$result = $handler($context);
|
||||||
|
|
||||||
|
$accessKey = $context["ACCESS_KEY"] ?? "";
|
||||||
|
|
||||||
|
$entry = new LogEntry(
|
||||||
|
$endpoint,
|
||||||
|
$_SERVER['REMOTE_ADDR'],
|
||||||
|
$accessKey,
|
||||||
|
);
|
||||||
|
$context[REPOSITORIES]->logs()->add($entry);
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
};
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ function useRenderer($handler, string $default = "JSON", string $query_param = "
|
||||||
$rendererMap = require(ROOT . "/renderer/renderer.php");
|
$rendererMap = require(ROOT . "/renderer/renderer.php");
|
||||||
|
|
||||||
$renderer = $rendererMap[strtoupper($_GET[$query_param] ?? "")] ?? $rendererMap[$default];
|
$renderer = $rendererMap[strtoupper($_GET[$query_param] ?? "")] ?? $rendererMap[$default];
|
||||||
$context["renderer"] = $renderer;
|
$context[RENDERER] = $renderer;
|
||||||
|
|
||||||
$result = $handler($context);
|
$result = $handler($context);
|
||||||
if ($result !== null) {
|
if ($result !== null) {
|
||||||
|
|
19
persistence/Repositories.php
Normal file
19
persistence/Repositories.php
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once(__DIR__ . "/repositories/Logs.php");
|
||||||
|
|
||||||
|
class Repositories {
|
||||||
|
private $map = [];
|
||||||
|
|
||||||
|
public function __construct(PDO $connection) {
|
||||||
|
$this->map[Logs::class] = new Logs($connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function logs(): Logs {
|
||||||
|
return $this->map[Logs::class];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return function(PDO $connection): Repositories {
|
||||||
|
return new Repositories($connection);
|
||||||
|
};
|
13
persistence/migrations/0001_addLoggingTable.sql
Normal file
13
persistence/migrations/0001_addLoggingTable.sql
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
CREATE TABLE `ua_logs` (
|
||||||
|
`id` BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`timestamp` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`endpoint` VARCHAR(100),
|
||||||
|
`client_address` VARCHAR(46),
|
||||||
|
`access_key` VARCHAR(255),
|
||||||
|
`clean` BOOLEAN DEFAULT 0,
|
||||||
|
|
||||||
|
INDEX (`endpoint`),
|
||||||
|
INDEX (`client_address`),
|
||||||
|
INDEX (`access_key`)
|
||||||
|
);
|
20
persistence/models/LogEntry.php
Normal file
20
persistence/models/LogEntry.php
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class LogEntry {
|
||||||
|
public int $id;
|
||||||
|
public DateTime $timestamp;
|
||||||
|
public string $endpoint;
|
||||||
|
public string $clientAddress;
|
||||||
|
public string $accessKey;
|
||||||
|
public bool $isClean;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
string $endpoint,
|
||||||
|
string $clientAddress,
|
||||||
|
string $accessKey,
|
||||||
|
) {
|
||||||
|
$this->endpoint = $endpoint;
|
||||||
|
$this->clientAddress = $clientAddress;
|
||||||
|
$this->accessKey = $accessKey;
|
||||||
|
}
|
||||||
|
}
|
26
persistence/repositories/Logs.php
Normal file
26
persistence/repositories/Logs.php
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once(__DIR__ . "/../models/LogEntry.php");
|
||||||
|
|
||||||
|
class Logs {
|
||||||
|
private string $table = "ua_logs";
|
||||||
|
|
||||||
|
private PDO $connection;
|
||||||
|
|
||||||
|
public function __construct(PDO $connection) {
|
||||||
|
$this->connection = $connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function add(LogEntry $entry) {
|
||||||
|
$statement = $this->connection->prepare(<<<EOF
|
||||||
|
INSERT INTO `$this->table`
|
||||||
|
(`endpoint`, `client_address`, `access_key`) VALUES
|
||||||
|
(?, ?, ?)
|
||||||
|
EOF);
|
||||||
|
$statement->execute([
|
||||||
|
$entry->endpoint,
|
||||||
|
$entry->clientAddress,
|
||||||
|
$entry->accessKey,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue