daUser->username();
$prefix = $ctx->daUser->prefix();
$dbNames = array_map(static fn(array $db): string => $db['name'], $ctx->pg->listDatabasesForUser($daUser));
$roleNames = array_map(static fn(array $r): string => $r['name'], $ctx->pg->listRolesForUser($daUser));
if (empty($dbNames)) {
$ctx->renderPage('Zarządzaj bazą danych', '
Brak baz danych do zarządzania.
', $ok, $errors);
return;
}
$selectedDb = $ctx->postString('db_name');
if ($selectedDb === '') {
$selectedDb = $ctx->queryString('db');
}
if ($selectedDb === '') {
$selectedDb = $dbNames[0];
}
try {
$selectedDb = NamePolicy::normalizeDatabaseName($selectedDb, $prefix);
} catch (Throwable $e) {
$selectedDb = $dbNames[0];
}
if (!in_array($selectedDb, $dbNames, true)) {
$selectedDb = $dbNames[0];
}
$selectedRole = $ctx->postString('role_name');
if ($selectedRole === '') {
$selectedRole = $ctx->queryString('role');
}
if ($ctx->isPost()) {
try {
$ctx->requireCsrf('modify_privileges_submit');
$syncHbaAfterChange = false;
$selectedDb = NamePolicy::normalizeDatabaseName($ctx->postString('db_name', $selectedDb), $prefix);
if (!in_array($selectedDb, $dbNames, true)) {
throw new RuntimeException('Baza nie należy do konta DA: ' . $selectedDb);
}
$action = $ctx->postString('form_action', 'save_privileges');
if ($action === 'revoke_user') {
$role = NamePolicy::normalizeRoleName($ctx->postString('role_name'), $prefix);
if (!in_array($role, $roleNames, true)) {
throw new RuntimeException('Nieprawidłowy użytkownik PostgreSQL: ' . $role);
}
$ctx->pg->revokePrivileges($selectedDb, $role);
$ctx->pg->deleteRoleHosts($daUser, $role, $selectedDb);
$syncHbaAfterChange = true;
$selectedRole = $role;
$ok[] = 'Odebrano dostęp użytkownikowi ' . $role . ' do bazy ' . $selectedDb . '.';
} elseif ($action === 'grant_user') {
$role = NamePolicy::normalizeRoleName($ctx->postString('role_name'), $prefix);
if (!in_array($role, $roleNames, true)) {
throw new RuntimeException('Nieprawidłowy użytkownik PostgreSQL: ' . $role);
}
$privileges = NamePolicy::sanitizePrivileges($ctx->postArray('grant_privileges'));
if (empty($privileges)) {
$privileges = NamePolicy::defaultPrivileges();
}
$ctx->pg->grantPrivileges($selectedDb, $role, $privileges);
$syncHbaAfterChange = true;
$selectedRole = $role;
$ok[] = 'Przyznano dostęp użytkownikowi ' . $role . ' do bazy ' . $selectedDb . '.';
} else {
$role = NamePolicy::normalizeRoleName($ctx->postString('role_name'), $prefix);
if (!in_array($role, $roleNames, true)) {
throw new RuntimeException('Nieprawidłowy użytkownik PostgreSQL: ' . $role);
}
$privileges = NamePolicy::sanitizePrivileges($ctx->postArray('privileges'));
if (empty($privileges)) {
throw new RuntimeException('Wybierz przynajmniej jedno uprawnienie.');
}
$ctx->pg->grantPrivileges($selectedDb, $role, $privileges);
$syncHbaAfterChange = true;
$selectedRole = $role;
$ok[] = 'Zaktualizowano uprawnienia użytkownika ' . $role . '.';
}
if ($syncHbaAfterChange) {
$sync = $ctx->pg->syncHbaRules();
if (!$sync['ok']) {
$errors[] = 'Uprawnienia zapisane, ale synchronizacja pg_hba nie powiodła się: ' . $sync['output'];
} else {
$ok[] = 'Synchronizacja pg_hba zakończona.';
}
}
} catch (Throwable $e) {
$errors[] = $e->getMessage();
}
}
$dbInfo = $ctx->pg->getDatabaseInfo($selectedDb);
$dbStats = $ctx->pg->getDatabaseObjectStats($selectedDb);
$dbUsers = $ctx->pg->listDatabaseUsers($daUser, $selectedDb);
if ($selectedRole !== '') {
try {
$selectedRole = NamePolicy::normalizeRoleName($selectedRole, $prefix);
} catch (Throwable $e) {
$selectedRole = '';
}
}
if ($selectedRole === '' && !empty($dbUsers)) {
$selectedRole = $dbUsers[0];
}
$currentProfile = [];
if ($selectedRole !== '') {
$currentProfile = $ctx->pg->getGrantProfile($selectedDb, $selectedRole);
if (empty($currentProfile) && in_array($selectedRole, $dbUsers, true)) {
$currentProfile = ['ALL'];
}
}
$dbOptions = '';
foreach ($dbNames as $dbName) {
$sel = ($dbName === $selectedDb) ? ' selected' : '';
$dbOptions .= '';
}
$assignableRoles = array_values(array_diff($roleNames, $dbUsers));
$assignOptions = '';
foreach ($assignableRoles as $role) {
$assignOptions .= '';
}
$usersRows = '';
foreach ($dbUsers as $role) {
$profile = $ctx->pg->getGrantProfile($selectedDb, $role);
$label = (empty($profile) || in_array('ALL', $profile, true))
? 'Pełny dostęp'
: implode(', ', $profile);
$usersRows .= '';
$usersRows .= '| ' . AppContext::e($role) . ' | ';
$usersRows .= '' . AppContext::e($label) . ' | ';
$usersRows .= '';
$usersRows .= 'Zarządzaj';
$usersRows .= 'Przywileje';
$usersRows .= '';
$usersRows .= ' | ';
$usersRows .= '
';
}
if ($usersRows === '') {
$usersRows = '| Brak użytkowników z dostępem do bazy. |
';
}
$privCheckboxes = '';
foreach (NamePolicy::PRIVILEGE_LABELS as $code => $label) {
$checked = in_array($code, $currentProfile, true) ? ' checked' : '';
$privCheckboxes .= '';
}
$body = '';
$body .= '';
$body .= 'Zarządzaj bazą danych
';
$body .= '';
$body .= 'Szczegółowe informacje o bazie danych.
';
$body .= '';
$body .= 'Nazwa bazy danych ' . AppContext::e($dbInfo['name']) . ' | Domyślne kodowanie znaków ' . AppContext::e($dbInfo['encoding']) . ' | Domyślne porównywanie znaków ' . AppContext::e($dbInfo['collation']) . ' |
';
$body .= 'Rozmiar ' . AppContext::e($dbInfo['size']) . ' | Użytkownicy ' . AppContext::e((string)count($dbUsers)) . ' | Liczba Tabel ' . AppContext::e((string)$dbStats['tables']) . ' |
';
$body .= 'Widoki ' . AppContext::e((string)$dbStats['views']) . ' | Wyzwalacze ' . AppContext::e((string)$dbStats['triggers']) . ' | Rutyny i procedury ' . AppContext::e((string)$dbStats['routines']) . ' |
';
$body .= '
';
$body .= '';
$body .= '';
$body .= 'Dostęp użytkownika
';
$body .= 'Lista użytkowników, którzy mają dostęp do tej bazy danych wraz z podsumowaniem uprawnień.
';
$body .= '| Nazwa użytkownika | Przywileje | Akcje |
' . $usersRows . '
';
$body .= '';
$body .= '';
if ($selectedRole !== '') {
$body .= '';
$body .= 'Przywileje użytkownika: ' . AppContext::e($selectedRole) . '
';
$body .= '';
$body .= '';
}
$ctx->renderPage('Zarządzaj bazą danych', $body, $ok, $errors);
};