hCaptcha Integration

This commit is contained in:
2024-04-23 14:05:29 +02:00
parent aea20b7a10
commit 51ee723dcb
22 changed files with 275 additions and 145 deletions

View File

@@ -16,7 +16,7 @@ class Info extends Request {
$settings = $this->context->getSettings();
$this->result["info"] = [
"registrationAllowed" => $settings->isRegistrationAllowed(),
"recaptchaEnabled" => $settings->isRecaptchaEnabled(),
"captchaEnabled" => $settings->isCaptchaEnabled(),
"version" => WEBBASE_VERSION,
"siteName" => $settings->getSiteName(),
];

View File

@@ -3,6 +3,8 @@
namespace Core\API {
use Core\API\Parameter\IntegerType;
use Core\API\Parameter\StringType;
use Core\Objects\Captcha\CaptchaProvider;
use Core\Objects\Context;
use Core\API\Parameter\ArrayType;
use Core\API\Parameter\Parameter;
@@ -20,7 +22,7 @@ namespace Core\API {
"allowed_extensions" => new ArrayType("allowed_extensions", Parameter::TYPE_STRING),
"trusted_domains" => new ArrayType("trusted_domains", Parameter::TYPE_STRING),
"user_registration_enabled" => new Parameter("user_registration_enabled", Parameter::TYPE_BOOLEAN),
"recaptcha_enabled" => new Parameter("recaptcha_enabled", Parameter::TYPE_BOOLEAN),
"captcha_provider" => new StringType("captcha_provider", -1, true, "none", CaptchaProvider::PROVIDERS),
"mail_enabled" => new Parameter("mail_enabled", Parameter::TYPE_BOOLEAN),
"mail_port" => new IntegerType("mail_port", 1, 65535)
];

View File

@@ -10,28 +10,12 @@ use Core\Objects\Context;
class Stats extends Request {
private bool $mailConfigured;
private bool $recaptchaConfigured;
public function __construct(Context $context, $externalCall = false) {
parent::__construct($context, $externalCall, array());
}
private function checkSettings(): bool {
$req = new \Core\API\Settings\Get($this->context);
$this->success = $req->execute(array("key" => "^(mail_enabled|recaptcha_enabled)$"));
$this->lastError = $req->getLastError();
if ($this->success) {
$settings = $req->getResult()["settings"];
$this->mailConfigured = $settings["mail_enabled"];
$this->recaptchaConfigured = $settings["recaptcha_enabled"];
}
return $this->success;
}
public function _execute(): bool {
$settings = $this->context->getSettings();
$sql = $this->context->getSQL();
$userCount = User::count($sql);
$pageCount = Route::count($sql, new CondBool("active"));
@@ -54,10 +38,6 @@ class Stats extends Request {
$loadAvg = sys_getloadavg();
}
if (!$this->checkSettings()) {
return false;
}
$this->result["data"] = [
"userCount" => $userCount,
"pageCount" => $pageCount,
@@ -69,8 +49,8 @@ class Stats extends Request {
"memory_usage" => memory_get_usage(),
"load_avg" => $loadAvg,
"database" => $this->context->getSQL()->getStatus(),
"mail" => $this->mailConfigured,
"reCaptcha" => $this->recaptchaConfigured
"mail" => $settings->isMailEnabled(),
"captcha" => $settings->getCaptchaProvider()?->jsonSerialize()
],
];

View File

@@ -727,7 +727,7 @@ namespace Core\API\User {
);
$settings = $context->getSettings();
if ($settings->isRecaptchaEnabled()) {
if ($settings->isCaptchaEnabled()) {
$parameters["captcha"] = new StringType("captcha");
}
@@ -747,7 +747,7 @@ namespace Core\API\User {
return $this->createError("User Registration is not enabled.");
}
if ($settings->isRecaptchaEnabled()) {
if ($settings->isCaptchaEnabled()) {
$captcha = $this->getParam("captcha");
$req = new VerifyCaptcha($this->context);
if (!$req->execute(array("captcha" => $captcha, "action" => "register"))) {
@@ -1003,7 +1003,7 @@ namespace Core\API\User {
);
$settings = $context->getSettings();
if ($settings->isRecaptchaEnabled()) {
if ($settings->isCaptchaEnabled()) {
$parameters["captcha"] = new StringType("captcha");
}
@@ -1021,7 +1021,7 @@ namespace Core\API\User {
return $this->createError("The mail service is not enabled, please contact the server administration.");
}
if ($settings->isRecaptchaEnabled()) {
if ($settings->isCaptchaEnabled()) {
$captcha = $this->getParam("captcha");
$req = new VerifyCaptcha($this->context);
if (!$req->execute(array("captcha" => $captcha, "action" => "resetPassword"))) {
@@ -1096,7 +1096,7 @@ namespace Core\API\User {
);
$settings = $context->getSettings();
if ($settings->isRecaptchaEnabled()) {
if ($settings->isCaptchaEnabled()) {
$parameters["captcha"] = new StringType("captcha");
}
@@ -1110,7 +1110,7 @@ namespace Core\API\User {
}
$settings = $this->context->getSettings();
if ($settings->isRecaptchaEnabled()) {
if ($settings->isCaptchaEnabled()) {
$captcha = $this->getParam("captcha");
$req = new VerifyCaptcha($this->context);
if (!$req->execute(array("captcha" => $captcha, "action" => "resendConfirmation"))) {

View File

@@ -18,45 +18,15 @@ class VerifyCaptcha extends Request {
public function _execute(): bool {
$settings = $this->context->getSettings();
if (!$settings->isRecaptchaEnabled()) {
return $this->createError("Google reCaptcha is not enabled.");
$captchaProvider = $settings->getCaptchaProvider();
if ($captchaProvider === null) {
return $this->createError("No Captcha configured.");
}
$url = "https://www.google.com/recaptcha/api/siteverify";
$secret = $settings->getRecaptchaSecretKey();
$captcha = $this->getParam("captcha");
$action = $this->getParam("action");
$params = array(
"secret" => $secret,
"response" => $captcha
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = @json_decode(curl_exec($ch), true);
curl_close($ch);
$this->success = false;
$this->lastError = "Could not verify captcha: No response from google received.";
if ($response) {
$this->success = $response["success"];
if (!$this->success) {
$this->lastError = "Could not verify captcha: " . implode(";", $response["error-codes"]);
} else {
$score = $response["score"];
if ($action !== $response["action"]) {
$this->createError("Could not verify captcha: Action does not match");
} else if ($score < 0.7) {
$this->createError("Could not verify captcha: Google ReCaptcha Score < 0.7 (Your score: $score), you are likely a bot");
}
}
}
$this->success = $captchaProvider->verify($captcha, $action);
$this->lastError = $captchaProvider->getError();
return $this->success;
}