146 lines
4.6 KiB
PHP
146 lines
4.6 KiB
PHP
<?php
|
|
|
|
namespace classes;
|
|
|
|
use Exception;
|
|
|
|
class edge_broker_transport_exception extends Exception
|
|
{
|
|
public function __construct(string $message, private readonly int $curlErrno = 0, int $code = 0, ?Exception $previous = null)
|
|
{
|
|
parent::__construct($message, $code, $previous);
|
|
}
|
|
|
|
public function curlErrno(): int
|
|
{
|
|
return $this->curlErrno;
|
|
}
|
|
}
|
|
|
|
class edge_broker_http_exception extends Exception
|
|
{
|
|
public function __construct(string $message, private readonly int $statusCode, int $code = 0, ?Exception $previous = null)
|
|
{
|
|
parent::__construct($message, $code, $previous);
|
|
}
|
|
|
|
public function statusCode(): int
|
|
{
|
|
return $this->statusCode;
|
|
}
|
|
}
|
|
|
|
class edge_broker_client
|
|
{
|
|
private const DEFAULT_BROKER_URL = 'http://edge-broker:4300';
|
|
|
|
public function __construct(
|
|
private readonly ?string $baseUrl = null,
|
|
private readonly ?string $sharedSecret = null,
|
|
private readonly int $timeoutSeconds = 10
|
|
) {
|
|
}
|
|
|
|
public function isConfigured(): bool
|
|
{
|
|
return trim((string)$this->resolveBaseUrl()) !== '';
|
|
}
|
|
|
|
public function dispatchCommand(int $gatewayId, string $commandType, array $payload): array
|
|
{
|
|
$url = rtrim($this->resolveBaseUrl(), '/') . '/api/gateways/' . $gatewayId . '/commands';
|
|
$response = $this->request('POST', $url, [
|
|
'commandType' => $commandType,
|
|
'payload' => $payload,
|
|
]);
|
|
|
|
return is_array($response) ? $response : ['ok' => false, 'response' => $response];
|
|
}
|
|
|
|
public function validateAgent(int $gatewayId, string $agentToken): array
|
|
{
|
|
$url = rtrim($this->resolveBaseUrl(), '/') . '/api/internal/agent/auth';
|
|
$response = $this->request('POST', $url, [
|
|
'gatewayId' => $gatewayId,
|
|
'agentToken' => $agentToken,
|
|
]);
|
|
|
|
return is_array($response) ? $response : [];
|
|
}
|
|
|
|
public function validateShellSession(string $sessionToken): array
|
|
{
|
|
$url = rtrim($this->resolveBaseUrl(), '/') . '/api/internal/shell/auth';
|
|
$response = $this->request('POST', $url, [
|
|
'sessionToken' => $sessionToken,
|
|
]);
|
|
|
|
return is_array($response) ? $response : [];
|
|
}
|
|
|
|
public function closeShellSession(int $sessionId, string $sessionToken, string $transcript, string $closedReason): array
|
|
{
|
|
$url = rtrim($this->resolveBaseUrl(), '/') . '/api/internal/shell-sessions/' . $sessionId . '/close';
|
|
$response = $this->request('POST', $url, [
|
|
'sessionToken' => $sessionToken,
|
|
'transcript' => $transcript,
|
|
'closedReason' => $closedReason,
|
|
]);
|
|
|
|
return is_array($response) ? $response : [];
|
|
}
|
|
|
|
private function resolveBaseUrl(): string
|
|
{
|
|
return trim((string)($this->baseUrl ?? getenv('EDGE_BROKER_URL') ?: self::DEFAULT_BROKER_URL));
|
|
}
|
|
|
|
private function resolveSharedSecret(): string
|
|
{
|
|
return trim((string)($this->sharedSecret
|
|
?? getenv('EDGE_BROKER_SHARED_SECRET')
|
|
?: getenv('EDGE_INTERNAL_SECRET')
|
|
?: ''));
|
|
}
|
|
|
|
/**
|
|
* @throws Exception
|
|
*/
|
|
private function request(string $method, string $url, array $payload): array|object|null
|
|
{
|
|
if (trim($url) === '') {
|
|
throw new Exception('Edge broker URL is not configured');
|
|
}
|
|
|
|
$ch = curl_init($url);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeoutSeconds);
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, array_values(array_filter([
|
|
'Content-Type: application/json',
|
|
$this->resolveSharedSecret() !== '' ? 'X-Edge-Broker-Secret: ' . $this->resolveSharedSecret() : null,
|
|
])));
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_UNICODE));
|
|
|
|
$rawResponse = curl_exec($ch);
|
|
$statusCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
$curlErrno = curl_errno($ch);
|
|
$curlError = curl_error($ch);
|
|
curl_close($ch);
|
|
|
|
if ($rawResponse === false) {
|
|
throw new edge_broker_transport_exception('Edge broker request failed: ' . $curlError, $curlErrno);
|
|
}
|
|
|
|
$decoded = json_decode((string)$rawResponse, true);
|
|
if ($statusCode >= 400) {
|
|
$message = is_array($decoded)
|
|
? (string)($decoded['error'] ?? $decoded['message'] ?? 'Edge broker request failed')
|
|
: 'Edge broker request failed';
|
|
throw new edge_broker_http_exception($message, $statusCode);
|
|
}
|
|
|
|
return $decoded;
|
|
}
|
|
}
|