Skip to content

Commit 0e4bd91

Browse files
committed
Implementing proposed Psr\Captcha
1 parent f52a8a6 commit 0e4bd91

File tree

7 files changed

+59
-7
lines changed

7 files changed

+59
-7
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"phpstan/phpstan": "^2.1"
2020
},
2121
"autoload": {
22-
"psr-4": {"ReCaptcha\\": "src/ReCaptcha"}
22+
"psr-4": {"ReCaptcha\\": "src/ReCaptcha", "Psr\\Captcha\\": "src/Captcha"}
2323
},
2424
"autoload-dev": {
2525
"psr-4": {"ReCaptcha\\": "tests/ReCaptcha/"}

src/Captcha/CaptchaException.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Psr\Captcha;
4+
5+
/**
6+
* MUST be thrown from CaptchaVerifierInterface methods if Captcha test itself cannot be passed due to any reason that is not user-related - network problems, incorrect secret token, unable to parse request-response, etc.
7+
* MUST NOT be thrown if CAPTCHA was actually performed validation - even if it failed - instead CaptchaVerifierInterface MUST return CaptchaResponseInterface which ::isSuccess() method MUST return false
8+
*/
9+
class CaptchaException extends \RuntimeException
10+
{
11+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Psr\Captcha;
4+
5+
/**
6+
* Interface of the object that CaptchaVerifierInterface MUST return on ::verify() method.
7+
* MUST contain enough information to consistently say whether user successfully passed Captcha or not.
8+
* SHOULD contain actual user's SCORING
9+
* MAY contain additional information (e.g., gathered from it's captcha-vendor service's verification endpoint) (i.e. message, errors, etc.)
10+
*/
11+
interface CaptchaResponseInterface
12+
{
13+
/**
14+
* MUST return true/false depends on whether verification was successful or not (is user a bot or not).
15+
*
16+
* @return bool
17+
*/
18+
public function isSuccess(): bool;
19+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace Psr\Captcha;
4+
5+
/**
6+
* Interface of Captcha verification service itself.
7+
* MUST decide whether user passed the Captcha or not and return corresponding response.
8+
* SHOULD contain method to configure SCORING threshold (if applicable by PROVIDER)
9+
* SHOULD throw a CaptchaException as soon as possible if appears any non-user related error that prevents correct Captcha solving (e.g. network problems, incorrect secret token, e.g.)
10+
*/
11+
interface CaptchaVerifierInterface
12+
{
13+
/**
14+
* Verifies client token and decides whether verification was successful or not (is user a bot or not).
15+
*
16+
* @param string $token
17+
*
18+
* @throws CaptchaException if Captcha cannot be validated because of non-user problems (e.g. due to network problems, incorrect secret token, etc.)
19+
* @return CaptchaResponseInterface
20+
*/
21+
public function verify(string $token): CaptchaResponseInterface;
22+
}

src/ReCaptcha/ReCaptcha.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
/**
3939
* reCAPTCHA client.
4040
*/
41-
class ReCaptcha
41+
class ReCaptcha implements \Psr\Captcha\CaptchaVerifierInterface
4242
{
4343
/**
4444
* Version of this client library.
@@ -123,12 +123,12 @@ class ReCaptcha
123123
*
124124
* @param string $secret The shared key between your site and reCAPTCHA.
125125
* @param ?RequestMethod $requestMethod method used to send the request. Defaults to POST.
126-
* @throws \RuntimeException if $secret is invalid
126+
* @throws \Psr\Captcha\CaptchaException if $secret is invalid
127127
*/
128128
public function __construct(private string $secret, private ?RequestMethod $requestMethod = null)
129129
{
130130
if (empty($secret)) {
131-
throw new \RuntimeException('No secret provided');
131+
throw new \Psr\Captcha\CaptchaException('No secret provided');
132132
}
133133

134134
if (is_null($requestMethod)) {
@@ -141,7 +141,7 @@ public function __construct(private string $secret, private ?RequestMethod $requ
141141
* CAPTCHA test and additionally runs any specified additional checks
142142
*
143143
* @param string $response The user response token provided by reCAPTCHA, verifying the user on your site.
144-
* @param string $remoteIp The end user's IP address.
144+
* @param ?string $remoteIp The end user's IP address.
145145
*
146146
* @return Response Response from the service.
147147
*/

src/ReCaptcha/Response.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
/**
3939
* The response returned from the service.
4040
*/
41-
class Response
41+
class Response implements \Psr\Captcha\CaptchaResponseInterface
4242
{
4343
/**
4444
* Build the response from the expected JSON returned by the service.

tests/ReCaptcha/ReCaptchaTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class ReCaptchaTest extends TestCase
4343
#[DataProvider('invalidSecretProvider')]
4444
public function testExceptionThrownOnInvalidSecret($invalid)
4545
{
46-
$this->expectException(\RuntimeException::class);
46+
$this->expectException(\Psr\Captcha\CaptchaException::class);
4747
$rc = new ReCaptcha($invalid);
4848
}
4949

0 commit comments

Comments
 (0)