Scope phpMyAdmin SSO to one database, fix logout, reset create form

After live testing on the real server, three follow-up issues surfaced:

- PhpMyAdminSso granted the temporary SSO MySQL role access to every
  database the account owns, not just the one the "Zaloguj do bazy"
  button was clicked for, so phpMyAdmin showed all databases. Extract
  determineGrantTargets() and scope the GRANT to only the requested
  database; also set phpMyAdmin's only_db from the SSO session so the
  UI itself only shows that database.

- phpMyAdmin's LogoutURL pointed at da_login.php with no ticket, which
  always produced "Missing or invalid phpMyAdmin login ticket." on
  logout. Add a DIRECTADMIN_PANEL_PORT setting (default 2222) and
  point LogoutURL at the plugin's own database list
  (/CMD_PLUGINS/alt-mysql/index.html) instead.

- The create-database form kept echoing back the just-submitted
  values after a successful creation, forcing manual clearing before
  creating the next database. Clear the relevant $_POST keys once
  creation succeeds so the form resets while still preserving sticky
  values on validation failure.

Bump version to 1.2.14 and rebuild the release archive.
This commit is contained in:
Marek Miklewicz
2026-07-04 20:38:04 +02:00
parent abbeaf67ec
commit 1560759c51
11 changed files with 140 additions and 9 deletions
+29
View File
@@ -38,6 +38,17 @@ function load_settings(string $contents): Settings
return $settings;
}
// --- phpMyAdmin logout must know the DirectAdmin panel port to build a valid return URL ---
$defaultPanelPortSettings = load_settings('');
assert_same('2222', $defaultPanelPortSettings->directAdminPanelPort(), 'DIRECTADMIN_PANEL_PORT should default to 2222');
$customPanelPortSettings = load_settings("DIRECTADMIN_PANEL_PORT=2280\n");
assert_same('2280', $customPanelPortSettings->directAdminPanelPort(), 'DIRECTADMIN_PANEL_PORT should be configurable');
$invalidPanelPortSettings = load_settings("DIRECTADMIN_PANEL_PORT=not-a-port\n");
assert_same('2222', $invalidPanelPortSettings->directAdminPanelPort(), 'a non-numeric DIRECTADMIN_PANEL_PORT should fall back to 2222');
// --- Temporary SSO role must be host-scoped, not wildcard '%' ---
$mysqlServiceSource = (string)file_get_contents($pluginDir . '/exec/lib/MySQLService.php');
@@ -50,6 +61,24 @@ $mysqlServiceClass = new ReflectionClass(MySQLService::class);
assert_true($mysqlServiceClass->hasConstant('TMP_ROLE_HOST'), 'MySQLService must define a TMP_ROLE_HOST constant');
assert_same('127.0.0.1', $mysqlServiceClass->getConstant('TMP_ROLE_HOST'), 'TMP_ROLE_HOST must scope the temporary SSO role to the phpMyAdmin app host');
// --- phpMyAdmin SSO must only grant access to the database being logged into, not every database the account owns ---
$ssoClassForGrants = new ReflectionClass(PhpMyAdminSso::class);
assert_true($ssoClassForGrants->hasMethod('determineGrantTargets'), 'PhpMyAdminSso must expose a determineGrantTargets() decision method');
$determineGrantTargets = $ssoClassForGrants->getMethod('determineGrantTargets');
$determineGrantTargets->setAccessible(true);
assert_same(
['demo_target'],
$determineGrantTargets->invoke(null, 'demo_target', ['demo_target', 'demo_other']),
'issuing a ticket for one database must only grant that database, not every database the user owns'
);
assert_same(
[],
$determineGrantTargets->invoke(null, 'not_owned', ['demo_target', 'demo_other']),
'a target database that is not in the owned list must never be granted'
);
// --- phpMyAdmin login ticket files must not be world-readable ---
$ssoDir = sys_get_temp_dir() . '/altmysql-pma-sso-' . bin2hex(random_bytes(4));