Commit 7b82e83d authored by Benni Mack's avatar Benni Mack Committed by Georg Ringer
Browse files

[TASK] Centralize Backend User Session Repository

Logic around Backend User Sessions and its access
across the EXT:beuser backend module is now encapsulated
and streamlined:

* The BackendUserSessionRepository does not inherit
from Extbase anymore, as there is nothing needed here
* No ObjectManager is needed, GeneralUtility can be used instead
* All access to the actual sessionBackend is now placed inside
this method.

This allows to further streamline the User Session handling
at a later stage.

Resolves: #93017
Releases: master
Change-Id: I02ab22d90e570cd04f4e6a3ea96412dfbf247967
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/67045


Tested-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: Georg Ringer's avatarGeorg Ringer <georg.ringer@gmail.com>
Reviewed-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Reviewed-by: Georg Ringer's avatarGeorg Ringer <georg.ringer@gmail.com>
parent d4fa3bbc
......@@ -32,9 +32,6 @@ use TYPO3\CMS\Core\Http\ImmediateResponseException;
use TYPO3\CMS\Core\Http\RedirectResponse;
use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Core\Pagination\SimplePagination;
use TYPO3\CMS\Core\Session\Backend\HashableSessionBackendInterface;
use TYPO3\CMS\Core\Session\Backend\SessionBackendInterface;
use TYPO3\CMS\Core\Session\SessionManager;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Http\ForwardResponse;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
......@@ -190,11 +187,8 @@ class BackendUserController extends ActionController
];
}
$currentSessionId = $this->getBackendUserAuthentication()->getSessionId();
$sessionBackend = $this->getSessionBackend();
if ($sessionBackend instanceof HashableSessionBackendInterface) {
$currentSessionId = $sessionBackend->hash($currentSessionId);
}
$currentSessionId = $this->backendUserSessionRepository->getPersistedSessionIdentifier($this->getBackendUserAuthentication());
$this->view->assignMultiple([
'shortcutLabel' => 'onlineUsers',
'onlineUsersAndSessions' => $onlineUsersAndSessions,
......@@ -327,8 +321,7 @@ class BackendUserController extends ActionController
protected function terminateBackendUserSessionAction(BackendUser $backendUser, $sessionId)
{
// terminating value of persisted session ID (probably hashed value)
$sessionBackend = $this->getSessionBackend();
$success = $sessionBackend->remove($sessionId);
$success = $this->backendUserSessionRepository->terminateSessionByIdentifier($sessionId);
if ($success) {
$this->addFlashMessage(LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:terminateSessionSuccess', 'beuser') ?? '');
......@@ -364,13 +357,7 @@ class BackendUserController extends ActionController
]
);
$this->getSessionBackend()->update(
$this->getBackendUserAuthentication()->getSessionId(),
[
'ses_userid' => (int)$targetUser['uid'],
'ses_backuserid' => (int)$this->getBackendUserAuthentication()->user['uid']
]
);
$this->backendUserSessionRepository->switchToUser($this->getBackendUserAuthentication(), (int)$targetUser['uid']);
$event = new SwitchUserEvent(
$this->getBackendUserAuthentication()->getSessionId(),
......@@ -419,15 +406,6 @@ class BackendUserController extends ActionController
return $GLOBALS['BE_USER'];
}
/**
* @return SessionBackendInterface
*/
protected function getSessionBackend()
{
$loginType = $this->getBackendUserAuthentication()->getLoginType();
return GeneralUtility::makeInstance(SessionManager::class)->getSessionBackend($loginType);
}
/**
* Create an array with the uids of online users as the keys
* [
......@@ -440,10 +418,8 @@ class BackendUserController extends ActionController
{
$onlineUsers = $this->backendUserSessionRepository->findAllActive();
$onlineBackendUsers = [];
if (is_array($onlineUsers)) {
foreach ($onlineUsers as $onlineUser) {
$onlineBackendUsers[$onlineUser['ses_userid']] = true;
}
foreach ($onlineUsers as $onlineUser) {
$onlineBackendUsers[$onlineUser['ses_userid']] = true;
}
return $onlineBackendUsers;
}
......
......@@ -17,26 +17,31 @@ namespace TYPO3\CMS\Beuser\Domain\Repository;
use TYPO3\CMS\Beuser\Domain\Model\BackendUser;
use TYPO3\CMS\Core\Authentication\AbstractUserAuthentication;
use TYPO3\CMS\Core\Session\Backend\HashableSessionBackendInterface;
use TYPO3\CMS\Core\Session\Backend\SessionBackendInterface;
use TYPO3\CMS\Core\Session\SessionManager;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Persistence\Repository;
/**
* Repository for \TYPO3\CMS\Extbase\Domain\Model\BackendUser
* @internal This class is a TYPO3 Backend implementation and is not considered part of the Public TYPO3 API.
*/
class BackendUserSessionRepository extends Repository
class BackendUserSessionRepository
{
protected SessionBackendInterface $sessionBackend;
public function __construct()
{
$this->sessionBackend = GeneralUtility::makeInstance(SessionManager::class)->getSessionBackend('BE');
}
/**
* Find all active sessions for all backend users
*
* @return array
*/
public function findAllActive()
public function findAllActive(): array
{
$sessionBackend = $this->getSessionBackend();
$allSessions = $sessionBackend->getAll();
$allSessions = $this->sessionBackend->getAll();
// Map array to correct keys
$allSessions = array_map(
......@@ -80,34 +85,49 @@ class BackendUserSessionRepository extends Repository
/**
* Update current session to move back to the original user.
*
* @param AbstractUserAuthentication $authentication
* @param AbstractUserAuthentication $userObject
*/
public function switchBackToOriginalUser(AbstractUserAuthentication $authentication)
public function switchBackToOriginalUser(AbstractUserAuthentication $userObject): void
{
$sessionBackend = $this->getSessionBackend();
$sessionId = $this->getBackendSessionId();
$sessionBackend->update(
$sessionId,
$this->sessionBackend->update(
$userObject->getSessionId(),
[
'ses_userid' => $authentication->user['ses_backuserid'],
'ses_userid' => $userObject->user['ses_backuserid'],
'ses_backuserid' => 0
]
);
}
/**
* @return string
* Update current session to move to the target user. This is done
* by setting the target user id as ses_userid and storing the current
* user in ses_backuserid to restore the session record later on.
*
* @param AbstractUserAuthentication $userObject
* @param int $targetUserId
*/
protected function getBackendSessionId(): string
public function switchToUser(AbstractUserAuthentication $userObject, int $targetUserId): void
{
return $GLOBALS['BE_USER']->id;
$this->sessionBackend->update(
$userObject->getSessionId(),
[
'ses_userid' => (int)$targetUserId,
'ses_backuserid' => (int)$userObject->user['uid']
]
);
}
/**
* @return SessionBackendInterface
*/
protected function getSessionBackend(): SessionBackendInterface
public function getPersistedSessionIdentifier(AbstractUserAuthentication $userObject): string
{
$currentSessionId = $userObject->getSessionId();
if ($this->sessionBackend instanceof HashableSessionBackendInterface) {
$currentSessionId = $this->sessionBackend->hash($currentSessionId);
}
return $currentSessionId;
}
public function terminateSessionByIdentifier(string $sessionIdentifier): string
{
return GeneralUtility::makeInstance(SessionManager::class)->getSessionBackend('BE');
return $this->sessionBackend->remove($sessionIdentifier);
}
}
......@@ -22,7 +22,6 @@ use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Http\ImmediateResponseException;
use TYPO3\CMS\Core\Http\RedirectResponse;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
/**
* Backend user switchback, for logoff_pre_processing hook within
......@@ -41,8 +40,7 @@ class SwitchBackUserHook
public function switchBack($params, AbstractUserAuthentication $authentication)
{
if ($this->isAHandledBackendSession($authentication)) {
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$backendUserSessionRepository = $objectManager->get(BackendUserSessionRepository::class);
$backendUserSessionRepository = GeneralUtility::makeInstance(BackendUserSessionRepository::class);
$backendUserSessionRepository->switchBackToOriginalUser($authentication);
/** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
......
<?php
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\Beuser\Tests\Unit\Domain\Repository;
use TYPO3\CMS\Beuser\Domain\Repository\BackendUserSessionRepository;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
/**
* Test case
*/
class BackendUserSessionRepositoryTest extends UnitTestCase
{
/**
* @test
*/
public function classCanBeInstantiated()
{
$objectManager = $this->getMockBuilder(ObjectManagerInterface::class)->getMock();
new BackendUserSessionRepository($objectManager);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment