[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/phpbb/captcha/plugins/ -> recaptcha_v3.php (source)

   1  <?php
   2  /**
   3   *
   4   * This file is part of the phpBB Forum Software package.
   5   *
   6   * @copyright (c) phpBB Limited <https://www.phpbb.com>
   7   * @license GNU General Public License, version 2 (GPL-2.0)
   8   *
   9   * For full copyright and license information, please see
  10   * the docs/CREDITS.txt file.
  11   *
  12   */
  13  
  14  namespace phpbb\captcha\plugins;
  15  
  16  /**
  17   * Google reCAPTCHA v3 plugin.
  18   */
  19  class recaptcha_v3 extends captcha_abstract
  20  {
  21      /**
  22       * Possible request methods to verify the token.
  23       */
  24      const CURL            = 'curl';
  25      const POST            = 'post';
  26      const SOCKET        = 'socket';
  27  
  28      /**
  29       * Possible domain names to load the script and verify the token.
  30       */
  31      const GOOGLE        = 'google.com';
  32      const RECAPTCHA        = 'recaptcha.net';
  33      const RECAPTCHA_CN    = 'recaptcha.google.cn';
  34  
  35      /** @var string[] List of supported domains */
  36      static public $supported_domains = [
  37          self::GOOGLE,
  38          self::RECAPTCHA,
  39          self::RECAPTCHA_CN
  40      ];
  41  
  42      /** @var array CAPTCHA types mapped to their action */
  43      static protected $actions = [
  44          0                => 'default',
  45          CONFIRM_REG        => 'register',
  46          CONFIRM_LOGIN    => 'login',
  47          CONFIRM_POST    => 'post',
  48          CONFIRM_REPORT    => 'report',
  49      ];
  50  
  51      /**
  52       * Get CAPTCHA types mapped to their action.
  53       *
  54       * @static
  55       * @return array
  56       */
  57  	static public function get_actions()
  58      {
  59          return self::$actions;
  60      }
  61  
  62      /**
  63       * Execute.
  64       *
  65       * Not needed by this CAPTCHA plugin.
  66       *
  67       * @return void
  68       */
  69  	public function execute()
  70      {
  71      }
  72  
  73      /**
  74       * Execute demo.
  75       *
  76       * Not needed by this CAPTCHA plugin.
  77       *
  78       * @return void
  79       */
  80  	public function execute_demo()
  81      {
  82      }
  83  
  84      /**
  85       * Get generator class.
  86       *
  87       * Not needed by this CAPTCHA plugin.
  88       *
  89       * @throws \Exception
  90       * @return void
  91       */
  92  	public function get_generator_class()
  93      {
  94          throw new \Exception('No generator class given.');
  95      }
  96  
  97      /**
  98       * Get CAPTCHA plugin name.
  99       *
 100       * @return string
 101       */
 102  	public function get_name()
 103      {
 104          return 'CAPTCHA_RECAPTCHA_V3';
 105      }
 106  
 107      /**
 108       * Indicator that this CAPTCHA plugin requires configuration.
 109       *
 110       * @return bool
 111       */
 112  	public function has_config()
 113      {
 114          return true;
 115      }
 116  
 117      /**
 118       * Initialize this CAPTCHA plugin.
 119       *
 120       * @param int    $type    The CAPTCHA type
 121       * @return void
 122       */
 123  	public function init($type)
 124      {
 125          /**
 126           * @var \phpbb\language\language    $language    Language object
 127           */
 128          global $language;
 129  
 130          $language->add_lang('captcha_recaptcha');
 131  
 132          parent::init($type);
 133      }
 134  
 135      /**
 136       * Whether or not this CAPTCHA plugin is available and setup.
 137       *
 138       * @return bool
 139       */
 140  	public function is_available()
 141      {
 142          /**
 143           * @var \phpbb\config\config        $config        Config object
 144           * @var \phpbb\language\language    $language    Language object
 145           */
 146          global $config, $language;
 147  
 148          $language->add_lang('captcha_recaptcha');
 149  
 150          return ($config->offsetGet('recaptcha_v3_key') ?? false) && ($config->offsetGet('recaptcha_v3_secret') ?? false);
 151      }
 152  
 153      /**
 154       * Create the ACP page for configuring this CAPTCHA plugin.
 155       *
 156       * @param string        $id            The ACP module identifier
 157       * @param \acp_captcha    $module        The ACP module basename
 158       * @return void
 159       */
 160  	public function acp_page($id, $module)
 161      {
 162          /**
 163           * @var \phpbb\config\config        $config        Config object
 164           * @var \phpbb\language\language    $language    Language object
 165           * @var \phpbb\log\log                $phpbb_log    Log object
 166           * @var \phpbb\request\request        $request    Request object
 167           * @var \phpbb\template\template    $template    Template object
 168           * @var \phpbb\user                    $user        User object
 169           */
 170          global $config, $language, $phpbb_log, $request, $template, $user;
 171  
 172          $module->tpl_name        = 'captcha_recaptcha_v3_acp';
 173          $module->page_title        = 'ACP_VC_SETTINGS';
 174          $recaptcha_v3_method    = $request->variable('recaptcha_v3_method', '', true);
 175  
 176          $form_key = 'acp_captcha';
 177          add_form_key($form_key);
 178  
 179          if ($request->is_set_post('submit'))
 180          {
 181              if (!check_form_key($form_key))
 182              {
 183                  trigger_error($language->lang('FORM_INVALID') . adm_back_link($module->u_action), E_USER_WARNING);
 184              }
 185  
 186              if (empty($recaptcha_v3_method))
 187              {
 188                  trigger_error($language->lang('EMPTY_RECAPTCHA_V3_REQUEST_METHOD') . adm_back_link($module->u_action), E_USER_WARNING);
 189              }
 190  
 191              $recaptcha_domain = $request->variable('recaptcha_v3_domain', '', true);
 192              if (in_array($recaptcha_domain, self::$supported_domains))
 193              {
 194                  $config->set('recaptcha_v3_domain', $recaptcha_domain);
 195              }
 196  
 197              $config->set('recaptcha_v3_key', $request->variable('recaptcha_v3_key', '', true));
 198              $config->set('recaptcha_v3_secret', $request->variable('recaptcha_v3_secret', '', true));
 199              $config->set('recaptcha_v3_method', $recaptcha_v3_method);
 200  
 201              foreach (self::$actions as $action)
 202              {
 203                  $config->set("recaptcha_v3_threshold_{$action}", $request->variable("recaptcha_v3_threshold_{$action}", 0.50));
 204              }
 205  
 206              $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_CONFIG_VISUAL');
 207  
 208              trigger_error($language->lang('CONFIG_UPDATED') . adm_back_link($module->u_action));
 209          }
 210  
 211          foreach (self::$actions as $action)
 212          {
 213              $template->assign_block_vars('thresholds', [
 214                  'key'    => "recaptcha_v3_threshold_{$action}",
 215                  'value'    => $config["recaptcha_v3_threshold_{$action}"] ?? 0.5,
 216              ]);
 217          }
 218  
 219          $template->assign_vars([
 220              'CAPTCHA_NAME'                => $this->get_service_name(),
 221              'CAPTCHA_PREVIEW'            => $this->get_demo_template($id),
 222  
 223              'RECAPTCHA_V3_KEY'            => $config['recaptcha_v3_key'] ?? '',
 224              'RECAPTCHA_V3_SECRET'        => $config['recaptcha_v3_secret'] ?? '',
 225  
 226              'RECAPTCHA_V3_DOMAIN'        => $config['recaptcha_v3_domain'] ?? self::GOOGLE,
 227              'RECAPTCHA_V3_DOMAINS'        => self::$supported_domains,
 228  
 229              'RECAPTCHA_V3_METHOD'        => $config['recaptcha_v3_method'] ?? '',
 230              'RECAPTCHA_V3_METHODS'        => [
 231                  self::POST        => ini_get('allow_url_fopen') && function_exists('file_get_contents'),
 232                  self::CURL        => extension_loaded('curl') && function_exists('curl_init'),
 233                  self::SOCKET    => function_exists('fsockopen'),
 234              ],
 235  
 236              'U_ACTION'                    => $module->u_action,
 237          ]);
 238      }
 239  
 240      /**
 241       * Create the ACP page for previewing this CAPTCHA plugin.
 242       *
 243       * @param string    $id        The module identifier
 244       * @return bool|string
 245       */
 246  	public function get_demo_template($id)
 247      {
 248          return $this->get_template();
 249      }
 250  
 251      /**
 252       * Get the template for this CAPTCHA plugin.
 253       *
 254       * @return bool|string        False if CAPTCHA is already solved, template file name otherwise
 255       */
 256  	public function get_template()
 257      {
 258          /**
 259           * @var \phpbb\config\config        $config                Config object
 260           * @var \phpbb\language\language    $language            Language object
 261           * @var \phpbb\template\template    $template            Template object
 262           * @var string                        $phpbb_root_path    phpBB root path
 263           * @var string                        $phpEx                php File extensions
 264           */
 265          global $config, $language, $template, $phpbb_root_path, $phpEx;
 266  
 267          if ($this->is_solved())
 268          {
 269              return false;
 270          }
 271  
 272          $contact = phpbb_get_board_contact_link($config, $phpbb_root_path, $phpEx);
 273          $explain = $this->type !== CONFIRM_POST ? 'CONFIRM_EXPLAIN' : 'POST_CONFIRM_EXPLAIN';
 274  
 275          $domain = $config['recaptcha_v3_domain'] ?? self::GOOGLE;
 276          $render = $config['recaptcha_v3_key'] ?? '';
 277  
 278          $template->assign_vars([
 279              'CONFIRM_EXPLAIN'        => $language->lang($explain, '<a href="' . $contact . '">', '</a>'),
 280  
 281              'RECAPTCHA_ACTION'        => self::$actions[$this->type] ?? reset(self::$actions),
 282              'RECAPTCHA_KEY'            => $config['recaptcha_v3_key'] ?? '',
 283              'U_RECAPTCHA_SCRIPT'    => sprintf('//%1$s/recaptcha/api.js?render=%2$s', $domain, $render),
 284  
 285              'S_CONFIRM_CODE'        => true,
 286              'S_RECAPTCHA_AVAILABLE'    => $this->is_available(),
 287              'S_TYPE'                => $this->type,
 288          ]);
 289  
 290          return 'captcha_recaptcha_v3.html';
 291      }
 292  
 293      /**
 294       * Validate the user's input.
 295       *
 296       * @return bool|string
 297       */
 298  	public function validate()
 299      {
 300          if (!parent::validate())
 301          {
 302              return false;
 303          }
 304  
 305          return $this->recaptcha_verify_token();
 306      }
 307  
 308      /**
 309       * Validate the token returned by Google reCAPTCHA v3.
 310       *
 311       * @return bool|string        False on success, string containing the error otherwise
 312       */
 313  	protected function recaptcha_verify_token()
 314      {
 315          /**
 316           * @var \phpbb\config\config        $config        Config object
 317           * @var \phpbb\language\language    $language    Language object
 318           * @var \phpbb\request\request        $request    Request object
 319           * @var \phpbb\user                    $user        User object
 320           */
 321          global $config, $language, $request, $user;
 322  
 323          $token        = $request->variable('recaptcha_token', '', true);
 324          $action        = $request->variable('recaptcha_action', '', true);
 325          $action        = in_array($action, self::$actions) ? $action : reset(self::$actions);
 326          $threshold    = (double) $config["recaptcha_v3_threshold_{$action}"] ?? 0.5;
 327  
 328          // No token was provided, discard spam submissions
 329          if (empty($token))
 330          {
 331              return $language->lang('RECAPTCHA_INCORRECT');
 332          }
 333  
 334          // Create the request method that should be used
 335          switch ($config['recaptcha_v3_method'] ?? '')
 336          {
 337              case self::CURL:
 338                  $method = new \ReCaptcha\RequestMethod\CurlPost();
 339              break;
 340  
 341              case self::SOCKET:
 342                  $method = new \ReCaptcha\RequestMethod\SocketPost();
 343              break;
 344  
 345              case self::POST:
 346              default:
 347                  $method = new \ReCaptcha\RequestMethod\Post();
 348              break;
 349          }
 350  
 351          // Create the recaptcha instance
 352          $recaptcha = new \ReCaptcha\ReCaptcha($config['recaptcha_v3_secret'], $method);
 353  
 354          // Set the expected action and threshold, and verify the token
 355          $result = $recaptcha->setExpectedAction($action)
 356                              ->setScoreThreshold($threshold)
 357                              ->verify($token, $user->ip);
 358  
 359          if ($result->isSuccess())
 360          {
 361              $this->solved = true;
 362              $this->confirm_code = $this->code;
 363  
 364              return false;
 365          }
 366  
 367          return $language->lang('RECAPTCHA_INCORRECT');
 368      }
 369  
 370      /**
 371       * {@inheritDoc}
 372       */
 373  	public function get_login_error_attempts(): string
 374      {
 375          global $language;
 376  
 377          $language->add_lang('captcha_recaptcha');
 378  
 379          return 'RECAPTCHA_V3_LOGIN_ERROR_ATTEMPTS';
 380      }
 381  }


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1