summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
Diffstat (limited to 'addons')
-rw-r--r--addons/copyable_captcha.php104
-rw-r--r--addons/funnyquestion.php160
-rw-r--r--addons/index.html1
-rw-r--r--addons/recaptcha.php136
4 files changed, 401 insertions, 0 deletions
diff --git a/addons/copyable_captcha.php b/addons/copyable_captcha.php
new file mode 100644
index 0000000..8f136d9
--- /dev/null
+++ b/addons/copyable_captcha.php
@@ -0,0 +1,104 @@
+<?php
+
+/**
+ * Copyable Captha plugin
+ * Copyright (C) 2016 artoodetoo
+ * Special thanks to Visman for his help
+ * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
+ */
+
+class addon_copyable_captcha extends flux_addon
+{
+ var $lang;
+ var $styles;
+ var $spans;
+
+ function register($manager)
+ {
+ global $pun_user;
+
+ if (!$pun_user['is_guest']) return;
+
+ $manager->bind('register_after_validation', array($this, 'hook_register_after_validation'));
+ $manager->bind('register_before_header', array($this, 'hook_register_before_header'));
+ $manager->bind('register_before_submit', array($this, 'hook_register_before_submit'));
+ }
+
+ function load_lang()
+ {
+ global $pun_user;
+
+ if (isset($this->lang)) return;
+
+ $user_lang = file_exists(PUN_ROOT.'lang/'.$pun_user['language'].'/copyable_captcha.php')
+ ? $pun_user['language']
+ : 'English';
+ require PUN_ROOT.'lang/'.$user_lang.'/copyable_captcha.php';
+
+ $this->lang = $lang_copyable_captcha;
+ }
+
+ function hook_register_after_validation()
+ {
+ global $errors, $cookie_name, $cookie_seed;
+
+ if (isset($_POST['req_word']) && isset($_COOKIE[$cookie_name.'_captcha']) && substr_count($_COOKIE[$cookie_name.'_captcha'], '-') === 1) {
+ list($hash, $time) = explode('-', $_COOKIE[$cookie_name.'_captcha']);
+ $word = $_POST['req_word'];
+ if ((int)$time <= time() - 120 || $hash !== sha1(strtolower($word).$cookie_seed.'secret'.$time)) {
+ $this->load_lang();
+ $errors[] = $this->lang['Captcha error'];
+ }
+ } else {
+ $this->load_lang();
+ $errors[] = $this->lang['Captcha error'];
+ }
+ }
+
+
+ function hook_register_before_header()
+ {
+ global $required_fields, $errors, $cookie_name, $cookie_seed;
+
+ $this->load_lang();
+ $required_fields['req_word'] = $this->lang['Captcha'];
+
+ $time = time();
+ $word = random_pass(mt_rand(4, 6));
+ $hash = sha1(strtolower($word).$cookie_seed.'secret'.$time);
+ forum_setcookie($cookie_name.'_captcha', $hash.'-'.$time, $time + 120);
+
+ $array = str_split($word);
+ $mixin = random_pass(mt_rand(1, 3));
+ $i = -1;
+ $this->styles = '';
+ foreach (str_split($mixin) as $ch) {
+ $i = mt_rand($i+1, count($array));
+ array_splice($array, $i, 0, $ch);
+ $this->styles .= '.masq i:nth-child('.($i + 1).'){display:none;} ';
+ }
+ $this->spans = '<i>'.implode('</i><i>', $array).'</i>';
+ }
+
+
+ function hook_register_before_submit()
+ {
+ global $lang_common;
+
+ $this->load_lang();
+
+?>
+ <div class="inform">
+ <fieldset>
+ <legend><?php echo $this->lang['Captcha legend'] ?></legend>
+ <div class="infldset">
+ <style> .masq i {font-style:normal;} <?php echo $this->styles ?></style>
+ <p><?php echo sprintf($this->lang['Captcha info'], $this->spans) ?></p>
+ <label class="required"><strong><?php echo $this->lang['Captcha'] ?> <span><?php echo $lang_common['Required'] ?></span></strong><br /><input type="text" name="req_word" size="25" maxlength="25" /><br /></label>
+ </div>
+ </fieldset>
+ </div>
+<?php
+
+ }
+}
diff --git a/addons/funnyquestion.php b/addons/funnyquestion.php
new file mode 100644
index 0000000..e3cd4e9
--- /dev/null
+++ b/addons/funnyquestion.php
@@ -0,0 +1,160 @@
+<?php
+
+if (!defined('PUN')) {
+ exit;
+}
+
+class addon_funnyquestion extends flux_addon
+{
+
+ public function __construct()
+ {
+ global $funnyquestion_disabled, $funnyquestion_hash, $funny_questions, $funnyquestion_timeout, $funnyquestion_remember, $funnyquestion_wait, $pun_user, $lang_funnyquestion;
+
+ !isset($funnyquestion_disabled) && $funnyquestion_disabled = false;
+ !isset($funnyquestion_hash) && $funnyquestion_hash = dirname(__FILE__);
+ !isset($funny_questions) && $funny_questions = array(
+ 'What is the Ultimate Answer to the Ultimate Question of Life, The Universe, and Everything?' => '42'
+ );
+ !isset($funnyquestion_timeout) && $funnyquestion_timeout = 3600;
+ !isset($funnyquestion_remember) && $funnyquestion_remember = 3600 * 24;
+ !isset($funnyquestion_wait) && $funnyquestion_wait = 2;
+
+ if (file_exists(PUN_ROOT . 'lang/' . $pun_user['language'] . '/funnyquestion.php')) {
+ require PUN_ROOT . 'lang/' . $pun_user['language'] . '/funnyquestion.php';
+ } else {
+ require PUN_ROOT . 'lang/English/funnyquestion.php';
+ }
+ }
+
+ /**
+ * @param flux_addon_manager $manager
+ */
+ public function register($manager)
+ {
+ $manager->bind('register_before_submit', array($this, 'print_funnyquestion'));
+ $manager->bind('quickpost_before_submit', array($this, 'print_funnyquestion'));
+ $manager->bind('post_before_submit', array($this, 'print_funnyquestion'));
+ $manager->bind('register_before_validation', array($this, 'set_error_on_check_funnyquestion'));
+ $manager->bind('post_before_validation', array($this, 'set_error_on_check_funnyquestion'));
+ }
+
+ public function print_funnyquestion()
+ {
+ echo $this->get_funnyquestion();
+ }
+
+ public function set_error_on_check_funnyquestion()
+ {
+ global $errors, $lang_funnyquestion;
+ $this->check_funnyquestion() || $errors[] = $lang_funnyquestion['wrong-answer'];
+ }
+
+ /**
+ * @param string $answer
+ * @return string
+ */
+ private function normalize_funnyanswer($answer)
+ {
+ return preg_replace('/[^a-z0-9]/', '', strtolower($answer));
+ }
+
+ private function set_funnycookie()
+ {
+ global $funnyquestion_hash, $funnyquestion_remember;
+
+ $time = time();
+ forum_setcookie('funnyquestion_hash', sha1($time . get_remote_address() . $funnyquestion_hash),
+ $time + $funnyquestion_remember);
+ forum_setcookie('funnyquestion_time', $time, $time + $funnyquestion_remember);
+ }
+
+ /**
+ * @return bool
+ */
+ private function has_funnycookie()
+ {
+ global $funnyquestion_hash, $funnyquestion_remember;
+
+ return (!empty($_COOKIE['funnyquestion_hash']) && !empty($_COOKIE['funnyquestion_time'])
+ && time() - $funnyquestion_remember <= $_COOKIE['funnyquestion_time']
+ && sha1($_COOKIE['funnyquestion_time'] . get_remote_address() . $funnyquestion_hash) == $_COOKIE['funnyquestion_hash']);
+ }
+
+ /**
+ * @return string
+ */
+ private function get_funnyquestion()
+ {
+ global $funnyquestion_disabled, $funnyquestion_hash, $funny_questions, $lang_funnyquestion, $lang_common, $pun_user;
+
+ if ($funnyquestion_disabled || !$pun_user['is_guest'] || $this->has_funnycookie()) {
+ return '';
+ }
+
+ $time = time();
+ $question = array_rand($funny_questions);
+ # make sure the user is not able to tell us the question to answer
+ $hash = sha1($time . $question . $funnyquestion_hash);
+
+ return '<div class="inform">
+ <fieldset>
+ <legend>' . $lang_funnyquestion['question-label'] . '</legend>
+ <div class="infldset">
+ <input type="hidden" name="funnyquestion_time" value="' . $time . '" />
+ <input type="hidden" name="funnyquestion_hash" value="' . $hash . '" />
+ <label class="required">
+ <strong>' . $question . '<span>' . $lang_common['Required'] . '</span></strong><br />
+ <input type="text" name="funny_answer" value="" size="50" /><br />
+ </label>
+ </div>
+ </fieldset>
+ </div>';
+ }
+
+ /**
+ * @return bool
+ */
+ private function check_funnyquestion()
+ {
+ global $funnyquestion_disabled, $funnyquestion_hash, $funnyquestion_timeout, $funnyquestion_wait, $funny_questions, $pun_user;
+
+ if ($funnyquestion_disabled || !$pun_user['is_guest'] || $this->has_funnycookie()) {
+ return true;
+ }
+
+ if (!empty($_POST['funnyquestion_time'])
+ && !empty($_POST['funnyquestion_hash'])
+ && !empty($_POST['funny_answer'])
+ ) {
+ $now = time();
+ $time = $_POST['funnyquestion_time'];
+ $hash = $_POST['funnyquestion_hash'];
+ $user_answer = $this->normalize_funnyanswer($_POST['funny_answer']);
+ } else {
+ return false;
+ }
+
+ if ($now - $time > $funnyquestion_timeout) {
+ return false;
+ } elseif ($now - $time < $funnyquestion_wait) {
+ return false;
+ }
+
+ foreach ($funny_questions as $question => $answers) {
+ if (!is_array($answers)) {
+ $answers = array($answers);
+ }
+ foreach ($answers as $answer) {
+ if ($this->normalize_funnyanswer($answer) == $user_answer
+ && $hash == sha1($time . $question . $funnyquestion_hash)
+ ) {
+ $this->set_funnycookie();
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/addons/index.html b/addons/index.html
new file mode 100644
index 0000000..cf1a99a
--- /dev/null
+++ b/addons/index.html
@@ -0,0 +1 @@
+<html><head><title>.</title></head><body>.</body></html>
diff --git a/addons/recaptcha.php b/addons/recaptcha.php
new file mode 100644
index 0000000..668de1c
--- /dev/null
+++ b/addons/recaptcha.php
@@ -0,0 +1,136 @@
+<?php
+
+class addon_recaptcha extends flux_addon
+{
+ function register($manager)
+ {
+ global $pun_user;
+
+ if (!$this->is_configured()) return;
+
+ $this->get_language();
+
+ if ($this->enabled_location('register'))
+ {
+ $manager->bind('register_after_validation', array($this, 'hook_after_validation'));
+ $manager->bind('register_before_submit', array($this, 'hook_before_submit'));
+ }
+
+ if ($this->enabled_location('login'))
+ {
+ $manager->bind('login_after_validation', array($this, 'hook_after_validation'));
+ $manager->bind('login_before_submit', array($this, 'hook_before_submit'));
+ }
+
+ if ($this->enabled_location('guestpost') && $pun_user['is_guest'])
+ {
+ $manager->bind('post_after_validation', array($this, 'hook_after_validation'));
+ $manager->bind('post_before_submit', array($this, 'hook_before_submit'));
+ $manager->bind('quickpost_before_submit', array($this, 'hook_before_submit'));
+ }
+ }
+
+ function is_configured()
+ {
+ global $pun_config;
+
+ return !empty($pun_config['recaptcha_enabled']) && !empty($pun_config['recaptcha_site_key']) && !empty($pun_config['recaptcha_secret_key']);
+ }
+
+ function enabled_location($page)
+ {
+ global $pun_config;
+
+ return !empty($pun_config['recaptcha_location_'.$page]);
+ }
+
+ function get_language()
+ {
+ global $pun_user;
+
+ if (file_exists(PUN_ROOT.'lang/'.$pun_user['language'].'/recaptcha_addon.php'))
+ require PUN_ROOT.'lang/'.$pun_user['language'].'/recaptcha_addon.php';
+ else
+ require PUN_ROOT.'lang/English/recaptcha_addon.php';
+ }
+
+ function hook_after_validation()
+ {
+ global $errors, $lang_recaptcha;
+
+ if (empty($errors) && !$this->verify_user_response())
+ {
+ $errors[] = $lang_recaptcha['Error'];
+ }
+ }
+
+ function hook_before_submit()
+ {
+ global $pun_config, $lang_recaptcha;
+
+ $site_key = $pun_config['recaptcha_site_key'];
+
+ ?>
+ <div class="inform">
+ <fieldset>
+ <legend><?= $lang_recaptcha['Human']; ?></legend>
+ <div class="infldset">
+ <p><?= $lang_recaptcha['Prove']; ?></p>
+ <script src="https://www.google.com/recaptcha/api.js"></script>
+ <div class="g-recaptcha" data-sitekey="<?php echo pun_htmlspecialchars($site_key) ?>"></div>
+ </div>
+ </fieldset>
+ </div>
+ <?php
+ }
+
+ function verify_user_response()
+ {
+ global $pun_config;
+
+ if (empty($_POST['g-recaptcha-response'])) return false;
+
+ $secret = $pun_config['recaptcha_secret_key'];
+ $response = $_POST['g-recaptcha-response'];
+ $ip = get_remote_address();
+
+ $query = "secret=$secret&response=$response&remoteip=$ip";
+ $url = "https://www.google.com/recaptcha/api/siteverify?$query";
+
+ $response = $this->send_request($url);
+
+ return strpos($response, '"success": true') !== false;
+ }
+
+ function send_request($url)
+ {
+ if (function_exists('curl_version'))
+ return $this->send_curl_request($url);
+ else
+ return $this->get_remote_file($url);
+ }
+
+ function send_curl_request($url)
+ {
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ $response = curl_exec($ch);
+ curl_close($ch);
+
+ return $response;
+ }
+
+ function get_remote_file($url)
+ {
+ global $lang_recaptcha;
+
+ $response = file_get_contents($url);
+
+ if ($response === false)
+ throw new Exception($lang_recaptcha['API error']);
+
+ return $response;
+ }
+}