2024-04-01 19:36:03 +02:00
|
|
|
<?php // Verify captchas server side.
|
|
|
|
namespace Vichan\Service;
|
|
|
|
|
|
|
|
use Vichan\Driver\HttpDriver;
|
|
|
|
|
|
|
|
defined('TINYBOARD') or exit;
|
|
|
|
|
|
|
|
|
2024-08-15 15:11:32 +02:00
|
|
|
class ReCaptchaQuery implements RemoteCaptchaQuery {
|
2024-04-01 19:36:03 +02:00
|
|
|
private HttpDriver $http;
|
|
|
|
private string $secret;
|
|
|
|
|
|
|
|
/**
|
2024-08-15 15:11:32 +02:00
|
|
|
* Creates a new ReCaptchaQuery using the google recaptcha service.
|
2024-04-01 19:36:03 +02:00
|
|
|
*
|
|
|
|
* @param HttpDriver $http The http client.
|
|
|
|
* @param string $secret Server side secret.
|
2024-08-15 15:11:32 +02:00
|
|
|
* @return ReCaptchaQuery A new ReCaptchaQuery query instance.
|
2024-04-01 19:36:03 +02:00
|
|
|
*/
|
2024-08-15 15:11:32 +02:00
|
|
|
public function __construct(HttpDriver $http, string $secret) {
|
|
|
|
$this->http = $http;
|
|
|
|
$this->secret = $secret;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function responseField(): string {
|
|
|
|
return 'g-recaptcha-response';
|
|
|
|
}
|
|
|
|
|
|
|
|
public function verify(string $response, ?string $remote_ip): bool {
|
|
|
|
$data = [
|
|
|
|
'secret' => $this->secret,
|
|
|
|
'response' => $response
|
|
|
|
];
|
|
|
|
|
|
|
|
if ($remote_ip !== null) {
|
|
|
|
$data['remoteip'] = $remote_ip;
|
|
|
|
}
|
|
|
|
|
|
|
|
$ret = $this->http->requestGet('https://www.google.com/recaptcha/api/siteverify', $data);
|
|
|
|
$resp = json_decode($ret, true, 16, JSON_THROW_ON_ERROR);
|
|
|
|
|
|
|
|
return isset($resp['success']) && $resp['success'];
|
2024-04-01 19:36:03 +02:00
|
|
|
}
|
2024-08-15 15:11:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
class HCaptchaQuery implements RemoteCaptchaQuery {
|
|
|
|
private HttpDriver $http;
|
|
|
|
private string $secret;
|
|
|
|
private string $sitekey;
|
2024-04-01 19:36:03 +02:00
|
|
|
|
|
|
|
/**
|
2024-08-15 15:11:32 +02:00
|
|
|
* Creates a new HCaptchaQuery using the hCaptcha service.
|
2024-04-01 19:36:03 +02:00
|
|
|
*
|
|
|
|
* @param HttpDriver $http The http client.
|
|
|
|
* @param string $secret Server side secret.
|
2024-08-15 15:11:32 +02:00
|
|
|
* @return HCaptchaQuery A new hCaptcha query instance.
|
2024-04-01 19:36:03 +02:00
|
|
|
*/
|
2024-08-15 15:11:32 +02:00
|
|
|
public function __construct(HttpDriver $http, string $secret, string $sitekey) {
|
2024-04-01 19:36:03 +02:00
|
|
|
$this->http = $http;
|
|
|
|
$this->secret = $secret;
|
2024-08-15 15:11:32 +02:00
|
|
|
$this->sitekey = $sitekey;
|
2024-04-01 19:36:03 +02:00
|
|
|
}
|
|
|
|
|
2024-08-15 15:11:32 +02:00
|
|
|
public function responseField(): string {
|
|
|
|
return 'h-captcha-response';
|
|
|
|
}
|
|
|
|
|
|
|
|
public function verify(string $response, ?string $remote_ip): bool {
|
|
|
|
$data = [
|
2024-04-01 19:36:03 +02:00
|
|
|
'secret' => $this->secret,
|
|
|
|
'response' => $response,
|
2024-08-15 15:11:32 +02:00
|
|
|
'sitekey' => $this->sitekey
|
|
|
|
];
|
2024-04-01 19:36:03 +02:00
|
|
|
|
2024-08-15 15:11:32 +02:00
|
|
|
if ($remote_ip !== null) {
|
|
|
|
$data['remoteip'] = $remote_ip;
|
|
|
|
}
|
|
|
|
|
|
|
|
$ret = $this->http->requestGet('https://hcaptcha.com/siteverify', $data);
|
2024-04-01 19:36:03 +02:00
|
|
|
$resp = json_decode($ret, true, 16, JSON_THROW_ON_ERROR);
|
|
|
|
|
|
|
|
return isset($resp['success']) && $resp['success'];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-15 15:11:32 +02:00
|
|
|
interface RemoteCaptchaQuery {
|
|
|
|
/**
|
|
|
|
* Name of the response field in the form data expected by the implementation.
|
|
|
|
*
|
|
|
|
* @return string The name of the field.
|
|
|
|
*/
|
|
|
|
public function responseField(): string;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if the user at the remote ip passed the captcha.
|
|
|
|
*
|
|
|
|
* @param string $response User provided response.
|
|
|
|
* @param ?string $remote_ip User ip. Leave to null to only check the response value.
|
|
|
|
* @return bool Returns true if the user passed the captcha.
|
|
|
|
* @throws RuntimeException|JsonException Throws on IO errors or if it fails to decode the answer.
|
|
|
|
*/
|
|
|
|
public function verify(string $response, ?string $remote_ip): bool;
|
|
|
|
}
|
|
|
|
|
2024-04-01 19:36:03 +02:00
|
|
|
class NativeCaptchaQuery {
|
|
|
|
private HttpDriver $http;
|
|
|
|
private string $domain;
|
|
|
|
private string $provider_check;
|
2024-08-15 15:17:54 +02:00
|
|
|
private string $extra;
|
2024-04-01 19:36:03 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @param HttpDriver $http The http client.
|
|
|
|
* @param string $domain The server's domain.
|
|
|
|
* @param string $provider_check Path to the endpoint.
|
2024-08-15 15:17:54 +02:00
|
|
|
* @param string $extra Extra http parameters.
|
2024-04-01 19:36:03 +02:00
|
|
|
*/
|
2024-08-15 15:17:54 +02:00
|
|
|
function __construct(HttpDriver $http, string $domain, string $provider_check, string $extra) {
|
2024-04-01 19:36:03 +02:00
|
|
|
$this->http = $http;
|
|
|
|
$this->domain = $domain;
|
|
|
|
$this->provider_check = $provider_check;
|
2024-08-15 15:17:54 +02:00
|
|
|
$this->extra = $extra;
|
2024-04-01 19:36:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if the user at the remote ip passed the native vichan captcha.
|
|
|
|
*
|
|
|
|
* @param string $user_text Remote user's text input.
|
|
|
|
* @param string $user_cookie Remote user cookie.
|
|
|
|
* @return bool Returns true if the user passed the check.
|
|
|
|
* @throws RuntimeException Throws on IO errors.
|
|
|
|
*/
|
2024-08-15 15:17:54 +02:00
|
|
|
public function verify(string $user_text, string $user_cookie): bool {
|
2024-08-15 15:11:32 +02:00
|
|
|
$data = [
|
2024-04-01 19:36:03 +02:00
|
|
|
'mode' => 'check',
|
|
|
|
'text' => $user_text,
|
2024-08-15 15:17:54 +02:00
|
|
|
'extra' => $this->extra,
|
2024-04-01 19:36:03 +02:00
|
|
|
'cookie' => $user_cookie
|
2024-08-15 15:11:32 +02:00
|
|
|
];
|
2024-04-01 19:36:03 +02:00
|
|
|
|
|
|
|
$ret = $this->http->requestGet($this->domain . '/' . $this->provider_check, $data);
|
|
|
|
return $ret === '1';
|
|
|
|
}
|
|
|
|
}
|