[ticket/17414] Move more functionality to base and fix turnstile language

PHPBB-17414
This commit is contained in:
Marc Alexander 2024-10-13 21:41:11 +02:00
parent 48454308ae
commit cf16a76f0c
No known key found for this signature in database
GPG key ID: 50E0D2423696F995
5 changed files with 103 additions and 39 deletions

View file

@ -2,34 +2,118 @@
namespace phpbb\captcha\plugins; namespace phpbb\captcha\plugins;
use phpbb\captcha\plugins\plugin_interface; use phpbb\config\config;
use phpbb\db\driver\driver_interface; use phpbb\db\driver\driver_interface;
use phpbb\request\request_interface;
use phpbb\user;
abstract class base implements plugin_interface abstract class base implements plugin_interface
{ {
/** @var config */
protected config $config;
/** @var driver_interface */ /** @var driver_interface */
protected driver_interface $db; protected driver_interface $db;
/** @var request_interface */
protected request_interface $request;
/** @var user */
protected user $user;
/** @var int Attempts at solving the CAPTCHA */
protected int $attempts = 0;
/** @var bool Resolved state of captcha */ /** @var bool Resolved state of captcha */
protected bool $solved = false; protected bool $solved = false;
/** @var string Confirm code */
protected string $confirm_code = '';
/** @var string Confirm id hash */ /** @var string Confirm id hash */
protected string $confirm_id = ''; protected string $confirm_id = '';
/** @var confirm_type Confirmation type */
protected confirm_type $type = confirm_type::UNDEFINED;
/** @var string Last error message */ /** @var string Last error message */
protected string $last_error = ''; protected string $last_error = '';
/** /**
* Constructor for abstract captcha base class * Constructor for abstract captcha base class
* *
* @param config $config
* @param driver_interface $db * @param driver_interface $db
* @param request_interface $request
* @param user $user
*/ */
public function __construct(driver_interface $db) public function __construct(config $config, driver_interface $db, request_interface $request, user $user)
{ {
$this->config = $config;
$this->db = $db; $this->db = $db;
$this->request = $request;
$this->user = $user;
}
/**
* {@inheritDoc}
*/
public function init(confirm_type $type): void
{
$this->confirm_id = $this->request->variable('confirm_id', '');
$this->type = $type;
if (empty($this->confirm_id) || !$this->load_confirm_data())
{
// we have no confirm ID, better get ready to display something
$this->generate_confirm_data();
}
}
/**
* Look up attempts from confirm table
*/
protected function load_confirm_data(): bool
{
$sql = 'SELECT attempts
FROM ' . CONFIRM_TABLE . "
WHERE confirm_id = '" . $this->db->sql_escape($this->confirm_id) . "'
AND session_id = '" . $this->db->sql_escape($this->user->session_id) . "'
AND confirm_type = " . (int) $this->type;
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
if ($row)
{
$this->attempts = $row['attempts'];
return true;
}
return false;
}
/**
* Generate confirm data for tracking attempts
*
* @return void
*/
protected function generate_confirm_data(): void
{
$this->confirm_id = md5(unique_id());
$sql = 'INSERT INTO ' . CONFIRM_TABLE . ' ' . $this->db->sql_build_array('INSERT', array(
'confirm_id' => $this->confirm_id,
'session_id' => (string) $this->user->session_id,
'confirm_type' => $this->type
));
$this->db->sql_query($sql);
}
/**
* {@inheritDoc}
*/
public function get_hidden_fields(): array
{
return ['confirm_id' => $this->confirm_id];
} }
/** /**

View file

@ -17,6 +17,7 @@ namespace phpbb\captcha\plugins;
* Confirmation types for CAPTCHA plugins * Confirmation types for CAPTCHA plugins
*/ */
enum confirm_type: int { enum confirm_type: int {
case UNDEFINED = 0;
case REGISTRATION = 1; case REGISTRATION = 1;
case LOGIN = 2; case LOGIN = 2;
case POST = 3; case POST = 3;

View file

@ -19,7 +19,12 @@ class legacy_wrapper implements plugin_interface
private string $last_error; private string $last_error;
public function __construct($legacy_captcha) /**
* Constructor for legacy CAPTCHA wrapper
*
* @param object $legacy_captcha
*/
public function __construct(object $legacy_captcha)
{ {
$this->legacy_captcha = $legacy_captcha; $this->legacy_captcha = $legacy_captcha;
} }
@ -77,7 +82,7 @@ class legacy_wrapper implements plugin_interface
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function init(int $type): void public function init(confirm_type $type): void
{ {
if (method_exists($this->legacy_captcha, 'init')) if (method_exists($this->legacy_captcha, 'init'))
{ {

View file

@ -16,7 +16,6 @@ namespace phpbb\captcha\plugins;
use GuzzleHttp\Client; use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Exception\GuzzleException;
use phpbb\config\config; use phpbb\config\config;
use phpbb\db\driver\driver;
use phpbb\db\driver\driver_interface; use phpbb\db\driver\driver_interface;
use phpbb\language\language; use phpbb\language\language;
use phpbb\log\log_interface; use phpbb\log\log_interface;
@ -32,24 +31,15 @@ class turnstile extends base
/** @var string API endpoint for turnstile verification */ /** @var string API endpoint for turnstile verification */
private const VERIFY_ENDPOINT = 'https://challenges.cloudflare.com/turnstile/v0/siteverify'; private const VERIFY_ENDPOINT = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
/** @var config */
protected config $config;
/** @var language */ /** @var language */
protected language $language; protected language $language;
/** @var log_interface */ /** @var log_interface */
protected log_interface $log; protected log_interface $log;
/** @var request_interface */
protected request_interface $request;
/** @var template */ /** @var template */
protected template $template; protected template $template;
/** @var user */
protected user $user;
/** @var string Service name */ /** @var string Service name */
protected string $service_name = ''; protected string $service_name = '';
@ -73,14 +63,11 @@ class turnstile extends base
*/ */
public function __construct(config $config, driver_interface $db, language $language, log_interface $log, request_interface $request, template $template, user $user) public function __construct(config $config, driver_interface $db, language $language, log_interface $log, request_interface $request, template $template, user $user)
{ {
parent::__construct($db); parent::__construct($config, $db, $request, $user);
$this->config = $config;
$this->language = $language; $this->language = $language;
$this->log = $log; $this->log = $log;
$this->request = $request;
$this->template = $template; $this->template = $template;
$this->user = $user;
} }
/** /**
@ -88,7 +75,7 @@ class turnstile extends base
*/ */
public function is_available(): bool public function is_available(): bool
{ {
$this->init(0); $this->init(confirm_type::UNDEFINED);
return !empty($this->config->offsetGet('captcha_turnstile_sitekey')) return !empty($this->config->offsetGet('captcha_turnstile_sitekey'))
&& !empty($this->config->offsetGet('captcha_turnstile_secret')); && !empty($this->config->offsetGet('captcha_turnstile_secret'));
@ -126,22 +113,6 @@ class turnstile extends base
$this->language->add_lang('captcha_turnstile'); $this->language->add_lang('captcha_turnstile');
} }
/**
* {@inheritDoc}
*/
public function get_hidden_fields(): array
{
$hidden_fields = [];
// Required for posting page to store solved state
if ($this->solved)
{
$hidden_fields['confirm_code'] = $this->confirm_code;
}
$hidden_fields['confirm_id'] = $this->confirm_id;
return $hidden_fields;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -196,6 +167,9 @@ class turnstile extends base
// TODO: Implement reset() method. // TODO: Implement reset() method.
} }
/**
* {@inheritDoc}
*/
public function get_attempt_count(): int public function get_attempt_count(): int
{ {
// TODO: Implement get_attempt_count() method. // TODO: Implement get_attempt_count() method.

View file

@ -6,7 +6,7 @@
<script src="{{ U_TURNSTILE_SCRIPT }}" async defer></script> <script src="{{ U_TURNSTILE_SCRIPT }}" async defer></script>
{# The cf-turnstile class is used in JavaScript #} {# The cf-turnstile class is used in JavaScript #}
<div class="cf-turnstile" data-sitekey="{{ TURNSTILE_SITEKEY }}"{% if TURNSTILE_THEME %} data-theme="{{ TURNSTILE_THEME }}"{% endif %}></div> <div class="cf-turnstile" data-language="{{ lang('TURNSTILE_LANG') }}" data-sitekey="{{ TURNSTILE_SITEKEY }}"{% if TURNSTILE_THEME %} data-theme="{{ TURNSTILE_THEME }}"{% endif %}></div>
{% else %} {% else %}
{{ lang('CAPTCHA_TURNSTILE_NOT_AVAILABLE') }} {{ lang('CAPTCHA_TURNSTILE_NOT_AVAILABLE') }}
{% endif %} {% endif %}