Skip to content

Commit

Permalink
update for TYPO3 10.4
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian Eßl committed Mar 12, 2021
1 parent 6541de1 commit 74f7904
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 86 deletions.
37 changes: 37 additions & 0 deletions Classes/Authentication/AuthService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace ChristianEssl\Impersonate\Authentication;

use TYPO3\CMS\Core\Authentication\AuthenticationService;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class AuthService extends AuthenticationService
{
public function getUser()
{
$uid = (int)GeneralUtility::_GET('uid');
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('fe_users');
$queryBuilder
->select('*')
->from('fe_users')
->where($queryBuilder->expr()->eq(
'uid',
$queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
));

return $queryBuilder->execute()->fetch();
}

public function authUser(array $user): int
{
return (int) (GeneralUtility::_GET('route') === '/impersonate/login' &&
$GLOBALS['BE_USER'] instanceof BackendUserAuthentication &&
$GLOBALS['BE_USER']->isAdmin());
}

}
108 changes: 29 additions & 79 deletions Classes/Authentication/FrontendUserAuthenticator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,10 @@
***/

use ChristianEssl\Impersonate\Exception\NoAdminUserException;
use ChristianEssl\Impersonate\Utility\ConfigurationUtility;
use Psr\Log\NullLogger;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Error\Http\ServiceUnavailableException;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;

/**
* Logs in a frontend user without a password - use with care!
Expand All @@ -38,89 +34,43 @@ public function authenticate($uid)
if (!$this->isAdminUserLoggedIn()) {
throw new NoAdminUserException('Missing backend administrator authentication.');
}
$this->buildTSFE();
$this->loginFrontendUser($uid);
}

/**
* @todo: fix this for TYPO3 10
* Initializing the TypoScriptFrontendController this way is deprecated, but the new
* TypoScriptFrontendInitialization middleware is not production ready yet - fix this in TYPO3 10
*
* @throws ServiceUnavailableException
*/
protected function buildTSFE()
{
$rootPageId = ConfigurationUtility::getRootPageId();
$GLOBALS['TSFE'] = new TypoScriptFrontendController(null, $rootPageId, 0);

if (VersionNumberUtility::convertVersionNumberToInteger(TYPO3_version) >= 9000000) {
$GLOBALS['TSFE']->setLogger(new NullLogger());
}

$GLOBALS['TSFE']->connectToDB();
$GLOBALS['TSFE']->initFEuser();
$this->loginFrontendUser((int)$uid);
}

/**
* Login the frontend user
*
* @param integer $uid
* @param int $uid
*/
protected function loginFrontendUser($uid)
protected function loginFrontendUser(int $uid)
{
$GLOBALS['TSFE']->fe_user->is_permanent = false;
$GLOBALS['TSFE']->fe_user->checkPid = false;
$GLOBALS['TSFE']->fe_user->createUserSession(['uid' => $uid]);
$GLOBALS['TSFE']->fe_user->user = $GLOBALS['TSFE']->fe_user->fetchUserSession();
$GLOBALS['TSFE']->fe_user->fetchGroupData();
$GLOBALS['TSFE']->fe_user->forceSetCookie = false;
$GLOBALS['TSFE']->fe_user->setAndSaveSessionData('Authenticated via impersonate extension', true);
$this->setSessionCookie($GLOBALS['TSFE']->fe_user);
}
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addService(
'impersonate',
'auth',
\ChristianEssl\Impersonate\Authentication\AuthService::class,
[
'title' => 'Temporary AuthService for impersonating a user',
'description' => 'Temporary AuthService for impersonating a user',
'subtype' => 'authUserFE,getUserFE',
'available' => true,
'priority' => 100,
'quality' => 70,
'os' => '',
'exec' => '',
'className' => \ChristianEssl\Impersonate\Authentication\AuthService::class,
]
);

/**
* Set the session cookie after login (otherwise the login will fail on first time, if no session cookie exists yet)
*
* @param FrontendUserAuthentication $user
*/
protected function setSessionCookie(FrontendUserAuthentication $user)
{
$cookieDomain = $this->getCookieDomain($user);
$cookiePath = $cookieDomain ? '/' : GeneralUtility::getIndpEnv('TYPO3_SITE_PATH');
$cookieSecure = (bool)$GLOBALS['TYPO3_CONF_VARS']['SYS']['cookieSecure'] && GeneralUtility::getIndpEnv('TYPO3_SSL');
setcookie($user->name, $user->id, 0, $cookiePath, $cookieDomain, $cookieSecure, true);
}
$frontendUser = GeneralUtility::makeInstance(FrontendUserAuthentication::class);
$frontendUser->svConfig = [
'setup' => [
'FE_alwaysFetchUser' => true
]
];

/**
* Gets the domain to be used on setting cookies.
* Code taken from typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication
*
* @param FrontendUserAuthentication $user
*
* @return string The domain to be used on setting cookies
*/
protected function getCookieDomain(FrontendUserAuthentication $user)
{
$result = '';
$cookieDomain = $GLOBALS['TYPO3_CONF_VARS']['SYS']['cookieDomain'];
// If a specific cookie domain is defined for a given TYPO3_MODE,
// use that domain
if (!empty($GLOBALS['TYPO3_CONF_VARS'][$user->loginType]['cookieDomain'])) {
$cookieDomain = $GLOBALS['TYPO3_CONF_VARS'][$user->loginType]['cookieDomain'];
}
if ($cookieDomain) {
if ($cookieDomain[0] === '/') {
$match = [];
$matchCnt = @preg_match($cookieDomain, GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY'), $match);
if ($matchCnt) {
$result = $match[0];
}
} else {
$result = $cookieDomain;
}
}
return $result;
$frontendUser->start();
$frontendUser->unpack_uc();
$frontendUser->storeSessionData();
}

/**
Expand All @@ -131,4 +81,4 @@ protected function isAdminUserLoggedIn()
return $GLOBALS['BE_USER'] instanceof BackendUserAuthentication &&
$GLOBALS['BE_USER']->isAdmin();
}
}
}
3 changes: 1 addition & 2 deletions Classes/Controller/FrontendLoginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,13 @@ class FrontendLoginController
{
/**
* @param ServerRequestInterface $request
* @param ResponseInterface $response
*
* @return RedirectResponse
* @throws NoUserIdException
* @throws ServiceUnavailableException
* @throws NoAdminUserException
*/
public function loginAction(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
public function loginAction(ServerRequestInterface $request): ResponseInterface
{
$uid = (int) $request->getQueryParams()['uid'];

Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
"role": "Developer"
}
],
"version": "1.0.0",
"version": "1.1.0",
"require": {
"typo3/cms-core": "^8.7.0 || ^9.5.0 || ^10.4.0"
"typo3/cms-core": "^10.4.0"
},
"autoload": {
"psr-4": {
Expand Down
4 changes: 2 additions & 2 deletions ext_emconf.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
'uploadfolder' => 0,
'createDirs' => '',
'clearCacheOnLoad' => 0,
'version' => '1.0.0',
'version' => '1.1.0',
'constraints' => [
'depends' => [
'typo3' => '8.7.0-10.4.99',
'typo3' => '10.4.0-10.4.99',
],
'conflicts' => [],
'suggests' => [],
Expand Down
2 changes: 1 addition & 1 deletion ext_tables.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
die('Access denied.');
}

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile($_EXTKEY, 'Configuration/TypoScript', 'Impersonate');
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('impersonate', 'Configuration/TypoScript', 'Impersonate');

0 comments on commit 74f7904

Please sign in to comment.