diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 07f46e26d6..b0911321b6 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -11043,7 +11043,7 @@ parameters: - message: '#^Construct empty\(\) is not allowed\. Use more strict comparison\.$#' identifier: empty.notAllowed - count: 13 + count: 12 path: src/Server/Privileges.php - @@ -11079,7 +11079,7 @@ parameters: - message: '#^Only booleans are allowed in a negated boolean, PhpMyAdmin\\Dbal\\ResultInterface\|false given\.$#' identifier: booleanNot.exprNotBoolean - count: 13 + count: 11 path: src/Server/Privileges.php - diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 2d0515e404..64435116d4 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -7555,7 +7555,6 @@ - diff --git a/src/Controllers/Server/PrivilegesController.php b/src/Controllers/Server/PrivilegesController.php index f69aaac6b6..92de55b47d 100644 --- a/src/Controllers/Server/PrivilegesController.php +++ b/src/Controllers/Server/PrivilegesController.php @@ -10,6 +10,8 @@ use PhpMyAdmin\ConfigStorage\RelationCleanup; use PhpMyAdmin\Controllers\InvocableController; use PhpMyAdmin\Current; use PhpMyAdmin\Dbal\DatabaseInterface; +use PhpMyAdmin\Exceptions\UpdateAuthPluginFailure; +use PhpMyAdmin\Exceptions\UserPasswordUpdateFailure; use PhpMyAdmin\Html\Generator; use PhpMyAdmin\Http\Response; use PhpMyAdmin\Http\ServerRequest; @@ -262,11 +264,23 @@ final class PrivilegesController implements InvocableController * Updates the password */ if ($request->hasBodyParam('change_pw')) { - Current::$message = $serverPrivileges->updatePassword( - $errorUrl, - $serverPrivileges->username ?? '', - $serverPrivileges->hostname ?? '', - ); + try { + Current::$message = $serverPrivileges->updatePassword( + $serverPrivileges->username ?? '', + $serverPrivileges->hostname ?? '', + ); + } catch (UpdateAuthPluginFailure | UserPasswordUpdateFailure $exception) { + if ($request->isAjax()) { + $this->response->setRequestStatus(false); + $this->response->addJSON('message', $exception->getMessage()); + + return $this->response->response(); + } + + $this->response->addHTML($exception->getMessage() . Generator::getBackUrlHtml($errorUrl)); + + return $this->response->response(); + } } /** @@ -392,6 +406,8 @@ final class PrivilegesController implements InvocableController $this->response->addHTML($serverPrivileges->getHtmlForUserOverview( $userPrivileges, $request->getQueryParam('initial'), + $request->isAjax(), + $request->has('ajax_page_request'), )); } elseif ($routinename !== '') { $this->response->addHTML( diff --git a/src/Exceptions/UpdateAuthPluginFailure.php b/src/Exceptions/UpdateAuthPluginFailure.php new file mode 100644 index 0000000000..317657eb2f --- /dev/null +++ b/src/Exceptions/UpdateAuthPluginFailure.php @@ -0,0 +1,11 @@ +getUserHostCondition($username, $hostname) . ';'; // Update the plugin for the user - if (! $this->dbi->tryQuery($updatePluginQuery)) { - $errorMessage = Generator::mysqlDie( + if ($this->dbi->tryQuery($updatePluginQuery) === false) { + throw new UpdateAuthPluginFailure(Generator::mysqlDie( $this->dbi->getError(), $updatePluginQuery, false, - ); - - $response = ResponseRenderer::getInstance(); - if ($response->isAjax()) { - $response->setRequestStatus(false); - $response->addJSON('message', $errorMessage); - $response->callExit(); - } - - $response->addHTML($errorMessage . Generator::getBackUrlHtml($errorUrl)); - $response->callExit(); + )); } $this->dbi->tryQuery('FLUSH PRIVILEGES;'); @@ -886,22 +874,12 @@ class Privileges . '(' . $this->dbi->quoteString($_POST['pma_pw']) . ')'); } - if (! $this->dbi->tryQuery($localQuery)) { - $errorMessage = Generator::mysqlDie( + if ($this->dbi->tryQuery($localQuery) === false) { + throw new UserPasswordUpdateFailure(Generator::mysqlDie( $this->dbi->getError(), $sqlQuery, false, - ); - - $response = ResponseRenderer::getInstance(); - if ($response->isAjax()) { - $response->setRequestStatus(false); - $response->addJSON('message', $errorMessage); - $response->callExit(); - } - - $response->addHTML($errorMessage . Generator::getBackUrlHtml($errorUrl)); - $response->callExit(); + )); } // Flush privileges after successful password change @@ -2456,8 +2434,12 @@ class Privileges /** * Get HTML snippet for display user overview page */ - public function getHtmlForUserOverview(UserPrivileges $userPrivileges, string|null $initial): string - { + public function getHtmlForUserOverview( + UserPrivileges $userPrivileges, + string|null $initial, + bool $isAjax, + bool $isAjaxPageRequest, + ): string { $serverVersion = $this->dbi->getVersion(); $passwordColumn = Compatibility::isMySqlOrPerconaDb($this->dbi) && $serverVersion >= 50706 ? 'authentication_string' @@ -2481,8 +2463,7 @@ class Privileges $this->template->render('export_modal'); } - $response = ResponseRenderer::getInstance(); - if (! $response->isAjax() || ! empty($_REQUEST['ajax_page_request'])) { + if (! $isAjax || $isAjaxPageRequest) { if ($userPrivileges->isReload) { $flushnote = new Message( __( diff --git a/tests/unit/Server/PrivilegesTest.php b/tests/unit/Server/PrivilegesTest.php index 333a6b6ebe..a6306e5983 100644 --- a/tests/unit/Server/PrivilegesTest.php +++ b/tests/unit/Server/PrivilegesTest.php @@ -417,11 +417,10 @@ class PrivilegesTest extends AbstractTestCase $username = 'pma_username'; $hostname = 'pma_hostname'; - $errUrl = 'error.php'; $_POST['pma_pw'] = 'pma_pw'; $_POST['authentication_plugin'] = 'mysql_native_password'; - $message = $serverPrivileges->updatePassword($errUrl, $username, $hostname); + $message = $serverPrivileges->updatePassword($username, $hostname); self::assertSame( 'The password for \'pma_username\'@\'pma_hostname\' was changed successfully.', @@ -1570,8 +1569,7 @@ class PrivilegesTest extends AbstractTestCase $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface($dummyDbi)); - $_REQUEST = ['ajax_page_request' => '1']; - $actual = $serverPrivileges->getHtmlForUserOverview($userPrivileges, null); + $actual = $serverPrivileges->getHtmlForUserOverview($userPrivileges, null, false, true); $dummyDbi->assertAllQueriesConsumed(); self::assertStringContainsString('Note: MySQL privilege names are expressed in English.', $actual); self::assertStringContainsString( @@ -1592,7 +1590,7 @@ class PrivilegesTest extends AbstractTestCase ); $dummyDbi->addResult('SELECT 1 FROM `mysql`.`user`', false); $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface($dummyDbi)); - $html = $serverPrivileges->getHtmlForUserOverview($userPrivileges, null); + $html = $serverPrivileges->getHtmlForUserOverview($userPrivileges, null, false, true); self::assertStringContainsString( Url::getCommon(['adduser' => 1], ''), @@ -1620,7 +1618,7 @@ class PrivilegesTest extends AbstractTestCase ); $dummyDbi->addResult('SELECT 1 FROM `mysql`.`user`', [[1]]); $serverPrivileges = $this->getPrivileges($this->createDatabaseInterface($dummyDbi)); - $actual = $serverPrivileges->getHtmlForUserOverview($userPrivileges, null); + $actual = $serverPrivileges->getHtmlForUserOverview($userPrivileges, null, false, true); self::assertStringContainsString('Your privilege table structure seems to be older than' . ' this MySQL version!
'