[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/plugins/captcha/recaptcha/ -> recaptcha.php (source)

   1  <?php
   2  
   3  /**
   4   * @package     Joomla.Plugin
   5   * @subpackage  Captcha
   6   *
   7   * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
   8   * @license     GNU General Public License version 2 or later; see LICENSE.txt
   9  
  10   * @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
  11   */
  12  
  13  use Joomla\CMS\Captcha\Google\HttpBridgePostRequestMethod;
  14  use Joomla\CMS\Factory;
  15  use Joomla\CMS\Language\Text;
  16  use Joomla\CMS\Plugin\CMSPlugin;
  17  use Joomla\Utilities\IpHelper;
  18  use ReCaptcha\ReCaptcha;
  19  
  20  // phpcs:disable PSR1.Files.SideEffects
  21  \defined('_JEXEC') or die;
  22  // phpcs:enable PSR1.Files.SideEffects
  23  
  24  /**
  25   * Recaptcha Plugin
  26   * Based on the official recaptcha library( https://packagist.org/packages/google/recaptcha )
  27   *
  28   * @since  2.5
  29   */
  30  class PlgCaptchaRecaptcha extends CMSPlugin
  31  {
  32      /**
  33       * Load the language file on instantiation.
  34       *
  35       * @var    boolean
  36       * @since  3.1
  37       */
  38      protected $autoloadLanguage = true;
  39  
  40      /**
  41       * Application object.
  42       *
  43       * @var    \Joomla\CMS\Application\CMSApplication
  44       * @since  4.0.0
  45       */
  46      protected $app;
  47  
  48      /**
  49       * Reports the privacy related capabilities for this plugin to site administrators.
  50       *
  51       * @return  array
  52       *
  53       * @since   3.9.0
  54       */
  55      public function onPrivacyCollectAdminCapabilities()
  56      {
  57          $this->loadLanguage();
  58  
  59          return array(
  60              Text::_('PLG_CAPTCHA_RECAPTCHA') => array(
  61                  Text::_('PLG_RECAPTCHA_PRIVACY_CAPABILITY_IP_ADDRESS'),
  62              ),
  63          );
  64      }
  65  
  66      /**
  67       * Initialise the captcha
  68       *
  69       * @param   string  $id  The id of the field.
  70       *
  71       * @return  Boolean True on success, false otherwise
  72       *
  73       * @since   2.5
  74       * @throws  \RuntimeException
  75       */
  76      public function onInit($id = 'dynamic_recaptcha_1')
  77      {
  78          $pubkey = $this->params->get('public_key', '');
  79  
  80          if ($pubkey === '') {
  81              throw new \RuntimeException(Text::_('PLG_RECAPTCHA_ERROR_NO_PUBLIC_KEY'));
  82          }
  83  
  84          $apiSrc = 'https://www.google.com/recaptcha/api.js?onload=JoomlainitReCaptcha2&render=explicit&hl='
  85              . Factory::getLanguage()->getTag();
  86  
  87          // Load assets, the callback should be first
  88          $this->app->getDocument()->getWebAssetManager()
  89              ->registerAndUseScript('plg_captcha_recaptcha', 'plg_captcha_recaptcha/recaptcha.min.js', [], ['defer' => true])
  90              ->registerAndUseScript('plg_captcha_recaptcha.api', $apiSrc, [], ['defer' => true], ['plg_captcha_recaptcha']);
  91  
  92          return true;
  93      }
  94  
  95      /**
  96       * Gets the challenge HTML
  97       *
  98       * @param   string  $name   The name of the field. Not Used.
  99       * @param   string  $id     The id of the field.
 100       * @param   string  $class  The class of the field.
 101       *
 102       * @return  string  The HTML to be embedded in the form.
 103       *
 104       * @since  2.5
 105       */
 106      public function onDisplay($name = null, $id = 'dynamic_recaptcha_1', $class = '')
 107      {
 108          $dom = new \DOMDocument('1.0', 'UTF-8');
 109          $ele = $dom->createElement('div');
 110          $ele->setAttribute('id', $id);
 111  
 112          $ele->setAttribute('class', ((trim($class) == '') ? 'g-recaptcha' : ($class . ' g-recaptcha')));
 113          $ele->setAttribute('data-sitekey', $this->params->get('public_key', ''));
 114          $ele->setAttribute('data-theme', $this->params->get('theme2', 'light'));
 115          $ele->setAttribute('data-size', $this->params->get('size', 'normal'));
 116          $ele->setAttribute('data-tabindex', $this->params->get('tabindex', '0'));
 117          $ele->setAttribute('data-callback', $this->params->get('callback', ''));
 118          $ele->setAttribute('data-expired-callback', $this->params->get('expired_callback', ''));
 119          $ele->setAttribute('data-error-callback', $this->params->get('error_callback', ''));
 120  
 121          $dom->appendChild($ele);
 122  
 123          return $dom->saveHTML($ele);
 124      }
 125  
 126      /**
 127       * Calls an HTTP POST function to verify if the user's guess was correct
 128       *
 129       * @param   string  $code  Answer provided by user. Not needed for the Recaptcha implementation
 130       *
 131       * @return  True if the answer is correct, false otherwise
 132       *
 133       * @since   2.5
 134       * @throws  \RuntimeException
 135       */
 136      public function onCheckAnswer($code = null)
 137      {
 138          $input      = Factory::getApplication()->input;
 139          $privatekey = $this->params->get('private_key');
 140          $version    = $this->params->get('version', '2.0');
 141          $remoteip   = IpHelper::getIp();
 142          $response   = null;
 143          $spam       = false;
 144  
 145          switch ($version) {
 146              case '2.0':
 147                  $response  = $code ?: $input->get('g-recaptcha-response', '', 'string');
 148                  $spam      = ($response === '');
 149                  break;
 150          }
 151  
 152          // Check for Private Key
 153          if (empty($privatekey)) {
 154              throw new \RuntimeException(Text::_('PLG_RECAPTCHA_ERROR_NO_PRIVATE_KEY'), 500);
 155          }
 156  
 157          // Check for IP
 158          if (empty($remoteip)) {
 159              throw new \RuntimeException(Text::_('PLG_RECAPTCHA_ERROR_NO_IP'), 500);
 160          }
 161  
 162          // Discard spam submissions
 163          if ($spam) {
 164              throw new \RuntimeException(Text::_('PLG_RECAPTCHA_ERROR_EMPTY_SOLUTION'), 500);
 165          }
 166  
 167          return $this->getResponse($privatekey, $remoteip, $response);
 168      }
 169  
 170      /**
 171       * Get the reCaptcha response.
 172       *
 173       * @param   string  $privatekey  The private key for authentication.
 174       * @param   string  $remoteip    The remote IP of the visitor.
 175       * @param   string  $response    The response received from Google.
 176       *
 177       * @return  bool True if response is good | False if response is bad.
 178       *
 179       * @since   3.4
 180       * @throws  \RuntimeException
 181       */
 182      private function getResponse(string $privatekey, string $remoteip, string $response)
 183      {
 184          $version = $this->params->get('version', '2.0');
 185  
 186          switch ($version) {
 187              case '2.0':
 188                  $apiResponse = (new ReCaptcha($privatekey, new HttpBridgePostRequestMethod()))->verify($response, $remoteip);
 189  
 190                  if (!$apiResponse->isSuccess()) {
 191                      foreach ($apiResponse->getErrorCodes() as $error) {
 192                          throw new \RuntimeException($error, 403);
 193                      }
 194  
 195                      return false;
 196                  }
 197  
 198                  break;
 199          }
 200  
 201          return true;
 202      }
 203  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer