Translated using Weblate (Lithuanian)
[phpmyadmin.git] / test / classes / Server / PrivilegesTest.php
blobcee9e1e94191006424ff00805fd81faf43765e36
1 <?php
3 declare(strict_types=1);
5 namespace PhpMyAdmin\Tests\Server;
7 use mysqli_result;
8 use mysqli_stmt;
9 use PhpMyAdmin\Config;
10 use PhpMyAdmin\ConfigStorage\Relation;
11 use PhpMyAdmin\ConfigStorage\RelationCleanup;
12 use PhpMyAdmin\ConfigStorage\RelationParameters;
13 use PhpMyAdmin\DatabaseInterface;
14 use PhpMyAdmin\Html\Generator;
15 use PhpMyAdmin\Message;
16 use PhpMyAdmin\Server\Plugins;
17 use PhpMyAdmin\Server\Privileges;
18 use PhpMyAdmin\Template;
19 use PhpMyAdmin\Tests\AbstractTestCase;
20 use PhpMyAdmin\Tests\Stubs\DbiDummy;
21 use PhpMyAdmin\Tests\Stubs\DummyResult;
22 use PhpMyAdmin\Url;
23 use PhpMyAdmin\Util;
24 use ReflectionMethod;
25 use stdClass;
27 use function __;
28 use function _pgettext;
29 use function htmlspecialchars;
30 use function implode;
32 /**
33 * @covers \PhpMyAdmin\Server\Privileges
35 class PrivilegesTest extends AbstractTestCase
37 /** @var Privileges $serverPrivileges */
38 private $serverPrivileges;
40 /**
41 * Prepares environment for the test.
43 protected function setUp(): void
45 parent::setUp();
46 parent::setLanguage();
47 parent::setGlobalConfig();
48 parent::setTheme();
49 $GLOBALS['cfg']['Server']['DisableIS'] = false;
50 $GLOBALS['table'] = 'table';
51 $GLOBALS['server'] = 1;
52 $GLOBALS['db'] = 'db';
53 $GLOBALS['hostname'] = 'hostname';
54 $GLOBALS['username'] = 'username';
56 $relation = new Relation($GLOBALS['dbi']);
57 $this->serverPrivileges = new Privileges(
58 new Template(),
59 $GLOBALS['dbi'],
60 $relation,
61 new RelationCleanup($GLOBALS['dbi'], $relation),
62 new Plugins($GLOBALS['dbi'])
65 $_POST['pred_password'] = 'none';
67 $_SESSION['relation'] = [];
68 $_SESSION['relation'][$GLOBALS['server']] = RelationParameters::fromArray([
69 'db' => 'pmadb',
70 'users' => 'users',
71 'usergroups' => 'usergroups',
72 'menuswork' => true,
73 'trackingwork' => true,
74 'tracking' => 'tracking',
75 ])->toArray();
77 $pmaconfig = $this->getMockBuilder(Config::class)
78 ->disableOriginalConstructor()
79 ->getMock();
81 $GLOBALS['config'] = $pmaconfig;
83 //Mock DBI
84 $dbi = $this->getMockBuilder(DatabaseInterface::class)
85 ->disableOriginalConstructor()
86 ->getMock();
88 $dbi->expects($this->any())
89 ->method('fetchResult')
90 ->will(
91 $this->returnValue(
93 'grant user1 select',
94 'grant user2 delete',
99 $fetchSingleRow = [
100 'password' => 'pma_password',
101 'Table_priv' => 'pri1, pri2',
102 'Type' => 'Type',
103 '@@old_passwords' => 0,
105 $dbi->expects($this->any())->method('fetchSingleRow')
106 ->will($this->returnValue($fetchSingleRow));
108 $fetchValue = ['key1' => 'value1'];
109 $dbi->expects($this->any())->method('fetchValue')
110 ->will($this->returnValue($fetchValue));
112 $resultStub = $this->createMock(DummyResult::class);
114 $dbi->expects($this->any())->method('tryQuery')
115 ->will($this->returnValue($resultStub));
117 $dbi->expects($this->any())->method('escapeString')
118 ->will($this->returnArgument(0));
120 $dbi->expects($this->any())->method('isCreateUser')
121 ->will($this->returnValue(true));
122 $dbi->expects($this->any())->method('isGrantUser')
123 ->will($this->returnValue(true));
125 $GLOBALS['dbi'] = $dbi;
126 $this->serverPrivileges->dbi = $dbi;
127 $this->serverPrivileges->relation->dbi = $dbi;
128 $GLOBALS['is_reload_priv'] = true;
132 * Test for getDataForDBInfo
134 public function testGetDataForDBInfo(): void
136 $_REQUEST['username'] = 'PMA_username';
137 $_REQUEST['hostname'] = 'PMA_hostname';
138 $_REQUEST['tablename'] = 'PMA_tablename';
139 $_REQUEST['dbname'] = 'PMA_dbname';
141 $username,
142 $hostname,
143 $dbname,
144 $tablename,
145 $routinename,
146 $db_and_table,
147 $dbname_is_wildcard,
148 ] = $this->serverPrivileges->getDataForDBInfo();
149 $this->assertEquals('PMA_username', $username);
150 $this->assertEquals('PMA_hostname', $hostname);
151 $this->assertEquals('PMA_dbname', $dbname);
152 $this->assertEquals('PMA_tablename', $tablename);
153 $this->assertEquals('`PMA_dbname`.`PMA_tablename`', $db_and_table);
154 $this->assertTrue($dbname_is_wildcard);
156 //pre variable have been defined
157 $_POST['pred_tablename'] = 'PMA_pred__tablename';
158 $_POST['pred_dbname'] = ['PMA_pred_dbname'];
160 $dbname,
161 $tablename,
162 $routinename,
163 $db_and_table,
164 $dbname_is_wildcard,
165 ] = $this->serverPrivileges->getDataForDBInfo();
166 $this->assertEquals('PMA_pred_dbname', $dbname);
167 $this->assertEquals('PMA_pred__tablename', $tablename);
168 $this->assertEquals('`PMA_pred_dbname`.`PMA_pred__tablename`', $db_and_table);
169 $this->assertTrue($dbname_is_wildcard);
171 // Escaped database
172 $_POST['pred_tablename'] = 'PMA_pred__tablename';
173 $_POST['pred_dbname'] = ['PMA\_pred\_dbname'];
175 $dbname,
176 $tablename,
177 $routinename,
178 $db_and_table,
179 $dbname_is_wildcard,
180 ] = $this->serverPrivileges->getDataForDBInfo();
181 $this->assertEquals('PMA\_pred\_dbname', $dbname);
182 $this->assertEquals('PMA_pred__tablename', $tablename);
183 $this->assertEquals('`PMA_pred_dbname`.`PMA_pred__tablename`', $db_and_table);
184 $this->assertEquals(false, $dbname_is_wildcard);
186 // Multiselect database - pred
187 unset($_POST['pred_tablename'], $_REQUEST['tablename'], $_REQUEST['dbname']);
188 $_POST['pred_dbname'] = ['PMA\_pred\_dbname', 'PMADbname2'];
190 $dbname,
191 $tablename,,
192 $db_and_table,
193 $dbname_is_wildcard,
194 ] = $this->serverPrivileges->getDataForDBInfo();
195 $this->assertEquals(['PMA\_pred\_dbname', 'PMADbname2'], $dbname);
196 $this->assertEquals(null, $tablename);
197 $this->assertEquals(['PMA\_pred\_dbname.*', 'PMADbname2.*'], $db_and_table);
198 $this->assertEquals(false, $dbname_is_wildcard);
200 // Multiselect database
201 unset($_POST['pred_tablename'], $_REQUEST['tablename'], $_POST['pred_dbname']);
202 $_REQUEST['dbname'] = ['PMA\_dbname', 'PMADbname2'];
204 $dbname,
205 $tablename,,
206 $db_and_table,
207 $dbname_is_wildcard,
208 ] = $this->serverPrivileges->getDataForDBInfo();
209 $this->assertEquals(['PMA\_dbname', 'PMADbname2'], $dbname);
210 $this->assertEquals(null, $tablename);
211 $this->assertEquals(['PMA\_dbname.*', 'PMADbname2.*'], $db_and_table);
212 $this->assertEquals(false, $dbname_is_wildcard);
216 * Test for wildcardEscapeForGrant
218 public function testWildcardEscapeForGrant(): void
220 $dbname = '';
221 $tablename = '';
222 $db_and_table = $this->serverPrivileges->wildcardEscapeForGrant($dbname, $tablename);
223 $this->assertEquals('*.*', $db_and_table);
225 $dbname = 'dbname';
226 $tablename = '';
227 $db_and_table = $this->serverPrivileges->wildcardEscapeForGrant($dbname, $tablename);
228 $this->assertEquals('`dbname`.*', $db_and_table);
230 $dbname = 'dbname';
231 $tablename = 'tablename';
232 $db_and_table = $this->serverPrivileges->wildcardEscapeForGrant($dbname, $tablename);
233 $this->assertEquals('`dbname`.`tablename`', $db_and_table);
237 * Test for rangeOfUsers
239 public function testRangeOfUsers(): void
241 $ret = $this->serverPrivileges->rangeOfUsers('INIT');
242 $this->assertEquals(" WHERE `User` LIKE 'INIT%' OR `User` LIKE 'init%'", $ret);
244 $ret = $this->serverPrivileges->rangeOfUsers();
245 $this->assertEquals('', $ret);
249 * Test for getTableGrantsArray
251 public function testGetTableGrantsArray(): void
253 $ret = $this->serverPrivileges->getTableGrantsArray();
254 $this->assertEquals(
256 'Delete',
257 'DELETE',
258 __('Allows deleting data.'),
260 $ret[0]
262 $this->assertEquals(
264 'Create',
265 'CREATE',
266 __('Allows creating new tables.'),
268 $ret[1]
273 * Test for getGrantsArray
275 public function testGetGrantsArray(): void
277 $ret = $this->serverPrivileges->getGrantsArray();
278 $this->assertEquals(
280 'Select_priv',
281 'SELECT',
282 __('Allows reading data.'),
284 $ret[0]
286 $this->assertEquals(
288 'Insert_priv',
289 'INSERT',
290 __('Allows inserting and replacing data.'),
292 $ret[1]
297 * Test for getSqlQueryForDisplayPrivTable
299 public function testGetSqlQueryForDisplayPrivTable(): void
301 $username = 'pma_username';
302 $db = '*';
303 $table = 'pma_table';
304 $hostname = 'pma_hostname';
306 //$db == '*'
307 $ret = $this->serverPrivileges->getSqlQueryForDisplayPrivTable($db, $table, $username, $hostname);
308 $sql = 'SELECT * FROM `mysql`.`user`'
309 . " WHERE `User` = '" . $GLOBALS['dbi']->escapeString($username) . "'"
310 . " AND `Host` = '" . $GLOBALS['dbi']->escapeString($hostname) . "';";
311 $this->assertEquals($sql, $ret);
313 //$table == '*'
314 $db = 'pma_db';
315 $table = '*';
316 $ret = $this->serverPrivileges->getSqlQueryForDisplayPrivTable($db, $table, $username, $hostname);
317 $sql = 'SELECT * FROM `mysql`.`db`'
318 . " WHERE `User` = '" . $GLOBALS['dbi']->escapeString($username) . "'"
319 . " AND `Host` = '" . $GLOBALS['dbi']->escapeString($hostname) . "'"
320 . ' AND `Db` = \'' . $db . '\'';
322 $this->assertEquals($sql, $ret);
324 //$table == 'pma_table'
325 $db = 'pma_db';
326 $table = 'pma_table';
327 $ret = $this->serverPrivileges->getSqlQueryForDisplayPrivTable($db, $table, $username, $hostname);
328 $sql = 'SELECT `Table_priv`'
329 . ' FROM `mysql`.`tables_priv`'
330 . " WHERE `User` = '" . $GLOBALS['dbi']->escapeString($username) . "'"
331 . " AND `Host` = '" . $GLOBALS['dbi']->escapeString($hostname) . "'"
332 . " AND `Db` = '" . Util::unescapeMysqlWildcards($db) . "'"
333 . " AND `Table_name` = '" . $GLOBALS['dbi']->escapeString($table) . "';";
334 $this->assertEquals($sql, $ret);
336 // SQL escaping
337 $db = "db' AND";
338 $table = 'pma_table';
339 $ret = $this->serverPrivileges->getSqlQueryForDisplayPrivTable($db, $table, $username, $hostname);
340 $this->assertEquals(
341 'SELECT `Table_priv` FROM `mysql`.`tables_priv` '
342 . "WHERE `User` = 'pma_username' AND "
343 . "`Host` = 'pma_hostname' AND `Db` = 'db' AND' AND "
344 . "`Table_name` = 'pma_table';",
345 $ret
350 * Test for getDataForChangeOrCopyUser
352 public function testGetDataForChangeOrCopyUser(): void
354 //$_POST['change_copy'] not set
355 [$queries, $password] = $this->serverPrivileges->getDataForChangeOrCopyUser();
356 $this->assertEquals(null, $queries);
357 $this->assertEquals(null, $queries);
359 //$_POST['change_copy'] is set
360 $_POST['change_copy'] = true;
361 $_POST['old_username'] = 'PMA_old_username';
362 $_POST['old_hostname'] = 'PMA_old_hostname';
363 [$queries, $password] = $this->serverPrivileges->getDataForChangeOrCopyUser();
364 $this->assertEquals('pma_password', $password);
365 $this->assertEquals(
367 $queries
369 unset($_POST['change_copy']);
373 * Test for getListForExportUserDefinition
375 public function testGetHtmlForExportUserDefinition(): void
377 $username = 'PMA_username';
378 $hostname = 'PMA_hostname';
380 [$title, $export] = $this->serverPrivileges->getListForExportUserDefinition($username, $hostname);
382 //validate 1: $export
383 $this->assertStringContainsString('grant user2 delete', $export);
384 $this->assertStringContainsString('grant user1 select', $export);
385 $this->assertStringContainsString('<textarea class="export"', $export);
387 //validate 2: $title
388 $title_user = __('User') . ' `' . htmlspecialchars($username)
389 . '`@`' . htmlspecialchars($hostname) . '`';
390 $this->assertStringContainsString($title_user, $title);
394 * Test for addUser
396 public function testAddUser(): void
398 // Case 1 : Test with Newer version
399 $GLOBALS['dbi']->expects($this->any())->method('getVersion')
400 ->will($this->returnValue(50706));
401 $this->serverPrivileges->dbi = $GLOBALS['dbi'];
403 $dbname = 'pma_dbname';
404 $username = 'pma_username';
405 $hostname = 'pma_hostname';
406 $_POST['adduser_submit'] = true;
407 $_POST['pred_username'] = 'any';
408 $_POST['pred_hostname'] = 'localhost';
409 $_POST['pred_password'] = 'keep';
410 $_POST['createdb-3'] = true;
411 $_POST['userGroup'] = 'username';
412 $_POST['authentication_plugin'] = 'mysql_native_password';
415 $ret_message,,,
416 $sql_query,
417 $_add_user_error,
418 ] = $this->serverPrivileges->addUser($dbname, $username, $hostname, $dbname, true);
419 $this->assertEquals(
420 'You have added a new user.',
421 $ret_message->getMessage()
423 $this->assertEquals(
424 "CREATE USER ''@'localhost' IDENTIFIED WITH mysql_native_password AS '***';"
425 . "GRANT USAGE ON *.* TO ''@'localhost' REQUIRE NONE;"
426 . "GRANT ALL PRIVILEGES ON `pma_dbname`.* TO ''@'localhost';",
427 $sql_query
429 $this->assertFalse($_add_user_error);
433 * Test for addUser
435 public function testAddUserOld(): void
437 $GLOBALS['dbi']->expects($this->any())->method('getVersion')
438 ->will($this->returnValue(50506));
439 $this->serverPrivileges->dbi = $GLOBALS['dbi'];
441 $dbname = 'pma_dbname';
442 $username = 'pma_username';
443 $hostname = 'pma_hostname';
444 $_POST['adduser_submit'] = true;
445 $_POST['pred_username'] = 'any';
446 $_POST['pred_hostname'] = 'localhost';
447 $_POST['pred_password'] = 'keep';
448 $_POST['createdb-3'] = true;
449 $_POST['userGroup'] = 'username';
450 $_POST['authentication_plugin'] = 'mysql_native_password';
453 $ret_message,,,
454 $sql_query,
455 $_add_user_error,
456 ] = $this->serverPrivileges->addUser($dbname, $username, $hostname, $dbname, true);
458 $this->assertEquals(
459 'You have added a new user.',
460 $ret_message->getMessage()
462 $this->assertEquals(
463 "CREATE USER ''@'localhost';"
464 . "GRANT USAGE ON *.* TO ''@'localhost' REQUIRE NONE;"
465 . "SET PASSWORD FOR ''@'localhost' = '***';"
466 . "GRANT ALL PRIVILEGES ON `pma_dbname`.* TO ''@'localhost';",
467 $sql_query
469 $this->assertFalse($_add_user_error);
473 * Test for updatePassword
475 public function testUpdatePassword(): void
477 $username = 'pma_username';
478 $hostname = 'pma_hostname';
479 $err_url = 'error.php';
480 $_POST['pma_pw'] = 'pma_pw';
481 $_POST['authentication_plugin'] = 'mysql_native_password';
483 $message = $this->serverPrivileges->updatePassword($err_url, $username, $hostname);
485 $this->assertEquals(
486 'The password for \'pma_username\'@\'pma_hostname\' was changed successfully.',
487 $message->getMessage()
492 * Test for getMessageAndSqlQueryForPrivilegesRevoke
494 public function testGetMessageAndSqlQueryForPrivilegesRevoke(): void
496 $dbname = 'pma_dbname';
497 $username = 'pma_username';
498 $hostname = 'pma_hostname';
499 $tablename = 'pma_tablename';
500 $_POST['adduser_submit'] = true;
501 $_POST['pred_username'] = 'any';
502 $_POST['pred_hostname'] = 'localhost';
503 $_POST['createdb-3'] = true;
504 $_POST['Grant_priv'] = 'Y';
505 $_POST['max_questions'] = 1000;
506 [$message, $sql_query] = $this->serverPrivileges->getMessageAndSqlQueryForPrivilegesRevoke(
507 $dbname,
508 $tablename,
509 $username,
510 $hostname,
514 $this->assertEquals(
515 "You have revoked the privileges for 'pma_username'@'pma_hostname'.",
516 $message->getMessage()
518 $this->assertEquals(
519 'REVOKE ALL PRIVILEGES ON `pma_dbname`.`pma_tablename` '
520 . "FROM 'pma_username'@'pma_hostname'; "
521 . 'REVOKE GRANT OPTION ON `pma_dbname`.`pma_tablename` '
522 . "FROM 'pma_username'@'pma_hostname';",
523 $sql_query
528 * Test for updatePrivileges
530 public function testUpdatePrivileges(): void
532 $dbname = 'pma_dbname';
533 $username = 'pma_username';
534 $hostname = 'pma_hostname';
535 $tablename = 'pma_tablename';
536 $_POST['adduser_submit'] = true;
537 $_POST['pred_username'] = 'any';
538 $_POST['pred_hostname'] = 'localhost';
539 $_POST['createdb-3'] = true;
540 $_POST['Grant_priv'] = 'Y';
541 $_POST['max_questions'] = 1000;
542 [$sql_query, $message] = $this->serverPrivileges->updatePrivileges(
543 $username,
544 $hostname,
545 $tablename,
546 $dbname,
550 $this->assertEquals(
551 "You have updated the privileges for 'pma_username'@'pma_hostname'.",
552 $message->getMessage()
554 $this->assertEquals(
555 'REVOKE ALL PRIVILEGES ON `pma_dbname`.`pma_tablename` FROM \'pma_username\'@\'pma_hostname\'; ',
556 $sql_query
561 * Test for updatePrivileges
563 public function testUpdatePrivilegesBeforeMySql8Dot11(): void
565 $dbname = '';
566 $username = 'pma_username';
567 $hostname = 'pma_hostname';
568 $tablename = '';
569 $_POST['adduser_submit'] = true;
570 $_POST['pred_username'] = 'any';
571 $_POST['pred_hostname'] = 'localhost';
572 $_POST['Grant_priv'] = 'Y';
573 $_POST['max_questions'] = 1000;
574 $_POST['max_connections'] = 20;
575 $_POST['max_updates'] = 30;
576 $_POST['max_user_connections'] = 40;
578 //Mock DBI
579 $dbi = $this->getMockBuilder(DatabaseInterface::class)
580 ->disableOriginalConstructor()
581 ->getMock();
583 $dbi->expects($this->any())->method('getVersion')
584 ->will($this->returnValue(8003));
585 $dbi->expects($this->any())
586 ->method('escapeString')
587 ->will($this->returnArgument(0));
589 $this->serverPrivileges->dbi = $dbi;
591 [$sql_query, $message] = $this->serverPrivileges->updatePrivileges(
592 $username,
593 $hostname,
594 $tablename,
595 $dbname,
599 $this->assertEquals(
600 "You have updated the privileges for 'pma_username'@'pma_hostname'.",
601 $message->getMessage()
603 $this->assertEquals(
604 ' GRANT USAGE ON *.* TO \'pma_username\'@\'pma_hostname\' REQUIRE NONE'
605 . ' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 1000 MAX_CONNECTIONS_PER_HOUR 20'
606 . ' MAX_UPDATES_PER_HOUR 30 MAX_USER_CONNECTIONS 40; ',
607 $sql_query
612 * Test for updatePrivileges
614 public function testUpdatePrivilegesAfterMySql8Dot11(): void
616 $dbname = '';
617 $username = 'pma_username';
618 $hostname = 'pma_hostname';
619 $tablename = '';
620 $_POST['adduser_submit'] = true;
621 $_POST['pred_username'] = 'any';
622 $_POST['pred_hostname'] = 'localhost';
623 $_POST['Grant_priv'] = 'Y';
624 $_POST['max_questions'] = 1000;
625 $_POST['max_connections'] = 20;
626 $_POST['max_updates'] = 30;
627 $_POST['max_user_connections'] = 40;
629 //Mock DBI
630 $dbi = $this->getMockBuilder(DatabaseInterface::class)
631 ->disableOriginalConstructor()
632 ->getMock();
634 $dbi->expects($this->any())->method('getVersion')
635 ->will($this->returnValue(80011));
636 $dbi->expects($this->any())
637 ->method('escapeString')
638 ->will($this->returnArgument(0));
640 $this->serverPrivileges->dbi = $dbi;
642 [$sql_query, $message] = $this->serverPrivileges->updatePrivileges(
643 $username,
644 $hostname,
645 $tablename,
646 $dbname,
650 $this->assertEquals(
651 "You have updated the privileges for 'pma_username'@'pma_hostname'.",
652 $message->getMessage()
654 $this->assertEquals(
655 ' GRANT USAGE ON *.* TO \'pma_username\'@\'pma_hostname\';'
656 . ' ALTER USER \'pma_username\'@\'pma_hostname\' REQUIRE NONE'
657 . ' WITH MAX_QUERIES_PER_HOUR 1000 MAX_CONNECTIONS_PER_HOUR'
658 . ' 20 MAX_UPDATES_PER_HOUR 30 MAX_USER_CONNECTIONS 40;',
659 $sql_query
664 * Test for getHtmlToDisplayPrivilegesTable
666 * @group medium
668 public function testGetHtmlToDisplayPrivilegesTable(): void
670 $GLOBALS['hostname'] = 'hostname';
671 $GLOBALS['username'] = 'username';
672 $GLOBALS['dbi'] = DatabaseInterface::load(new DbiDummy());
674 $relation = new Relation($GLOBALS['dbi']);
675 $serverPrivileges = new Privileges(
676 new Template(),
677 $GLOBALS['dbi'],
678 $relation,
679 new RelationCleanup($GLOBALS['dbi'], $relation),
680 new Plugins($GLOBALS['dbi'])
682 $html = $serverPrivileges->getHtmlToDisplayPrivilegesTable();
683 $GLOBALS['username'] = 'username';
685 //validate 1: fieldset
686 $this->assertStringContainsString(
687 '<fieldset id="fieldset_user_privtable_footer" class="pma-fieldset tblFooters">',
688 $html
691 //validate 2: button
692 $this->assertStringContainsString(
693 __('Go'),
694 $html
697 //validate 3: getHtmlForGlobalOrDbSpecificPrivs
698 $this->assertStringContainsString('<fieldset class="pma-fieldset" id="fieldset_user_global_rights">', $html);
699 $this->assertStringContainsString(
700 '<legend data-submenu-label="' . __('Global') . '">',
701 $html
703 $this->assertStringContainsString(
704 __('Global privileges'),
705 $html
707 $this->assertStringContainsString(
708 __('Check all'),
709 $html
711 $this->assertStringContainsString(
712 __('Note: MySQL privilege names are expressed in English'),
713 $html
716 //validate 4: getHtmlForGlobalPrivTableWithCheckboxes items
717 //Select_priv
718 $this->assertStringContainsString('<input type="checkbox" class="checkall" name="Select_priv"', $html);
719 //Create_user_priv
720 $this->assertStringContainsString('<input type="checkbox" class="checkall" name="Create_user_priv"', $html);
721 //Insert_priv
722 $this->assertStringContainsString('<input type="checkbox" class="checkall" name="Insert_priv"', $html);
723 //Update_priv
724 $this->assertStringContainsString('<input type="checkbox" class="checkall" name="Update_priv"', $html);
725 //Create_priv
726 $this->assertStringContainsString('<input type="checkbox" class="checkall" name="Create_priv"', $html);
727 //Create_routine_priv
728 $this->assertStringContainsString('<input type="checkbox" class="checkall" name="Create_routine_priv"', $html);
729 //Execute_priv
730 $this->assertStringContainsString('<input type="checkbox" class="checkall" name="Execute_priv"', $html);
732 //validate 5: getHtmlForResourceLimits
733 $this->assertStringContainsString(
734 '<legend>' . __('Resource limits') . '</legend>',
735 $html
737 $this->assertStringContainsString(
738 __('Note: Setting these options to 0 (zero) removes the limit.'),
739 $html
741 $this->assertStringContainsString('MAX QUERIES PER HOUR', $html);
742 $this->assertStringContainsString('id="text_max_updates" value="0"', $html);
743 $this->assertStringContainsString(
744 __('Limits the number of new connections the user may open per hour.'),
745 $html
747 $this->assertStringContainsString(
748 __('Limits the number of simultaneous connections the user may have.'),
749 $html
752 $this->assertStringContainsString('<legend>SSL</legend>', $html);
753 $this->assertStringContainsString('value="NONE"', $html);
754 $this->assertStringContainsString('value="ANY"', $html);
755 $this->assertStringContainsString('value="X509"', $html);
756 $this->assertStringContainsString('value="SPECIFIED"', $html);
760 * Test case for getSqlQueriesForDisplayAndAddUser
762 public function testGetSqlQueriesForDisplayAndAddUserMySql8011(): void
764 $GLOBALS['dbi']->expects($this->any())->method('getVersion')
765 ->will($this->returnValue(80011));
766 $this->serverPrivileges->dbi = $GLOBALS['dbi'];
768 $username = 'PMA_username';
769 $hostname = 'PMA_hostname';
770 $password = 'pma_password';
771 $_POST['pred_password'] = 'keep';
772 $_POST['authentication_plugin'] = 'mysql_native_password';
775 $create_user_real,
776 $create_user_show,
777 ] = $this->serverPrivileges->getSqlQueriesForDisplayAndAddUser($username, $hostname, $password);
779 //validate 1: $create_user_real
780 $this->assertEquals(
781 'CREATE USER \'PMA_username\'@\'PMA_hostname\' IDENTIFIED WITH mysql_native_password BY \'pma_password\';',
782 $create_user_real
785 //validate 2: $create_user_show
786 $this->assertEquals(
787 'CREATE USER \'PMA_username\'@\'PMA_hostname\' IDENTIFIED WITH mysql_native_password BY \'***\';',
788 $create_user_show
793 * Test case for getSqlQueriesForDisplayAndAddUser
795 public function testGetSqlQueriesForDisplayAndAddUserMySql8016(): void
797 $GLOBALS['dbi']->expects($this->any())->method('getVersion')
798 ->will($this->returnValue(80016));
799 $this->serverPrivileges->dbi = $GLOBALS['dbi'];
801 $username = 'PMA_username';
802 $hostname = 'PMA_hostname';
803 $password = 'pma_password';
804 $_POST['pred_password'] = 'keep';
807 $create_user_real,
808 $create_user_show,
809 ] = $this->serverPrivileges->getSqlQueriesForDisplayAndAddUser($username, $hostname, $password);
811 //validate 1: $create_user_real
812 $this->assertEquals(
813 'CREATE USER \'PMA_username\'@\'PMA_hostname\' IDENTIFIED BY \'pma_password\';',
814 $create_user_real
817 //validate 2: $create_user_show
818 $this->assertEquals('CREATE USER \'PMA_username\'@\'PMA_hostname\' IDENTIFIED BY \'***\';', $create_user_show);
822 * Test for getSqlQueriesForDisplayAndAddUser
824 public function testGetSqlQueriesForDisplayAndAddUser(): void
826 $GLOBALS['dbi']->expects($this->any())->method('getVersion')
827 ->will($this->returnValue(50706));
828 $this->serverPrivileges->dbi = $GLOBALS['dbi'];
830 $username = 'PMA_username';
831 $hostname = 'PMA_hostname';
832 $password = 'pma_password';
833 $_POST['pred_password'] = 'keep';
834 $_POST['authentication_plugin'] = 'mysql_native_password';
835 $dbname = 'PMA_db';
838 $create_user_real,
839 $create_user_show,
840 $real_sql_query,
841 $sql_query,,,
842 $alter_real_sql_query,
843 $alter_sql_query,
844 ] = $this->serverPrivileges->getSqlQueriesForDisplayAndAddUser($username, $hostname, $password);
846 //validate 1: $create_user_real
847 $this->assertEquals(
848 'CREATE USER \'PMA_username\'@\'PMA_hostname\' IDENTIFIED WITH mysql_native_password AS \'pma_password\';',
849 $create_user_real
852 //validate 2: $create_user_show
853 $this->assertEquals(
854 'CREATE USER \'PMA_username\'@\'PMA_hostname\' IDENTIFIED WITH mysql_native_password AS \'***\';',
855 $create_user_show
858 //validate 3:$real_sql_query
859 $this->assertEquals("GRANT USAGE ON *.* TO 'PMA_username'@'PMA_hostname' REQUIRE NONE;", $real_sql_query);
861 //validate 4:$sql_query
862 $this->assertEquals("GRANT USAGE ON *.* TO 'PMA_username'@'PMA_hostname' REQUIRE NONE;", $sql_query);
864 $this->assertSame('', $alter_real_sql_query);
866 $this->assertSame('', $alter_sql_query);
868 //Test for addUserAndCreateDatabase
869 [$sql_query, $message] = $this->serverPrivileges->addUserAndCreateDatabase(
870 false,
871 $real_sql_query,
872 $sql_query,
873 $username,
874 $hostname,
875 $dbname,
876 $alter_real_sql_query,
877 $alter_sql_query,
878 false,
879 false,
880 false
883 //validate 5: $sql_query
884 $this->assertEquals("GRANT USAGE ON *.* TO 'PMA_username'@'PMA_hostname' REQUIRE NONE;", $sql_query);
886 $this->assertInstanceOf(Message::class, $message);
888 //validate 6: $message
889 $this->assertEquals(
890 'You have added a new user.',
891 $message->getMessage()
896 * Test for getHtmlForTableSpecificPrivileges
898 public function testGetHtmlToDisplayPrivilegesTableWithTableSpecific(): void
900 $dbi_old = $GLOBALS['dbi'];
901 $GLOBALS['dbi'] = DatabaseInterface::load(new DbiDummy());
902 $this->serverPrivileges->dbi = $GLOBALS['dbi'];
904 $GLOBALS['username'] = 'PMA_username';
905 $GLOBALS['hostname'] = 'PMA_hostname';
906 $html = $this->serverPrivileges->getHtmlToDisplayPrivilegesTable('PMA_db', 'PMA_table');
908 $this->assertStringContainsString('checkbox_Update_priv_none', $html);
909 $this->assertStringContainsString('<dfn title="Allows changing data.">UPDATE</dfn>', $html);
910 $this->assertStringContainsString('checkbox_Insert_priv_none', $html);
911 $this->assertStringContainsString(
912 __('Allows reading data.'),
913 $html
915 $this->assertStringContainsString(
916 __('Allows inserting and replacing data'),
917 $html
919 $this->assertStringContainsString(
920 __('Allows changing data.'),
921 $html
923 $this->assertStringContainsString(
924 __('Has no effect in this MySQL version.'),
925 $html
928 $this->assertStringContainsString('title="Allows performing SHOW CREATE VIEW queries." checked>', $html);
929 $this->assertStringContainsString('<dfn title="Allows creating new views.">', $html);
930 $this->assertStringContainsString('CREATE VIEW', $html);
931 $this->assertStringContainsString('Create_view_priv', $html);
932 $this->assertStringContainsString('Show_view_priv', $html);
933 $this->assertStringContainsString(
934 _pgettext('None privileges', 'None'),
935 $html
938 $GLOBALS['dbi'] = $dbi_old;
939 $this->serverPrivileges->dbi = $dbi_old;
943 * Test for getHtmlForLoginInformationFields
945 public function testGetHtmlForLoginInformationFields(): void
947 $GLOBALS['username'] = 'pma_username';
949 $dbi_old = $GLOBALS['dbi'];
950 $dbi = $this->getMockBuilder(DatabaseInterface::class)
951 ->disableOriginalConstructor()
952 ->getMock();
953 $fields_info = [
955 'COLUMN_NAME' => 'Host',
956 'CHARACTER_MAXIMUM_LENGTH' => 80,
959 'COLUMN_NAME' => 'User',
960 'CHARACTER_MAXIMUM_LENGTH' => 40,
963 $dbi->expects($this->any())->method('fetchResult')
964 ->will($this->returnValue($fields_info));
965 $dbi->expects($this->any())
966 ->method('escapeString')
967 ->will($this->returnArgument(0));
969 $GLOBALS['dbi'] = $dbi;
970 $this->serverPrivileges->dbi = $dbi;
972 $html = $this->serverPrivileges->getHtmlForLoginInformationFields();
974 //validate 1: __('Login Information')
975 $this->assertStringContainsString(
976 __('Login Information'),
977 $html
979 $this->assertStringContainsString(
980 __('User name:'),
981 $html
983 $this->assertStringContainsString(
984 __('Any user'),
985 $html
987 $this->assertStringContainsString(
988 __('Use text field'),
989 $html
992 $output = Generator::showHint(
994 'When Host table is used, this field is ignored and values stored in Host table are used instead.'
997 $this->assertStringContainsString($output, $html);
999 $GLOBALS['dbi'] = $dbi_old;
1000 $this->serverPrivileges->dbi = $dbi_old;
1004 * Test for getWithClauseForAddUserAndUpdatePrivs
1006 public function testGetWithClauseForAddUserAndUpdatePrivs(): void
1008 $_POST['Grant_priv'] = 'Y';
1009 $_POST['max_questions'] = 10;
1010 $_POST['max_connections'] = 20;
1011 $_POST['max_updates'] = 30;
1012 $_POST['max_user_connections'] = 40;
1014 $sql_query = $this->serverPrivileges->getWithClauseForAddUserAndUpdatePrivs();
1015 $expect = 'WITH GRANT OPTION MAX_QUERIES_PER_HOUR 10 '
1016 . 'MAX_CONNECTIONS_PER_HOUR 20'
1017 . ' MAX_UPDATES_PER_HOUR 30 MAX_USER_CONNECTIONS 40';
1018 $this->assertStringContainsString($expect, $sql_query);
1022 * Test for getHtmlForAddUser
1024 * @group medium
1026 public function testGetHtmlForAddUser(): void
1028 $dbi_old = $GLOBALS['dbi'];
1029 $dbi = $this->getMockBuilder(DatabaseInterface::class)
1030 ->disableOriginalConstructor()
1031 ->getMock();
1032 $fields_info = [
1034 'COLUMN_NAME' => 'Host',
1035 'CHARACTER_MAXIMUM_LENGTH' => 80,
1038 'COLUMN_NAME' => 'User',
1039 'CHARACTER_MAXIMUM_LENGTH' => 40,
1042 $dbi->expects($this->any())->method('fetchResult')
1043 ->will($this->returnValue($fields_info));
1044 $dbi->expects($this->any())
1045 ->method('escapeString')
1046 ->will($this->returnArgument(0));
1047 $dbi->expects($this->any())->method('isGrantUser')
1048 ->will($this->returnValue(true));
1050 $GLOBALS['dbi'] = $dbi;
1051 $this->serverPrivileges->dbi = $dbi;
1053 $dbname = 'pma_dbname';
1055 $html = $this->serverPrivileges->getHtmlForAddUser($dbname);
1057 //validate 1: Url::getHiddenInputs
1058 $this->assertStringContainsString(
1059 Url::getHiddenInputs('', ''),
1060 $html
1063 //validate 2: getHtmlForLoginInformationFields
1064 $this->assertStringContainsString(
1065 $this->serverPrivileges->getHtmlForLoginInformationFields('new'),
1066 $html
1069 //validate 3: Database for user
1070 $this->assertStringContainsString(
1071 __('Database for user'),
1072 $html
1075 $this->assertStringContainsString(
1076 __('Grant all privileges on wildcard name (username\\_%).'),
1077 $html
1079 $this->assertStringContainsString('<input type="checkbox" name="createdb-2" id="createdb-2">', $html);
1081 //validate 4: getHtmlToDisplayPrivilegesTable
1082 $this->assertStringContainsString(
1083 $this->serverPrivileges->getHtmlToDisplayPrivilegesTable('*', '*', false),
1084 $html
1087 //validate 5: button
1088 $this->assertStringContainsString(
1089 __('Go'),
1090 $html
1093 $GLOBALS['dbi'] = $dbi_old;
1094 $this->serverPrivileges->dbi = $dbi_old;
1098 * Test for getUserLink
1100 public function testGetUserLink(): void
1102 $username = 'pma_username';
1103 $hostname = 'pma_hostname';
1104 $dbname = 'pma_dbname';
1105 $tablename = 'pma_tablename';
1107 $html = $this->serverPrivileges->getUserLink('edit', $username, $hostname, $dbname, $tablename, '');
1109 $dbname = 'pma_dbname';
1110 $url_html = Url::getCommon([
1111 'username' => $username,
1112 'hostname' => $hostname,
1113 'dbname' => $dbname,
1114 'tablename' => $tablename,
1115 'routinename' => '',
1116 ], '');
1117 $this->assertStringContainsString($url_html, $html);
1118 $this->assertStringContainsString(
1119 __('Edit privileges'),
1120 $html
1123 $dbname = 'pma_dbname';
1124 $html = $this->serverPrivileges->getUserLink('revoke', $username, $hostname, $dbname, $tablename, '');
1126 $dbname = 'pma_dbname';
1127 $url_html = Url::getCommon(
1129 'username' => $username,
1130 'hostname' => $hostname,
1131 'dbname' => $dbname,
1132 'tablename' => $tablename,
1133 'routinename' => '',
1134 'revokeall' => 1,
1138 $this->assertStringContainsString($url_html, $html);
1139 $this->assertStringContainsString(
1140 __('Revoke'),
1141 $html
1144 $html = $this->serverPrivileges->getUserLink('export', $username, $hostname);
1146 $url_html = Url::getCommon([
1147 'username' => $username,
1148 'hostname' => $hostname,
1149 'initial' => '',
1150 'export' => 1,
1151 ], '');
1152 $this->assertStringContainsString($url_html, $html);
1153 $this->assertStringContainsString(
1154 __('Export'),
1155 $html
1160 * Test for getUserLink
1162 public function testGetUserLinkWildcardsEscaped(): void
1164 $username = 'pma\_username';
1165 $hostname = 'pma\_hostname';
1166 $dbname = 'pma\_dbname';
1167 $tablename = 'pma\_tablename';
1169 $html = $this->serverPrivileges->getUserLink('edit', $username, $hostname, $dbname, $tablename, '');
1171 $dbname = 'pma\_dbname';
1172 $url_html = Url::getCommon([
1173 'username' => $username,
1174 'hostname' => $hostname,
1175 'dbname' => $dbname,
1176 'tablename' => $tablename,
1177 'routinename' => '',
1178 ], '');
1179 $this->assertStringContainsString($url_html, $html);
1180 $this->assertStringContainsString(
1181 __('Edit privileges'),
1182 $html
1185 $dbname = 'pma\_dbname';
1186 $html = $this->serverPrivileges->getUserLink('revoke', $username, $hostname, $dbname, $tablename, '');
1188 $dbname = 'pma\_dbname';
1189 $url_html = Url::getCommon(
1191 'username' => $username,
1192 'hostname' => $hostname,
1193 'dbname' => $dbname,
1194 'tablename' => $tablename,
1195 'routinename' => '',
1196 'revokeall' => 1,
1200 $this->assertStringContainsString($url_html, $html);
1201 $this->assertStringContainsString(
1202 __('Revoke'),
1203 $html
1206 $html = $this->serverPrivileges->getUserLink('export', $username, $hostname);
1208 $url_html = Url::getCommon([
1209 'username' => $username,
1210 'hostname' => $hostname,
1211 'initial' => '',
1212 'export' => 1,
1213 ], '');
1214 $this->assertStringContainsString($url_html, $html);
1215 $this->assertStringContainsString(
1216 __('Export'),
1217 $html
1222 * Test for getExtraDataForAjaxBehavior
1224 public function testGetExtraDataForAjaxBehavior(): void
1226 $password = 'pma_password';
1227 $sql_query = 'pma_sql_query';
1228 $username = 'pma_username';
1229 $hostname = 'pma_hostname';
1230 $GLOBALS['dbname'] = 'pma_dbname';
1231 $_POST['adduser_submit'] = 'adduser_submit';
1232 $_POST['username'] = 'username';
1233 $_POST['change_copy'] = 'change_copy';
1234 $_GET['validate_username'] = 'validate_username';
1235 $_GET['username'] = 'username';
1236 $_POST['update_privs'] = 'update_privs';
1238 $extra_data = $this->serverPrivileges->getExtraDataForAjaxBehavior($password, $sql_query, $hostname, $username);
1240 //user_exists
1241 $this->assertFalse($extra_data['user_exists']);
1243 //db_wildcard_privs
1244 $this->assertTrue($extra_data['db_wildcard_privs']);
1246 //user_exists
1247 $this->assertFalse($extra_data['db_specific_privs']);
1249 //new_user_initial
1250 $this->assertEquals('P', $extra_data['new_user_initial']);
1252 //sql_query
1253 $this->assertEquals(
1254 Generator::getMessage('', $sql_query),
1255 $extra_data['sql_query']
1258 //new_user_string
1259 $this->assertStringContainsString(
1260 htmlspecialchars($hostname),
1261 $extra_data['new_user_string']
1263 $this->assertStringContainsString(
1264 htmlspecialchars($username),
1265 $extra_data['new_user_string']
1268 //new_privileges
1269 $this->assertStringContainsString(
1270 implode(', ', $this->serverPrivileges->extractPrivInfo(null, true)),
1271 $extra_data['new_privileges']
1276 * Test for getUserGroupForUser
1278 public function testGetUserGroupForUser(): void
1280 $username = 'pma_username';
1282 $dbi_old = $GLOBALS['dbi'];
1283 $dbi = $this->getMockBuilder(DatabaseInterface::class)
1284 ->disableOriginalConstructor()
1285 ->getMock();
1286 $expected_userGroup = 'pma_usergroup';
1288 $dbi->expects($this->any())->method('fetchValue')
1289 ->will($this->returnValue($expected_userGroup));
1290 $dbi->expects($this->any())
1291 ->method('escapeString')
1292 ->will($this->returnArgument(0));
1294 $GLOBALS['dbi'] = $dbi;
1295 $this->serverPrivileges->dbi = $dbi;
1297 $returned_userGroup = $this->serverPrivileges->getUserGroupForUser($username);
1299 $this->assertEquals($expected_userGroup, $returned_userGroup);
1301 $GLOBALS['dbi'] = $dbi_old;
1302 $this->serverPrivileges->dbi = $dbi_old;
1306 * Test for getUsersOverview
1308 public function testGetUsersOverview(): void
1310 $resultStub = $this->createMock(DummyResult::class);
1311 $db_rights = [];
1312 $text_dir = 'text_dir';
1314 $html = $this->serverPrivileges->getUsersOverview($resultStub, $db_rights, $text_dir);
1316 //Url::getHiddenInputs
1317 $this->assertStringContainsString(
1318 Url::getHiddenInputs('', ''),
1319 $html
1322 //items
1323 $this->assertStringContainsString(
1324 __('User'),
1325 $html
1327 $this->assertStringContainsString(
1328 __('Host'),
1329 $html
1331 $this->assertStringContainsString(
1332 __('Password'),
1333 $html
1335 $this->assertStringContainsString(
1336 __('Global privileges'),
1337 $html
1340 //Util::showHint
1341 $this->assertStringContainsString(
1342 Generator::showHint(
1343 __('Note: MySQL privilege names are expressed in English.')
1345 $html
1348 //__('User group')
1349 $this->assertStringContainsString(
1350 __('User group'),
1351 $html
1353 $this->assertStringContainsString(
1354 __('Grant'),
1355 $html
1357 $this->assertStringContainsString(
1358 __('Action'),
1359 $html
1362 //$text_dir
1363 $this->assertStringContainsString($text_dir, $html);
1365 $this->assertStringContainsString(
1366 Url::getCommon(['adduser' => 1], ''),
1367 $html
1370 //labels
1371 $this->assertStringContainsString(
1372 __('Add user account'),
1373 $html
1375 $this->assertStringContainsString(
1376 __('Remove selected user accounts'),
1377 $html
1379 $this->assertStringContainsString(
1380 __('Drop the databases that have the same names as the users.'),
1381 $html
1383 $this->assertStringContainsString(
1384 __('Drop the databases that have the same names as the users.'),
1385 $html
1390 * Test for getDataForDeleteUsers
1392 public function testGetDataForDeleteUsers(): void
1394 $_POST['change_copy'] = 'change_copy';
1395 $_POST['old_hostname'] = 'old_hostname';
1396 $_POST['old_username'] = 'old_username';
1397 $_SESSION['relation'] = [];
1398 $_SESSION['relation'][$GLOBALS['server']] = RelationParameters::fromArray([])->toArray();
1400 $queries = [];
1402 $ret = $this->serverPrivileges->getDataForDeleteUsers($queries);
1404 $item = [
1405 "# Deleting 'old_username'@'old_hostname' ...",
1406 "DROP USER 'old_username'@'old_hostname';",
1408 $this->assertEquals($item, $ret);
1412 * Test for getAddUserHtmlFieldset
1414 public function testGetAddUserHtmlFieldset(): void
1416 $html = $this->serverPrivileges->getAddUserHtmlFieldset();
1418 $this->assertStringContainsString(
1419 Url::getCommon(['adduser' => 1], ''),
1420 $html
1422 $this->assertStringContainsString(
1423 Generator::getIcon('b_usradd'),
1424 $html
1426 $this->assertStringContainsString(
1427 __('Add user'),
1428 $html
1433 * Test for getHtmlHeaderForUserProperties
1435 public function testGetHtmlHeaderForUserProperties(): void
1437 $dbname_is_wildcard = true;
1438 $url_dbname = 'url_dbname';
1439 $dbname = 'dbname';
1440 $username = 'username';
1441 $hostname = 'hostname';
1442 $tablename = 'tablename';
1443 $_REQUEST['tablename'] = 'tablename';
1445 // $this->serverPrivileges->dbi->expects($this->once())->method('tryQuery')->with
1447 $html = $this->serverPrivileges->getHtmlForUserProperties(
1448 $dbname_is_wildcard,
1449 $url_dbname,
1450 $username,
1451 $hostname,
1452 $tablename,
1453 $_REQUEST['tablename']
1456 //title
1457 $this->assertStringContainsString(
1458 __('Edit privileges:'),
1459 $html
1461 $this->assertStringContainsString(
1462 __('User account'),
1463 $html
1466 //Url::getCommon
1467 $item = Url::getCommon([
1468 'username' => $username,
1469 'hostname' => $hostname,
1470 'dbname' => '',
1471 'tablename' => '',
1472 ], '');
1473 $this->assertStringContainsString($item, $html);
1475 //$username & $hostname
1476 $this->assertStringContainsString(
1477 htmlspecialchars($username),
1478 $html
1480 $this->assertStringContainsString(
1481 htmlspecialchars($hostname),
1482 $html
1485 //$dbname_is_wildcard = true
1486 $this->assertStringContainsString(
1487 __('Databases'),
1488 $html
1491 //$dbname_is_wildcard = true
1492 $this->assertStringContainsString(
1493 __('Databases'),
1494 $html
1497 //Url::getCommon
1498 $item = Url::getCommon([
1499 'username' => $username,
1500 'hostname' => $hostname,
1501 'dbname' => $url_dbname,
1502 'tablename' => '',
1503 ], '');
1504 $this->assertStringContainsString($item, $html);
1505 $this->assertStringContainsString($dbname, $html);
1509 * Tests for getHtmlForViewUsersError
1511 public function testGetHtmlForViewUsersError(): void
1513 $this->assertStringContainsString(
1514 'Not enough privilege to view users.',
1515 $this->serverPrivileges->getHtmlForViewUsersError()
1520 * Tests for getHtmlForUserProperties
1522 public function testGetHtmlForUserProperties(): void
1524 $this->dummyDbi->addResult(
1525 'SELECT \'1\' FROM `mysql`.`user` WHERE `User` = \'user\' AND `Host` = \'host\';',
1526 [['1']],
1527 ['1']
1529 $this->dummyDbi->addResult(
1530 'SELECT `Table_priv` FROM `mysql`.`tables_priv` WHERE `User` = \'user\' AND `Host` = \'host\''
1531 . ' AND `Db` = \'sakila\' AND `Table_name` = \'actor\';',
1533 ['Table_priv']
1535 $this->dummyDbi->addResult(
1536 'SHOW COLUMNS FROM `sakila`.`actor`;',
1538 ['actor_id', 'smallint(5) unsigned', 'NO', 'PRI', null, 'auto_increment'],
1539 ['first_name', 'varchar(45)', 'NO', '', null, ''],
1540 ['last_name', 'varchar(45)', 'NO', 'MUL', null, ''],
1541 ['last_update', 'timestamp', 'NO', '', 'current_timestamp()', 'on update current_timestamp()'],
1543 ['Field', 'Type', 'Null', 'Key', 'Default', 'Extra']
1545 $this->dummyDbi->addResult(
1546 'SELECT `Column_name`, `Column_priv` FROM `mysql`.`columns_priv` WHERE `User` = \'user\''
1547 . ' AND `Host` = \'host\' AND `Db` = \'sakila\' AND `Table_name` = \'actor\';',
1549 ['Column_name', 'Column_priv']
1552 $relation = new Relation($this->dbi);
1553 $serverPrivileges = new Privileges(
1554 new Template(),
1555 $this->dbi,
1556 $relation,
1557 new RelationCleanup($this->dbi, $relation),
1558 new Plugins($this->dbi)
1561 $GLOBALS['username'] = 'user';
1562 $GLOBALS['hostname'] = 'host';
1564 $actual = $serverPrivileges->getHtmlForUserProperties(false, 'sakila', 'user', 'host', 'sakila', 'actor');
1565 $this->assertStringContainsString('addUsersForm', $actual);
1566 $this->assertStringContainsString('SELECT', $actual);
1567 $this->assertStringContainsString('Allows reading data.', $actual);
1568 $this->assertStringContainsString('INSERT', $actual);
1569 $this->assertStringContainsString('Allows inserting and replacing data.', $actual);
1570 $this->assertStringContainsString('UPDATE', $actual);
1571 $this->assertStringContainsString('Allows changing data.', $actual);
1572 $this->assertStringContainsString('DELETE', $actual);
1573 $this->assertStringContainsString('Allows deleting data.', $actual);
1574 $this->assertStringContainsString('CREATE', $actual);
1575 $this->assertStringContainsString('Allows creating new tables.', $actual);
1577 $this->assertStringContainsString(
1578 Url::getHiddenInputs(),
1579 $actual
1582 //$username & $hostname
1583 $this->assertStringContainsString('user', $actual);
1584 $this->assertStringContainsString('host', $actual);
1586 //Create a new user with the same privileges
1587 $this->assertStringContainsString('Create a new user account with the same privileges', $actual);
1589 $this->assertStringContainsString(
1590 __('Database'),
1591 $actual
1593 $this->assertStringContainsString(
1594 Util::getScriptNameForOption(
1595 $GLOBALS['cfg']['DefaultTabDatabase'],
1596 'database'
1598 $actual
1600 $item = Url::getCommon([
1601 'db' => 'sakila',
1602 'reload' => 1,
1603 ], '');
1604 $this->assertStringContainsString($item, $actual);
1605 $this->assertStringContainsString('sakila', $actual);
1607 //$tablename
1608 $this->assertStringContainsString(
1609 __('Table'),
1610 $actual
1612 $this->assertStringContainsString(
1613 Util::getScriptNameForOption(
1614 $GLOBALS['cfg']['DefaultTabTable'],
1615 'table'
1617 $actual
1619 $item = Url::getCommon([
1620 'db' => 'sakila',
1621 'table' => 'actor',
1622 'reload' => 1,
1623 ], '');
1624 $this->assertStringContainsString($item, $actual);
1625 $this->assertStringContainsString('table', $actual);
1626 $item = Util::getTitleForTarget($GLOBALS['cfg']['DefaultTabTable']);
1627 $this->assertStringContainsString((string) $item, $actual);
1631 * Tests for getHtmlForUserOverview
1633 public function testGetHtmlForUserOverview(): void
1635 $_REQUEST = ['ajax_page_request' => '1'];
1636 $actual = $this->serverPrivileges->getHtmlForUserOverview('ltr');
1637 $this->assertStringContainsString('Note: MySQL privilege names are expressed in English.', $actual);
1638 $this->assertStringContainsString(
1639 'Note: phpMyAdmin gets the users’ privileges directly from MySQL’s privilege tables.',
1640 $actual
1645 * Tests for getHtmlForAllTableSpecificRights
1647 public function testGetHtmlForAllTableSpecificRights(): void
1649 // Test case 1
1650 $actual = $this->serverPrivileges->getHtmlForAllTableSpecificRights('pma', 'host', 'table', 'pmadb');
1651 $this->assertStringContainsString('<input type="hidden" name="username" value="pma">', $actual);
1652 $this->assertStringContainsString('<input type="hidden" name="hostname" value="host">', $actual);
1653 $this->assertStringContainsString('<legend data-submenu-label="Table">', $actual);
1654 $this->assertStringContainsString('Table-specific privileges', $actual);
1656 // Test case 2
1657 $GLOBALS['dblist'] = new stdClass();
1658 $GLOBALS['dblist']->databases = [
1659 'x',
1660 'y',
1661 'z',
1663 $actual = $this->serverPrivileges->getHtmlForAllTableSpecificRights('pma2', 'host2', 'database', '');
1664 $this->assertStringContainsString('<legend data-submenu-label="Database">', $actual);
1665 $this->assertStringContainsString('Database-specific privileges', $actual);
1669 * Tests for getHtmlForInitials
1671 public function testGetHtmlForInitials(): void
1673 // Setup for the test
1674 $dbi = $this->getMockBuilder(DatabaseInterface::class)
1675 ->disableOriginalConstructor()
1676 ->getMock();
1677 $resultStub = $this->createMock(DummyResult::class);
1679 $dbi->expects($this->once())
1680 ->method('tryQuery')
1681 ->will($this->returnValue($resultStub));
1682 $resultStub->expects($this->atLeastOnce())
1683 ->method('fetchRow')
1684 ->will($this->onConsecutiveCalls(['-'], []));
1685 $this->serverPrivileges->dbi = $dbi;
1687 $actual = $this->serverPrivileges->getHtmlForInitials(['"' => true]);
1688 $this->assertStringContainsString(
1689 '<a class="page-link" href="#" tabindex="-1" aria-disabled="true">A</a>',
1690 $actual
1692 $this->assertStringContainsString(
1693 '<a class="page-link" href="#" tabindex="-1" aria-disabled="true">Z</a>',
1694 $actual
1696 $this->assertStringContainsString(
1697 '<a class="page-link" href="index.php?route=/server/privileges&initial=-&lang=en">-</a>',
1698 $actual
1700 $this->assertStringContainsString(
1701 '<a class="page-link" href="index.php?route=/server/privileges&initial=%22&lang=en">&quot;</a>',
1702 $actual
1704 $this->assertStringContainsString('Show all', $actual);
1708 * Tests for getDbRightsForUserOverview
1710 public function testGetDbRightsForUserOverview(): void
1712 $resultStub = $this->createMock(DummyResult::class);
1714 //Mock DBI
1715 $dbi = $this->getMockBuilder(DatabaseInterface::class)
1716 ->disableOriginalConstructor()
1717 ->getMock();
1718 $dbi->expects($this->any())
1719 ->method('query')
1720 ->will($this->returnValue($resultStub));
1721 $dbi->expects($this->any())
1722 ->method('fetchResult')
1723 ->will($this->returnValue(['db', 'columns_priv']));
1724 $resultStub->expects($this->any())
1725 ->method('fetchAssoc')
1726 ->will(
1727 $this->onConsecutiveCalls(
1729 'User' => 'pmauser',
1730 'Host' => 'local',
1735 $dbi->expects($this->any())
1736 ->method('escapeString')
1737 ->will($this->returnArgument(0));
1739 $_GET['initial'] = 'A';
1740 $GLOBALS['dbi'] = $dbi;
1741 $this->serverPrivileges->dbi = $dbi;
1743 $expected = [
1744 'pmauser' => [
1745 'local' => [
1746 'User' => 'pmauser',
1747 'Host' => 'local',
1748 'Password' => '?',
1749 'Grant_priv' => 'N',
1750 'privs' => ['USAGE'],
1754 $actual = $this->serverPrivileges->getDbRightsForUserOverview();
1755 $this->assertEquals($expected, $actual);
1759 * Tests for deleteUser
1761 public function testDeleteUser(): void
1763 $resultStub = $this->createMock(DummyResult::class);
1765 //Mock DBI
1766 $dbi = $this->getMockBuilder(DatabaseInterface::class)
1767 ->disableOriginalConstructor()
1768 ->getMock();
1769 $dbi->expects($this->any())
1770 ->method('tryQuery')
1771 ->will($this->onConsecutiveCalls($resultStub, $resultStub, false));
1772 $dbi->expects($this->any())
1773 ->method('getError')
1774 ->will($this->returnValue('Some error occurred!'));
1775 $dbi->expects($this->any())
1776 ->method('escapeString')
1777 ->will($this->returnArgument(0));
1779 $GLOBALS['dbi'] = $dbi;
1780 $this->serverPrivileges->dbi = $dbi;
1782 // Test case 1 : empty queries
1783 $queries = [];
1784 $actual = $this->serverPrivileges->deleteUser($queries);
1785 $this->assertArrayHasKey(0, $actual);
1786 $this->assertArrayHasKey(1, $actual);
1787 $this->assertEquals('', $actual[0]);
1788 $this->assertEquals(
1789 'No users selected for deleting!',
1790 $actual[1]->getMessage()
1793 // Test case 2 : all successful queries
1794 $_POST['mode'] = 3;
1795 $queries = ['foo'];
1796 $actual = $this->serverPrivileges->deleteUser($queries);
1797 $this->assertArrayHasKey(0, $actual);
1798 $this->assertArrayHasKey(1, $actual);
1799 $this->assertEquals("foo\n# Reloading the privileges …\nFLUSH PRIVILEGES;", $actual[0]);
1800 $this->assertEquals(
1801 'The selected users have been deleted successfully.',
1802 $actual[1]->getMessage()
1805 // Test case 3 : failing queries
1806 $_POST['mode'] = 1;
1807 $queries = ['bar'];
1808 $actual = $this->serverPrivileges->deleteUser($queries);
1809 $this->assertArrayHasKey(0, $actual);
1810 $this->assertArrayHasKey(1, $actual);
1811 $this->assertEquals('bar', $actual[0]);
1812 $this->assertEquals(
1813 'Some error occurred!' . "\n",
1814 $actual[1]->getMessage()
1818 public function testGetFormForChangePassword(): void
1820 global $route;
1822 $username = 'pma_username';
1823 $hostname = 'pma_hostname';
1824 $route = '/server/privileges';
1826 $html = $this->serverPrivileges->getFormForChangePassword($username, $hostname, false);
1828 $this->assertStringContainsString(
1829 Url::getFromRoute('/server/privileges'),
1830 $html
1833 //Url::getHiddenInputs
1834 $this->assertStringContainsString(
1835 Url::getHiddenInputs(),
1836 $html
1839 //$username & $hostname
1840 $this->assertStringContainsString(
1841 htmlspecialchars($username),
1842 $html
1844 $this->assertStringContainsString(
1845 htmlspecialchars($hostname),
1846 $html
1849 //labels
1850 $this->assertStringContainsString(
1851 __('Change password'),
1852 $html
1854 $this->assertStringContainsString(
1855 __('No Password'),
1856 $html
1858 $this->assertStringContainsString(
1859 __('Password:'),
1860 $html
1862 $this->assertStringContainsString(
1863 __('Password:'),
1864 $html
1868 public function testGetUserPrivileges(): void
1870 $mysqliResultStub = $this->createMock(mysqli_result::class);
1871 $mysqliStmtStub = $this->createMock(mysqli_stmt::class);
1872 $mysqliStmtStub->expects($this->exactly(2))->method('bind_param')->willReturn(true);
1873 $mysqliStmtStub->expects($this->exactly(2))->method('execute')->willReturn(true);
1874 $mysqliStmtStub->expects($this->exactly(2))
1875 ->method('get_result')
1876 ->willReturn($mysqliResultStub);
1878 $dbi = $this->createMock(DatabaseInterface::class);
1879 $dbi->expects($this->once())->method('isMariaDB')->willReturn(true);
1880 $dbi->expects($this->exactly(2))
1881 ->method('prepare')
1882 ->withConsecutive(
1883 [$this->equalTo('SELECT * FROM `mysql`.`user` WHERE `User` = ? AND `Host` = ?;')],
1884 [$this->equalTo('SELECT * FROM `mysql`.`global_priv` WHERE `User` = ? AND `Host` = ?;')]
1886 ->willReturn($mysqliStmtStub);
1887 $mysqliResultStub->expects($this->exactly(2))
1888 ->method('fetch_assoc')
1889 ->willReturnOnConsecutiveCalls(
1890 ['Host' => 'test.host', 'User' => 'test.user'],
1891 ['Host' => 'test.host', 'User' => 'test.user', 'Priv' => '{"account_locked":true}']
1894 $relation = new Relation($this->dbi);
1895 $serverPrivileges = new Privileges(
1896 new Template(),
1897 $dbi,
1898 $relation,
1899 new RelationCleanup($this->dbi, $relation),
1900 new Plugins($this->dbi)
1902 $method = new ReflectionMethod(Privileges::class, 'getUserPrivileges');
1903 $method->setAccessible(true);
1905 /** @var array|null $actual */
1906 $actual = $method->invokeArgs($serverPrivileges, ['test.user', 'test.host', true]);
1908 $this->assertEquals(['Host' => 'test.host', 'User' => 'test.user', 'account_locked' => 'Y'], $actual);