fix: use documented directadmin binary

This commit is contained in:
Marek Miklewicz
2026-06-02 22:23:27 +02:00
parent 7e392e4ee7
commit 7561077eee
3 changed files with 32 additions and 4 deletions
+26 -3
View File
@@ -5,14 +5,19 @@ class DirectAdminVacationApi
{ {
/** @var callable|null */ /** @var callable|null */
private $request; private $request;
private string $daBinary = '/usr/local/bin/da'; private string $daBinary = '/usr/local/directadmin/directadmin';
public function __construct(string $daBinary = '/usr/local/bin/da', ?callable $request = null) public function __construct(string $daBinary = '/usr/local/directadmin/directadmin', ?callable $request = null)
{ {
$this->daBinary = $daBinary; $this->daBinary = $daBinary;
$this->request = $request; $this->request = $request;
} }
public function directAdminBinary(): string
{
return $this->daBinary;
}
/** @param array<string,mixed> $rule @return array<string,string> */ /** @param array<string,mixed> $rule @return array<string,string> */
public function buildSavePayload(string $email, array $rule, bool $exists = true): array public function buildSavePayload(string $email, array $rule, bool $exists = true): array
{ {
@@ -133,7 +138,7 @@ class DirectAdminVacationApi
private function apiUrl(string $owner): string private function apiUrl(string $owner): string
{ {
$output = $this->run([$this->daBinary, 'api-url', '--user=' . $owner], ''); $output = $this->run([$this->resolveDirectAdminBinary(), 'api-url', '--user=' . $owner], '');
$url = trim($output); $url = trim($output);
if ($url === '' || !preg_match('#^https?://#', $url)) { if ($url === '' || !preg_match('#^https?://#', $url)) {
throw new RuntimeException('Cannot determine DirectAdmin API URL for user'); throw new RuntimeException('Cannot determine DirectAdmin API URL for user');
@@ -141,9 +146,27 @@ class DirectAdminVacationApi
return $url; return $url;
} }
private function resolveDirectAdminBinary(): string
{
$candidates = array_values(array_unique([
$this->daBinary,
'/usr/local/directadmin/directadmin',
'/usr/bin/da',
]));
foreach ($candidates as $candidate) {
if ($candidate !== '' && is_executable($candidate)) {
return $candidate;
}
}
throw new RuntimeException('DirectAdmin binary is not executable. Checked: ' . implode(', ', $candidates));
}
/** @param string[] $args */ /** @param string[] $args */
private function run(array $args, string $stdin): string private function run(array $args, string $stdin): string
{ {
if (($args[0] ?? '') !== '' && str_contains($args[0], '/') && !is_executable($args[0])) {
throw new RuntimeException('DirectAdmin API command is not executable: ' . $args[0]);
}
$process = proc_open($args, [['pipe', 'r'], ['pipe', 'w'], ['pipe', 'w']], $pipes); $process = proc_open($args, [['pipe', 'r'], ['pipe', 'w'], ['pipe', 'w']], $pipes);
if (!is_resource($process)) { if (!is_resource($process)) {
throw new RuntimeException('Cannot start DirectAdmin API command'); throw new RuntimeException('Cannot start DirectAdmin API command');
+1 -1
View File
@@ -2,7 +2,7 @@ name=global-autoresponder
id=global-autoresponder id=global-autoresponder
type=user type=user
author=HITME.PL author=HITME.PL
version=1.0.11 version=1.1.1
active=no active=no
installed=no installed=no
user_run_as=root user_run_as=root
+5
View File
@@ -3,6 +3,11 @@ declare(strict_types=1);
require_once PLUGIN_ROOT . '/exec/lib/DirectAdminVacationApi.php'; require_once PLUGIN_ROOT . '/exec/lib/DirectAdminVacationApi.php';
test('directadmin vacation api default binary follows documented directadmin path', function (): void {
$api = new DirectAdminVacationApi();
assert_same('/usr/local/directadmin/directadmin', $api->directAdminBinary());
});
test('directadmin vacation api builds scoped payload for one mailbox', function (): void { test('directadmin vacation api builds scoped payload for one mailbox', function (): void {
$api = new DirectAdminVacationApi('/usr/local/directadmin/directadmin'); $api = new DirectAdminVacationApi('/usr/local/directadmin/directadmin');
$payload = $api->buildSavePayload('info@example.com', [ $payload = $api->buildSavePayload('info@example.com', [