Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Captcha
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 4
380
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
20
 setErrorMode
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 verify
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
90
 active
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3/**
4 * VuFind Action Helper - Captcha handler
5 *
6 * PHP version 8
7 *
8 * Copyright (C) Villanova University 2020.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2,
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 *
23 * @category VuFind
24 * @package  Controller_Plugins
25 * @author   Chris Hallberg <crhallberg@gmail.com>
26 * @author   Mario Trojan <mario.trojan@uni-tuebingen.de>
27 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
28 * @link     https://vufind.org Main Page
29 */
30
31namespace VuFind\Controller\Plugin;
32
33use Laminas\Mvc\Controller\Plugin\AbstractPlugin;
34use VuFind\I18n\Translator\TranslatorAwareInterface;
35
36use function count;
37use function in_array;
38
39/**
40 * Action helper to manage Captcha fields
41 *
42 * @category VuFind
43 * @package  Controller_Plugins
44 * @author   Chris Hallberg <crhallberg@gmail.com>
45 * @author   Mario Trojan <mario.trojan@uni-tuebingen.de>
46 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
47 * @link     https://vufind.org Main Page
48 */
49class Captcha extends AbstractPlugin implements TranslatorAwareInterface
50{
51    use \VuFind\I18n\Translator\TranslatorAwareTrait;
52
53    /**
54     * Captcha services
55     *
56     * @var array
57     */
58    protected $captchas = [];
59
60    /**
61     * String array of forms where Captcha is active
62     *
63     * @var bool|string[]
64     */
65    protected $domains = [];
66
67    /**
68     * Captcha activated in config
69     *
70     * @var bool
71     */
72    protected $active = false;
73
74    /**
75     * Flash message or throw Exception
76     *
77     * @var string
78     */
79    protected $errorMode = 'flash';
80
81    /**
82     * Constructor
83     *
84     * @param \Laminas\Config\Config $config   Config file
85     * @param array                  $captchas CAPTCHA objects
86     *
87     * @return void
88     */
89    public function __construct($config, array $captchas = [])
90    {
91        $this->captchas = $captchas;
92        if (count($captchas) > 0 && isset($config->Captcha->forms)) {
93            $this->active = true;
94            $this->domains = '*' == trim($config->Captcha->forms)
95                ? true
96                : array_map(
97                    'trim',
98                    explode(',', $config->Captcha->forms)
99                );
100        }
101    }
102
103    /**
104     * Flash messages ('flash') or throw exceptions ('throw')
105     *
106     * @param string $mode 'flash' or 'throw'
107     *
108     * @return bool
109     */
110    public function setErrorMode($mode): bool
111    {
112        if (in_array($mode, ['flash', 'throw', 'none'])) {
113            $this->errorMode = $mode;
114            return true;
115        }
116        return false;
117    }
118
119    /**
120     * Pull the captcha field from controller params and check them for accuracy
121     *
122     * @return bool
123     */
124    public function verify(): bool
125    {
126        if (!$this->active()) {
127            return true;
128        }
129        $captchaPassed = false;
130        $errorMessage = '';
131
132        foreach ($this->captchas as $captcha) {
133            try {
134                $captchaPassed = $captcha->verify(
135                    $this->getController()->params()
136                );
137                if (!$captchaPassed) {
138                    $errorMessage = $captcha->getErrorMessage();
139                }
140            } catch (\Exception $e) {
141                $captchaPassed = false;
142                $errorMessage = $this->translate('captcha_technical_difficulties');
143            }
144
145            if ($captchaPassed) {
146                break;
147            }
148        }
149
150        if (!empty($errorMessage)) {
151            if ($this->errorMode == 'flash') {
152                $this->getController()->flashMessenger()
153                    ->addErrorMessage($errorMessage);
154            }
155            if ($this->errorMode == 'throw') {
156                throw new \Exception($errorMessage);
157            }
158        }
159        return $captchaPassed;
160    }
161
162    /**
163     * Return whether a specific form is set for Captcha in the config
164     *
165     * @param bool|string $domain The specific config term are we checking; ie. "sms"
166     *
167     * @return bool
168     */
169    public function active($domain = false): bool
170    {
171        return $this->active
172        && ($domain == false || $this->domains === true
173        || in_array($domain, $this->domains));
174    }
175}