feat: Add IP Whois API

This commit is contained in:
overflowerror 2023-11-24 10:01:17 +01:00
parent 57d39bc02f
commit 7708c7c0f1
9 changed files with 130 additions and 17 deletions

View file

@ -11,5 +11,8 @@ function fromController(string $path) {
return function(Router $router) {
$router->addRoute(GET, "/", fromController("/GET"));
$router->addRoute(GET, "/test", useRenderer(fromController("/test/GET")));
$router->addRoute(GET, "/ipaddress", useRenderer(fromController("/ipaddress/GET")));
$router->addRoute(GET, "/whois", useRenderer(fromController("/whois/GET")));
};

71
controllers/whois/GET.php Normal file
View file

@ -0,0 +1,71 @@
<?php
require_once(__DIR__ . "/settings.php");
require_once(ROOT . "/utils/error.php");
require_once(ROOT . "/utils/http.php");
require_once(ROOT . "/utils/arrays.php");
function getContactData(array $data) {
$contacts = [];
foreach ($data["entities"] as $entity) {
if (!key_exists("vcardArray", $entity))
continue;
$vcardArray = $entity["vcardArray"][1];
$fn = array_values(array_filter($vcardArray, fn(array $a) => $a[0] == "fn"))[0][3] ?? null;
$kind = array_values(array_filter($vcardArray, fn(array $a) => $a[0] == "kind"))[0][3] ?? null;
$email = array_map(fn(array $a) => $a[3], array_values(array_filter($vcardArray, fn(array $a) => $a[0] == "email")));
$adr = array_values(array_filter($vcardArray, fn(array $a) => $a[0] == "adr"))[0]["label"] ?? null;
$contacts[] = [
"handle" => $entity["handle"],
"roles" => $entity["roles"],
"function" => $fn,
"kind" => $kind,
"address" => $adr,
"email" => $email,
];
}
return $contacts;
}
function whoisIp(string $ip) {
$data = json_decode(getRequest(RDAP_URL . "/ip/" . $ip), true);
return [
"query" => $ip,
"version" => $data["ipVersion"],
"network" => [
"name" => $data["name"],
"type" => $data["type"] ?? null,
"cidr" => $data["cidr0_cidrs"][0][$data["ipVersion"] . "prefix"] . "/" . $data["cidr0_cidrs"][0]["length"],
"startAddress" => $data["startAddress"],
"endAddress" => $data["endAddress"],
"status" => $data["status"],
"remarks" => $data["remarks"]["description"][0] ?? "",
"contacts" => getContactData($data),
]
];
}
return function (array $context) {
$result = null;
if (key_exists("ip", $_GET)) {
$ip = $_GET["ip"];
if (!filter_var($ip, FILTER_VALIDATE_IP)) {
setStatusCode(400);
$result = errorResponse("Invalid IP address", "Please provide a valid IP address.");
} else {
$result = whoisIp($ip);
}
} else {
setStatusCode(400);
$result = errorResponse("Unknown mode", "Please specify one of the following query parameters: ip");
}
$context["renderer"]($result);
};

View file

@ -0,0 +1,3 @@
<?php
const RDAP_URL = "https://rdap-bootstrap.arin.net/bootstrap";

View file

@ -6,13 +6,7 @@ function useRenderer($handler, string $default = "JSON", string $query_param = "
return function (array $context) use ($handler, $default, $query_param) {
$rendererMap = require(ROOT . "/renderer/renderer.php");
$format = array_default($query_param, $_GET);
if (!$format || !key_exists(strtoupper($format), $rendererMap)) {
$format = $default;
}
$context["renderer"] = $rendererMap[strtoupper($format)];
$context["renderer"] = $rendererMap[strtoupper($_GET[$query_param] ?? "")] ?? $rendererMap[$default];
$handler($context);
};

View file

@ -1,5 +1,6 @@
<?php
return function($data) {
echo json_encode($data);
header("Content-Type: application/json");
echo json_encode($data, JSON_PRETTY_PRINT);
};

View file

@ -1,6 +1,7 @@
<?php
require_once(ROOT . "/utils/arrays.php");
require_once(ROOT . "/utils/error.php");
const GET = "GET";
const POST = "POST";
@ -18,7 +19,7 @@ class Router {
function __construct() {
$this->notFoundHandler = function($context) {
header("HTTP/", true, 404);
setStatusCode(404);
require(ROOT . "/templates/404.php");
};
}

View file

@ -8,11 +8,3 @@ function &array_get_or_add($needle, array &$haystack, $default=null) {
return $haystack[$needle];
}
}
function array_default($needle, array $haystack, $default=null) {
if (key_exists($needle, $haystack)) {
return $haystack[$needle];
} else {
return $default;
}
}

13
utils/error.php Normal file
View file

@ -0,0 +1,13 @@
<?php
function setStatusCode(int $status) {
header("HTTP/", true, $status);
}
function errorResponse(string $error, string $description) {
return [
"error" => $error,
"description" => $description,
"timestamp" => (new DateTime())->format("c")
];
}

35
utils/http.php Normal file
View file

@ -0,0 +1,35 @@
<?php
function request(string $method, string $url, string $body = null, array $headers = []) {
$curlResource = curl_init();
curl_setopt($curlResource, CURLOPT_URL, $url);
curl_setopt($curlResource, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curlResource, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($curlResource, CURLOPT_FOLLOWLOCATION, true);
if ($body)
curl_setopt($curlResource, CURLOPT_POSTFIELDS, $body);
if ($headers) {
if (!array_is_list($headers))
$headers = array_map(fn($k, $v) => $k . ": " . $v, array_keys($headers), array_values($headers));
curl_setopt($curlResource, CURLOPT_HTTPHEADER, $headers);
}
$result = curl_exec($curlResource);
curl_close($curlResource);
return $result;
}
function getRequest(string $url, array $headers = []) {
return request("GET", $url, null, $headers);
}
function postRequest(string $url, string $body = null, $headers = []) {
return request("POST", $url, $body, $headers);
}