From 2c325c2c80c58d23054007f51c62e91e1054c5d8 Mon Sep 17 00:00:00 2001 From: Niko Date: Thu, 23 Apr 2020 10:11:22 +0400 Subject: [PATCH 1/2] first version of hcaptcha field --- field-hcaptcha/config.php | 38 ++++++++++ field-hcaptcha/field.php | 143 ++++++++++++++++++++++++++++++++++++++ field-hcaptcha/plugin.php | 12 ++++ 3 files changed, 193 insertions(+) create mode 100644 field-hcaptcha/config.php create mode 100644 field-hcaptcha/field.php create mode 100644 field-hcaptcha/plugin.php diff --git a/field-hcaptcha/config.php b/field-hcaptcha/config.php new file mode 100644 index 0000000..63fc97f --- /dev/null +++ b/field-hcaptcha/config.php @@ -0,0 +1,38 @@ + new SectionBreakField(array( + 'label' => 'hCaptcha Configuration', + 'hint' => 'Requires separate registration for a key set' + )), + 'siteKey' => new TextboxField(array( + 'required' => true, + 'configuration'=>array('length'=>36, 'size'=>40), + 'label' => 'Site Key', + )), + 'secretKey' => new TextboxField(array( + 'widget' => 'PasswordWidget', + 'required' => false, + 'configuration'=>array('length'=>42, 'size'=>40), + 'label' => 'Secret Key', + )), + ); + } + + function pre_save($config, &$errors) { + // Todo: verify key + + if (!function_exists('curl_init')) { + Messages::error('CURL extension is required'); + return false; + } + + global $msg; + if (!$errors) + $msg = 'Successfully updated hCaptcha settings'; + + return true; + } +} diff --git a/field-hcaptcha/field.php b/field-hcaptcha/field.php new file mode 100644 index 0000000..55f31b7 --- /dev/null +++ b/field-hcaptcha/field.php @@ -0,0 +1,143 @@ +get('id'); + $config = $this->getPluginConfig()->getInfo(); + if (!isset($validation[$id])) { + list($code, $json) = $this->http_post( + ' https://hcaptcha.com/siteverify ', + array( + 'secret' => $config['secretKey'], + 'response' => $value, + 'remoteip' => $_SERVER['REMOTE_ADDR'], + )); + if ($code !== 200) { + $response = array( + 'error-codes' => array('no-response'), + ); + } else { + $response = JsonDataParser::decode($json); + } + $I = &$validation[$id]; + if (!($I['valid'] = $response['success'])) { + $errors = array(); + foreach ($response['error-codes'] as $code) { + switch ($code) { + case 'missing-input-response': + $errors[] = sprintf(__('%s is a required field'), + $this->getLabel() ?: __('This')); + break; + case 'invalid-input-response': + $errors[] = "Your response doesn't look right. Please try again"; + break; + case 'no-response': + $errors[] = "Unable to communicate with the hCaptcha server"; + } + } + $I['errors'] = $errors; + } + } + if (!$validation[$id]['valid']) { + foreach ($validation[$id]['errors'] as $e) { + $this->_errors[] = $e; + } + } + } + + protected function http_post($url, array $data) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_USERAGENT, 'osTicket/'.THIS_VERSION); + curl_setopt($ch, CURLOPT_HEADER, FALSE); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + if (isset($_SERVER['HTTPS_PROXY'])) + curl_setopt($ch, CURLOPT_PROXY, $_SERVER['HTTPS_PROXY']); + + $result=curl_exec($ch); + $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + return array($code, $result); + } + + function getConfigurationOptions() { + return array( + 'theme' => new ChoiceField(array( + 'label' => 'hCaptcha Theme', + 'choices' => array('dark' => 'Dark', 'light' => 'Light'), + 'default' => 'light', + )), + 'size' => new ChoiceField(array( + 'label' => 'hCaptcha Size', + 'choices' => array('compact' => 'Compact', 'normal' => 'Normal'), + 'default' => 'normal', + )), + ); + } + + function getMedia() { + return array( + 'js' => array( + '//hcaptcha.com/1/api.js?hl=' + . Internationalization::getCurrentLanguage() + ), + ); + } + } + + class hCaptchaWidget extends Widget { + function render() { + $fconfig = $this->field->getConfiguration(); + $pconfig = $this->field->getPluginConfig()->getInfo(); + ?> +
+ field->getSource())) + return null; + + if (!isset($data['h-captcha-response'])) + return null; + + return $data['h-captcha-response']; + } + } + + require_once 'config.php'; + + class hCaptchaPlugin extends Plugin { + var $config_class = 'hCaptchaConfig'; + + function bootstrap() { + hCaptchaField::$plugin_config = $this->getConfig(); + FormField::addFieldTypes(__('Verification'), function() { + return array( + 'hCaptcha' => array('Cloudflare hCaptcha', 'hCaptchaField') + ); + }); + } + } diff --git a/field-hcaptcha/plugin.php b/field-hcaptcha/plugin.php new file mode 100644 index 0000000..4569681 --- /dev/null +++ b/field-hcaptcha/plugin.php @@ -0,0 +1,12 @@ + 'field:hCaptcha', # notrans + 'version' => '0.1', + 'name' => 'Cloudflare hCaptcha field', + 'author' => 'Niko', + 'description' => 'Provides a hCaptcha field. This will help verify humans for both new + tickets by guests as well as client registration. Loosely based on the reCaptcha Plugin by Jared', + 'url' => 'http://www.osticket.com/plugins/field/hcaptcha', + 'plugin' => 'field.php:hCaptchaPlugin', +); From 297241d4e90c37e4163e9a75a200f8d59122e3a6 Mon Sep 17 00:00:00 2001 From: Niko Date: Thu, 23 Apr 2020 10:29:27 +0400 Subject: [PATCH 2/2] remove mentions of cloudflare --- field-hcaptcha/field.php | 2 +- field-hcaptcha/plugin.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/field-hcaptcha/field.php b/field-hcaptcha/field.php index 55f31b7..a88767a 100644 --- a/field-hcaptcha/field.php +++ b/field-hcaptcha/field.php @@ -136,7 +136,7 @@ function bootstrap() { hCaptchaField::$plugin_config = $this->getConfig(); FormField::addFieldTypes(__('Verification'), function() { return array( - 'hCaptcha' => array('Cloudflare hCaptcha', 'hCaptchaField') + 'hCaptcha' => array('hCaptcha', 'hCaptchaField') ); }); } diff --git a/field-hcaptcha/plugin.php b/field-hcaptcha/plugin.php index 4569681..42f2518 100644 --- a/field-hcaptcha/plugin.php +++ b/field-hcaptcha/plugin.php @@ -3,7 +3,7 @@ return array( 'id' => 'field:hCaptcha', # notrans 'version' => '0.1', - 'name' => 'Cloudflare hCaptcha field', + 'name' => 'hCaptcha field', 'author' => 'Niko', 'description' => 'Provides a hCaptcha field. This will help verify humans for both new tickets by guests as well as client registration. Loosely based on the reCaptcha Plugin by Jared',