From 448c8c393a193020d506bc445b9e45afeda668bd Mon Sep 17 00:00:00 2001 From: Loek Hilgersom <loek@netcoop.nl> Date: Tue, 19 Apr 2016 16:42:14 +0200 Subject: [PATCH] [TASK] Doctrine: migrate ext:felogin Resolves: #75781 Releases: master Change-Id: Iffdf7512bcc83a05c89e057ef7e7695b0ac1cb85 Reviewed-on: https://review.typo3.org/47814 Reviewed-by: Morton Jonuschat <m.jonuschat@mojocode.de> Reviewed-by: Daniel Goerz <ervaude@gmail.com> Tested-by: Daniel Goerz <ervaude@gmail.com> Reviewed-by: Frank Naegler <frank.naegler@typo3.org> Tested-by: Frank Naegler <frank.naegler@typo3.org> --- .../Controller/FrontendLoginController.php | 116 +++++++++++++----- .../FrontendLoginControllerTest.php | 61 +++++---- 2 files changed, 122 insertions(+), 55 deletions(-) diff --git a/typo3/sysext/felogin/Classes/Controller/FrontendLoginController.php b/typo3/sysext/felogin/Classes/Controller/FrontendLoginController.php index 9eea3c6cd8b6..4571b18e7ab2 100644 --- a/typo3/sysext/felogin/Classes/Controller/FrontendLoginController.php +++ b/typo3/sysext/felogin/Classes/Controller/FrontendLoginController.php @@ -15,6 +15,8 @@ namespace TYPO3\CMS\Felogin\Controller; */ use TYPO3\CMS\Core\Crypto\Random; +use TYPO3\CMS\Core\Database\ConnectionPool; +use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\StringUtility; @@ -225,17 +227,30 @@ class FrontendLoginController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin $postedHash = $postData['forgot_hash']; $hashData = $this->frontendController->fe_user->getKey('ses', 'forgot_hash'); if ($postedHash === $hashData['forgot_hash']) { - $row = false; - // Look for user record - $data = $this->databaseConnection->fullQuoteStr($this->piVars['forgot_email'], 'fe_users'); - $res = $this->databaseConnection->exec_SELECTquery( - 'uid, username, password, email', - 'fe_users', - '(email=' . $data . ' OR username=' . $data . ') AND pid IN (' . $this->databaseConnection->cleanIntList($this->spid) . ') ' . $this->cObj->enableFields('fe_users') - ); - if ($this->databaseConnection->sql_num_rows($res)) { - $row = $this->databaseConnection->sql_fetch_assoc($res); - } + + /** @var QueryBuilder $queryBuilder */ + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('fe_users'); + $row = $queryBuilder + ->select('uid', 'username', 'password', 'email') + ->from('fe_users') + ->where( + $queryBuilder->expr()->andX( + $queryBuilder->expr()->orX( + $queryBuilder->expr()->eq( + 'email', + $queryBuilder->createNamedParameter($this->piVars['forgot_email']) + ), + $queryBuilder->expr()->eq( + 'username', + $queryBuilder->createNamedParameter($this->piVars['forgot_email']) + ) + ), + $queryBuilder->expr()->in('pid', GeneralUtility::intExplode(',', $this->spid)) + ) + ) + ->execute() + ->fetch(); + $error = null; if ($row) { // Generate an email with the hashed link @@ -349,12 +364,17 @@ class FrontendLoginController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin } $newPass = $_params['newPassword']; } + // Save new password and clear DB-hash - $res = $this->databaseConnection->exec_UPDATEquery( - 'fe_users', - 'uid=' . $user['uid'], - array('password' => $newPass, 'felogin_forgotHash' => '', 'tstamp' => $GLOBALS['EXEC_TIME']) - ); + /** @var QueryBuilder $queryBuilder */ + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('fe_users'); + $queryBuilder->update('fe_users') + ->set('password', $newPass) + ->set('felogin_forgotHash', '') + ->set('tstamp', $GLOBALS['EXEC_TIME']) + ->where($queryBuilder->expr()->eq('uid', (int)$user['uid'])) + ->execute(); + $markerArray['###STATUS_MESSAGE###'] = $this->getDisplayText( 'change_password_done_message', $this->conf['changePasswordDoneMessage_stdWrap.'] @@ -401,8 +421,15 @@ class FrontendLoginController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin $hash = md5(GeneralUtility::makeInstance(Random::class)->generateRandomBytes(64)); $randHash = $validEnd . '|' . $hash; $randHashDB = $validEnd . '|' . md5($hash); + // Write hash to DB - $res = $this->databaseConnection->exec_UPDATEquery('fe_users', 'uid=' . $user['uid'], array('felogin_forgotHash' => $randHashDB)); + /** @var QueryBuilder $queryBuilder */ + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('fe_users'); + $queryBuilder->update('fe_users') + ->set('felogin_forgotHash', (string)$randHashDB) + ->where($queryBuilder->expr()->eq('uid', (int)$user['uid'])) + ->execute(); + // Send hashlink to user $this->conf['linkPrefix'] = -1; $isAbsRefPrefix = !empty($this->frontendController->absRefPrefix); @@ -641,26 +668,52 @@ class FrontendLoginController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin // taken from dkd_redirect_at_login written by Ingmar Schlecht; database-field changed $groupData = $this->frontendController->fe_user->groupData; if (!empty($groupData['uid'])) { + // take the first group with a redirect page - $row = $this->databaseConnection->exec_SELECTgetSingleRow( - 'felogin_redirectPid', - $this->frontendController->fe_user->usergroup_table, - 'felogin_redirectPid<>\'\' AND uid IN (' . implode(',', $groupData['uid']) . ')' - ); + $userGroupTable = $this->frontendController->fe_user->usergroup_table; + /** @var QueryBuilder $queryBuilder */ + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($userGroupTable); + $row = $queryBuilder + ->select('felogin_redirectPid') + ->from($userGroupTable) + ->where( + $queryBuilder->expr()->andX( + $queryBuilder->expr()->neq('felogin_redirectPid', $queryBuilder->quote('')), + $queryBuilder->expr()->in('uid', implode(',', $groupData['uid'])) + ) + ) + ->execute() + ->fetch(); + if ($row) { $redirect_url[] = $this->pi_getPageLink($row['felogin_redirectPid']); } } break; case 'userLogin': - $row = $this->databaseConnection->exec_SELECTgetSingleRow( - 'felogin_redirectPid', - $this->frontendController->fe_user->user_table, - $this->frontendController->fe_user->userid_column . '=' . $this->frontendController->fe_user->user['uid'] . ' AND felogin_redirectPid<>\'\'' - ); + + $userTable = $this->frontendController->fe_user->user_table; + /** @var QueryBuilder $queryBuilder */ + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($userTable); + $row = $queryBuilder + ->select('felogin_redirectPid') + ->from($userTable) + ->where( + $queryBuilder->expr()->andX( + $queryBuilder->expr()->neq('felogin_redirectPid', $queryBuilder->quote('')), + $queryBuilder->expr()->eq( + $this->frontendController->fe_user->userid_column, + (int)$this->frontendController->fe_user->user['uid'] + ) + ) + ) + ->execute() + ->fetch(); + if ($row) { $redirect_url[] = $this->pi_getPageLink($row['felogin_redirectPid']); } + break; case 'login': if ($this->conf['redirectPageLogin']) { @@ -998,7 +1051,14 @@ class FrontendLoginController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin $host = $parsedUrl['host']; // Removes the last path segment and slash sequences like /// (if given): $path = preg_replace('#/+[^/]*$#', '', $parsedUrl['path']); - $localDomains = $this->databaseConnection->exec_SELECTgetRows('domainName', 'sys_domain', '1=1' . $this->cObj->enableFields('sys_domain')); + + /** @var QueryBuilder $queryBuilder */ + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_domain'); + $localDomains = $queryBuilder->select('domainName') + ->from('sys_domain') + ->execute() + ->fetchAll(); + if (is_array($localDomains)) { foreach ($localDomains as $localDomain) { // strip trailing slashes (if given) diff --git a/typo3/sysext/felogin/Tests/Unit/Controller/FrontendLoginControllerTest.php b/typo3/sysext/felogin/Tests/Unit/Controller/FrontendLoginControllerTest.php index 3b84fbac0fe0..0757f8bdf93a 100644 --- a/typo3/sysext/felogin/Tests/Unit/Controller/FrontendLoginControllerTest.php +++ b/typo3/sysext/felogin/Tests/Unit/Controller/FrontendLoginControllerTest.php @@ -14,6 +14,13 @@ namespace TYPO3\CMS\Felogin\Tests\Unit\Controller; * The TYPO3 project - inspiring people to share! */ +use Prophecy\Argument; +use Prophecy\Prophecy\ObjectProphecy; +use TYPO3\CMS\Core\Database\Connection; +use TYPO3\CMS\Core\Database\ConnectionPool; +use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder; +use TYPO3\CMS\Core\Database\Query\QueryBuilder; +use TYPO3\CMS\Core\Tests\Unit\Database\Mocks\MockPlatform; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; @@ -71,34 +78,34 @@ class FrontendLoginControllerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase */ protected function setUpDatabaseMock() { - $db = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, array('exec_SELECTgetRows')); - $db - ->expects($this->any()) - ->method('exec_SELECTgetRows') - ->will($this->returnCallback(array($this, 'getDomainRecordsCallback'))); - $this->accessibleFixture->_set('databaseConnection', $db); - } - - /** - * Callback method for pageIdCanBeDetermined test cases. - * Simulates TYPO3_DB->exec_SELECTgetRows(). - * - * @param string $fields - * @param string $table - * @param string $where - * @return mixed - * @see setUpDatabaseMock - */ - public function getDomainRecordsCallback($fields, $table, $where) - { - if ($table !== $this->testTableName) { - return false; - } - return array( - array('domainName' => 'domainhostname.tld'), - array('domainName' => 'otherhostname.tld/path'), - array('domainName' => 'sub.domainhostname.tld/path/') + /** @var Connection|ObjectProphecy $connection */ + $connection = $this->prophesize(Connection::class); + $connection->getDatabasePlatform()->willReturn(new MockPlatform()); + $connection->getExpressionBuilder()->willReturn(new ExpressionBuilder($connection->reveal())); + $connection->quoteIdentifier(Argument::cetera())->willReturnArgument(0); + + $queryBuilder = GeneralUtility::makeInstance( + QueryBuilder::class, + $connection->reveal(), + null, + new \Doctrine\DBAL\Query\QueryBuilder($connection->reveal()) ); + + /** @var \Doctrine\DBAL\Driver\Statement|ObjectProphecy $resultSet */ + $resultSet = $this->prophesize(\Doctrine\DBAL\Driver\Statement::class); + $resultSet->fetchAll()->willReturn([ + ['domainName' => 'domainhostname.tld'], + ['domainName' => 'otherhostname.tld/path'], + ['domainName' => 'sub.domainhostname.tld/path/'] + ]); + + /** @var ConnectionPool|ObjectProphecy $connectionPool */ + $connectionPool = $this->prophesize(ConnectionPool::class); + $connectionPool->getQueryBuilderForTable('sys_domain')->willReturn($queryBuilder); + GeneralUtility::addInstance(ConnectionPool::class, $connectionPool->reveal()); + + $connection->executeQuery('SELECT domainName FROM sys_domain', Argument::cetera()) + ->willReturn($resultSet->reveal()); } /** -- GitLab