Passed
Push — master ( 35d462...0e1d87 )
by
unknown
75:26
created

FrontendUserAuthenticator::applyHeadersToResponse()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 8
c 2
b 0
f 0
dl 0
loc 12
rs 10
cc 2
nc 2
nop 1
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\MiddlewareInterface;
23
use Psr\Http\Server\RequestHandlerInterface;
24
use TYPO3\CMS\Core\Context\Context;
25
use TYPO3\CMS\Core\Session\UserSessionManager;
26
use TYPO3\CMS\Core\Utility\GeneralUtility;
27
use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication;
28
29
/**
30
 * This middleware authenticates a Frontend User (fe_users).
31
 */
32
class FrontendUserAuthenticator implements MiddlewareInterface
33
{
34
    /**
35
     * @var Context
36
     */
37
    protected $context;
38
39
    public function __construct(Context $context)
40
    {
41
        $this->context = $context;
42
    }
43
44
    /**
45
     * Creates a frontend user authentication object, tries to authenticate a user and stores
46
     * it in the current request as attribute.
47
     *
48
     * @param ServerRequestInterface $request
49
     * @param RequestHandlerInterface $handler
50
     * @return ResponseInterface
51
     */
52
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
53
    {
54
        $frontendUser = GeneralUtility::makeInstance(FrontendUserAuthentication::class);
55
56
        // List of page IDs where to look for frontend user records
57
        $pid = $request->getParsedBody()['pid'] ?? $request->getQueryParams()['pid'] ?? 0;
58
        if ($pid) {
59
            $frontendUser->checkPid_value = implode(',', GeneralUtility::intExplode(',', $pid));
60
        }
61
62
        // Authenticate now
63
        $frontendUser->start();
64
        $frontendUser->unpack_uc();
65
        // no matter if we have an active user we try to fetch matching groups which can
66
        // be set without an user (simulation for instance!)
67
        $frontendUser->fetchGroupData();
68
69
        // Register the frontend user as aspect and within the request
70
        $userAspect = $frontendUser->createUserAspect();
71
        $this->context->setAspect('frontend.user', $userAspect);
72
        $request = $request->withAttribute('frontend.user', $frontendUser);
73
74
        $response = $handler->handle($request);
75
76
        // Store session data for fe_users if it still exists
77
        if ($frontendUser instanceof FrontendUserAuthentication) {
78
            $frontendUser->storeSessionData();
79
            $response = $frontendUser->appendCookieToResponse($response);
80
            // Collect garbage in Frontend requests, which aren't fully cacheable (e.g. with cookies)
81
            if ($response->hasHeader('Set-Cookie')) {
82
                $this->sessionGarbageCollection();
83
            }
84
        }
85
86
        return $response;
87
    }
88
89
    /**
90
     * Garbage collection for fe_sessions (with a probability)
91
     */
92
    protected function sessionGarbageCollection(): void
93
    {
94
        UserSessionManager::create('FE')->collectGarbage();
95
    }
96
}
97