Passed
Push — typo3_11 ( 59ee00...f038b8 )
by Torben
07:22
created

CaptchaValidator::isValid()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 41
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 24
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 41
rs 8.9137
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Extension "sf_event_mgt" for TYPO3 CMS.
7
 *
8
 * For the full copyright and license information, please read the
9
 * LICENSE.txt file that was distributed with this source code.
10
 */
11
12
namespace DERHANSEN\SfEventMgt\Validation\Validator;
13
14
use DERHANSEN\SfEventMgt\Domain\Model\Registration;
15
use DERHANSEN\SfEventMgt\Service\CaptchaConfigurationService;
16
use Psr\Http\Message\ServerRequestInterface;
17
use TYPO3\CMS\Core\Http\RequestFactory;
18
use TYPO3\CMS\Core\Utility\GeneralUtility;
19
use TYPO3\CMS\Core\Utility\HttpUtility;
20
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
21
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
22
use TYPO3\CMS\Extbase\Validation\Validator\AbstractValidator;
23
24
/**
25
 * Validator for either reCaptcha or hCaptcha
26
 */
27
class CaptchaValidator extends AbstractValidator
28
{
29
    /**
30
     * This validator always needs to be executed even if the given value is empty.
31
     * See AbstractValidator::validate()
32
     *
33
     * @var bool
34
     */
35
    protected $acceptsEmptyValues = false;
36
37
    protected ConfigurationManagerInterface $configurationManager;
38
    protected RequestFactory $requestFactory;
39
40
    protected array $settings;
41
42
    public function __construct(array $options = [])
43
    {
44
        parent::__construct($options);
45
        $this->configurationManager = GeneralUtility::makeInstance(ConfigurationManagerInterface::class);
46
        $this->requestFactory = GeneralUtility::makeInstance(RequestFactory::class);
47
48
        $this->settings = $this->configurationManager->getConfiguration(
49
            ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
50
            'SfEventMgt',
51
            'Pievent'
52
        );
53
    }
54
55
    /**
56
     * @param Registration $value Registration
57
     * @return void
58
     */
59
    protected function isValid($value)
60
    {
61
        $configurationService = new CaptchaConfigurationService($this->settings['registration']['captcha'] ?? []);
62
63
        if (!$configurationService->getEnabled()) {
64
            return;
65
        }
66
67
        /** @var ServerRequestInterface $request */
68
        $request = $GLOBALS['TYPO3_REQUEST'];
69
        $parsedBody = $request->getParsedBody();
70
        $captchaFormFieldValue = $parsedBody[$configurationService->getResponseField()] ?? null;
71
        if (null === $captchaFormFieldValue) {
72
            $this->addError(
73
                LocalizationUtility::translate('validation.missing_captcha', 'SfEventMgt'),
74
                1631943016
75
            );
76
            return;
77
        }
78
79
        $url = HttpUtility::buildUrl(
80
            [
81
                'host' => $configurationService->getVerificationServer(),
82
                'query' => \http_build_query(
83
                    [
84
                        'secret' => $configurationService->getPrivateKey(),
85
                        'response' => $captchaFormFieldValue,
86
                        'remoteip' => $request->getAttribute('normalizedParams')->getRemoteAddress(),
87
                    ]
88
                ),
89
            ]
90
        );
91
92
        $response = $this->requestFactory->request($url, 'POST');
93
94
        $body = (string)$response->getBody();
95
        $responseArray = json_decode($body, true);
96
        if (!is_array($responseArray) || empty($responseArray) || $responseArray['success'] === false) {
97
            $this->addError(
98
                $this->translateErrorMessage('validation.possible_robot', 'SfEventMgt'),
99
                1631940277
100
            );
101
        }
102
    }
103
}
104