Grant all owned databases when phpMyAdmin SSO has no specific target
The top-nav PHPMYADMIN button intentionally omits adminer_db to request access to every database. determineGrantTargets() and the ticket's new restrict_db field now distinguish that case from a specific per-row database request instead of collapsing both into single-database scope.
This commit is contained in:
+14
-10
@@ -39,19 +39,19 @@ final class PhpMyAdminSso
|
||||
}
|
||||
$databaseNames = array_values(array_unique($databaseNames));
|
||||
|
||||
$targetDatabase = '';
|
||||
$normalizedRequestedDatabase = null;
|
||||
if ($requestedDatabase !== null) {
|
||||
$requestedDatabase = trim($requestedDatabase);
|
||||
if ($requestedDatabase !== '') {
|
||||
if (!in_array($requestedDatabase, $databaseNames, true)) {
|
||||
throw new RuntimeException('Wskazana baza danych nie należy do zalogowanego użytkownika.');
|
||||
}
|
||||
$targetDatabase = $requestedDatabase;
|
||||
$normalizedRequestedDatabase = $requestedDatabase;
|
||||
}
|
||||
}
|
||||
if ($targetDatabase === '') {
|
||||
$targetDatabase = $databaseNames[0];
|
||||
}
|
||||
|
||||
$targetDatabase = $normalizedRequestedDatabase ?? $databaseNames[0];
|
||||
$restrictToDatabase = $normalizedRequestedDatabase ?? '';
|
||||
|
||||
$roleTtl = max($this->settings->adminerRoleTtl(), $this->settings->adminerSessionTtl() + 120);
|
||||
$role = $this->generateTemporaryRoleName();
|
||||
@@ -60,7 +60,7 @@ final class PhpMyAdminSso
|
||||
|
||||
$this->db->createTemporaryRole($role, $password, $expiresAt);
|
||||
try {
|
||||
foreach (self::determineGrantTargets($targetDatabase, $databaseNames) as $dbName) {
|
||||
foreach (self::determineGrantTargets($normalizedRequestedDatabase, $databaseNames) as $dbName) {
|
||||
$this->db->grantTemporaryAdminerAccess($dbName, $role);
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
@@ -78,7 +78,7 @@ final class PhpMyAdminSso
|
||||
'port' => $this->db->connectionEndpoint()['port'],
|
||||
'db' => $targetDatabase,
|
||||
];
|
||||
$ticket = $this->writeLoginTicket($auth, $targetDatabase);
|
||||
$ticket = $this->writeLoginTicket($auth, $targetDatabase, $restrictToDatabase);
|
||||
|
||||
return [
|
||||
'target' => $this->buildPhpMyAdminLoginUrl($targetDatabase, $ticket),
|
||||
@@ -90,9 +90,12 @@ final class PhpMyAdminSso
|
||||
* @param string[] $ownedDatabases
|
||||
* @return string[]
|
||||
*/
|
||||
private static function determineGrantTargets(string $targetDatabase, array $ownedDatabases): array
|
||||
private static function determineGrantTargets(?string $requestedDatabase, array $ownedDatabases): array
|
||||
{
|
||||
return in_array($targetDatabase, $ownedDatabases, true) ? [$targetDatabase] : [];
|
||||
if ($requestedDatabase === null || $requestedDatabase === '') {
|
||||
return $ownedDatabases;
|
||||
}
|
||||
return in_array($requestedDatabase, $ownedDatabases, true) ? [$requestedDatabase] : [];
|
||||
}
|
||||
|
||||
private function buildPhpMyAdminLoginUrl(string $database, string $ticket): string
|
||||
@@ -136,7 +139,7 @@ final class PhpMyAdminSso
|
||||
/**
|
||||
* @param array<string,string|int> $auth
|
||||
*/
|
||||
private function writeLoginTicket(array $auth, string $database): string
|
||||
private function writeLoginTicket(array $auth, string $database, string $restrictToDatabase): string
|
||||
{
|
||||
$ticketDir = rtrim($this->settings->adminerSsoDir(), '/') . '/tickets';
|
||||
if (!is_dir($ticketDir) && !@mkdir($ticketDir, 0755, true) && !is_dir($ticketDir)) {
|
||||
@@ -153,6 +156,7 @@ final class PhpMyAdminSso
|
||||
'auth' => $auth,
|
||||
'route' => '/database/structure',
|
||||
'db' => $database,
|
||||
'restrict_db' => $restrictToDatabase,
|
||||
];
|
||||
$encoded = json_encode($payload, JSON_UNESCAPED_SLASHES);
|
||||
if (!is_string($encoded) || $encoded === '') {
|
||||
|
||||
Reference in New Issue
Block a user