diff --git a/README.md b/README.md index c93805f..7835209 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ A spam protection field for Silverstripe using the hCaptcha service. * Silverstripe Framework 4.x * [Silverstripe Spam Protection 3.x](https://github.com/silverstripe/silverstripe-spamprotection/) -* PHP CURL +* [Guzzle 6.5](https://github.com/guzzle/guzzle/tree/6.5) ## Installation (with composer) diff --git a/composer.json b/composer.json index fb58576..123dba8 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,7 @@ } ], "require": { + "guzzlehttp/guzzle": "^6.5", "silverstripe/framework": "^4.0", "silverstripe/spamprotection": "^3.0" }, diff --git a/src/Forms/HCaptchaField.php b/src/Forms/HCaptchaField.php index 319ebc0..1893ea0 100644 --- a/src/Forms/HCaptchaField.php +++ b/src/Forms/HCaptchaField.php @@ -79,9 +79,9 @@ public function Field($properties = []) */ public function validate($validator) { - $hCaptchaResponse = Controller::curr()->getRequest()->requestVar('h-captcha-response'); + $valid = $this->processCaptcha(); - if (!isset($hCaptchaResponse)) { + if (!$valid) { $validator->validationError( $this->name, _t( @@ -90,50 +90,45 @@ public function validate($validator) ), 'validation' ); - - return false; } - if (!function_exists('curl_init')) { - user_error('You must enable php-curl to use this field', E_USER_ERROR); + return $valid; + } + + + /** + * Validates the captcha against the hCaptcha API + * @return bool Returns boolean true if valid false if not + */ + private function processCaptcha() + { + $hCaptchaResponse = Controller::curr()->getRequest()->requestVar('h-captcha-response'); + if (!isset($hCaptchaResponse) || !$hCaptchaResponse) { return false; } $secretKey = $this->getSecretKey(); - $url = 'https://hcaptcha.com/siteverify' . - '?secret=' . $secretKey . - '&response=' . rawurlencode($hCaptchaResponse) . - '&remoteip=' . rawurlencode($_SERVER['REMOTE_ADDR']); - $ch = curl_init($url); - - curl_setopt($ch, CURLOPT_TIMEOUT, 10); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_USERAGENT, str_replace(',', '/', 'SilverStripe')); - $response = json_decode(curl_exec($ch), true); - - if (is_array($response)) { - if (array_key_exists('success', $response) && $response['success'] == false) { - $validator->validationError( - $this->name, - _t( - 'X3dgoo\\HCaptcha\\Forms\\HCaptchaField.EMPTY', - 'Please answer the captcha. If you do not see the captcha please enable Javascript' - ), - 'validation' - ); - - return false; - } - } else { - $validator->validationError( - $this->name, - _t( - 'X3dgoo\\HCaptcha\\Forms\\HCaptchaField.VALIDATE_ERROR', - 'Captcha could not be validated' - ), - 'validation' - ); + + $client = new \GuzzleHttp\Client([ + 'base_uri' => 'https://hcaptcha.com/', + ]); + + $response = $client->request( + 'GET', + 'siteverify', + [ + 'query' => [ + 'secret' => $secretKey, + 'response' => rawurlencode($hCaptchaResponse), + 'remoteip' => rawurlencode($_SERVER['REMOTE_ADDR']), + ], + ] + ); + + $response = json_decode($response->getBody(), true); + + if (!is_array($response)) { $logger = Injector::inst()->get(LoggerInterface::class); $logger->error( 'Captcha validation failed as request was not successful.' @@ -142,6 +137,10 @@ public function validate($validator) return false; } + if (array_key_exists('success', $response) && $response['success'] === false) { + return false; + } + return true; }