added version to api

This commit is contained in:
tracer 2024-04-26 19:22:44 +02:00
parent 96689879c4
commit 578f76426e
2 changed files with 134 additions and 81 deletions

View File

@ -2,7 +2,7 @@
"name": "24unix/bindapi", "name": "24unix/bindapi",
"description": "manage Bind9 DNS server via REST API", "description": "manage Bind9 DNS server via REST API",
"version": "1.0.9", "version": "1.0.9",
"build_number": "357", "build_number": "358",
"authors": [ "authors": [
{ {
"name": "Micha Espey", "name": "Micha Espey",

View File

@ -23,7 +23,7 @@ use function Symfony\Component\String\s;
/** /**
* *
*/ */
#[OAT\Info(version: '0.0.1', title: 'bindAPI')] #[OAT\Info(version: '1.0.9', title: 'bindAPI')]
#[OAT\Server( #[OAT\Server(
url: "{schema}://{hostname}/api", url: "{schema}://{hostname}/api",
description: "The bindAPI URL.", description: "The bindAPI URL.",
@ -60,76 +60,70 @@ class RequestController
private array $uri; private array $uri;
public function __construct(
private readonly ApikeyRepository $apikeyRepository, // server tag
private readonly DomainController $domainController,
private readonly DomainRepository $domainRepository, #[OAT\Get(
private readonly DynDNSRepository $dynDNSRepository, path: '/ping',
private readonly PanelRepository $panelRepository, operationId: 'ping',
private readonly ConfigController $configController, description: 'Checks for connectivity and valid APIkey',
private readonly EncryptionController $encryptionController, security: [
private readonly Logger $logger) ['Authorization' => []]
],
tags: ['Server'],
responses: [
new OAT\Response(
response: 200,
description: 'OK'
),
new OAT\Response(
response: 401,
description: 'API key is missing or invalid.'
)
]
)]
private function handlePing(): void
{ {
$this->status = ''; if ($this->validateApiKey()) {
$this->response = ''; $this->status = '200 OK';
$this->message = ''; $this->response = 'pong';
$this->result = []; } else {
$this->status = '401 Unauthorized';
$this->message = 'API key is missing or invalid';
}
} }
public function handleRequest(string $requestMethod, array $uri): void #[OAT\Get(
path: '/version',
operationId: 'version',
description: 'Check the API version of the nameserver.',
security: [
['Authorization' => []]
],
tags: ['Server'],
responses: [
new OAT\Response(
response: 200,
description: 'x.y.y'
),
new OAT\Response(
response: 401,
description: 'API key is missing or invalid.'
)
]
)]
private function getVersion(): void
{ {
$this->logger->debug(message: "Request: $requestMethod $uri[1]"); if ($this->validateApiKey()) {
$this->status = '200 OK';
$this->requestMethod = strtoupper(string: $requestMethod); $this->response = '1.2.3';
$this->uri = $uri;
$command = $this->uri[2];
// use my router class from address book?
$routes = ['domains', 'ping', 'apidoc', 'dyndns'];
if (empty($command) || !(in_array(needle: $command, haystack: $routes))) {
$this->status = "404 Not Found";
$this->message = "Endpoint not found.";
} else { } else {
try { $this->status = '401 Unauthorized';
match ($command) { $this->message = 'API key is missing or invalid';
'dyndns' => $this->handleDynDNS(),
'ping' => $this->handlePing(),
'domains' => $this->handleDomains(),
'apidoc' => $this->apiDoc(),
};
} catch (UnhandledMatchError) {
$this->status = '400 Bad Request';
$this->message = 'Unknown path: ' . $command;
} }
} }
// process api requests
if (!empty($this->status)) {
header(header: $_SERVER['SERVER_PROTOCOL'] . ' ' . $this->status);
}
if (!empty($this->response)) {
echo json_encode(value: [
'response' => $this->response
]);
} elseif (!empty($this->result)) {
echo json_encode(value: [
'result' => $this->result
]);
} elseif (!empty($this->message)) {
echo json_encode(value: [
'message' => $this->message
]);
} else {
echo json_encode(value: [
'message' => $this->message ?? 'Error: No message.'
]);
}
}
#[OAT\Get( #[OAT\Get(
path: '/domains', path: '/domains',
operationId: 'getAllDomains', operationId: 'getAllDomains',
@ -170,16 +164,6 @@ class RequestController
/** /**
*/ */
private function handlePing(): void
{
if ($this->checkPassword()) {
$this->status = '200 OK';
$this->response = 'pong';
} else {
$this->status = '401 Unauthorized';
$this->message = 'API key is missing or invalid';
}
}
/** /**
@ -187,7 +171,7 @@ class RequestController
*/ */
private function handleDomains(): void private function handleDomains(): void
{ {
if ($this->checkPassword()) { if ($this->validateApiKey()) {
try { try {
match ($this->requestMethod) { match ($this->requestMethod) {
'GET' => $this->handleDomainsGetRequest(), 'GET' => $this->handleDomainsGetRequest(),
@ -275,9 +259,7 @@ class RequestController
)] )]
)] )]
private function validateApiKey(): bool
private function checkPassword(): bool
{ {
$headers = array_change_key_case(array: getallheaders(), case: CASE_UPPER); $headers = array_change_key_case(array: getallheaders(), case: CASE_UPPER);
$apiKey = $headers['X-API-KEY'] ?? ''; $apiKey = $headers['X-API-KEY'] ?? '';
@ -459,7 +441,7 @@ class RequestController
{ {
$this->logger->debug(message: 'handleDynDNS()'); $this->logger->debug(message: 'handleDynDNS()');
if ($this->checkPassword()) { if ($this->validateApiKey()) {
$host = $this->uri[3] ?? ''; $host = $this->uri[3] ?? '';
if (empty($host)) { if (empty($host)) {
@ -665,5 +647,76 @@ class RequestController
exit(0); exit(0);
} }
public function __construct(
private readonly ApikeyRepository $apikeyRepository,
private readonly DomainController $domainController,
private readonly DomainRepository $domainRepository,
private readonly DynDNSRepository $dynDNSRepository,
private readonly PanelRepository $panelRepository,
private readonly ConfigController $configController,
private readonly EncryptionController $encryptionController,
private readonly Logger $logger)
{
$this->status = '';
$this->response = '';
$this->message = '';
$this->result = [];
}
public function handleRequest(string $requestMethod, array $uri): void
{
$this->logger->debug(message: "Request: $requestMethod $uri[1]");
$this->requestMethod = strtoupper(string: $requestMethod);
$this->uri = $uri;
$command = $this->uri[2];
// use my router class from address book?
$routes = ['domains', 'ping', 'apidoc', 'dyndns'];
if (empty($command) || !(in_array(needle: $command, haystack: $routes))) {
$this->status = "404 Not Found";
$this->message = "Endpoint not found.";
} else {
try {
match ($command) {
// server
'ping' => $this->handlePing(),
'version' => $this->getVersion(),
// domains
'domains' => $this->handleDomains(),
'dyndns' => $this->handleDynDNS(),
'apidoc' => $this->apiDoc(),
};
} catch (UnhandledMatchError) {
$this->status = '400 Bad Request';
$this->message = 'Unknown path: ' . $command;
}
}
// process api requests
if (!empty($this->status)) {
header(header: $_SERVER['SERVER_PROTOCOL'] . ' ' . $this->status);
}
if (!empty($this->response)) {
echo json_encode(value: [
'response' => $this->response
]);
} elseif (!empty($this->result)) {
echo json_encode(value: [
'result' => $this->result
]);
} elseif (!empty($this->message)) {
echo json_encode(value: [
'message' => $this->message
]);
} else {
echo json_encode(value: [
'message' => $this->message ?? 'Error: No message.'
]);
}
}
} }