Passed
Push — master ( 0a1053...4cce54 )
by
unknown
25:41 queued 13:11
created

BackendUserAuthenticator::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
namespace TYPO3\CMS\Frontend\Middleware;
19
20
use Psr\Http\Message\ResponseInterface;
21
use Psr\Http\Message\ServerRequestInterface;
22
use Psr\Http\Server\RequestHandlerInterface;
23
use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
24
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
25
use TYPO3\CMS\Core\Authentication\Mfa\MfaRequiredException;
26
use TYPO3\CMS\Core\Context\Context;
27
use TYPO3\CMS\Core\Core\Bootstrap;
28
use TYPO3\CMS\Core\Http\NormalizedParams;
29
use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
30
use TYPO3\CMS\Core\Utility\GeneralUtility;
31
32
/**
33
 * This middleware authenticates a Backend User (be_user) (pre)-viewing a frontend page.
34
 *
35
 * This middleware also ensures that $GLOBALS['LANG'] is available, however it is possible that
36
 * a different middleware later-on might unset the BE_USER as he/she is not allowed to preview a certain
37
 * page due to rights management. As this can only happen once the page ID is resolved, this will happen
38
 * after the routing middleware.
39
 */
40
class BackendUserAuthenticator extends \TYPO3\CMS\Core\Middleware\BackendUserAuthenticator
41
{
42
    private LanguageServiceFactory $languageServiceFactory;
43
44
    public function __construct(
45
        Context $context,
46
        LanguageServiceFactory $languageServiceFactory
47
    ) {
48
        parent::__construct($context);
49
        $this->languageServiceFactory = $languageServiceFactory;
50
    }
51
52
    /**
53
     * Creates a backend user authentication object, tries to authenticate a user
54
     *
55
     * @param ServerRequestInterface $request
56
     * @param RequestHandlerInterface $handler
57
     * @return ResponseInterface
58
     */
59
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
60
    {
61
        // Initializing a possible logged-in Backend User
62
        // If the backend cookie is set,
63
        // we proceed and check if a backend user is logged in.
64
        $backendUserObject = null;
65
        if (isset($request->getCookieParams()[BackendUserAuthentication::getCookieName()])) {
66
            $backendUserObject = $this->initializeBackendUser($request);
67
        }
68
        $GLOBALS['BE_USER'] = $backendUserObject;
69
        // Load specific dependencies which are necessary for a valid Backend User
70
        // like $GLOBALS['LANG'] for labels in the language of the BE User, the router, and ext_tables.php for all modules
71
        // So things like Frontend Editing and Admin Panel can use this for generating links to the TYPO3 Backend.
72
        if ($GLOBALS['BE_USER'] instanceof FrontendBackendUserAuthentication) {
73
            $GLOBALS['LANG'] = $this->languageServiceFactory->createFromUserPreferences($GLOBALS['BE_USER']);
74
            Bootstrap::loadExtTables();
75
            $this->setBackendUserAspect($GLOBALS['BE_USER']);
76
        }
77
78
        $response = $handler->handle($request);
79
80
        // If, when building the response, the user is still available, then ensure that the headers are sent properly
81
        if ($this->context->getAspect('backend.user')->isLoggedIn()) {
0 ignored issues
show
Bug introduced by
The method isLoggedIn() does not exist on TYPO3\CMS\Core\Context\AspectInterface. It seems like you code against a sub-type of TYPO3\CMS\Core\Context\AspectInterface such as TYPO3\CMS\Core\Context\UserAspect. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

81
        if ($this->context->getAspect('backend.user')->/** @scrutinizer ignore-call */ isLoggedIn()) {
Loading history...
82
            return $this->applyHeadersToResponse($response);
83
        }
84
        return $response;
85
    }
86
87
    /**
88
     * Creates the backend user object and returns it.
89
     *
90
     * @param ServerRequestInterface $request
91
     * @return FrontendBackendUserAuthentication|null the backend user object or null if there was no valid user found
92
     * @throws \TYPO3\CMS\Core\Exception
93
     */
94
    protected function initializeBackendUser(ServerRequestInterface $request)
95
    {
96
        // New backend user object
97
        $backendUserObject = GeneralUtility::makeInstance(FrontendBackendUserAuthentication::class);
98
        try {
99
            $backendUserObject->start();
100
        } catch (MfaRequiredException $e) {
101
            // Do nothing, as the user is not fully authenticated - has not
102
            // passed required multi-factor authentication - via the backend.
103
            return null;
104
        }
105
        $backendUserObject->unpack_uc();
106
        if (!empty($backendUserObject->user['uid'])) {
107
            $this->setBackendUserAspect($backendUserObject, (int)$backendUserObject->user['workspace_id']);
108
            $backendUserObject->fetchGroupData();
109
        }
110
        // Unset the user initialization if any setting / restriction applies
111
        if (!$this->isAuthenticated($backendUserObject, $request->getAttribute('normalizedParams'))) {
112
            $backendUserObject = null;
113
            $this->setBackendUserAspect(null);
114
        }
115
        return $backendUserObject;
116
    }
117
118
    /**
119
     * Implementing the access checks that the TYPO3 CMS bootstrap script does before a user is ever logged in.
120
     *
121
     * @param FrontendBackendUserAuthentication $user
122
     * @param NormalizedParams $normalizedParams
123
     * @return bool Returns TRUE if access is OK
124
     */
125
    protected function isAuthenticated(FrontendBackendUserAuthentication $user, NormalizedParams $normalizedParams)
126
    {
127
        // Check IP
128
        $ipMask = trim($GLOBALS['TYPO3_CONF_VARS']['BE']['IPmaskList'] ?? '');
129
        if ($ipMask && !GeneralUtility::cmpIP($normalizedParams->getRemoteAddress(), $ipMask)) {
130
            return false;
131
        }
132
        // Check SSL (https)
133
        if ((bool)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL'] && !$normalizedParams->isHttps()) {
134
            return false;
135
        }
136
        return $user->backendCheckLogin();
137
    }
138
}
139