diff options
author | William Desportes <williamdes@wdes.fr> | 2021-08-31 01:14:03 +0300 |
---|---|---|
committer | William Desportes <williamdes@wdes.fr> | 2021-08-31 01:18:17 +0300 |
commit | 2d307ed06285528375be24eb1b6dc43006a5259d (patch) | |
tree | d480703d9cdd8bc3d36dc51a9b5e32140eb53102 | |
parent | bd2ef2b8eeac35ed8654cc0f8320123bf4dec7dd (diff) | |
parent | f7a328842d8d3d473e5b904c4b6b316ba3bf8cef (diff) |
Merge branch 'QA_5_1'
Signed-off-by: William Desportes <williamdes@wdes.fr>
-rw-r--r-- | libraries/classes/Controllers/CheckRelationsController.php | 4 | ||||
-rw-r--r-- | libraries/classes/Relation.php | 73 | ||||
-rw-r--r-- | test/classes/DatabaseInterfaceTest.php | 33 | ||||
-rw-r--r-- | test/classes/RelationTest.php | 737 | ||||
-rw-r--r-- | test/classes/TwoFactorTest.php | 2 |
5 files changed, 825 insertions, 24 deletions
diff --git a/libraries/classes/Controllers/CheckRelationsController.php b/libraries/classes/Controllers/CheckRelationsController.php index 9f93ec13ca..5e075e9539 100644 --- a/libraries/classes/Controllers/CheckRelationsController.php +++ b/libraries/classes/Controllers/CheckRelationsController.php @@ -49,12 +49,14 @@ class CheckRelationsController extends AbstractController $this->relation->fixPmaTables($db); } - $cfgRelation = $this->relation->getRelationsParam(); // If request for creating missing PMA tables. if (isset($fixPmaDb)) { + $cfgRelation = $this->relation->getRelationsParam(); $this->relation->fixPmaTables($cfgRelation['db']); } + // Do not use any previous $cfgRelation value as it could have changed after a successfull fixPmaTables() + $cfgRelation = $this->relation->getRelationsParam(); $this->response->addHTML($this->relation->getRelationsParamDiagnostic($cfgRelation)); } } diff --git a/libraries/classes/Relation.php b/libraries/classes/Relation.php index c08ee235e4..898c1c43c7 100644 --- a/libraries/classes/Relation.php +++ b/libraries/classes/Relation.php @@ -745,7 +745,7 @@ class Relation public function canAccessStorageTable(string $tableDbName): bool { $result = $this->queryAsControlUser( - 'SELECT NULL FROM ' . $tableDbName . ' LIMIT 0', + 'SELECT NULL FROM ' . Util::backquote($tableDbName) . ' LIMIT 0', false, DatabaseInterface::QUERY_STORE ); @@ -1792,7 +1792,7 @@ class Relation 'table_name' ); } else { - // if the table is moved out of the database we can no loger keep the + // if the table is moved out of the database we can no longer keep the // record for table coordinate $remove_query = 'DELETE FROM ' . Util::backquote($GLOBALS['cfgRelation']['db']) . '.' @@ -2023,9 +2023,9 @@ class Relation /** * Returns default PMA table names and their create queries. * - * @return array table name, create query + * @return array<string,string> table name, create query */ - public function getDefaultPmaTableNames() + public function getDefaultPmaTableNames(array $tableNameReplacements): array { $pma_tables = []; $create_tables_file = (string) file_get_contents( @@ -2045,7 +2045,14 @@ class Relation continue; } - $pma_tables[$table[1]] = $query . ';'; + $tableName = (string) $table[1]; + + // Replace the table name with another one + if (isset($tableNameReplacements[$tableName])) { + $query = str_replace($tableName, $tableNameReplacements[$tableName], $query); + } + + $pma_tables[$tableName] = $query . ';'; } return $pma_tables; @@ -2057,11 +2064,17 @@ class Relation public function createPmaDatabase(string $configurationStorageDbName): bool { $this->dbi->tryQuery( - 'CREATE DATABASE IF NOT EXISTS ' . Util::backquote($configurationStorageDbName) + 'CREATE DATABASE IF NOT EXISTS ' . Util::backquote($configurationStorageDbName), + DatabaseInterface::CONNECT_CONTROL ); - $error = $this->dbi->getError(); + $error = $this->dbi->getError(DatabaseInterface::CONNECT_CONTROL); if (! $error) { + // Re-build the cache to show the list of tables created or not + // This is the case when the DB could be created but no tables just after + // So just purge the cache and show the new configuration storage state + $_SESSION['relation'][$GLOBALS['server']] = $this->checkRelationsParam(); + return true; } @@ -2115,19 +2128,45 @@ class Relation $existingTables = $this->dbi->getTables($db, DatabaseInterface::CONNECT_CONTROL); + /** @var array<string,string> $tableNameReplacements */ + $tableNameReplacements = []; + + // Build a map of replacements between default table names and name built by the user + foreach ($tablesToFeatures as $table => $feature) { + // Empty, we can not do anything about it + if (empty($GLOBALS['cfg']['Server'][$feature])) { + continue; + } + + // Default table name, nothing to do + if ($GLOBALS['cfg']['Server'][$feature] === $table) { + continue; + } + + // Set the replacement to transform the default table name into a custom name + $tableNameReplacements[$table] = $GLOBALS['cfg']['Server'][$feature]; + } + $createQueries = null; $foundOne = false; foreach ($tablesToFeatures as $table => $feature) { - if (! in_array($table, $existingTables)) { + // Check if the table already exists + // use the possible replaced name first and fallback on the table name + // if no replacement exists + if (! in_array($tableNameReplacements[$table] ?? $table, $existingTables)) { if ($create) { if ($createQueries == null) { // first create - $createQueries = $this->getDefaultPmaTableNames(); - $this->dbi->selectDb($db); + $createQueries = $this->getDefaultPmaTableNames($tableNameReplacements); + if (! $this->dbi->selectDb($db, DatabaseInterface::CONNECT_CONTROL)) { + $GLOBALS['message'] = $this->dbi->getError(DatabaseInterface::CONNECT_CONTROL); + + return; + } } - $this->dbi->tryQuery($createQueries[$table]); + $this->dbi->tryQuery($createQueries[$table], DatabaseInterface::CONNECT_CONTROL); - $error = $this->dbi->getError(); + $error = $this->dbi->getError(DatabaseInterface::CONNECT_CONTROL); if ($error) { $GLOBALS['message'] = $error; @@ -2135,11 +2174,17 @@ class Relation } $foundOne = true; - $GLOBALS['cfg']['Server'][$feature] = $table; + if (empty($GLOBALS['cfg']['Server'][$feature])) { + // Do not override a user defined value, only fill if empty + $GLOBALS['cfg']['Server'][$feature] = $table; + } } } else { $foundOne = true; - $GLOBALS['cfg']['Server'][$feature] = $table; + if (empty($GLOBALS['cfg']['Server'][$feature])) { + // Do not override a user defined value, only fill if empty + $GLOBALS['cfg']['Server'][$feature] = $table; + } } } diff --git a/test/classes/DatabaseInterfaceTest.php b/test/classes/DatabaseInterfaceTest.php index 78712ff76e..f08704d76d 100644 --- a/test/classes/DatabaseInterfaceTest.php +++ b/test/classes/DatabaseInterfaceTest.php @@ -601,7 +601,7 @@ class DatabaseInterfaceTest extends AbstractTestCase ); $this->dummyDbi->addResult( - 'SELECT NULL FROM pma__userconfig LIMIT 0', + 'SELECT NULL FROM `pma__userconfig` LIMIT 0', [ ['NULL'], ], @@ -714,7 +714,7 @@ class DatabaseInterfaceTest extends AbstractTestCase ); $this->dummyDbi->addResult( - 'SELECT NULL FROM pma__userconfig LIMIT 0', + 'SELECT NULL FROM `pma__userconfig` LIMIT 0', false ); @@ -829,7 +829,7 @@ class DatabaseInterfaceTest extends AbstractTestCase ); $this->dummyDbi->addResult( - 'SELECT NULL FROM pma__userconfig_custom LIMIT 0', + 'SELECT NULL FROM `pma__userconfig_custom` LIMIT 0', [ ['NULL'], ], @@ -838,11 +838,32 @@ class DatabaseInterfaceTest extends AbstractTestCase $this->dbi->initRelationParamsCache(); - $this->assertArrayNotHasKey( + $this->assertArrayHasKey( 'relation', $_SESSION, - 'The cache is NOT expected to be filled because no default phpMyAdmin storage tables' - . ' with a default name where found (pma__userconfig vs pma__userconfig_custom)' + 'The cache is expected to be filled because the custom override' + . 'was undertood (pma__userconfig vs pma__userconfig_custom)' + ); + + $this->assertAllQueriesConsumed(); + + $this->dummyDbi->addResult( + 'SHOW TABLES FROM `PMA-storage`', + [ + [ + 'pma__userconfig_custom', + 'pma__usergroups', + ], + ], + ['Tables_in_PMA-storage'] + ); + + $this->dummyDbi->addResult( + 'SELECT NULL FROM `pma__userconfig_custom` LIMIT 0', + [ + ['NULL'], + ], + ['NULL'] ); $this->dummyDbi->addSelectDb('PMA-storage'); diff --git a/test/classes/RelationTest.php b/test/classes/RelationTest.php index bcb1975226..e56ca5d6ff 100644 --- a/test/classes/RelationTest.php +++ b/test/classes/RelationTest.php @@ -8,6 +8,7 @@ use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Relation; use function __; +use function implode; /** * @covers \PhpMyAdmin\Relation @@ -391,7 +392,7 @@ class RelationTest extends AbstractTestCase ); $this->dummyDbi->addResult( - 'SELECT NULL FROM pma__userconfig LIMIT 0', + 'SELECT NULL FROM `pma__userconfig` LIMIT 0', [['NULL']] ); $this->dummyDbi->addSelectDb('db_pma'); @@ -482,7 +483,7 @@ class RelationTest extends AbstractTestCase ); $this->dummyDbi->addResult( - 'SELECT NULL FROM pma__userconfig LIMIT 0', + 'SELECT NULL FROM `pma__userconfig` LIMIT 0', [['NULL']] ); $this->dummyDbi->addSelectDb('db_pma'); @@ -732,6 +733,308 @@ class RelationTest extends AbstractTestCase $this->assertAllSelectsConsumed(); } + public function testFixPmaTablesNormalFixTablesWithCustomOverride(): void + { + parent::setGlobalDbi(); + parent::loadDefaultConfig(); + + $GLOBALS['db'] = ''; + $GLOBALS['server'] = 1; + $GLOBALS['cfg']['Server']['user'] = ''; + $GLOBALS['cfg']['Server']['pmadb'] = 'db_pma'; + $GLOBALS['cfg']['Server']['bookmarktable'] = ''; + $GLOBALS['cfg']['Server']['relation'] = 'custom_relation_pma'; + $GLOBALS['cfg']['Server']['table_info'] = ''; + $GLOBALS['cfg']['Server']['table_coords'] = ''; + $GLOBALS['cfg']['Server']['column_info'] = ''; + $GLOBALS['cfg']['Server']['pdf_pages'] = ''; + $GLOBALS['cfg']['Server']['history'] = ''; + $GLOBALS['cfg']['Server']['recent'] = ''; + $GLOBALS['cfg']['Server']['favorite'] = ''; + $GLOBALS['cfg']['Server']['table_uiprefs'] = ''; + $GLOBALS['cfg']['Server']['tracking'] = ''; + $GLOBALS['cfg']['Server']['userconfig'] = ''; + $GLOBALS['cfg']['Server']['users'] = ''; + $GLOBALS['cfg']['Server']['usergroups'] = ''; + $GLOBALS['cfg']['Server']['navigationhiding'] = ''; + $GLOBALS['cfg']['Server']['savedsearches'] = ''; + $GLOBALS['cfg']['Server']['central_columns'] = ''; + $GLOBALS['cfg']['Server']['designer_settings'] = ''; + $GLOBALS['cfg']['Server']['export_templates'] = ''; + + $this->relation = new Relation($this->dbi); + + $this->dummyDbi->removeDefaultResults(); + $this->dummyDbi->addResult( + 'SHOW TABLES FROM `db_pma`;', + [ + ['pma__userconfig'], + // This is important as it tricks default existing table detection + // If the check does not consider the custom name it will skip the table + ['pma__relation'], + ], + ['Tables_in_db_pma'] + ); + + $this->dummyDbi->addResult( + 'SHOW TABLES FROM `db_pma`', + [ + ['pma__userconfig'], + // This is important as it tricks default existing table detection + // If the check does not consider the custom name it will skip the table + ['pma__relation'], + ], + ['Tables_in_db_pma'] + ); + + $this->dummyDbi->addResult( + 'SELECT NULL FROM `pma__userconfig` LIMIT 0', + [['NULL']] + ); + + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `pma__bookmark` ' + . '-- CREATE TABLE IF NOT EXISTS `pma__bookmark` ( ' + . '`id` int(10) unsigned NOT NULL auto_increment,' + . ' `dbase` varchar(255) NOT NULL default \'\',' + . ' `user` varchar(255) NOT NULL default \'\',' + . ' `label` varchar(255) COLLATE utf8_general_ci NOT NULL default \'\',' + . ' `query` text NOT NULL, PRIMARY KEY (`id`) )' + . ' COMMENT=\'Bookmarks\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `custom_relation_pma` ' + . '-- CREATE TABLE IF NOT EXISTS `custom_relation_pma` ( ' + . '`master_db` varchar(64) NOT NULL default \'\', `master_table` varchar(64) NOT NULL default \'\',' + . ' `master_field` varchar(64) NOT NULL default \'\', `foreign_db` varchar(64) NOT NULL default \'\',' + . ' `foreign_table` varchar(64) NOT NULL default \'\',' + . ' `foreign_field` varchar(64) NOT NULL default \'\',' + . ' PRIMARY KEY (`master_db`,`master_table`,`master_field`),' + . ' KEY `foreign_field` (`foreign_db`,`foreign_table`) ) COMMENT=\'Relation table\'' + . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `pma__table_info`' + . ' -- CREATE TABLE IF NOT EXISTS `pma__table_info` ( ' + . '`db_name` varchar(64) NOT NULL default \'\', `table_name` varchar(64) NOT NULL default \'\',' + . ' `display_field` varchar(64) NOT NULL default \'\', PRIMARY KEY (`db_name`,`table_name`) )' + . ' COMMENT=\'Table information for phpMyAdmin\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `pma__table_coords`' + . ' -- CREATE TABLE IF NOT EXISTS `pma__table_coords` ( ' + . '`db_name` varchar(64) NOT NULL default \'\', `table_name` varchar(64) NOT NULL default \'\',' + . ' `pdf_page_number` int(11) NOT NULL default \'0\', `x` float unsigned NOT NULL default \'0\',' + . ' `y` float unsigned NOT NULL default \'0\',' + . ' PRIMARY KEY (`db_name`,`table_name`,`pdf_page_number`) )' + . ' COMMENT=\'Table coordinates for phpMyAdmin PDF output\'' + . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `pma__pdf_pages`' + . ' -- CREATE TABLE IF NOT EXISTS `pma__pdf_pages` ( ' + . '`db_name` varchar(64) NOT NULL default \'\', `page_nr` int(10) unsigned NOT NULL auto_increment,' + . ' `page_descr` varchar(50) COLLATE utf8_general_ci NOT NULL default \'\', PRIMARY KEY (`page_nr`),' + . ' KEY `db_name` (`db_name`) ) COMMENT=\'PDF relation pages for phpMyAdmin\'' + . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `pma__column_info`' + . ' -- CREATE TABLE IF NOT EXISTS `pma__column_info` ( ' + . '`id` int(5) unsigned NOT NULL auto_increment, `db_name` varchar(64) NOT NULL default \'\',' + . ' `table_name` varchar(64) NOT NULL default \'\', `column_name` varchar(64) NOT NULL default \'\',' + . ' `comment` varchar(255) COLLATE utf8_general_ci NOT NULL default \'\',' + . ' `mimetype` varchar(255) COLLATE utf8_general_ci NOT NULL default \'\',' + . ' `transformation` varchar(255) NOT NULL default \'\',' + . ' `transformation_options` varchar(255) NOT NULL default \'\',' + . ' `input_transformation` varchar(255) NOT NULL default \'\',' + . ' `input_transformation_options` varchar(255) NOT NULL default \'\',' + . ' PRIMARY KEY (`id`), UNIQUE KEY `db_name` (`db_name`,`table_name`,`column_name`) )' + . ' COMMENT=\'Column information for phpMyAdmin\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `pma__history` ' + . '-- CREATE TABLE IF NOT EXISTS `pma__history` ( ' + . '`id` bigint(20) unsigned NOT NULL auto_increment, `username` varchar(64) NOT NULL default \'\',' + . ' `db` varchar(64) NOT NULL default \'\', `table` varchar(64) NOT NULL default \'\',' + . ' `timevalue` timestamp NOT NULL default CURRENT_TIMESTAMP, `sqlquery` text NOT NULL,' + . ' PRIMARY KEY (`id`), KEY `username` (`username`,`db`,`table`,`timevalue`) )' + . ' COMMENT=\'SQL history for phpMyAdmin\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `pma__recent` ' + . '-- CREATE TABLE IF NOT EXISTS `pma__recent` ( ' + . '`username` varchar(64) NOT NULL, `tables` text NOT NULL, PRIMARY KEY (`username`) )' + . ' COMMENT=\'Recently accessed tables\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `pma__favorite` ' + . '-- CREATE TABLE IF NOT EXISTS `pma__favorite` ( ' + . '`username` varchar(64) NOT NULL, `tables` text NOT NULL, PRIMARY KEY (`username`) )' + . ' COMMENT=\'Favorite tables\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `pma__table_uiprefs`' + . ' -- CREATE TABLE IF NOT EXISTS `pma__table_uiprefs` ( ' + . '`username` varchar(64) NOT NULL, `db_name` varchar(64) NOT NULL,' + . ' `table_name` varchar(64) NOT NULL, `prefs` text NOT NULL,' + . ' `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,' + . ' PRIMARY KEY (`username`,`db_name`,`table_name`) ) COMMENT=\'Tables\'\' UI preferences\'' + . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `pma__tracking` ' + . '-- CREATE TABLE IF NOT EXISTS `pma__tracking` ( ' + . '`db_name` varchar(64) NOT NULL, `table_name` varchar(64) NOT NULL,' + . ' `version` int(10) unsigned NOT NULL, `date_created` datetime NOT NULL,' + . ' `date_updated` datetime NOT NULL, `schema_snapshot` text NOT NULL,' + . ' `schema_sql` text, `data_sql` longtext, `tracking`' + . ' set(\'UPDATE\',\'REPLACE\',\'INSERT\',\'DELETE\',' + . '\'TRUNCATE\',\'CREATE DATABASE\',\'ALTER DATABASE\',' + . '\'DROP DATABASE\',\'CREATE TABLE\',\'ALTER TABLE\',' + . '\'RENAME TABLE\',\'DROP TABLE\',\'CREATE INDEX\',' + . '\'DROP INDEX\',\'CREATE VIEW\',\'ALTER VIEW\',\'DROP VIEW\')' + . ' default NULL, `tracking_active` int(1) unsigned NOT NULL' + . ' default \'1\', PRIMARY KEY (`db_name`,`table_name`,`version`) )' + . ' COMMENT=\'Database changes tracking for phpMyAdmin\'' + . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `pma__users` ' + . '-- CREATE TABLE IF NOT EXISTS `pma__users` ( ' + . '`username` varchar(64) NOT NULL, `usergroup` varchar(64) NOT NULL,' + . ' PRIMARY KEY (`username`,`usergroup`) )' + . ' COMMENT=\'Users and their assignments to user groups\'' + . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `pma__usergroups`' + . ' -- CREATE TABLE IF NOT EXISTS `pma__usergroups` ( ' + . '`usergroup` varchar(64) NOT NULL, `tab` varchar(64) NOT NULL,' + . ' `allowed` enum(\'Y\',\'N\') NOT NULL DEFAULT \'N\',' + . ' PRIMARY KEY (`usergroup`,`tab`,`allowed`) )' + . ' COMMENT=\'User groups with configured menu items\'' + . ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `pma__navigationhiding`' + . ' -- CREATE TABLE IF NOT EXISTS `pma__navigationhiding` ( ' + . '`username` varchar(64) NOT NULL, `item_name` varchar(64)' + . ' NOT NULL, `item_type` varchar(64) NOT NULL, `db_name` varchar(64) NOT NULL,' + . ' `table_name` varchar(64) NOT NULL,' + . ' PRIMARY KEY (`username`,`item_name`,`item_type`,`db_name`,`table_name`) )' + . ' COMMENT=\'Hidden items of navigation tree\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `pma__savedsearches`' + . ' -- CREATE TABLE IF NOT EXISTS `pma__savedsearches` ( ' + . '`id` int(5) unsigned NOT NULL auto_increment, `username` varchar(64) NOT NULL default \'\',' + . ' `db_name` varchar(64) NOT NULL default \'\', `search_name` varchar(64) NOT NULL default \'\',' + . ' `search_data` text NOT NULL, PRIMARY KEY (`id`),' + . ' UNIQUE KEY `u_savedsearches_username_dbname` (`username`,`db_name`,`search_name`) )' + . ' COMMENT=\'Saved searches\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `pma__central_columns`' + . ' -- CREATE TABLE IF NOT EXISTS `pma__central_columns` ( ' + . '`db_name` varchar(64) NOT NULL, `col_name` varchar(64) NOT NULL, `col_type` varchar(64) NOT NULL,' + . ' `col_length` text, `col_collation` varchar(64) NOT NULL, `col_isNull` boolean NOT NULL,' + . ' `col_extra` varchar(255) default \'\', `col_default` text,' + . ' PRIMARY KEY (`db_name`,`col_name`) )' + . ' COMMENT=\'Central list of columns\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `pma__designer_settings`' + . ' -- CREATE TABLE IF NOT EXISTS `pma__designer_settings` ( ' + . '`username` varchar(64) NOT NULL, `settings_data` text NOT NULL,' + . ' PRIMARY KEY (`username`) )' + . ' COMMENT=\'Settings related to Designer\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + $this->dummyDbi->addResult( + '-- -------------------------------------------------------- -- --' + . ' Table structure for table `pma__export_templates`' + . ' -- CREATE TABLE IF NOT EXISTS `pma__export_templates` ( ' + . '`id` int(5) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(64) NOT NULL,' + . ' `export_type` varchar(10) NOT NULL, `template_name` varchar(64) NOT NULL,' + . ' `template_data` text NOT NULL, PRIMARY KEY (`id`),' + . ' UNIQUE KEY `u_user_type_template` (`username`,`export_type`,`template_name`) )' + . ' COMMENT=\'Saved export templates\' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + [] + ); + + $this->assertSame('db_pma', $GLOBALS['cfg']['Server']['pmadb']); + $this->assertArrayHasKey('relation', $_SESSION, 'The cache is expected to be filled'); + $this->assertSame([], $_SESSION['relation']); + + $this->relation->fixPmaTables('db_pma', true); + $this->assertArrayNotHasKey('message', $GLOBALS); + $this->assertArrayHasKey('relation', $_SESSION, 'The cache is expected to be filled'); + $this->assertSame('db_pma', $GLOBALS['cfg']['Server']['pmadb']); + + $this->assertSame([ + 'PMA_VERSION' => $_SESSION['relation'][$GLOBALS['server']]['PMA_VERSION'], + 'relwork' => false, + 'displaywork' => false, + 'bookmarkwork' => false, + 'pdfwork' => false, + 'commwork' => false, + 'mimework' => false, + 'historywork' => false, + 'recentwork' => false, + 'favoritework' => false, + 'uiprefswork' => false, + 'trackingwork' => false, + 'userconfigwork' => true,// The only one than has a table and passes check + 'menuswork' => false, + 'navwork' => false, + 'savedsearcheswork' => false, + 'centralcolumnswork' => false, + 'designersettingswork' => false, + 'exporttemplateswork' => false, + 'allworks' => false, + 'user' => '', + 'db' => 'db_pma', + 'userconfig' => 'pma__userconfig', + ], $_SESSION['relation'][$GLOBALS['server']]); + + $this->assertAllQueriesConsumed(); + } + public function testFixPmaTablesNormalFixTablesFails(): void { parent::setGlobalDbi(); @@ -819,6 +1122,11 @@ class RelationTest extends AbstractTestCase [] ); + $this->dummyDbi->addResult( + 'SHOW TABLES FROM `phpmyadmin`', + [] + ); + $this->assertArrayNotHasKey('errno', $GLOBALS); $this->assertTrue( @@ -890,4 +1198,429 @@ class RelationTest extends AbstractTestCase $this->assertAllQueriesConsumed(); $this->assertAllErrorCodesConsumed(); } + + public function testGetDefaultPmaTableNames(): void + { + $this->relation = new Relation(null); + + $data = [ + 'pma__bookmark' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__bookmark`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__bookmark` (', + ' `id` int(10) unsigned NOT NULL auto_increment,', + ' `dbase` varchar(255) NOT NULL default \'\',', + ' `user` varchar(255) NOT NULL default \'\',', + ' `label` varchar(255) COLLATE utf8_general_ci NOT NULL default \'\',', + ' `query` text NOT NULL,', + ' PRIMARY KEY (`id`)', + ')', + ' COMMENT=\'Bookmarks\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__column_info' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__column_info`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__column_info` (', + ' `id` int(5) unsigned NOT NULL auto_increment,', + ' `db_name` varchar(64) NOT NULL default \'\',', + ' `table_name` varchar(64) NOT NULL default \'\',', + ' `column_name` varchar(64) NOT NULL default \'\',', + ' `comment` varchar(255) COLLATE utf8_general_ci NOT NULL default \'\',', + ' `mimetype` varchar(255) COLLATE utf8_general_ci NOT NULL default \'\',', + ' `transformation` varchar(255) NOT NULL default \'\',', + ' `transformation_options` varchar(255) NOT NULL default \'\',', + ' `input_transformation` varchar(255) NOT NULL default \'\',', + ' `input_transformation_options` varchar(255) NOT NULL default \'\',', + ' PRIMARY KEY (`id`),', + ' UNIQUE KEY `db_name` (`db_name`,`table_name`,`column_name`)', + ')', + ' COMMENT=\'Column information for phpMyAdmin\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__history' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__history`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__history` (', + ' `id` bigint(20) unsigned NOT NULL auto_increment,', + ' `username` varchar(64) NOT NULL default \'\',', + ' `db` varchar(64) NOT NULL default \'\',', + ' `table` varchar(64) NOT NULL default \'\',', + ' `timevalue` timestamp NOT NULL default CURRENT_TIMESTAMP,', + ' `sqlquery` text NOT NULL,', + ' PRIMARY KEY (`id`),', + ' KEY `username` (`username`,`db`,`table`,`timevalue`)', + ')', + ' COMMENT=\'SQL history for phpMyAdmin\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__pdf_pages' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__pdf_pages`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__pdf_pages` (', + ' `db_name` varchar(64) NOT NULL default \'\',', + ' `page_nr` int(10) unsigned NOT NULL auto_increment,', + ' `page_descr` varchar(50) COLLATE utf8_general_ci NOT NULL default \'\',', + ' PRIMARY KEY (`page_nr`),', + ' KEY `db_name` (`db_name`)', + ')', + ' COMMENT=\'PDF relation pages for phpMyAdmin\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__recent' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__recent`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__recent` (', + ' `username` varchar(64) NOT NULL,', + ' `tables` text NOT NULL,', + ' PRIMARY KEY (`username`)', + ')', + ' COMMENT=\'Recently accessed tables\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__favorite' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__favorite`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__favorite` (', + ' `username` varchar(64) NOT NULL,', + ' `tables` text NOT NULL,', + ' PRIMARY KEY (`username`)', + ')', + ' COMMENT=\'Favorite tables\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__table_uiprefs' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__table_uiprefs`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__table_uiprefs` (', + ' `username` varchar(64) NOT NULL,', + ' `db_name` varchar(64) NOT NULL,', + ' `table_name` varchar(64) NOT NULL,', + ' `prefs` text NOT NULL,', + ' `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,', + ' PRIMARY KEY (`username`,`db_name`,`table_name`)', + ')', + ' COMMENT=\'Tables\'\' UI preferences\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__relation' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__relation`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__relation` (', + ' `master_db` varchar(64) NOT NULL default \'\',', + ' `master_table` varchar(64) NOT NULL default \'\',', + ' `master_field` varchar(64) NOT NULL default \'\',', + ' `foreign_db` varchar(64) NOT NULL default \'\',', + ' `foreign_table` varchar(64) NOT NULL default \'\',', + ' `foreign_field` varchar(64) NOT NULL default \'\',', + ' PRIMARY KEY (`master_db`,`master_table`,`master_field`),', + ' KEY `foreign_field` (`foreign_db`,`foreign_table`)', + ')', + ' COMMENT=\'Relation table\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__table_coords' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__table_coords`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__table_coords` (', + ' `db_name` varchar(64) NOT NULL default \'\',', + ' `table_name` varchar(64) NOT NULL default \'\',', + ' `pdf_page_number` int(11) NOT NULL default \'0\',', + ' `x` float unsigned NOT NULL default \'0\',', + ' `y` float unsigned NOT NULL default \'0\',', + ' PRIMARY KEY (`db_name`,`table_name`,`pdf_page_number`)', + ')', + ' COMMENT=\'Table coordinates for phpMyAdmin PDF output\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__table_info' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__table_info`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__table_info` (', + ' `db_name` varchar(64) NOT NULL default \'\',', + ' `table_name` varchar(64) NOT NULL default \'\',', + ' `display_field` varchar(64) NOT NULL default \'\',', + ' PRIMARY KEY (`db_name`,`table_name`)', + ')', + ' COMMENT=\'Table information for phpMyAdmin\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__tracking' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__tracking`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__tracking` (', + ' `db_name` varchar(64) NOT NULL,', + ' `table_name` varchar(64) NOT NULL,', + ' `version` int(10) unsigned NOT NULL,', + ' `date_created` datetime NOT NULL,', + ' `date_updated` datetime NOT NULL,', + ' `schema_snapshot` text NOT NULL,', + ' `schema_sql` text,', + ' `data_sql` longtext,', + ' `tracking` set(\'UPDATE\',\'REPLACE\',\'INSERT\',\'DELETE\',' + . '\'TRUNCATE\',\'CREATE DATABASE\',\'ALTER DATABASE\',\'DROP DATABASE\',' + . '\'CREATE TABLE\',\'ALTER TABLE\',\'RENAME TABLE\',\'DROP TABLE\',' + . '\'CREATE INDEX\',\'DROP INDEX\',\'CREATE VIEW\',\'ALTER VIEW\',' + . '\'DROP VIEW\') default NULL,', + ' `tracking_active` int(1) unsigned NOT NULL default \'1\',', + ' PRIMARY KEY (`db_name`,`table_name`,`version`)', + ')', + ' COMMENT=\'Database changes tracking for phpMyAdmin\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__userconfig' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__userconfig`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__userconfig` (', + ' `username` varchar(64) NOT NULL,', + ' `timevalue` timestamp NOT NULL default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,', + ' `config_data` text NOT NULL,', + ' PRIMARY KEY (`username`)', + ')', + ' COMMENT=\'User preferences storage for phpMyAdmin\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__users' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__users`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__users` (', + ' `username` varchar(64) NOT NULL,', + ' `usergroup` varchar(64) NOT NULL,', + ' PRIMARY KEY (`username`,`usergroup`)', + ')', + ' COMMENT=\'Users and their assignments to user groups\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__usergroups' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__usergroups`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__usergroups` (', + ' `usergroup` varchar(64) NOT NULL,', + ' `tab` varchar(64) NOT NULL,', + ' `allowed` enum(\'Y\',\'N\') NOT NULL DEFAULT \'N\',', + ' PRIMARY KEY (`usergroup`,`tab`,`allowed`)', + ')', + ' COMMENT=\'User groups with configured menu items\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__navigationhiding' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__navigationhiding`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__navigationhiding` (', + ' `username` varchar(64) NOT NULL,', + ' `item_name` varchar(64) NOT NULL,', + ' `item_type` varchar(64) NOT NULL,', + ' `db_name` varchar(64) NOT NULL,', + ' `table_name` varchar(64) NOT NULL,', + ' PRIMARY KEY (`username`,`item_name`,`item_type`,`db_name`,`table_name`)', + ')', + ' COMMENT=\'Hidden items of navigation tree\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__savedsearches' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__savedsearches`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__savedsearches` (', + ' `id` int(5) unsigned NOT NULL auto_increment,', + ' `username` varchar(64) NOT NULL default \'\',', + ' `db_name` varchar(64) NOT NULL default \'\',', + ' `search_name` varchar(64) NOT NULL default \'\',', + ' `search_data` text NOT NULL,', + ' PRIMARY KEY (`id`),', + ' UNIQUE KEY `u_savedsearches_username_dbname` (`username`,`db_name`,`search_name`)', + ')', + ' COMMENT=\'Saved searches\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__central_columns' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__central_columns`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__central_columns` (', + ' `db_name` varchar(64) NOT NULL,', + ' `col_name` varchar(64) NOT NULL,', + ' `col_type` varchar(64) NOT NULL,', + ' `col_length` text,', + ' `col_collation` varchar(64) NOT NULL,', + ' `col_isNull` boolean NOT NULL,', + ' `col_extra` varchar(255) default \'\',', + ' `col_default` text,', + ' PRIMARY KEY (`db_name`,`col_name`)', + ')', + ' COMMENT=\'Central list of columns\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__designer_settings' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__designer_settings`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__designer_settings` (', + ' `username` varchar(64) NOT NULL,', + ' `settings_data` text NOT NULL,', + ' PRIMARY KEY (`username`)', + ')', + ' COMMENT=\'Settings related to Designer\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + 'pma__export_templates' => implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `pma__export_templates`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `pma__export_templates` (', + ' `id` int(5) unsigned NOT NULL AUTO_INCREMENT,', + ' `username` varchar(64) NOT NULL,', + ' `export_type` varchar(10) NOT NULL,', + ' `template_name` varchar(64) NOT NULL,', + ' `template_data` text NOT NULL,', + ' PRIMARY KEY (`id`),', + ' UNIQUE KEY `u_user_type_template` (`username`,`export_type`,`template_name`)', + ')', + ' COMMENT=\'Saved export templates\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]), + ]; + + $this->assertSame( + $data, + $this->relation->getDefaultPmaTableNames([]) + ); + + $data['pma__export_templates'] = implode("\n", [ + '', + '', + '-- --------------------------------------------------------', + '', + '--', + '-- Table structure for table `db_exporttemplates_pma`', + '--', + '', + 'CREATE TABLE IF NOT EXISTS `db_exporttemplates_pma` (', + ' `id` int(5) unsigned NOT NULL AUTO_INCREMENT,', + ' `username` varchar(64) NOT NULL,', + ' `export_type` varchar(10) NOT NULL,', + ' `template_name` varchar(64) NOT NULL,', + ' `template_data` text NOT NULL,', + ' PRIMARY KEY (`id`),', + ' UNIQUE KEY `u_user_type_template` (`username`,`export_type`,`template_name`)', + ')', + ' COMMENT=\'Saved export templates\'', + ' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;', + ]); + + $this->assertSame( + $data, + $this->relation->getDefaultPmaTableNames(['pma__export_templates' => 'db_exporttemplates_pma']) + ); + } } diff --git a/test/classes/TwoFactorTest.php b/test/classes/TwoFactorTest.php index 14f048c610..e5d18ada83 100644 --- a/test/classes/TwoFactorTest.php +++ b/test/classes/TwoFactorTest.php @@ -87,7 +87,7 @@ class TwoFactorTest extends AbstractTestCase ); $this->dummyDbi->addResult( - 'SELECT NULL FROM pma__userconfig LIMIT 0', + 'SELECT NULL FROM `pma__userconfig` LIMIT 0', [ ['NULL'], ], |