daUser->username(); $prefix = $ctx->daUser->prefix(); $showRemoteHosts = $ctx->settings->allowRemoteHosts(); $fixedHosts = array_flip($ctx->mysql->requiredAccessHosts()); $passwordChangedFor = ''; $changedPassword = ''; $createdRoleName = ''; $createdRolePassword = ''; $createdRoleAssignedDbs = []; $showCreateUserForm = (strtolower(trim($ctx->queryString('add_user'))) === '1'); $deletePromptRoleRaw = trim($ctx->postString('delete_role')); if ($deletePromptRoleRaw === '') { $deletePromptRoleRaw = trim($ctx->queryString('delete_role')); } $deletePromptRole = ''; $deletePromptAssignedDbs = []; $createRoleSuffixInput = trim($ctx->postString('create_role_name')); if (strpos($createRoleSuffixInput, $prefix) === 0) { $createRoleSuffixInput = substr($createRoleSuffixInput, strlen($prefix)); } $createPasswordInput = $ctx->postString('create_password'); $createSelectedDbsRaw = $ctx->postArray('create_user_databases'); $createSelectedDbs = array_values(array_unique(array_filter($createSelectedDbsRaw, static fn(string $db): bool => $db !== ''))); $databases = $ctx->mysql->listDatabasesForUser($daUser); $allDbs = array_map(static fn(array $db): string => $db['name'], $databases); $roles = $ctx->mysql->listRolesForUser($daUser); $roleNames = array_map(static fn(array $r): string => $r['name'], $roles); $preferredRoleRaw = $ctx->postString('role_name'); if ($preferredRoleRaw === '') { $preferredRoleRaw = $ctx->queryString('role'); } if ($ctx->isPost()) { $postAction = $ctx->postString('form_action'); try { if ($postAction === 'create_user_inline') { $ctx->requireCsrf('create_user_inline_submit'); $showCreateUserForm = true; $newRole = NamePolicy::normalizeRoleName($ctx->postString('create_role_name'), $prefix); if ($ctx->mysql->roleExists($newRole)) { throw new RuntimeException('Użytkownik MySQL już istnieje: ' . $newRole); } $newPassword = $ctx->postString('create_password'); if (strlen($newPassword) < 12) { throw new RuntimeException('Hasło użytkownika musi mieć co najmniej 12 znaków.'); } $selectedDbs = []; foreach ($createSelectedDbs as $rawDbName) { $dbName = NamePolicy::normalizeDatabaseName($rawDbName, $prefix); if (!in_array($dbName, $allDbs, true)) { throw new RuntimeException('Baza nie należy do konta DA: ' . $dbName); } if (!in_array($dbName, $selectedDbs, true)) { $selectedDbs[] = $dbName; } } $ctx->mysql->createRole($newRole, $newPassword); try { $ctx->mysql->replaceRoleHostsWithNotes($daUser, $newRole, []); foreach ($selectedDbs as $dbName) { $ctx->mysql->grantPrivileges($dbName, $newRole, NamePolicy::defaultPrivileges()); } $sync = $ctx->mysql->syncHostRules(); if (!$sync['ok']) { $errors[] = 'Użytkownik został utworzony, ale synchronizacja hostów MySQL nie powiodła się: ' . $sync['output']; } $createdRoleName = $newRole; $createdRolePassword = $newPassword; $createdRoleAssignedDbs = $selectedDbs; if (empty($selectedDbs)) { $ok[] = 'Utworzono użytkownika ' . $newRole . ' bez przypisanych baz danych.'; } else { $ok[] = 'Utworzono użytkownika ' . $newRole . ' i przypisano do ' . count($selectedDbs) . ' baz(y).'; } $preferredRoleRaw = $newRole; $showCreateUserForm = false; $createRoleSuffixInput = ''; $createPasswordInput = ''; $createSelectedDbs = []; } catch (Throwable $inner) { try { $ctx->mysql->deleteRoleHosts($daUser, $newRole); } catch (Throwable $ignored) { } try { $ctx->mysql->dropRole($newRole); } catch (Throwable $ignored) { } throw $inner; } } elseif ($postAction === 'delete_user_confirm') { $ctx->requireCsrf('delete_user_submit'); $roleToDelete = NamePolicy::normalizeRoleName($ctx->postString('delete_role'), $prefix); if (!in_array($roleToDelete, $roleNames, true)) { throw new RuntimeException('Użytkownik MySQL nie należy do konta DA: ' . $roleToDelete); } $owned = array_values(array_unique($ctx->mysql->roleOwnedDatabases($roleToDelete, $daUser))); if (!empty($owned)) { throw new RuntimeException( 'Nie można usunąć użytkownika, ponieważ jest właścicielem baz: ' . implode(', ', $owned) ); } $assigned = array_values(array_unique($ctx->mysql->roleAssignedDatabases($roleToDelete, $daUser))); foreach ($assigned as $dbName) { $owner = $ctx->mysql->getDatabaseOwner($dbName); if ($owner !== null && $owner !== $roleToDelete) { $ctx->mysql->reassignOwnedObjects($dbName, $roleToDelete, $owner); } $ctx->mysql->revokePrivileges($dbName, $roleToDelete); } $ctx->mysql->deleteRoleHosts($daUser, $roleToDelete); $ctx->mysql->dropRole($roleToDelete); $sync = $ctx->mysql->syncHostRules(); if (!$sync['ok']) { $errors[] = 'Usuwanie wykonane, ale synchronizacja hostów MySQL nie powiodła się: ' . $sync['output']; } $ok[] = 'Usunięto użytkownika ' . $roleToDelete . '.'; if ($preferredRoleRaw === $roleToDelete) { $preferredRoleRaw = ''; } $deletePromptRoleRaw = ''; } else { $ctx->requireCsrf('user_manage_submit'); if (empty($roleNames)) { throw new RuntimeException('Brak użytkowników MySQL do zarządzania.'); } $selectedRole = NamePolicy::normalizeRoleName($ctx->postString('role_name', $preferredRoleRaw), $prefix); if (!in_array($selectedRole, $roleNames, true)) { throw new RuntimeException('Użytkownik MySQL nie należy do konta DA: ' . $selectedRole); } $preferredRoleRaw = $selectedRole; if ($postAction === 'change_password') { $password = $ctx->postString('password'); if (strlen($password) < 12) { throw new RuntimeException('Nowe hasło musi mieć minimum 12 znaków.'); } $ctx->mysql->changeRolePassword($selectedRole, $password); $passwordChangedFor = $selectedRole; $changedPassword = $password; } elseif ($postAction === 'grant_db') { $dbName = NamePolicy::normalizeDatabaseName($ctx->postString('db_name'), $prefix); if (!in_array($dbName, $allDbs, true)) { throw new RuntimeException('Baza nie należy do konta DA: ' . $dbName); } $privileges = NamePolicy::sanitizePrivileges($ctx->postArray('privileges')); if (empty($privileges)) { $privileges = NamePolicy::defaultPrivileges(); } $ctx->mysql->grantPrivileges($dbName, $selectedRole, $privileges); $ok[] = 'Przyznano dostęp do bazy ' . $dbName . ' użytkownikowi ' . $selectedRole . '.'; } elseif ($postAction === 'revoke_db') { $dbName = NamePolicy::normalizeDatabaseName($ctx->postString('db_name'), $prefix); $ctx->mysql->revokePrivileges($dbName, $selectedRole); $ok[] = 'Odebrano dostęp do bazy ' . $dbName . ' użytkownikowi ' . $selectedRole . '.'; } elseif ($postAction === 'add_host' && $showRemoteHosts) { $host = NamePolicy::normalizeRemoteIpv4Host($ctx->postString('host')); $note = NamePolicy::normalizeHostComment($ctx->postString('host_note')); $entries = $ctx->mysql->getRoleHostEntries($daUser, $selectedRole); $map = []; foreach ($entries as $entry) { $map[$entry['host']] = $entry['note']; } $map[$host] = $note; $customHostsCount = 0; foreach (array_keys($map) as $mapHost) { if (!isset($fixedHosts[$mapHost])) { $customHostsCount++; } } if ($customHostsCount > $ctx->settings->maxHostsPerUser()) { throw new RuntimeException('Przekroczono limit hostów dla użytkownika MySQL.'); } $save = []; foreach ($map as $h => $n) { $save[] = ['host' => $h, 'note' => $n]; } $ctx->mysql->replaceRoleHostsWithNotes($daUser, $selectedRole, $save); $sync = $ctx->mysql->syncHostRules(); if (!$sync['ok']) { $errors[] = 'Host dodany, ale synchronizacja hostów MySQL nie powiodła się: ' . $sync['output']; } $ok[] = 'Dodano host ' . $host . ' dla użytkownika ' . $selectedRole . '.'; } elseif ($postAction === 'remove_host' && $showRemoteHosts) { $host = trim($ctx->postString('host')); if (isset($fixedHosts[$host])) { throw new RuntimeException('Ten host jest dodawany automatycznie i nie moze zostac usuniety.'); } $entries = $ctx->mysql->getRoleHostEntries($daUser, $selectedRole); $save = []; foreach ($entries as $entry) { if ($entry['host'] === $host) { continue; } $save[] = $entry; } $ctx->mysql->replaceRoleHostsWithNotes($daUser, $selectedRole, $save); $sync = $ctx->mysql->syncHostRules(); if (!$sync['ok']) { $errors[] = 'Host usunięty, ale synchronizacja hostów MySQL nie powiodła się: ' . $sync['output']; } $ok[] = 'Usunięto host ' . $host . ' dla użytkownika ' . $selectedRole . '.'; } } } catch (Throwable $e) { $errors[] = $e->getMessage(); if ($postAction === 'create_user_inline') { $showCreateUserForm = true; } if ($postAction === 'delete_user_confirm') { $deletePromptRoleRaw = trim($ctx->postString('delete_role')); } } } $databases = $ctx->mysql->listDatabasesForUser($daUser); $allDbs = array_map(static fn(array $db): string => $db['name'], $databases); $roles = $ctx->mysql->listRolesForUser($daUser); $roleNames = array_map(static fn(array $r): string => $r['name'], $roles); $selectedRole = ''; if (!empty($roleNames)) { $candidateRaw = $preferredRoleRaw !== '' ? $preferredRoleRaw : $roleNames[0]; try { $candidate = NamePolicy::normalizeRoleName($candidateRaw, $prefix); } catch (Throwable $e) { $candidate = $roleNames[0]; } if (!in_array($candidate, $roleNames, true)) { $candidate = $roleNames[0]; } $selectedRole = $candidate; } if ($deletePromptRoleRaw !== '') { try { $deletePromptRole = NamePolicy::normalizeRoleName($deletePromptRoleRaw, $prefix); if (!in_array($deletePromptRole, $roleNames, true)) { throw new RuntimeException('Użytkownik MySQL nie należy do konta DA: ' . $deletePromptRole); } $deletePromptAssignedDbs = array_values(array_unique($ctx->mysql->roleAssignedDatabases($deletePromptRole, $daUser))); } catch (Throwable $e) { $errors[] = $e->getMessage(); $deletePromptRole = ''; $deletePromptAssignedDbs = []; } } $createSelectedDbSet = []; foreach ($createSelectedDbs as $rawDbName) { try { $dbName = NamePolicy::normalizeDatabaseName($rawDbName, $prefix); } catch (Throwable $e) { continue; } if (in_array($dbName, $allDbs, true)) { $createSelectedDbSet[$dbName] = true; } } $roleOptions = ''; foreach ($roleNames as $roleName) { $sel = ($roleName === $selectedRole) ? ' selected' : ''; $roleOptions .= ''; } $assignedDbs = []; $grantableDbs = $allDbs; if ($selectedRole !== '') { $assignedDbs = $ctx->mysql->roleAssignedDatabases($selectedRole, $daUser); $grantableDbs = array_values(array_diff($allDbs, $assignedDbs)); } $dbOptions = ''; foreach ($grantableDbs as $dbName) { $dbOptions .= ''; } $dbRows = ''; foreach ($assignedDbs as $dbName) { $profile = $ctx->mysql->getGrantProfile($dbName, $selectedRole); $label = (empty($profile) || in_array('ALL', $profile, true)) ? 'Pełny dostęp' : implode(', ', $profile); $dbRows .= ''; $dbRows .= '' . AppContext::e($dbName) . ''; $dbRows .= '' . AppContext::e($label) . ''; $dbRows .= ''; $dbRows .= 'Zarządzaj'; $dbRows .= 'Przywileje'; $dbRows .= '
'; $dbRows .= $ctx->csrfField('user_manage_submit'); $dbRows .= ''; $dbRows .= ''; $dbRows .= ''; $dbRows .= ''; $dbRows .= '
'; $dbRows .= ''; $dbRows .= ''; } if ($dbRows === '') { $dbRows = 'Brak przypisanych baz danych.'; } $hostEntries = []; if ($selectedRole !== '') { $hostEntries = $ctx->mysql->getRoleHostEntries($daUser, $selectedRole); } $hostsRows = ''; $hostsCount = count($hostEntries); if ($showRemoteHosts && $selectedRole !== '') { $hostsCount = count($hostEntries); foreach ($hostEntries as $entry) { $host = $entry['host']; $note = $entry['note']; $hostsRows .= ''; $hostsRows .= '' . AppContext::e($host) . ''; $hostsRows .= '' . AppContext::e($note) . ''; $hostsRows .= ''; if (!isset($fixedHosts[$host])) { $hostsRows .= '
'; $hostsRows .= $ctx->csrfField('user_manage_submit'); $hostsRows .= ''; $hostsRows .= ''; $hostsRows .= ''; $hostsRows .= ''; $hostsRows .= '
'; } else { $hostsRows .= 'host stały'; } $hostsRows .= ''; $hostsRows .= ''; } if ($hostsRows === '') { $hostsRows = 'Brak dozwolonych hostów.'; } } $endpoint = $ctx->mysql->connectionEndpoint(); $endpointHost = trim($endpoint['host']) !== '' ? $endpoint['host'] : 'localhost'; $endpointPort = $endpoint['port'] > 0 ? (string)$endpoint['port'] : '3306'; $createdUserCard = ''; if ($createdRoleName !== '' && $createdRolePassword !== '') { $assignedDbsHtml = ''; if (!empty($createdRoleAssignedDbs)) { $assignedItems = ''; foreach ($createdRoleAssignedDbs as $assignedDbName) { $assignedItems .= '
  • ' . AppContext::e($assignedDbName) . '
  • '; } $assignedDbsHtml .= '
    Przypisane bazy danych:
    '; $assignedDbsHtml .= '
    '; } $createdUserCard .= '
    '; $createdUserCard .= '
    '; $createdUserCard .= '
    '; $createdUserCard .= '

    Dane dostępowe użytkownika MySQL

    '; $createdUserCard .= '
    '; $createdUserCard .= '
    Nazwa hosta:
    ' . AppContext::e($endpointHost) . ' (Port: ' . AppContext::e($endpointPort) . ')
    '; $createdUserCard .= '
    Nazwa użytkownika:
    ' . AppContext::e($createdRoleName) . '
    '; $createdUserCard .= '
    Hasło:
    ' . AppContext::e($createdRolePassword) . '
    '; $createdUserCard .= $assignedDbsHtml; $createdUserCard .= '
    '; } $passwordChangedCard = ''; if ($passwordChangedFor !== '' && $changedPassword !== '') { $passwordChangedCard .= '
    '; $passwordChangedCard .= '
    '; $passwordChangedCard .= '
    '; $passwordChangedCard .= '

    Hasło zostało zmienione

    '; $passwordChangedCard .= '
    '; $passwordChangedCard .= '
    Nazwa hosta:
    ' . AppContext::e($endpointHost) . ' (Port: ' . AppContext::e($endpointPort) . ')
    '; $passwordChangedCard .= '
    Nazwa użytkownika:
    ' . AppContext::e($passwordChangedFor) . '
    '; $passwordChangedCard .= '
    Hasło:
    ' . AppContext::e($changedPassword) . '
    '; $passwordChangedCard .= '
    '; } $body = ''; $body .= $createdUserCard; $body .= $passwordChangedCard; $body .= '
    '; $body .= '

    Zarządzaj użytkownikami

    '; $body .= '
    '; $body .= '
    '; $body .= 'Dodaj użytkownika'; if ($showCreateUserForm) { $body .= 'Anuluj'; } $body .= '
    '; if ($selectedRole !== '') { $body .= '
    '; $body .= '
    '; $body .= ''; $body .= ''; $body .= '
    '; $body .= 'Usuń użytkownika'; $body .= '
    '; } else { $body .= 'Brak użytkowników MySQL. Dodaj pierwszego użytkownika.'; } $body .= '
    '; $body .= '

    Szczegółowe informacje o użytkowniku.

    '; if ($selectedRole !== '') { $body .= ''; $body .= ''; if ($showRemoteHosts) { $body .= ''; } else { $fixedHostSummary = implode(', ', array_keys($fixedHosts)); $body .= ''; } $body .= '
    Nazwa użytkownika
    ' . AppContext::e($selectedRole) . '
    Bazy danych
    ' . AppContext::e((string)count($assignedDbs)) . '
    Dozwolone hosty
    ' . AppContext::e((string)$hostsCount) . '
    Dozwolone hosty
    ' . AppContext::e($fixedHostSummary) . '
    '; } else { $body .= '

    Aby zarządzać użytkownikami najpierw utwórz użytkownika MySQL.

    '; } $body .= '
    '; if ($deletePromptRole !== '') { $cancelUrl = $ctx->url('change_password.html', $selectedRole !== '' ? ['role' => $selectedRole] : []); $body .= '
    '; $body .= '
    Czy na pewno chcesz usunąć użytkownika ' . AppContext::e($deletePromptRole) . '?
    '; if (count($deletePromptAssignedDbs) === 1) { $body .= '
    Uwaga użytkownik ' . AppContext::e($deletePromptRole) . ' jest przypisany do następującej bazy danych ' . AppContext::e($deletePromptAssignedDbs[0]) . '.
    '; } elseif (count($deletePromptAssignedDbs) > 1) { $body .= '
    Uwaga użytkownik ' . AppContext::e($deletePromptRole) . ' jest przypisany do następujących baz danych:
    '; $body .= ''; } $body .= '
    '; $body .= $ctx->csrfField('delete_user_submit'); $body .= ''; $body .= ''; $body .= '
    '; $body .= ''; $body .= 'Anuluj'; $body .= '
    '; $body .= '
    '; $body .= '
    '; } if ($showCreateUserForm) { $body .= '
    '; $body .= '

    Utwórz nowego użytkownika MySQL

    '; $body .= '
    '; $body .= $ctx->csrfField('create_user_inline_submit'); $body .= ''; $body .= '
    '; $body .= '
    ' . AppContext::e($prefix) . '
    '; $body .= '
    '; $body .= '
    '; $body .= ''; $body .= ''; $body .= ''; $body .= '
    '; $body .= '
    '; $body .= '
    '; $body .= '
    '; $body .= 'Przypisz do baz danych (opcjonalnie)'; if (empty($allDbs)) { $body .= '

    Brak baz do przypisania.

    '; } else { $body .= '
    '; foreach ($allDbs as $dbName) { $checked = isset($createSelectedDbSet[$dbName]) ? ' checked' : ''; $body .= ''; } $body .= '
    '; } $body .= '

    Możesz pozostawić użytkownika bez przypisania do baz i nadać dostęp później.

    '; $body .= '
    '; $body .= '
    '; $body .= '
    '; $body .= '
    '; } if ($selectedRole !== '') { $body .= '
    '; $body .= '

    Zarządzanie hasłami

    '; $body .= '
    '; $body .= $ctx->csrfField('user_manage_submit'); $body .= ''; $body .= ''; $body .= ''; $body .= '
    '; $body .= ''; $body .= ''; $body .= ''; $body .= '
    '; $body .= '
    '; $body .= '
    '; $body .= '
    '; $body .= '
    '; $body .= '

    Dostęp do baz danych

    '; $body .= '' . $dbRows . '
    Nazwa bazy danychPrzywilejeAkcje
    '; $body .= '
    '; $body .= $ctx->csrfField('user_manage_submit'); $body .= ''; $body .= ''; $body .= ''; $body .= ''; $body .= ''; $body .= '
    '; $body .= '
    '; $body .= '
    '; if ($showRemoteHosts) { $fixedHostsHelp = '`localhost` jest dodawany automatycznie.'; if (count($fixedHosts) > 1) { $fixedHostsHelp .= ' Przy zdalnym serwerze MySQL plugin dodaje tez adres IP serwera DirectAdmin.'; } $body .= '
    '; $body .= '

    Dozwolone hosty

    '; $body .= '

    Lista źródłowych adresów IP, które mogą łączyć się z bazą przy użyciu poświadczeń użytkownika. ' . $fixedHostsHelp . '

    '; $body .= '' . $hostsRows . '
    HostKomentarzAkcje
    '; $body .= '
    '; $body .= $ctx->csrfField('user_manage_submit'); $body .= ''; $body .= ''; $body .= '
    '; $body .= '
    '; $body .= '
    '; $body .= '
    '; $body .= '
    '; $body .= '
    '; $body .= '
    '; } } $ctx->renderPage('Zarządzaj użytkownikami', $body, $ok, $errors); };