Passed
Push — typo3v9 ( 580ae6...b5443c )
by Tomas Norre
05:36
created

isRequestHashMatchingQueueRecord()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 1
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 3
ccs 0
cts 3
cp 0
crap 6
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AOE\Crawler\Middleware;
6
7
/*
8
 * (c) 2020 AOE GmbH <[email protected]>
9
 *
10
 * This file is part of the TYPO3 Crawler Extension.
11
 *
12
 * It is free software; you can redistribute it and/or modify it under
13
 * the terms of the GNU General Public License, either version 2
14
 * of the License, or any later version.
15
 *
16
 * For the full copyright and license information, please read the
17
 * LICENSE.txt file that was distributed with this source code.
18
 *
19
 * The TYPO3 project - inspiring people to share!
20
 */
21
22
use AOE\Crawler\Domain\Repository\QueueRepository;
23
use Psr\Http\Message\ResponseInterface;
24
use Psr\Http\Message\ServerRequestInterface;
25
use Psr\Http\Server\MiddlewareInterface;
26
use Psr\Http\Server\RequestHandlerInterface;
27
use TYPO3\CMS\Core\Context\Context;
28
use TYPO3\CMS\Core\Context\UserAspect;
29
use TYPO3\CMS\Core\Utility\GeneralUtility;
30
use TYPO3\CMS\Extbase\Object\ObjectManager;
31
use TYPO3\CMS\Frontend\Controller\ErrorController;
32
33
/**
34
 * Evaluates HTTP headers and checks if Crawler should register itself.
35
 */
36
class FrontendUserAuthenticator implements MiddlewareInterface
37
{
38
    /**
39
     * @var string
40
     */
41
    protected $headerName = 'X-T3CRAWLER';
42
43
    /**
44
     * @var Context
45
     */
46
    protected $context;
47
48
    /**
49
     * @var QueueRepository
50
     */
51
    protected $queueRepository;
52
53
    /**
54
     * @param Context|null $context
55
     */
56
    public function __construct(?Context $context = null)
57
    {
58
        $this->context = $context ?? GeneralUtility::makeInstance(Context::class);
59
        $this->queueRepository = GeneralUtility::makeInstance(ObjectManager::class)->get(QueueRepository::class);
60
    }
61
62
    /**
63
     * @param ServerRequestInterface $request
64
     * @param RequestHandlerInterface $handler
65
     * @return ResponseInterface
66
     * @throws \TYPO3\CMS\Core\Context\Exception\AspectNotFoundException
67
     * @throws \TYPO3\CMS\Core\Error\Http\ServiceUnavailableException
68
     */
69
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
70
    {
71
        $crawlerInformation = $request->getHeaderLine($this->headerName) ?? null;
72
        if (empty($crawlerInformation)) {
73
            return $handler->handle($request);
74
        }
75
76
        // Authenticate crawler request:
77
        //@todo: ask service to exclude current call for special reasons: for example no relevance because the language version is not affected
78
        [$queueId, $hash] = explode(':', $crawlerInformation);
79
        $queueRec = $this->queueRepository->findByQueueId($queueId);
80
81
        // If a crawler record was found and hash was matching, set it up
82
        if (!$this->isRequestHashMatchingQueueRecord($queueRec, $hash)) {
83
            return GeneralUtility::makeInstance(ErrorController::class)->unavailableAction($request, 'No crawler entry found');
84
        }
85
86
        $queueParameters = unserialize($queueRec['parameters']);
87
        $request = $request->withAttribute('tx_crawler', $queueParameters);
88
89
        // Now ensure to set the proper user groups
90
        $grList = $queueParameters['feUserGroupList'];
91
        if ($grList) {
92
            $frontendUser = $request->getAttribute('frontend.user');
93
            $frontendUser->user[$frontendUser->usergroup_column] = $grList;
94
            // we have to set the fe user group to the user aspect since indexed_search only reads the user aspect
95
            // to get the groups. otherwise groups are ignored during indexing.
96
            // we need to add the groups 0, and -2 too, like the getGroupIds getter does.
97
            $this->context->setAspect(
98
                'frontend.user',
99
                GeneralUtility::makeInstance(
100
                    UserAspect::class,
101
                    $frontendUser,
102
                    explode(',', '0,-2,' . $grList)
103
                )
104
            );
105
        }
106
107
        return $handler->handle($request);
108
    }
109
110
    protected function isRequestHashMatchingQueueRecord(?array $queueRec, string $hash): bool
111
    {
112
        return is_array($queueRec) && $hash === md5($queueRec['qid'] . '|' . $queueRec['set_id'] . '|' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']);
113
    }
114
}
115