Import alt-mysql plugin
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
return static function (AppContext $ctx): void {
|
||||
$ok = [];
|
||||
$errors = [];
|
||||
|
||||
$daUser = $ctx->daUser->username();
|
||||
$prefix = $ctx->daUser->prefix();
|
||||
$showRemoteHosts = $ctx->settings->allowRemoteHosts();
|
||||
$fixedHosts = array_flip($ctx->mysql->requiredAccessHosts());
|
||||
|
||||
$databases = $ctx->mysql->listDatabasesForUser($daUser);
|
||||
$dbNames = array_map(static fn(array $db): string => $db['name'], $databases);
|
||||
|
||||
if ($ctx->isPost()) {
|
||||
try {
|
||||
$ctx->requireCsrf('create_user_submit');
|
||||
|
||||
$role = NamePolicy::normalizeRoleName($ctx->postString('role_name'), $prefix);
|
||||
if ($ctx->mysql->roleExists($role)) {
|
||||
throw new RuntimeException('Użytkownik MySQL już istnieje: ' . $role);
|
||||
}
|
||||
|
||||
$password = $ctx->postString('password');
|
||||
if (strlen($password) < 12) {
|
||||
throw new RuntimeException('Hasło użytkownika musi mieć co najmniej 12 znaków.');
|
||||
}
|
||||
|
||||
$selectedDbsRaw = $ctx->postArray('databases');
|
||||
$selectedDbs = [];
|
||||
foreach ($selectedDbsRaw as $db) {
|
||||
$normalizedDb = NamePolicy::normalizeDatabaseName($db, $prefix);
|
||||
if (!in_array($normalizedDb, $dbNames, true)) {
|
||||
throw new RuntimeException('Nieprawidłowa baza do przypisania: ' . $normalizedDb);
|
||||
}
|
||||
$selectedDbs[] = $normalizedDb;
|
||||
}
|
||||
$selectedDbs = array_values(array_unique($selectedDbs));
|
||||
|
||||
$privileges = NamePolicy::sanitizePrivileges($ctx->postArray('privileges'));
|
||||
if (empty($privileges)) {
|
||||
$privileges = NamePolicy::defaultPrivileges();
|
||||
}
|
||||
|
||||
$hostMap = [];
|
||||
if ($showRemoteHosts) {
|
||||
$remoteHostRaw = trim($ctx->postString('remote_host'));
|
||||
if ($remoteHostRaw !== '') {
|
||||
$remoteHost = NamePolicy::normalizeRemoteIpv4Host($remoteHostRaw);
|
||||
$remoteComment = NamePolicy::normalizeHostComment($ctx->postString('remote_comment'));
|
||||
$hostMap[$remoteHost] = $remoteComment;
|
||||
}
|
||||
}
|
||||
$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.');
|
||||
}
|
||||
|
||||
$hostEntries = [];
|
||||
foreach ($hostMap as $host => $note) {
|
||||
$hostEntries[] = ['host' => $host, 'note' => $note];
|
||||
}
|
||||
|
||||
$ctx->mysql->createRole($role, $password);
|
||||
try {
|
||||
$ctx->mysql->replaceRoleHostsWithNotes($daUser, $role, $hostEntries);
|
||||
|
||||
foreach ($selectedDbs as $dbName) {
|
||||
$ctx->mysql->grantPrivileges($dbName, $role, $privileges);
|
||||
}
|
||||
|
||||
$sync = $ctx->mysql->syncHostRules();
|
||||
if (!$sync['ok']) {
|
||||
$errors[] = 'Użytkownik został utworzony, ale synchronizacja hostów MySQL nie powiodła się: ' . $sync['output'];
|
||||
}
|
||||
|
||||
$ok[] = 'Utworzono użytkownika ' . $role . ' i przypisano ' . count($selectedDbs) . ' baz(y).';
|
||||
} catch (Throwable $inner) {
|
||||
try {
|
||||
foreach ($selectedDbs as $dbName) {
|
||||
$ctx->mysql->revokePrivileges($dbName, $role);
|
||||
}
|
||||
$ctx->mysql->deleteRoleHosts($daUser, $role);
|
||||
$ctx->mysql->dropRole($role);
|
||||
} catch (Throwable $ignored) {
|
||||
}
|
||||
throw $inner;
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
$errors[] = $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
$dbCheckboxes = '';
|
||||
foreach ($dbNames as $dbName) {
|
||||
$dbCheckboxes .= '<label class="inline"><input type="checkbox" name="databases[]" value="' . AppContext::e($dbName) . '"> ' . AppContext::e($dbName) . '</label>';
|
||||
}
|
||||
if ($dbCheckboxes === '') {
|
||||
$dbCheckboxes = '<p class="muted">Brak baz do przypisania.</p>';
|
||||
}
|
||||
|
||||
$privCheckboxes = '';
|
||||
foreach (NamePolicy::PRIVILEGE_LABELS as $code => $label) {
|
||||
$checked = ($code === 'ALL') ? ' checked' : '';
|
||||
$privCheckboxes .= '<label class="inline"><input type="checkbox" name="privileges[]" value="' . AppContext::e($code) . '"' . $checked . '> ' . AppContext::e($label) . '</label>';
|
||||
}
|
||||
|
||||
$remoteFields = '';
|
||||
if ($showRemoteHosts) {
|
||||
$remoteFields .= '<div class="row">';
|
||||
$remoteFields .= '<div><label>Dodatkowy host IPv4</label><input type="text" name="remote_host" placeholder="203.0.113.10"></div>';
|
||||
$remoteFields .= '<div><label>Komentarz hosta</label><input type="text" name="remote_comment" placeholder="np. Laptop administratora"></div>';
|
||||
$remoteFields .= '</div>';
|
||||
} else {
|
||||
$remoteFields .= '<p class="muted">Hosty zdalne są wyłączone w konfiguracji pluginu (`allow_remote_hosts=0`).</p>';
|
||||
}
|
||||
|
||||
$body = '';
|
||||
$body .= '<form method="post">';
|
||||
$body .= $ctx->csrfField('create_user_submit');
|
||||
|
||||
$body .= '<div class="row">';
|
||||
$body .= '<div><label>Nazwa użytkownika MySQL</label><input type="text" name="role_name" placeholder="' . AppContext::e($prefix) . 'app_user" required></div>';
|
||||
$body .= '<div><label>Hasło</label><input type="password" name="password" placeholder="min. 12 znaków" required></div>';
|
||||
$body .= '</div>';
|
||||
|
||||
$defaultAccessText = '`localhost` jest dodawany automatycznie.';
|
||||
if (count($fixedHosts) > 1) {
|
||||
$defaultAccessText .= ' Przy zdalnym serwerze MySQL plugin dodaje tez adres IP serwera DirectAdmin.';
|
||||
}
|
||||
|
||||
$body .= '<div class="row">';
|
||||
$body .= '<div><label>Domyślny dostęp</label><p class="muted">' . $defaultAccessText . '</p></div>';
|
||||
$body .= '<div><label>Przypisz do baz</label><div>' . $dbCheckboxes . '</div></div>';
|
||||
$body .= '</div>';
|
||||
|
||||
$body .= $remoteFields;
|
||||
|
||||
$body .= '<div class="panel"><h3>Uprawnienia dla przypisywanych baz</h3><div class="privileges-group" data-privileges-group>' . $privCheckboxes . '</div></div>';
|
||||
$body .= '<div class="actions"><button class="primary" type="submit">Utwórz użytkownika</button></div>';
|
||||
$body .= '</form>';
|
||||
|
||||
$ctx->renderPage('Tworzenie Użytkownika MySQL', $body, $ok, $errors);
|
||||
};
|
||||
Reference in New Issue
Block a user