Inline RecaptchaHandlerV2::validate() in RecaptchaHandler
authorTim Düsterhus <duesterhus@woltlab.com>
Thu, 3 Dec 2020 10:11:43 +0000 (11:11 +0100)
committerTim Düsterhus <duesterhus@woltlab.com>
Thu, 3 Dec 2020 10:15:23 +0000 (11:15 +0100)
wcfsetup/install/files/lib/system/captcha/RecaptchaHandler.class.php
wcfsetup/install/files/lib/system/recaptcha/RecaptchaHandlerV2.class.php

index cb15d569de9772862ba17fdd51886da6fb93a616..bf77a5eeeadd8c412a0ac667150b8ef2e7e95460 100644 (file)
@@ -1,13 +1,16 @@
 <?php
 namespace wcf\system\captcha;
-use wcf\system\recaptcha\RecaptchaHandlerV2;
+use wcf\system\exception\UserInputException;
 use wcf\system\WCF;
+use wcf\util\HTTPRequest;
+use wcf\util\JSON;
+use wcf\util\UserUtil;
 
 /**
  * Captcha handler for reCAPTCHA.
  * 
- * @author     Matthias Schmidt
- * @copyright  2001-2019 WoltLab GmbH
+ * @author     Tim Duesterhus, Matthias Schmidt
+ * @copyright  2001-2020 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\Captcha
  */
@@ -81,6 +84,44 @@ class RecaptchaHandler implements ICaptchaHandler {
        public function validate() {
                if (WCF::getSession()->getVar('recaptchaDone')) return;
                
-               RecaptchaHandlerV2::getInstance()->validate($this->response, $this->challenge ?: 'v2');
+               // fail if response is empty to avoid sending api requests
+               if (empty($this->response)) {
+                       throw new UserInputException('recaptchaString', 'false');
+               }
+               
+               $type = $this->challenge ?: 'v2';
+               
+               if ($type === 'v2') {
+                       $key = RECAPTCHA_PRIVATEKEY;
+               }
+               else if ($type === 'invisible') {
+                       $key = RECAPTCHA_PRIVATEKEY_INVISIBLE;
+               }
+               else {
+                       throw new \InvalidArgumentException('$type must be either v2 or invisible.');
+               }
+               
+               $request = new HTTPRequest('https://www.google.com/recaptcha/api/siteverify?secret='.rawurlencode($key).'&response='.rawurlencode($this->response).'&remoteip='.rawurlencode(UserUtil::getIpAddress()), ['timeout' => 10]);
+               
+               try {
+                       $request->execute();
+                       $reply = $request->getReply();
+                       $data = JSON::decode($reply['body']);
+                       
+                       if ($data['success']) {
+                               // yeah
+                       }
+                       else {
+                               throw new UserInputException('recaptchaString', 'false');
+                       }
+               }
+               catch (\Exception $e) {
+                       if ($e instanceof UserInputException) throw $e;
+                       
+                       // log error, but accept captcha
+                       \wcf\functions\exception\logThrowable($e);
+               }
+               
+               WCF::getSession()->register('recaptchaDone', true);
        }
 }
index 6d5941d345b17a2e6b4d095f0b8d53ce37fe02db..eb50ec2ad2ed1e32a5b22b71eadfcabc90515440 100644 (file)
@@ -14,6 +14,7 @@ use wcf\util\UserUtil;
  * @copyright  2001-2019 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\Recaptcha
+ * @deprecated 5.4 - This was an implementation detail of wcf\system\captcha\RecaptchaHandler.
  */
 class RecaptchaHandlerV2 extends SingletonFactory {
        /**