|
|
@ -2,30 +2,28 @@ |
|
|
|
|
|
|
|
namespace Darksparrow\DeegraphInteractions\Core; |
|
|
|
|
|
|
|
use Auxilium\Exceptions\DatabaseConnectionException; |
|
|
|
use Auxilium\Exceptions\DeegraphException; |
|
|
|
use Darksparrow\DeegraphInteractions\DataStructures\DeegraphNodeDetails; |
|
|
|
use Darksparrow\DeegraphInteractions\DataStructures\ServerInfo; |
|
|
|
use Darksparrow\DeegraphInteractions\DataStructures\UUID; |
|
|
|
use Exception; |
|
|
|
|
|
|
|
class DeegraphServer |
|
|
|
{ |
|
|
|
private string $Token; |
|
|
|
private string $Actor; |
|
|
|
|
|
|
|
|
|
|
|
private string $ServerDomain; |
|
|
|
private int $Port; |
|
|
|
private bool $AllowSelfSignedCerts; |
|
|
|
|
|
|
|
|
|
|
|
public function __construct( |
|
|
|
string $token, |
|
|
|
string $actor, |
|
|
|
string $server = "localhost", |
|
|
|
int $port = 8088, |
|
|
|
bool $allowSelfSignedCerts = false) |
|
|
|
{ |
|
|
|
$this->Token = $token; |
|
|
|
$this->Actor = $actor; |
|
|
|
|
|
|
|
$this->ServerDomain = $server; |
|
|
|
$this->Port = $port; |
|
|
|
$this->AllowSelfSignedCerts = $allowSelfSignedCerts; |
|
|
@ -41,48 +39,130 @@ class DeegraphServer |
|
|
|
return new ServerInfo(response: $response); |
|
|
|
} |
|
|
|
|
|
|
|
public function RunRawRequest(string $endpoint, string $method = "GET", string $body = null): array |
|
|
|
/** |
|
|
|
* Runs a request against the Deegraph server. |
|
|
|
* |
|
|
|
* @param string $actorID The Actor for the request. |
|
|
|
* @param string $endpoint What endpoint on the server to target. |
|
|
|
* @param string $method What method to use. |
|
|
|
* @param string|null $body |
|
|
|
* |
|
|
|
* @return array |
|
|
|
* |
|
|
|
* @throws Exception |
|
|
|
*/ |
|
|
|
private function RunRawRequest( |
|
|
|
UUID $actorID, |
|
|
|
string $endpoint, |
|
|
|
string $method = "GET", |
|
|
|
string $body = null |
|
|
|
): array |
|
|
|
{ |
|
|
|
$ch = curl_init("https://{$this->ServerDomain}:{$this->Port}{$endpoint}"); |
|
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, [ |
|
|
|
'Content-Type: application/json', |
|
|
|
"Authorization: Bearer {$this->Token}", |
|
|
|
"X-Auxilium-Actor: {$this->Actor}", |
|
|
|
]); |
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); |
|
|
|
// Convert the provided method string to capital letters |
|
|
|
$method = strtoupper($method); |
|
|
|
|
|
|
|
if ($method == "POST") { |
|
|
|
curl_setopt($ch, CURLOPT_POST, 1); |
|
|
|
} |
|
|
|
// Break the endpoint into components, and URL-encode each component to ensure safe transmission |
|
|
|
$endpointComponents = explode("/", $endpoint); |
|
|
|
foreach($endpointComponents as &$cmp) |
|
|
|
$cmp = urlencode($cmp); |
|
|
|
|
|
|
|
// Construct the full URL using the server domain and encoded endpoint |
|
|
|
$url = "https://" . $this->ServerDomain . implode("/", $endpointComponents); |
|
|
|
|
|
|
|
// Initialize a cURL session |
|
|
|
$ch = curl_init(); |
|
|
|
curl_setopt(handle: $ch, option: CURLOPT_URL, value: $url); |
|
|
|
|
|
|
|
// If the request method is POST, set the CURLOPT_POST option |
|
|
|
if($method == "POST") |
|
|
|
curl_setopt(handle: $ch, option: CURLOPT_POST, value: true); |
|
|
|
|
|
|
|
// Specify the port for the connection |
|
|
|
curl_setopt(handle: $ch, option: CURLOPT_PORT, value: $this->Port); |
|
|
|
|
|
|
|
// Allow self-signed certificates if configured |
|
|
|
if($this->AllowSelfSignedCerts) |
|
|
|
{ |
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); |
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); |
|
|
|
curl_setopt(handle: $ch, option: CURLOPT_SSL_VERIFYPEER, value: false); |
|
|
|
curl_setopt(handle: $ch, option: CURLOPT_SSL_VERIFYHOST, value: false); |
|
|
|
} |
|
|
|
|
|
|
|
// Ensure the Actor property is set; if not, throw an exception |
|
|
|
if($actorID == null) |
|
|
|
{ |
|
|
|
throw new Exception("Client's user account is invalid"); |
|
|
|
} |
|
|
|
|
|
|
|
if ($method == "POST" || $method == "PUT") { |
|
|
|
if ($body != null) { |
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $body); |
|
|
|
// Set HTTP headers, including authorization and custom headers |
|
|
|
curl_setopt(handle: $ch, option: CURLOPT_HTTPHEADER, value: [ |
|
|
|
"Content-Type: text/plain", |
|
|
|
"Authorization: Bearer " . $this->Token, |
|
|
|
"X-Auxilium-Actor: " . $actorID->GetPlainUUID(), |
|
|
|
]); |
|
|
|
|
|
|
|
// Handle request body for POST and PUT methods |
|
|
|
if($method == "POST" || $method == "PUT") |
|
|
|
{ |
|
|
|
if($body != null) |
|
|
|
{ |
|
|
|
curl_setopt(handle: $ch, option: CURLOPT_POSTFIELDS, value: $body); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
$result = curl_exec($ch); |
|
|
|
// Configure cURL to return the server response as a string |
|
|
|
curl_setopt(handle: $ch, option: CURLOPT_RETURNTRANSFER, value: true); |
|
|
|
|
|
|
|
// Execute the cURL request and store the response |
|
|
|
$serverResponse = curl_exec($ch); |
|
|
|
|
|
|
|
// Check if the request failed |
|
|
|
if($serverResponse === false) |
|
|
|
{ |
|
|
|
throw new Exception("Deegraph server did not respond to Auxilium query"); |
|
|
|
} |
|
|
|
|
|
|
|
// Handle specific SSL certificate errors |
|
|
|
if(curl_error($ch) == "SSL certificate problem: unable to get local issuer certificate") |
|
|
|
{ |
|
|
|
throw new \Exception(); |
|
|
|
die(); |
|
|
|
} |
|
|
|
|
|
|
|
// Check for server-side errors (HTTP status codes 500–599) |
|
|
|
if( |
|
|
|
curl_getinfo($ch, CURLINFO_RESPONSE_CODE) >= 500 |
|
|
|
&& curl_getinfo($ch, CURLINFO_RESPONSE_CODE) < 600 |
|
|
|
) |
|
|
|
{ |
|
|
|
throw new Exception( |
|
|
|
message: "Deegraph server responded with an internal error code", |
|
|
|
code: 0, |
|
|
|
previous: null, |
|
|
|
// trade: isset($server_output["@trace"]) ? $server_output["@trace"] : null |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
// Close the cURL session |
|
|
|
curl_close($ch); |
|
|
|
|
|
|
|
$temp = json_decode($result, true); |
|
|
|
// Decode the JSON response into an associative array |
|
|
|
$temp = json_decode($serverResponse, associative: true); |
|
|
|
return $temp; |
|
|
|
} |
|
|
|
|
|
|
|
public function GetRawNode(UUID $nodeID): DeegraphNodeDetails |
|
|
|
public function RunQuery(UUID $actorID, string $queryString): array |
|
|
|
{ |
|
|
|
return $this->RunRawRequest( |
|
|
|
actorID: $actorID, |
|
|
|
endpoint: "/api/v1/@query", |
|
|
|
method: "POST", |
|
|
|
body: $queryString |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
public function GetRawNode(UUID $actorID, UUID $nodeID): DeegraphNodeDetails |
|
|
|
{ |
|
|
|
$response = $this->RunRawRequest( |
|
|
|
actorID: $actorID, |
|
|
|
endpoint: "/api/v1/{$nodeID}", |
|
|
|
method: "GET", |
|
|
|
body: null, |
|
|
|