Lines 100.00% 23 / 23
Methods 100.00% 5 / 5
Classes 100.00% 1 / 1
Covered by tests of size
Name Lines Methods CRAP
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 checkCaptchaCode 100.00% 14 / 14 100.00% 1 / 1 6
 fetchUrl 100.00% 5 / 5 100.00% 1 / 1 1
 isUserIsLoggedIn 100.00% 1 / 1 100.00% 1 / 1 1
 setUserIsLoggedIn 100.00% 2 / 2 100.00% 1 / 1 1
24class GoogleRecaptcha implements CaptchaInterface
25{
26    private bool $userIsLoggedIn;
27
28    /**
29     * Constructor.
30     */
31    public function __construct(
32        private readonly Configuration $configuration,
33    ) {
34    }
35
36    public function checkCaptchaCode(string $code): bool
37    {
38        if ($this->isUserIsLoggedIn()) {
39            return true;
40        }
41
42        $url = sprintf(
43            'https://www.google.com/recaptcha/api/siteverify?secret=%s&response=%s',
44            (string) $this->configuration->get(item: 'security.googleReCaptchaV2SecretKey'),
45            $code,
46        );
47
48        $response = $this->fetchUrl($url);
49
50        if (!is_string($response) || $response === '') {
51            return false;
52        }
53
54        try {
55            $decoded = json_decode($response, associative: true, depth: 512, flags: JSON_THROW_ON_ERROR);
56        } catch (\JsonException) {
57            return false;
58        }
59
60        return is_array($decoded) && ($decoded['success'] ?? false) === true;
61    }
62
63    /**
64     * Fetch the contents of a URL.
65     */
66    protected function fetchUrl(string $url): string|false
67    {
68        $response = false;
69        set_error_handler(static fn() => true);
70        try {
71            $response = file_get_contents($url);
72        } finally {
73            restore_error_handler();
74        }
75
76        return $response;
77    }
78
79    public function isUserIsLoggedIn(): bool
80    {
81        return $this->userIsLoggedIn;
82    }
83
84    public function setUserIsLoggedIn(bool $userIsLoggedIn): GoogleRecaptcha
85    {
86        $this->userIsLoggedIn = $userIsLoggedIn;
87        return $this;
88    }
89}