Completed
Push — master ( 36b975...da6bda )
by ARCANEDEV
21s queued 11s
created

AbstractNoCaptcha::getVerificationUrl()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php namespace Arcanedev\NoCaptcha;
2
3
use Arcanedev\NoCaptcha\Utilities\Request;
4
use Illuminate\Support\HtmlString;
5
use Psr\Http\Message\ServerRequestInterface;
6
7
/**
8
 * Class     AbstractNoCaptcha
9
 *
10
 * @package  Arcanedev\NoCaptcha
11
 * @author   ARCANEDEV <[email protected]>
12
 */
13
abstract class AbstractNoCaptcha implements Contracts\NoCaptcha
14
{
15
    /* -----------------------------------------------------------------
16
     |  Constants
17
     | -----------------------------------------------------------------
18
     */
19
20
    const CAPTCHA_NAME = 'g-recaptcha-response';
21
22
    /* -----------------------------------------------------------------
23
     |  Properties
24
     | -----------------------------------------------------------------
25
     */
26
27
    /**
28
     * The shared key between your site and ReCAPTCHA
29
     *
30
     * @var string
31
     */
32
    protected $secret;
33
34
    /**
35
     * Your site key
36
     *
37
     * @var string
38
     */
39
    protected $siteKey;
40
41
    /**
42
     * Forces the widget to render in a specific language.
43
     * Auto-detects the user's language if unspecified.
44
     *
45
     * @var string
46
     */
47
    protected $lang;
48
49
    /**
50
     * HTTP Request Client
51
     *
52
     * @var \Arcanedev\NoCaptcha\Contracts\Utilities\Request
53
     */
54
    protected $request;
55
56
    /**
57
     * ReCaptcha's response.
58
     *
59
     * @var \Arcanedev\NoCaptcha\Utilities\ResponseV3|null
60
     */
61
    protected $response;
62
63
    /**
64
     * Use the global domain.
65
     *
66
     * @var bool
67
     */
68
    public static $useGlobalDomain = false;
69
70
    /* -----------------------------------------------------------------
71
     |  Constructor
72
     | -----------------------------------------------------------------
73
     */
74
75
    /**
76
     * NoCaptcha constructor.
77
     *
78
     * @param  string       $secret
79
     * @param  string       $siteKey
80
     * @param  string|null  $lang
81
     */
82 236
    public function __construct($secret, $siteKey, $lang = null)
83
    {
84 236
        $this->setSecret($secret);
85 236
        $this->setSiteKey($siteKey);
86 236
        $this->setLang($lang);
87
88 236
        $this->setRequestClient(new Request);
89 236
    }
90
91
    /* -----------------------------------------------------------------
92
     |  Getters & Setters
93
     | -----------------------------------------------------------------
94
     */
95
96
    /**
97
     * Set the secret key.
98
     *
99
     * @param  string  $secret
100
     *
101
     * @return $this
102
     */
103 236
    protected function setSecret($secret)
104
    {
105 236
        self::checkKey('secret key', $secret);
106
107 236
        $this->secret = $secret;
108
109 236
        return $this;
110
    }
111
112
    /**
113
     * Get the site key.
114
     *
115
     * @return string
116
     */
117 24
    public function getSiteKey()
118
    {
119 24
        return $this->siteKey;
120
    }
121
122
    /**
123
     * Set Site key.
124
     *
125
     * @param  string  $siteKey
126
     *
127
     * @return $this
128
     */
129 236
    protected function setSiteKey($siteKey)
130
    {
131 236
        self::checkKey('site key', $siteKey);
132
133 236
        $this->siteKey = $siteKey;
134
135 236
        return $this;
136
    }
137
138
    /**
139
     * Set language code.
140
     *
141
     * @param  string  $lang
142
     *
143
     * @return $this
144
     */
145 236
    public function setLang($lang)
146
    {
147 236
        $this->lang = $lang;
148
149 236
        return $this;
150
    }
151
152
    /**
153
     * Set HTTP Request Client.
154
     *
155
     * @param  \Arcanedev\NoCaptcha\Contracts\Utilities\Request  $request
156
     *
157
     * @return $this
158
     */
159 236
    public function setRequestClient(Contracts\Utilities\Request $request)
160
    {
161 236
        $this->request = $request;
162
163 236
        return $this;
164
    }
165
166
    /**
167
     * Get the last response.
168
     *
169
     * @return \Arcanedev\NoCaptcha\Utilities\AbstractResponse|null
170
     */
171 4
    public function getLastResponse()
172
    {
173 4
        return $this->response;
174
    }
175
176
    /**
177
     * Get the client url.
178
     *
179
     * @return string
180
     */
181 48
    public static function getClientUrl()
182
    {
183 48
        return static::$useGlobalDomain
184 6
            ? 'https://www.recaptcha.net/recaptcha/api.js'
185 48
            : 'https://www.google.com/recaptcha/api.js';
186
    }
187
188
    /**
189
     * Get the verification url.
190
     *
191
     * @return string
192
     */
193 40
    public static function getVerificationUrl()
194
    {
195 40
        return static::$useGlobalDomain
196 6
            ? 'https://www.recaptcha.net/recaptcha/api/siteverify'
197 40
            : 'https://www.google.com/recaptcha/api/siteverify';
198
    }
199
200
    /* -----------------------------------------------------------------
201
     |  Main Methods
202
     | -----------------------------------------------------------------
203
     */
204
205
    /**
206
     * Verify Response.
207
     *
208
     * @param  string  $response
209
     * @param  string  $clientIp
210
     *
211
     * @return \Arcanedev\NoCaptcha\Utilities\AbstractResponse|mixed
212
     */
213 32
    public function verify($response, $clientIp = null)
214
    {
215 32
        return $this->response = $this->sendVerifyRequest([
216 32
            'secret'   => $this->secret,
217 32
            'response' => $response,
218 32
            'remoteip' => $clientIp
219
        ]);
220
    }
221
222
    /**
223
     * Calls the reCAPTCHA siteverify API to verify whether the user passes CAPTCHA
224
     * test using a PSR-7 ServerRequest object.
225
     *
226
     * @param  \Psr\Http\Message\ServerRequestInterface  $request
227
     *
228
     * @return \Arcanedev\NoCaptcha\Utilities\AbstractResponse
229
     */
230 8
    public function verifyRequest(ServerRequestInterface $request)
231
    {
232 8
        $body   = $request->getParsedBody();
233 8
        $server = $request->getServerParams();
234
235 8
        return $this->verify(
236 8
            $body[self::CAPTCHA_NAME] ?? '',
237 8
            $server['REMOTE_ADDR'] ?? null
238
        );
239
    }
240
241
    /**
242
     * Send verify request to API and get response.
243
     *
244
     * @param  array  $query
245
     *
246
     * @return \Arcanedev\NoCaptcha\Utilities\ResponseV3
247
     */
248 32
    protected function sendVerifyRequest(array $query = [])
249
    {
250 32
        $query = array_filter($query);
251 32
        $json  = $this->request->send(
252 32
            $this->getVerificationUrl().'?'.http_build_query($query)
253
        );
254
255 32
        return $this->parseResponse($json);
256
    }
257
258
    /**
259
     * Parse the response.
260
     *
261
     * @param  string  $json
262
     *
263
     * @return \Arcanedev\NoCaptcha\Utilities\AbstractResponse|mixed
264
     */
265
    abstract protected function parseResponse($json);
266
267
    /* -----------------------------------------------------------------
268
     |  Check Methods
269
     | -----------------------------------------------------------------
270
     */
271
272
    /**
273
     * Check if has lang.
274
     *
275
     * @return bool
276
     */
277 40
    protected function hasLang()
278
    {
279 40
        return ! empty($this->lang);
280
    }
281
282
    /**
283
     * Check key.
284
     *
285
     * @param  string  $name
286
     * @param  string  $value
287
     */
288 236
    private static function checkKey($name, &$value)
289
    {
290 236
        self::checkIsString($name, $value);
291
292 236
        $value = trim($value);
293
294 236
        self::checkIsNotEmpty($name, $value);
295 236
    }
296
297
    /**
298
     * Check if the value is a string value.
299
     *
300
     * @param  string  $name
301
     * @param  string  $value
302
     *
303
     * @throws \Arcanedev\NoCaptcha\Exceptions\ApiException
304
     */
305 236
    private static function checkIsString($name, $value)
306
    {
307 236
        if ( ! is_string($value)) {
308 16
            throw new Exceptions\ApiException(
309 16
                "The {$name} must be a string value, ".gettype($value).' given.'
310
            );
311
        }
312 236
    }
313
314
    /**
315
     * Check if the value is not empty.
316
     *
317
     * @param string  $name
318
     * @param string  $value
319
     *
320
     * @throws \Arcanedev\NoCaptcha\Exceptions\ApiException
321
     */
322 236
    private static function checkIsNotEmpty($name, $value)
323
    {
324 236
        if (empty($value)) {
325 16
            throw new Exceptions\ApiException("The {$name} must not be empty");
326
        }
327 236
    }
328
329
    /* -----------------------------------------------------------------
330
     |  Other Methods
331
     | -----------------------------------------------------------------
332
     */
333
334
    /**
335
     * Transform the string to an Html serializable object
336
     *
337
     * @param  string  $html
338
     *
339
     * @return \Illuminate\Support\HtmlString
340
     */
341 44
    protected function toHtmlString($html)
342
    {
343 44
        return new HtmlString($html);
344
    }
345
}
346