163 lines
6.3 KiB
PHP
163 lines
6.3 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
return static function (AppContext $ctx): void {
|
|
if (!$ctx->settings->allowRemoteHosts()) {
|
|
$ctx->renderFatal('Zarządzanie hostami zdalnymi jest wyłączone (`allow_remote_hosts=0`).', 403);
|
|
return;
|
|
}
|
|
|
|
$ok = [];
|
|
$errors = [];
|
|
|
|
$daUser = $ctx->daUser->username();
|
|
$prefix = $ctx->daUser->prefix();
|
|
$fixedHosts = array_flip($ctx->mysql->requiredAccessHosts());
|
|
|
|
if (!$ctx->isPost()) {
|
|
$sync = $ctx->mysql->syncHostRules();
|
|
if (!$sync['ok']) {
|
|
$errors[] = 'Synchronizacja zdalnych hostów MySQL nie powiodła się: ' . $sync['output'];
|
|
}
|
|
}
|
|
|
|
$roleNames = array_map(static fn(array $r): string => $r['name'], $ctx->mysql->listRolesForUser($daUser));
|
|
$selectedRole = $ctx->queryString('role');
|
|
|
|
if ($ctx->isPost()) {
|
|
$selectedRole = $ctx->postString('role_name');
|
|
|
|
try {
|
|
$ctx->requireCsrf('manage_hosts_submit');
|
|
|
|
$selectedRole = NamePolicy::normalizeRoleName($selectedRole, $prefix);
|
|
if (!in_array($selectedRole, $roleNames, true)) {
|
|
throw new RuntimeException('Użytkownik MySQL nie należy do konta DA: ' . $selectedRole);
|
|
}
|
|
|
|
$currentEntries = $ctx->mysql->getRoleHostEntries($daUser, $selectedRole);
|
|
$hostMap = [];
|
|
foreach ($currentEntries as $entry) {
|
|
$hostMap[$entry['host']] = $entry['note'];
|
|
}
|
|
|
|
$removeHosts = $ctx->postArray('remove_hosts');
|
|
$removeHosts = array_values(array_unique($removeHosts));
|
|
foreach ($removeHosts as $rawHost) {
|
|
$host = trim($rawHost);
|
|
if ($host === '' || isset($fixedHosts[$host])) {
|
|
continue;
|
|
}
|
|
if (array_key_exists($host, $hostMap)) {
|
|
unset($hostMap[$host]);
|
|
}
|
|
}
|
|
|
|
$addHostRaw = trim($ctx->postString('add_host'));
|
|
if ($addHostRaw !== '') {
|
|
$addHost = NamePolicy::normalizeRemoteIpv4Host($addHostRaw);
|
|
$addComment = NamePolicy::normalizeHostComment($ctx->postString('add_comment'));
|
|
$hostMap[$addHost] = $addComment;
|
|
}
|
|
|
|
$customHostsCount = 0;
|
|
foreach (array_keys($hostMap) as $host) {
|
|
if (!isset($fixedHosts[$host])) {
|
|
$customHostsCount++;
|
|
}
|
|
}
|
|
if ($customHostsCount > $ctx->settings->maxHostsPerUser()) {
|
|
throw new RuntimeException('Przekroczono limit hostów dla użytkownika MySQL.');
|
|
}
|
|
|
|
$finalEntries = [];
|
|
foreach ($hostMap as $host => $note) {
|
|
$finalEntries[] = ['host' => $host, 'note' => $note];
|
|
}
|
|
|
|
$ctx->mysql->replaceRoleHostsWithNotes($daUser, $selectedRole, $finalEntries);
|
|
$sync = $ctx->mysql->syncHostRules();
|
|
if (!$sync['ok']) {
|
|
$errors[] = 'Hosty zapisane, ale synchronizacja hostów MySQL nie powiodła się: ' . $sync['output'];
|
|
}
|
|
|
|
$ok[] = 'Zaktualizowano hosty dostępu dla użytkownika ' . $selectedRole . '.';
|
|
} catch (Throwable $e) {
|
|
$errors[] = $e->getMessage();
|
|
}
|
|
}
|
|
|
|
if ($selectedRole !== '') {
|
|
try {
|
|
$selectedRole = NamePolicy::normalizeRoleName($selectedRole, $prefix);
|
|
} catch (Throwable $e) {
|
|
$selectedRole = '';
|
|
}
|
|
}
|
|
|
|
if ($selectedRole === '' && !empty($roleNames)) {
|
|
$selectedRole = $roleNames[0];
|
|
}
|
|
|
|
$currentEntries = [];
|
|
if ($selectedRole !== '') {
|
|
$currentEntries = $ctx->mysql->getRoleHostEntries($daUser, $selectedRole);
|
|
}
|
|
|
|
$roleOptions = '<option value="">-- wybierz użytkownika --</option>';
|
|
foreach ($roleNames as $roleName) {
|
|
$sel = ($roleName === $selectedRole) ? ' selected' : '';
|
|
$roleOptions .= '<option value="' . AppContext::e($roleName) . '"' . $sel . '>' . AppContext::e($roleName) . '</option>';
|
|
}
|
|
|
|
$hostRows = '';
|
|
if (empty($currentEntries)) {
|
|
$hostRows = '<tr><td colspan="3" class="muted">Brak zapisanych hostów.</td></tr>';
|
|
} else {
|
|
foreach ($currentEntries as $entry) {
|
|
$host = $entry['host'];
|
|
$note = $entry['note'];
|
|
$canRemove = !isset($fixedHosts[$host]);
|
|
|
|
$hostRows .= '<tr>';
|
|
$hostRows .= '<td>' . AppContext::e($host) . '</td>';
|
|
$hostRows .= '<td>' . AppContext::e($note) . '</td>';
|
|
if ($canRemove) {
|
|
$hostRows .= '<td><label class="inline"><input type="checkbox" name="remove_hosts[]" value="' . AppContext::e($host) . '"> usuń</label></td>';
|
|
} else {
|
|
$hostRows .= '<td><span class="muted">host stały</span></td>';
|
|
}
|
|
$hostRows .= '</tr>';
|
|
}
|
|
}
|
|
|
|
$body = '';
|
|
$body .= '<form method="post">';
|
|
$body .= $ctx->csrfField('manage_hosts_submit');
|
|
|
|
$body .= '<div class="row">';
|
|
$body .= '<div><label>Użytkownik MySQL</label><select name="role_name" required>' . $roleOptions . '</select></div>';
|
|
$body .= '<div><label>Dodaj IPv4</label><input type="text" name="add_host" placeholder="198.51.100.12"></div>';
|
|
$body .= '</div>';
|
|
|
|
$infoText = 'Dozwolone są wyłącznie pojedyncze adresy IPv4, bez CIDR i bez nazw hostów.';
|
|
if (count($fixedHosts) > 1) {
|
|
$infoText .= ' `localhost` oraz adres IP serwera DirectAdmin sa hostami stalymi i nie mozna ich usunac.';
|
|
} else {
|
|
$infoText .= ' `localhost` jest hostem stalym i nie mozna go usunac.';
|
|
}
|
|
|
|
$body .= '<div class="row">';
|
|
$body .= '<div><label>Komentarz do nowego hosta</label><input type="text" name="add_comment" placeholder="np. serwer aplikacyjny PROD"></div>';
|
|
$body .= '<div><label>Informacja</label><p class="muted">' . $infoText . '</p></div>';
|
|
$body .= '</div>';
|
|
|
|
$body .= '<div class="panel"><h3>Aktualne hosty</h3>';
|
|
$body .= '<table><thead><tr><th>Host</th><th>Komentarz</th><th>Akcja</th></tr></thead><tbody>' . $hostRows . '</tbody></table>';
|
|
$body .= '</div>';
|
|
$body .= '<div class="actions"><button class="primary" type="submit">Zapisz hosty</button></div>';
|
|
$body .= '</form>';
|
|
|
|
$ctx->renderPage('Hosty Zdalne Użytkownika', $body, $ok, $errors);
|
|
};
|