Merge pull request #18375 from MauricioFauth/config-current-server

Add the `Config::getCurrentServer()` method
This commit is contained in:
Maurício Meneghini Fauth 2023-04-30 19:26:10 -03:00 committed by GitHub
commit 5021f361ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 82 additions and 124 deletions

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace PhpMyAdmin;
use PhpMyAdmin\Config\ConfigFile;
use PhpMyAdmin\Config\Settings\Server;
use PhpMyAdmin\ConfigStorage\Relation;
use PhpMyAdmin\Dbal\Connection;
use PhpMyAdmin\Dbal\DatabaseName;
@ -185,7 +186,7 @@ final class Common
return;
}
self::setCurrentServerGlobal($container, $config);
self::setCurrentServerGlobal($container, $config, $request->getParam('server'));
$GLOBALS['cfg'] = $config->settings;
$settings = $config->getSettings();
@ -228,7 +229,8 @@ final class Common
$container->set(DatabaseInterface::class, $GLOBALS['dbi']);
$container->setAlias('dbi', DatabaseInterface::class);
if (! empty($GLOBALS['cfg']['Server'])) {
$currentServer = $config->getCurrentServer();
if ($currentServer !== null) {
$config->getLoginCookieValidityFromCache($GLOBALS['server']);
/** @var AuthenticationPluginFactory $authPluginFactory */
@ -251,12 +253,12 @@ final class Common
// phpcs:enable
}
self::connectToDatabaseServer($GLOBALS['dbi'], $authPlugin);
self::connectToDatabaseServer($GLOBALS['dbi'], $authPlugin, $currentServer);
$authPlugin->rememberCredentials();
$authPlugin->checkTwoFactor();
/* Log success */
Logging::logUser($config, $GLOBALS['cfg']['Server']['user']);
Logging::logUser($config, $currentServer->user);
if ($GLOBALS['dbi']->getVersion() < $settings->mysqlMinVersion['internal']) {
echo self::getGenericError(sprintf(
@ -549,14 +551,17 @@ final class Common
throw new RuntimeException(__('possible exploit'));
}
private static function connectToDatabaseServer(DatabaseInterface $dbi, AuthenticationPlugin $auth): void
{
private static function connectToDatabaseServer(
DatabaseInterface $dbi,
AuthenticationPlugin $auth,
Server $currentServer,
): void {
/**
* Try to connect MySQL with the control user profile (will be used to get the privileges list for the current
* user but the true user link must be open after this one so it would be default one for all the scripts).
* user but the true user link must be open after this one, so it would be default one for all the scripts).
*/
$controlConnection = null;
if ($GLOBALS['cfg']['Server']['controluser'] !== '') {
if ($currentServer->controluser !== '') {
$controlConnection = $dbi->connect(Connection::TYPE_CONTROL);
}
@ -631,9 +636,12 @@ final class Common
$container->setParameter('sql_query', $sqlQuery);
}
private static function setCurrentServerGlobal(ContainerInterface $container, Config $config): void
{
$server = $config->selectServer();
private static function setCurrentServerGlobal(
ContainerInterface $container,
Config $config,
mixed $serverParamFromRequest,
): void {
$server = $config->selectServer($serverParamFromRequest);
$GLOBALS['server'] = $server;
$GLOBALS['urlParams']['server'] = $server;
$container->setParameter('server', $server);

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace PhpMyAdmin;
use PhpMyAdmin\Config\Settings;
use PhpMyAdmin\Config\Settings\Server;
use PhpMyAdmin\Dbal\Connection;
use PhpMyAdmin\Exceptions\ConfigException;
use PhpMyAdmin\Theme\ThemeManager;
@ -86,17 +87,15 @@ class Config
public bool $errorConfigFile = false;
/** @var mixed[] */
public array $defaultServer;
private bool $isHttps = false;
private Settings $config;
public Settings $config;
/** @var int<0, max> */
public int $server = 0;
public function __construct()
{
$this->config = new Settings([]);
$this->defaultServer = $this->config->Servers[1]->asArray();
$config = $this->config->asArray();
$this->default = $config;
$this->settings = $config;
@ -1063,34 +1062,27 @@ class Config
return null;
}
/**
* Selects server based on request parameters.
*/
public function selectServer(): int
/** @return int<0, max> */
public function selectServer(mixed $serverParamFromRequest): int
{
$request = empty($_REQUEST['server']) ? 0 : $_REQUEST['server'];
/**
* Lookup server by name
* (see FAQ 4.8)
*/
if (! is_numeric($request)) {
foreach ($this->settings['Servers'] as $i => $server) {
$verboseToLower = mb_strtolower($server['verbose']);
$serverToLower = mb_strtolower($request);
if (
$server['host'] == $request
|| $server['verbose'] == $request
|| $verboseToLower === $serverToLower
|| md5($verboseToLower) === $serverToLower
) {
$request = $i;
$serverNumber = 0;
if (is_numeric($serverParamFromRequest)) {
$serverNumber = (int) $serverParamFromRequest;
$serverNumber = $serverNumber >= 1 ? $serverNumber : 0;
} elseif (is_string($serverParamFromRequest) && $serverParamFromRequest !== '') {
/** Lookup server by name (see FAQ 4.8) */
foreach ($this->config->Servers as $i => $server) {
if ($server->host === $serverParamFromRequest || $server->verbose === $serverParamFromRequest) {
$serverNumber = $i;
break;
}
}
if (is_string($request)) {
$request = 0;
$verboseToLower = mb_strtolower($server->verbose);
$serverToLower = mb_strtolower($serverParamFromRequest);
if ($verboseToLower === $serverToLower || md5($verboseToLower) === $serverToLower) {
$serverNumber = $i;
break;
}
}
}
@ -1102,21 +1094,19 @@ class Config
* present a choice of servers in the case that there are multiple servers
* and '$this->settings['ServerDefault'] = 0' is set.
*/
if (is_numeric($request) && ! empty($request) && ! empty($this->settings['Servers'][$request])) {
$server = $request;
$this->settings['Server'] = $this->settings['Servers'][$server];
if (isset($this->config->Servers[$serverNumber])) {
$this->settings['Server'] = $this->config->Servers[$serverNumber]->asArray();
} elseif (isset($this->config->Servers[$this->config->ServerDefault])) {
$serverNumber = $this->config->ServerDefault;
$this->settings['Server'] = $this->config->Servers[$this->config->ServerDefault]->asArray();
} else {
if (! empty($this->settings['Servers'][$this->settings['ServerDefault']])) {
$server = $this->settings['ServerDefault'];
$this->settings['Server'] = $this->settings['Servers'][$server];
} else {
$server = 0;
$this->settings['Server'] = [];
}
$serverNumber = 0;
$this->settings['Server'] = [];
}
return (int) $server;
$this->server = $serverNumber;
return $this->server;
}
/**
@ -1252,4 +1242,9 @@ class Config
{
return $this->config;
}
public function getCurrentServer(): Server|null
{
return $this->config->Servers[$this->server] ?? null;
}
}

View File

@ -160,31 +160,6 @@ parameters:
count: 1
path: libraries/classes/Common.php
-
message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#"
count: 1
path: libraries/classes/Config.php
-
message: "#^Cannot access offset 'host' on mixed\\.$#"
count: 1
path: libraries/classes/Config.php
-
message: "#^Cannot access offset 'verbose' on mixed\\.$#"
count: 2
path: libraries/classes/Config.php
-
message: "#^Cannot access offset float\\|int\\<min, \\-1\\>\\|int\\<1, max\\>\\|\\(non\\-falsy\\-string&numeric\\-string\\) on mixed\\.$#"
count: 2
path: libraries/classes/Config.php
-
message: "#^Cannot access offset mixed on mixed\\.$#"
count: 2
path: libraries/classes/Config.php
-
message: "#^Cannot cast mixed to string\\.$#"
count: 2
@ -200,11 +175,6 @@ parameters:
count: 1
path: libraries/classes/Config.php
-
message: "#^Parameter \\#1 \\$string of function mb_strtolower expects string, mixed given\\.$#"
count: 1
path: libraries/classes/Config.php
-
message: "#^Parameter \\#1 \\$string of function rtrim expects string, mixed given\\.$#"
count: 1

View File

@ -212,17 +212,12 @@
<file src="libraries/classes/Common.php">
<InvalidArrayOffset>
<code><![CDATA[$GLOBALS['back']]]></code>
<code><![CDATA[$GLOBALS['cfg']['Server']['controluser']]]></code>
<code><![CDATA[$GLOBALS['theme']]]></code>
</InvalidArrayOffset>
<MixedArgument>
<code><![CDATA[$GLOBALS['cfg']['Server']['user']]]></code>
<code><![CDATA[$_SESSION[' PMA_token ']]]></code>
<code>$sqlDelimiter</code>
</MixedArgument>
<MixedArrayAccess>
<code><![CDATA[$GLOBALS['cfg']['Server']['user']]]></code>
</MixedArrayAccess>
<MixedAssignment>
<code><![CDATA[$GLOBALS['back']]]></code>
<code><![CDATA[$GLOBALS['theme']]]></code>
@ -260,7 +255,6 @@
<code>$defaultValue</code>
<code><![CDATA[$gdInfo['GD Version']]]></code>
<code>$path</code>
<code><![CDATA[$server['verbose']]]></code>
<code><![CDATA[$this->settings['ThemeDefault']]]></code>
<code><![CDATA[$this->settings['ThemeDefault']]]></code>
<code>$url</code>
@ -272,11 +266,6 @@
<code><![CDATA[$_SESSION['cache'][$cacheKey]['userprefs_mtime']]]></code>
<code><![CDATA[$_SESSION['cache'][$cacheKey]['userprefs_type']]]></code>
<code><![CDATA[$configData['lang']]]></code>
<code><![CDATA[$server['host']]]></code>
<code><![CDATA[$server['verbose']]]></code>
<code><![CDATA[$server['verbose']]]></code>
<code><![CDATA[$this->settings['Servers'][$server]]]></code>
<code><![CDATA[$this->settings['Servers'][$server]]]></code>
</MixedArrayAccess>
<MixedArrayAssignment>
<code><![CDATA[$_SESSION['cache'][$cacheKey]]]></code>
@ -289,10 +278,6 @@
<code><![CDATA[$_SESSION['cache'][$cacheKey]['userprefs_type']]]></code>
<code>$tempDir[$name]</code>
</MixedArrayAssignment>
<MixedArrayOffset>
<code><![CDATA[$this->settings['Servers'][$server]]]></code>
<code><![CDATA[$this->settings['Servers'][$this->settings['ServerDefault']]]]></code>
</MixedArrayOffset>
<MixedAssignment>
<code><![CDATA[$GLOBALS['cfg']['LoginCookieValidity']]]></code>
<code>$collationConnection</code>
@ -300,15 +285,11 @@
<code>$defaultValue</code>
<code>$defaultValue</code>
<code>$evalResult</code>
<code>$i</code>
<code>$password</code>
<code>$password</code>
<code>$path</code>
<code>$prefsType</code>
<code>$prefsType</code>
<code>$request</code>
<code>$server</code>
<code>$server</code>
<code>$server[$item]</code>
<code><![CDATA[$server['hide_connection_errors']]]></code>
<code><![CDATA[$server['host']]]></code>
@ -331,14 +312,10 @@
</MixedReturnStatement>
<PossiblyInvalidArgument>
<code>$defaultValue</code>
<code>$request</code>
</PossiblyInvalidArgument>
<PossiblyInvalidArrayOffset>
<code><![CDATA[$_COOKIE[$this->getCookieName($cookieName)]]]></code>
</PossiblyInvalidArrayOffset>
<PossiblyInvalidCast>
<code>$request</code>
</PossiblyInvalidCast>
<RiskyCast>
<code><![CDATA[$server['port']]]></code>
</RiskyCast>

View File

@ -377,7 +377,6 @@ PHP;
$config = $settings->asArray();
$this->assertIsArray($config['Servers']);
$this->assertEquals($settings, $object->getSettings());
$this->assertSame($config['Servers'][1], $object->defaultServer);
$this->assertEquals($config, $object->default);
$this->assertSame($config, $object->settings);
$this->assertSame($config, $object->baseSettings);
@ -720,24 +719,29 @@ PHP;
/**
* Test for selectServer
*
* @param mixed[] $settings settings array
* @param string $request request
* @param int $expected expected result
* @param mixed[] $settings settings array
* @param string|mixed[] $request request
* @param int $expected expected result
*
* @dataProvider selectServerProvider
*/
public function testSelectServer(array $settings, string $request, int $expected): void
public function testSelectServer(array $settings, string|array $request, int $expected): void
{
$object = new Config();
$object->settings = (new Settings(['Servers' => $settings]))->asArray();
$_REQUEST['server'] = $request;
$this->assertEquals($expected, $object->selectServer());
$config = new Config();
$config->config = new Settings(['Servers' => $settings, 'ServerDefault' => 1]);
$selectedServer = $config->selectServer($request);
$this->assertSame($expected, $selectedServer);
$this->assertGreaterThanOrEqual(0, $selectedServer);
$expectedServer = $expected >= 1 ? $config->config->Servers[$expected]->asArray() : [];
$this->assertArrayHasKey('Server', $config->settings);
$this->assertSame($config->settings['Server'], $expectedServer);
$this->assertSame($expected, $config->server);
}
/**
* Data provider for selectServer test
*
* @return array<string, array{mixed[], string, int}>
* @return array<string, array{mixed[], string|mixed[], int}>
*/
public static function selectServerProvider(): array
{
@ -749,6 +753,10 @@ PHP;
'md5' => [[66 => ['verbose' => 'Server 66', 'host' => '']], md5('server 66'), 66],
'nonexisting_string' => [[1 => []], 'invalid', 1],
'nonexisting' => [[1 => []], '100', 1],
'none selected' => [[2 => []], '100', 0],
'none selected with string' => [[2 => []], 'unknown', 0],
'negative number' => [[1 => []], '-1', 1],
'array' => [[1 => []], ['1'], 1],
];
}

View File

@ -49,7 +49,7 @@ class ExportControllerTest extends AbstractTestCase
$GLOBALS['lang'] = 'en';
$GLOBALS['sql_indexes'] = null;
$GLOBALS['sql_auto_increments'] = null;
$GLOBALS['config']->selectServer();
$GLOBALS['config']->selectServer('1');
$GLOBALS['cfg'] = $GLOBALS['config']->settings;
$this->dummyDbi->addResult(

View File

@ -21,7 +21,7 @@ class AddFieldControllerTest extends AbstractTestCase
$GLOBALS['db'] = 'test_db';
$GLOBALS['table'] = 'test_table';
$GLOBALS['regenerate'] = null;
$GLOBALS['cfg']['Server'] = $GLOBALS['config']->defaultServer;
$GLOBALS['cfg']['Server'] = $GLOBALS['config']->getSettings()->Servers[1]->asArray();
$_POST = [
'db' => 'test_db',
'table' => 'test_table',

View File

@ -22,7 +22,7 @@ class CreateControllerTest extends AbstractTestCase
{
$GLOBALS['db'] = 'test_db';
$GLOBALS['table'] = 'new_test_table';
$GLOBALS['cfg']['Server'] = $GLOBALS['config']->defaultServer;
$GLOBALS['cfg']['Server'] = $GLOBALS['config']->getSettings()->Servers[1]->asArray();
$_POST = ['db' => 'test_db', 'table' => 'new_test_table', 'num_fields' => '2'];
$dummyDbi = $this->createDbiDummy();

View File

@ -21,7 +21,7 @@ class DeleteRowsControllerTest extends AbstractTestCase
$GLOBALS['db'] = 'test_db';
$GLOBALS['table'] = 'test_table';
$GLOBALS['urlParams'] = [];
$GLOBALS['cfg']['Server'] = $GLOBALS['config']->defaultServer;
$GLOBALS['cfg']['Server'] = $GLOBALS['config']->getSettings()->Servers[1]->asArray();
$GLOBALS['cfg']['Server']['DisableIS'] = true;
$_POST = [
'db' => 'test_db',

View File

@ -33,7 +33,7 @@ class ExportControllerTest extends AbstractTestCase
$GLOBALS['db'] = 'test_db';
$GLOBALS['table'] = 'test_table';
$GLOBALS['cfg']['Server'] = $GLOBALS['config']->defaultServer;
$GLOBALS['cfg']['Server'] = $GLOBALS['config']->getSettings()->Servers[1]->asArray();
$GLOBALS['cfg']['Server']['DisableIS'] = true;
$GLOBALS['single_table'] = '1';

View File

@ -25,7 +25,7 @@ class ImportControllerTest extends AbstractTestCase
$GLOBALS['table'] = 'test_table';
$GLOBALS['text_dir'] = 'ltr';
$GLOBALS['lang'] = 'en';
$GLOBALS['cfg']['Server'] = $GLOBALS['config']->defaultServer;
$GLOBALS['cfg']['Server'] = $GLOBALS['config']->getSettings()->Servers[1]->asArray();
$_GET['format'] = 'xml';
$dummyDbi = $this->createDbiDummy();

View File

@ -38,7 +38,7 @@ class OperationsControllerTest extends AbstractTestCase
$GLOBALS['db'] = 'test_db';
$GLOBALS['table'] = 'test_table';
$GLOBALS['config']->selectServer();
$GLOBALS['config']->selectServer('1');
$GLOBALS['cfg'] = $GLOBALS['config']->settings;
$GLOBALS['cfg']['MaxDbList'] = 0;

View File

@ -41,7 +41,7 @@ class SqlControllerTest extends AbstractTestCase
$GLOBALS['table'] = 'test_table';
$GLOBALS['lang'] = 'en';
$GLOBALS['text_dir'] = 'ltr';
$GLOBALS['cfg']['Server'] = $GLOBALS['config']->defaultServer;
$GLOBALS['cfg']['Server'] = $GLOBALS['config']->getSettings()->Servers[1]->asArray();
$this->dummyDbi->addSelectDb('test_db');
$this->dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]);

View File

@ -41,7 +41,7 @@ class StructureControllerTest extends AbstractTestCase
$GLOBALS['table'] = 'test_table';
$GLOBALS['text_dir'] = 'ltr';
$GLOBALS['lang'] = 'en';
$GLOBALS['cfg']['Server'] = $GLOBALS['config']->defaultServer;
$GLOBALS['cfg']['Server'] = $GLOBALS['config']->getSettings()->Servers[1]->asArray();
$GLOBALS['cfg']['Server']['DisableIS'] = true;
$GLOBALS['cfg']['ShowStats'] = false;
$GLOBALS['cfg']['ShowPropertyComments'] = false;