-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
An _events_ user will be created and used on demand in order to allow execution of upgrade wizards within install tool.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* Copyright (C) 2023 Daniel Siepmann <[email protected]> | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; either version 2 | ||
* of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
* 02110-1301, USA. | ||
*/ | ||
|
||
namespace Wrm\Events\Updates; | ||
|
||
use Psr\Http\Message\ServerRequestInterface; | ||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; | ||
use TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory; | ||
use TYPO3\CMS\Core\Crypto\Random; | ||
use TYPO3\CMS\Core\Database\ConnectionPool; | ||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; | ||
use TYPO3\CMS\Core\Utility\GeneralUtility; | ||
|
||
/** | ||
* An backend user used by Update Wizards. | ||
* | ||
* That way they can use Data Handler no matter how they are executed, e.g. cli, or install tool. | ||
* That way edits also always have this user assigned. | ||
* | ||
* This was mostly copied from TYPO3 core CommandLineUserAuthentication. | ||
*/ | ||
class UserAuthentication extends BackendUserAuthentication | ||
{ | ||
/** | ||
* @var string | ||
*/ | ||
protected $username = '_events_'; | ||
|
||
public function __construct() | ||
{ | ||
if (!$this->isUserAllowedToLogin()) { | ||
throw new \RuntimeException('Login Error: TYPO3 is in maintenance mode at the moment. Only administrators are allowed access.', 1483971855); | ||
} | ||
$this->dontSetCookie = true; | ||
parent::__construct(); | ||
} | ||
|
||
public function start(ServerRequestInterface $request = null) | ||
Check failure on line 58 in Classes/Updates/UserAuthentication.php GitHub Actions / code-quality (7.2, ^10.4)
Check failure on line 58 in Classes/Updates/UserAuthentication.php GitHub Actions / code-quality (7.3, ^10.4)
|
||
{ | ||
// do nothing | ||
} | ||
|
||
public function checkAuthentication(ServerRequestInterface $request = null) | ||
Check failure on line 63 in Classes/Updates/UserAuthentication.php GitHub Actions / code-quality (7.2, ^10.4)
Check failure on line 63 in Classes/Updates/UserAuthentication.php GitHub Actions / code-quality (7.3, ^10.4)
|
||
{ | ||
// do nothing | ||
} | ||
|
||
public function authenticate() | ||
Check failure on line 68 in Classes/Updates/UserAuthentication.php GitHub Actions / code-quality (7.2, ^10.4)
Check failure on line 68 in Classes/Updates/UserAuthentication.php GitHub Actions / code-quality (7.3, ^10.4)
|
||
{ | ||
// check if a _events_ user exists, if not, create one | ||
$this->setBeUserByName($this->username); | ||
if (!$this->user['uid']) { | ||
Check failure on line 72 in Classes/Updates/UserAuthentication.php GitHub Actions / code-quality (7.2, ^10.4)
Check failure on line 72 in Classes/Updates/UserAuthentication.php GitHub Actions / code-quality (7.3, ^10.4)
|
||
// create a new BE user in the database | ||
if (!$this->checkIfEventUserExists()) { | ||
$this->createEventUser(); | ||
} else { | ||
throw new \RuntimeException('No backend user named "_events_" could be authenticated, maybe this user is "hidden"?', 1484050401); | ||
} | ||
$this->setBeUserByName($this->username); | ||
} | ||
if (!$this->user['uid']) { | ||
Check failure on line 81 in Classes/Updates/UserAuthentication.php GitHub Actions / code-quality (7.2, ^10.4)
Check failure on line 81 in Classes/Updates/UserAuthentication.php GitHub Actions / code-quality (7.3, ^10.4)
|
||
throw new \RuntimeException('No backend user named "_events_" could be created.', 1476107195); | ||
} | ||
// The groups are fetched and ready for permission checking in this initialization. | ||
$this->fetchGroupData(); | ||
$this->backendSetUC(); | ||
// activate this functionality for DataHandler | ||
$this->uc['recursiveDelete'] = true; | ||
} | ||
|
||
public function backendCheckLogin($proceedIfNoUserIsLoggedIn = false) | ||
Check failure on line 91 in Classes/Updates/UserAuthentication.php GitHub Actions / code-quality (7.2, ^10.4)
Check failure on line 91 in Classes/Updates/UserAuthentication.php GitHub Actions / code-quality (7.3, ^10.4)
|
||
{ | ||
$this->authenticate(); | ||
} | ||
|
||
/** | ||
* Determines whether a CLI backend user is allowed to access TYPO3. | ||
* Only when adminOnly is off (=0), and only allowed for admins and CLI users (=2) | ||
*/ | ||
public function isUserAllowedToLogin() | ||
{ | ||
return in_array((int)$GLOBALS['TYPO3_CONF_VARS']['BE']['adminOnly'], [0, 2], true); | ||
} | ||
|
||
protected function checkIfEventUserExists(): bool | ||
{ | ||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('be_users'); | ||
$queryBuilder->getRestrictions() | ||
->removeAll() | ||
->add(GeneralUtility::makeInstance(DeletedRestriction::class)); | ||
$count = $queryBuilder | ||
->count('*') | ||
->from('be_users') | ||
->where($queryBuilder->expr()->eq('username', $queryBuilder->createNamedParameter('_events_'))) | ||
->execute() | ||
->fetchColumn(0); | ||
return (bool)$count; | ||
} | ||
|
||
protected function createEventUser(): void | ||
{ | ||
$userFields = [ | ||
'username' => $this->username, | ||
'password' => $this->generateHashedPassword(), | ||
'admin' => 1, | ||
'tstamp' => $GLOBALS['EXEC_TIME'], | ||
'crdate' => $GLOBALS['EXEC_TIME'], | ||
]; | ||
|
||
$databaseConnection = GeneralUtility::makeInstance(ConnectionPool::class) | ||
->getConnectionForTable('be_users'); | ||
$databaseConnection->insert('be_users', $userFields); | ||
} | ||
|
||
protected function generateHashedPassword(): string | ||
{ | ||
$cryptoService = GeneralUtility::makeInstance(Random::class); | ||
$password = $cryptoService->generateRandomBytes(20); | ||
$hashInstance = GeneralUtility::makeInstance(PasswordHashFactory::class)->getDefaultHashInstance('BE'); | ||
return $hashInstance->getHashedPassword($password); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* Copyright (C) 2023 Daniel Siepmann <[email protected]> | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; either version 2 | ||
* of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
* 02110-1301, USA. | ||
*/ | ||
|
||
namespace Wrm\Events\Updates; | ||
|
||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; | ||
use TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory; | ||
use TYPO3\CMS\Core\Crypto\Random; | ||
use TYPO3\CMS\Core\Database\ConnectionPool; | ||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; | ||
use TYPO3\CMS\Core\Utility\GeneralUtility; | ||
use TYPO3\CMS\Core\Utility\VersionNumberUtility; | ||
|
||
/** | ||
* An backend user used by Update Wizards. | ||
* | ||
* That way they can use Data Handler no matter how they are executed, e.g. cli, or install tool. | ||
* That way edits also always have this user assigned. | ||
* | ||
* This was mostly copied from TYPO3 core CommandLineUserAuthentication. | ||
*/ | ||
class UserAuthenticationV10 extends BackendUserAuthentication | ||
{ | ||
/** | ||
* @var string | ||
*/ | ||
protected $username = '_events_'; | ||
|
||
public function __construct() | ||
{ | ||
if (!$this->isUserAllowedToLogin()) { | ||
throw new \RuntimeException('Login Error: TYPO3 is in maintenance mode at the moment. Only administrators are allowed access.', 1483971855); | ||
} | ||
$this->dontSetCookie = true; | ||
parent::__construct(); | ||
} | ||
|
||
public function start() | ||
Check failure on line 58 in Classes/Updates/UserAuthenticationV10.php GitHub Actions / code-quality (7.2, ^10.4)
Check failure on line 58 in Classes/Updates/UserAuthenticationV10.php GitHub Actions / code-quality (7.3, ^10.4)
|
||
{ | ||
// do nothing | ||
} | ||
|
||
public function checkAuthentication() | ||
Check failure on line 63 in Classes/Updates/UserAuthenticationV10.php GitHub Actions / code-quality (7.2, ^10.4)
Check failure on line 63 in Classes/Updates/UserAuthenticationV10.php GitHub Actions / code-quality (7.3, ^10.4)
|
||
{ | ||
// do nothing | ||
} | ||
|
||
public function authenticate() | ||
Check failure on line 68 in Classes/Updates/UserAuthenticationV10.php GitHub Actions / code-quality (7.2, ^10.4)
Check failure on line 68 in Classes/Updates/UserAuthenticationV10.php GitHub Actions / code-quality (7.3, ^10.4)
|
||
{ | ||
// check if a _events_ user exists, if not, create one | ||
$this->setBeUserByName($this->username); | ||
if (!$this->user['uid']) { | ||
Check failure on line 72 in Classes/Updates/UserAuthenticationV10.php GitHub Actions / code-quality (7.2, ^10.4)
Check failure on line 72 in Classes/Updates/UserAuthenticationV10.php GitHub Actions / code-quality (7.3, ^10.4)
|
||
// create a new BE user in the database | ||
if (!$this->checkIfCliUserExists()) { | ||
$this->createCliUser(); | ||
} else { | ||
throw new \RuntimeException('No backend user named "_events_" could be authenticated, maybe this user is "hidden"?', 1484050401); | ||
} | ||
$this->setBeUserByName($this->username); | ||
} | ||
if (!$this->user['uid']) { | ||
throw new \RuntimeException('No backend user named "_events_" could be created.', 1476107195); | ||
} | ||
// The groups are fetched and ready for permission checking in this initialization. | ||
$this->fetchGroupData(); | ||
$this->backendSetUC(); | ||
// activate this functionality for DataHandler | ||
$this->uc['recursiveDelete'] = true; | ||
} | ||
|
||
public function backendCheckLogin($proceedIfNoUserIsLoggedIn = false) | ||
{ | ||
$this->authenticate(); | ||
} | ||
|
||
/** | ||
* Determines whether a CLI backend user is allowed to access TYPO3. | ||
* Only when adminOnly is off (=0), and only allowed for admins and CLI users (=2) | ||
*/ | ||
protected function isUserAllowedToLogin(): bool | ||
{ | ||
return in_array((int)$GLOBALS['TYPO3_CONF_VARS']['BE']['adminOnly'], [0, 2], true); | ||
} | ||
|
||
protected function checkIfCliUserExists(): bool | ||
{ | ||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('be_users'); | ||
$queryBuilder->getRestrictions() | ||
->removeAll() | ||
->add(GeneralUtility::makeInstance(DeletedRestriction::class)); | ||
$count = $queryBuilder | ||
->count('*') | ||
->from('be_users') | ||
->where($queryBuilder->expr()->eq('username', $queryBuilder->createNamedParameter('_events_'))) | ||
->execute() | ||
->fetchColumn(0); | ||
return (bool)$count; | ||
} | ||
|
||
protected function createCliUser(): void | ||
{ | ||
$userFields = [ | ||
'username' => $this->username, | ||
'password' => $this->generateHashedPassword(), | ||
'admin' => 1, | ||
'tstamp' => $GLOBALS['EXEC_TIME'], | ||
'crdate' => $GLOBALS['EXEC_TIME'], | ||
]; | ||
|
||
$databaseConnection = GeneralUtility::makeInstance(ConnectionPool::class) | ||
->getConnectionForTable('be_users'); | ||
$databaseConnection->insert('be_users', $userFields); | ||
} | ||
|
||
protected function generateHashedPassword(): string | ||
{ | ||
$cryptoService = GeneralUtility::makeInstance(Random::class); | ||
$password = $cryptoService->generateRandomBytes(20); | ||
$hashInstance = GeneralUtility::makeInstance(PasswordHashFactory::class)->getDefaultHashInstance('BE'); | ||
return $hashInstance->getHashedPassword($password); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
3.4.1 | ||
===== | ||
|
||
Breaking | ||
-------- | ||
|
||
Nothing | ||
|
||
Features | ||
-------- | ||
|
||
Nothing | ||
|
||
Fixes | ||
----- | ||
|
||
* Do not break Upgrade Wizards in install tool. | ||
|
||
TYPO3 does not provide a BE_USER within install tool. | ||
That will break the Upgrade Wizards as they use DataHandler that relies on an existing backend user. | ||
This was not an issue on command line where _cli_ user will be created and used by TYPO3. | ||
The extension now adds an _events_ user as admin as well when necessary. | ||
|
||
Tasks | ||
----- | ||
|
||
Nothing | ||
|
||
Deprecation | ||
----------- | ||
|
||
Nothing |