Skip to content

Commit

Permalink
v1.1.2 - Quality
Browse files Browse the repository at this point in the history
  • Loading branch information
Ente committed Nov 6, 2024
1 parent 12cebbe commit 83e98dc
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 23 deletions.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# technitium-dnsserver-php-api

This API client is intended to be used with Technitiums DNS Server
For the full Technitium API Documentation please visit [Technitium API Documentation](https://github.com/TechnitiumSoftware/DnsServer/blob/master/APIDOCS.md)

## Installation

Expand Down Expand Up @@ -55,6 +56,20 @@ if($api->apps->downloadAndInstall($sampleApp["name"], $sampleApp["url"])) {

```

### Send to custom endpoint

```php
<?php

require_once "/vendor/autoload.php";
use Technitium\DNSServer\API;

$api = new API();
// You have to set <bool>$bypass to true to use this feature
echo var_dump($api->sendCall(data: array("field" => "value"), endpoint: "admin/users/list", skip: false, bypass: true))

```

## DDNS

You can use the `DDNS.Helper.API.dnsserver.ente.php` class to configure records to point to the current IP address.
Expand Down Expand Up @@ -108,6 +123,12 @@ DDNS(new API(__DIR__ . "/configurations", ".env-custom"), file_get_contents("/my

## Changes

### v1.1.2: Quality

- Added more documentation to the classes
- Small code changes
<!-- Removed whitespaces -->

### v1.1.1: Fixes

- Small changes to the `README.md`
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "ente/technitium-dnsserver-php-api",
"type": "library",
"license": "GPL-3.0-only",
"version": "1.1.1",
"version": "1.1.2",
"authors": [
{
"name": "Ente",
Expand Down
84 changes: 65 additions & 19 deletions src/API.dnsserver.ente.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
class API {

private $protocol;

private $admin;
private $allowed;
private $apps;
Expand All @@ -32,16 +31,13 @@ class API {
private $users;
private $zones;
private $ddns;

private $log;

private $conf;

private $path;

private $fullPath;

private $env = [];
const PREFIX_GET = "&token=";
const PREFIX_POST = "?token=";

public function __construct($confPath = null, $name = null){
$this->loader();
Expand All @@ -57,6 +53,12 @@ private function setProtocol(){
}
}

/**
* `loadConf()` - Load the .env file and set the environment variables.
* @param mixed $path The full path to the directory containing the .env file. (optional)
* @param mixed $name The name of the .env file. (optional)
* @return void
*/
private function loadConf($path = null, $name = null){
$this->conf = $name ?? ".env";
$this->path = $path ?? $_SERVER["DOCUMENT_ROOT"];
Expand Down Expand Up @@ -102,6 +104,15 @@ public function loader(){
require_once __DIR__ . "/helper/Log.Helper.API.dnsserver.ente.php";
}

/**
* `sendCall()` - Send a request to the Technitium API.
* @param array $data The data to send to the API
* @param string $endpoint The endpoint to send the data to, e.g. "admin/users/list"
* @param mixed $method The HTTP method to use. Default is "POST".
* @param mixed $skip Set to `true` to skip the authentication URI append.
* @param mixed $bypass Set to `true` to bypass the endpoint check allowing to access not (yet) implemented methods.
* @return array Returns the response from the API or an error (["status" => "error"]) as an array.
*/
public function sendCall($data, $endpoint, $method = "POST", $skip = false, $bypass = false){
$c = curl_init();
$endpoint = $this->prepareEndpoint($endpoint, $bypass);
Expand All @@ -126,50 +137,72 @@ public function sendCall($data, $endpoint, $method = "POST", $skip = false, $byp
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
break;
}
$result = ["status" => "error", "error" => "Unknown error"];
try {
$response = curl_exec($c);
if(!$response){
Log::error_rep("Failed to send request: " . curl_error($c));
return ["status" => "error", "error" => curl_error($c)];
$result = ["status" => "error", "error" => curl_error($c)];
}
} catch (\Throwable $e){
Log::error_rep("Failed to send request: " . $e->getMessage());
return ["status" => "error", "error" => $e->getMessage()];
$result = ["status" => "error", "error" => $e->getMessage()];
}
curl_close($c);
if($this->checkResponse($response)){
Log::error_rep("Successfully accessed endpoint: " . $endpoint);
return json_decode($response, true);
$result = json_decode($response, true);
}
return [
"error" => "An error occurred",
];
return $result;
}

/**
* `appendAuth()` - Append the authentication token to the URI.
* @param mixed $m The HTTP method to use. Default is "POST".
* @param mixed $skip Set to `true` to skip the authentication URI append, allowing the use of `API::getPermanentToken()`.
* @return string Returns the authentication token URI string or an empty string.
*/
private function appendAuth($m = "POST", $skip = false){
$this->loadConf($this->path, $this->conf);
$authAppend = null;
if($skip){
return "";
}
if(!empty($this->env["TOKEN"])){
switch($m){
case "POST":
return "?token=" . @$this->env["TOKEN"];
$authAppend = $this::PREFIX_POST . @$this->env["TOKEN"];
break;
case "GET":
return "&token=" . @$this->env["TOKEN"];
$authAppend = $this::PREFIX_GET . @$this->env["TOKEN"];
break;
default:
$authAppend = $this::PREFIX_POST . @$this->env["TOKEN"];
break;
}
} else {
$this->getPermanentToken();
$this->loadConf($this->path, $this->conf);
switch($m){
case "POST":
return "?token=" . @$this->env["TOKEN"];
$authAppend = $this::PREFIX_POST . @$this->env["TOKEN"];
break;
case "GET":
return "&token=" . @$this->env["TOKEN"];
$authAppend = $this::PREFIX_GET . @$this->env["TOKEN"];
break;
default:
$authAppend = $this::PREFIX_POST . @$this->env["TOKEN"];
break;
}
}
return $authAppend;
}

/**
* `getPermanentToken()` - Get a permanent token from the Technitium API.
* This function is called when the token is not found in the .env file.
* @return bool Returns `true` if the token was successfully written to the .env file.
*/
private function getPermanentToken(){
Log::error_rep("Getting permanent token... | .env: " . $this->fullPath);
$response = $this->sendCall([
Expand All @@ -190,11 +223,18 @@ private function getPermanentToken(){
->write(true);

} catch(\Throwable $e){
Log::error_rep("Unable to write to .env file: " . $this->fullPath); }
Log::error_rep("Unable to write to .env file: " . $this->fullPath);
}
return true;
}

private function checkResponse($response){
/**
* `checkResponse()` - Check if the Technitium API response is valid.
* If the response status contains either "error" or "invalid-token" it is considered invalid.
* @param mixed $response The response returned by `API::sendCall()` function.
* @return bool Returns `true` if the response is valid, otherwise `false`.
*/
private function checkResponse(string $response){
if(is_null($response)){
return false;
} else {
Expand All @@ -203,6 +243,12 @@ private function checkResponse($response){
}
}

/**
* `prepareEndpoint()` - Generates the API URI for the endpoint in question.
* @param mixed $endpoint The endpoint to generate the URI for.
* @param mixed $bypass Set to `true` to bypass the endpoint check allowing to access not (yet) implemented methods.
* @return bool|string Returns the URI as string or `false` if the endpoint is not implemented.
*/
private function prepareEndpoint($endpoint, $bypass = false){
if($bypass){
return $this->protocol . "://" . $this->env["API_URL"] . "/api/" . $endpoint;
Expand Down Expand Up @@ -280,7 +326,7 @@ public function ddns(): DDNS {
}

public function log(): Log {
if(!$this->log) $this->log = new Log($this);
if(!$this->log) $this->log = new Log(null);
return $this->log;
}
}
2 changes: 1 addition & 1 deletion src/endpoints/admin/Groups.admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

/**
* Groups class
*
*
* This class is used to interact with the groups endpoint of the Technitium DNS Server API
*/
class groups {
Expand Down
2 changes: 1 addition & 1 deletion src/endpoints/allowed/Allowed.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public function __construct($api){
* `list()` - Returns a list of all allowed domains.
* @param string $domain The domain to list.
* @param string $direction The direction to list the domains. Valid values are [`up`, `down`].
* @return array|bool Returns the result array or `false` if the group was not found.
* @return array|bool Returns the result array or `false` if the group was not found.
*/
public function list(string $domain = "", string $direction = "up"){
$response = $this->API->sendCall(["domain" => $domain, "direction" => $direction], "allowed/list");
Expand Down
2 changes: 1 addition & 1 deletion src/endpoints/apps/Config.apps.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public function __construct($api){
/**
* `get()` - Returns the configuration of an app.
* @param string $name The name of the app.
* @return array|bool Returns the result array or `false` if the group was not found.
* @return array|bool Returns the result array or `false` if the group was not found.
*/
public function get(string $name){
$response = $this->API->sendCall(["name" => $name], "apps/config/get");
Expand Down
10 changes: 10 additions & 0 deletions src/endpoints/dhcp/Scopes.dhcp.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,21 @@ public function enable(string $name){
return $response["status"] == "ok";
}

/**
* `disable()` - Disables the DHCP scope.
* @param string $name The name of the scope.
* @return bool Returns `true` if the request was successful, `false` otherwise.
*/
public function disable(string $name){
$response = $this->API->sendCall(["name" => $name], "dhcp/scopes/disable");
return $response["status"] == "ok";
}

/**
* `delete()` - Deletes the DHCP scope.
* @param string $name The name of the scope.
* @return bool Returns `true` if the request was successful, `false` otherwise.
*/
public function delete(string $name){
$response = $this->API->sendCall(["name" => $name], "dhcp/scopes/delete");
return $response["status"] == "ok";
Expand Down

0 comments on commit 83e98dc

Please sign in to comment.