summaryrefslogtreecommitdiff
path: root/modules/recaptcha
diff options
context:
space:
mode:
authorTristan Zur <tzur@webserver.ccwn.org>2015-06-10 20:55:53 +0200
committerTristan Zur <tzur@webserver.ccwn.org>2015-06-10 20:55:53 +0200
commit406abd7c4df1ace2cd3e4e17159e8941a2e8c0c4 (patch)
treea324be16021f44f2fd6d55e609f47024e945b1db /modules/recaptcha
Initial import
Diffstat (limited to 'modules/recaptcha')
-rw-r--r--modules/recaptcha/controllers/admin_recaptcha.php61
-rw-r--r--modules/recaptcha/css/recaptcha.css7
-rw-r--r--modules/recaptcha/helpers/recaptcha.php152
-rw-r--r--modules/recaptcha/helpers/recaptcha_event.php42
-rw-r--r--modules/recaptcha/helpers/recaptcha_installer.php28
-rw-r--r--modules/recaptcha/helpers/recaptcha_theme.php28
-rw-r--r--modules/recaptcha/libraries/Form_Recaptcha.php67
-rw-r--r--modules/recaptcha/module.info7
-rw-r--r--modules/recaptcha/views/admin_recaptcha.html.php35
-rw-r--r--modules/recaptcha/views/form_recaptcha.html.php18
10 files changed, 445 insertions, 0 deletions
diff --git a/modules/recaptcha/controllers/admin_recaptcha.php b/modules/recaptcha/controllers/admin_recaptcha.php
new file mode 100644
index 0000000..8ba43bb
--- /dev/null
+++ b/modules/recaptcha/controllers/admin_recaptcha.php
@@ -0,0 +1,61 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2013 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class Admin_Recaptcha_Controller extends Admin_Controller {
+ public function index() {
+ $form = recaptcha::get_configure_form();
+ if (request::method() == "post") {
+ // @todo move the "save" part of this into a separate controller function
+ access::verify_csrf();
+ $old_public_key = module::get_var("recaptcha", "public_key");
+ $old_private_key = module::get_var("recaptcha", "private_key");
+ if ($form->validate()) {
+ $public_key = $form->configure_recaptcha->public_key->value;
+ $private_key = $form->configure_recaptcha->private_key->value;
+
+ if ($public_key && $private_key) {
+ module::set_var("recaptcha", "public_key", $public_key);
+ module::set_var("recaptcha", "private_key", $private_key);
+ message::success(t("reCAPTCHA configured!"));
+ log::success("recaptcha", t("reCAPTCHA public and private keys set"));
+ url::redirect("admin/recaptcha");
+ } else if ($public_key && !$private_key) {
+ $form->configure_recaptcha->private_key->add_error("invalid");
+ } else if ($private_key && !$public_key) {
+ $form->configure_recaptcha->public_key->add_error("invalid");
+ } else {
+ module::set_var("recaptcha", "public_key", "");
+ module::set_var("recaptcha", "private_key", "");
+ message::success(t("No keys provided. reCAPTCHA is disabled!"));
+ log::success("recaptcha", t("reCAPTCHA public and private keys cleared"));
+ url::redirect("admin/recaptcha");
+ }
+ }
+ }
+
+ recaptcha::check_config();
+ $view = new Admin_View("admin.html");
+ $view->page_title = t("reCAPTCHA");
+ $view->content = new View("admin_recaptcha.html");
+ $view->content->public_key = module::get_var("recaptcha", "public_key");
+ $view->content->private_key = module::get_var("recaptcha", "private_key");
+ $view->content->form = $form;
+ print $view;
+ }
+}
diff --git a/modules/recaptcha/css/recaptcha.css b/modules/recaptcha/css/recaptcha.css
new file mode 100644
index 0000000..27117a5
--- /dev/null
+++ b/modules/recaptcha/css/recaptcha.css
@@ -0,0 +1,7 @@
+#g-content #g-comments ul li #g-recaptcha {
+ padding: 0;
+}
+
+#g-content #g-comments ul li #g-recaptcha div {
+ padding: 0;
+}
diff --git a/modules/recaptcha/helpers/recaptcha.php b/modules/recaptcha/helpers/recaptcha.php
new file mode 100644
index 0000000..cc50d72
--- /dev/null
+++ b/modules/recaptcha/helpers/recaptcha.php
@@ -0,0 +1,152 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2013 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class recaptcha_Core {
+ static function get_configure_form() {
+ $form = new Forge("admin/recaptcha", "", "post", array("id" => "g-configure-recaptcha-form"));
+ $group = $form->group("configure_recaptcha")
+ ->label(t("Configure reCAPTCHA"));
+ $group->input("public_key")
+ ->label(t("Public Key"))
+ ->value(module::get_var("recaptcha", "public_key"))
+ ->rules("required")
+ ->error_messages("required", t("You must enter a public key"))
+ ->error_messages("invalid", t("This public key is invalid"));
+ $group->input("private_key")
+ ->label(t("Private Key"))
+ ->value(module::get_var("recaptcha", "private_key"))
+ ->callback("recaptcha::verify_key")
+ ->error_messages("required", t("You must enter a private key"))
+ ->error_messages("invalid", t("This private key is invalid"));
+
+ $group->submit("")->value(t("Save"));
+ $site_domain = urlencode(stripslashes($_SERVER["HTTP_HOST"]));
+ $form->get_key_url = "http://www.google.com/recaptcha/admin/create?domains=$site_domain&app=Gallery3";
+ return $form;
+ }
+
+ static function check_config() {
+ $public_key = module::get_var("recaptcha", "public_key");
+ $private_key = module::get_var("recaptcha", "private_key");
+ if (empty($public_key) || empty($private_key)) {
+ site_status::warning(
+ t("reCAPTCHA is not quite ready! Please configure the <a href=\"%url\">reCAPTCHA Keys</a>",
+ array("url" => html::mark_clean(url::site("admin/recaptcha")))),
+ "recaptcha_config");
+ } else {
+ site_status::clear("recaptcha_config");
+ }
+ }
+
+ /**
+ * Verify that the recaptcha key is valid.
+ * @param string $private_key
+ * @return boolean
+ */
+ static function verify_key($private_key_input) {
+ if (!$private_key_input->value) {
+ $private_key_input->add_error("required", 1);
+ return;
+ }
+
+ $remote_ip = Input::instance()->server("REMOTE_ADDR");
+ $response = self::_http_post("api-verify.recaptcha.net", "/verify",
+ array("privatekey" => $private_key_input->value,
+ "remoteip" => $remote_ip,
+ "challenge" => "right",
+ "response" => "wrong"));
+
+ if ($response[1] == "false\ninvalid-site-private-key") {
+ // This is the only thing I can figure out how to verify.
+ // See http://recaptcha.net/apidocs/captcha for possible return values
+ $private_key_input->add_error("invalid", 1);
+ }
+ }
+
+ /**
+ * Form validation call back for captcha validation
+ * @param string $form
+ * @return string error message or null
+ */
+ static function is_recaptcha_valid($challenge, $response, $private_key) {
+ $input = Input::instance();
+ $remote_ip = $input->server("REMOTE_ADDR");
+
+ // discard spam submissions
+ if (empty($challenge) || empty($response)) {
+ return "incorrect-captcha-sol";
+ }
+
+ $response = self::_http_post("api-verify.recaptcha.net", "/verify",
+ array("privatekey" => $private_key,
+ "remoteip" => $remote_ip,
+ "challenge" => $challenge,
+ "response" => $response));
+
+ $answers = explode ("\n", $response [1]);
+ if (trim ($answers [0]) == "true") {
+ return null;
+ } else {
+ return $answers[1];
+ }
+ }
+
+ /**
+ * Encodes the given data into a query string format
+ * @param $data - array of string elements to be encoded
+ * @return string - encoded request
+ */
+ private static function _encode(array $data){
+ $req = array();
+ foreach ($data as $key => $value){
+ $req[] = "$key=" . urlencode(stripslashes($value));
+ }
+ return implode("&", $req);
+ }
+
+ /**
+ * Submits an HTTP POST to a reCAPTCHA server
+ * @param string $host
+ * @param string $path
+ * @param array $data
+ * @param int port
+ * @return array response
+ */
+ private static function _http_post($host, $path, $data, $port = 80) {
+ $req = self::_encode($data);
+ $http_request = "POST $path HTTP/1.0\r\n";
+ $http_request .= "Host: $host\r\n";
+ $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
+ $http_request .= "Content-Length: " . strlen($req) . "\r\n";
+ $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
+ $http_request .= "\r\n";
+ $http_request .= $req;
+ $response = "";
+ if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {
+ throw new Exception("@todo COULD NOT OPEN SOCKET");
+ }
+ fwrite($fs, $http_request);
+ while (!feof($fs)) {
+ $response .= fgets($fs, 1160); // One TCP-IP packet
+ }
+ fclose($fs);
+ $response = explode("\r\n\r\n", $response, 2);
+ return $response;
+ }
+}
diff --git a/modules/recaptcha/helpers/recaptcha_event.php b/modules/recaptcha/helpers/recaptcha_event.php
new file mode 100644
index 0000000..4ccacc7
--- /dev/null
+++ b/modules/recaptcha/helpers/recaptcha_event.php
@@ -0,0 +1,42 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2013 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class recaptcha_event_Core {
+ static function captcha_protect_form($form) {
+ if (module::get_var("recaptcha", "public_key")) {
+ foreach ($form->inputs as $input) {
+ if ($input instanceof Form_Group) {
+ $input->recaptcha("recaptcha")->label("")->id("g-recaptcha");
+ return;
+ }
+ }
+
+ // If we haven't returned yet, then add the captcha at the end of the form
+ $form->recaptcha("recaptcha")->label("")->id("g-recaptcha");
+ }
+ }
+
+ static function admin_menu($menu, $theme) {
+ $menu->get("settings_menu")
+ ->append(Menu::factory("link")
+ ->id("recaptcha")
+ ->label(t("reCAPTCHA"))
+ ->url(url::site("admin/recaptcha")));
+ }
+}
diff --git a/modules/recaptcha/helpers/recaptcha_installer.php b/modules/recaptcha/helpers/recaptcha_installer.php
new file mode 100644
index 0000000..1b526e5
--- /dev/null
+++ b/modules/recaptcha/helpers/recaptcha_installer.php
@@ -0,0 +1,28 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2013 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class recaptcha_installer {
+ static function activate() {
+ recaptcha::check_config();
+ }
+
+ static function deactivate() {
+ site_status::clear("recaptcha_config");
+ }
+}
diff --git a/modules/recaptcha/helpers/recaptcha_theme.php b/modules/recaptcha/helpers/recaptcha_theme.php
new file mode 100644
index 0000000..36087ff
--- /dev/null
+++ b/modules/recaptcha/helpers/recaptcha_theme.php
@@ -0,0 +1,28 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2013 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class recaptcha_theme_Core {
+ static function head($theme) {
+ return $theme->css("recaptcha.css");
+ }
+
+ static function admin_head($theme) {
+ return $theme->css("recaptcha.css");
+ }
+} \ No newline at end of file
diff --git a/modules/recaptcha/libraries/Form_Recaptcha.php b/modules/recaptcha/libraries/Form_Recaptcha.php
new file mode 100644
index 0000000..8a9e63a
--- /dev/null
+++ b/modules/recaptcha/libraries/Form_Recaptcha.php
@@ -0,0 +1,67 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2013 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class Form_Recaptcha_Core extends Form_Input {
+ private $_error = null;
+
+ protected $data = array(
+ 'name' => '',
+ 'value' => '',
+ );
+
+ public function __construct($name) {
+ parent::__construct($name);
+ $this->error_messages("incorrect-captcha-sol",
+ t("The values supplied to reCAPTCHA are incorrect."));
+ $this->error_messages("invalid-site-private-key", t("The site private key is incorrect."));
+ }
+
+ public function render() {
+ $public_key = module::get_var("recaptcha", "public_key");
+ if (empty($public_key)) {
+ throw new Exception("@todo NEED KEY <a href=\"http://recaptcha.net/api/getkey\">" .
+ "http://recaptcha.net/api/getkey</a>");
+ }
+
+ $view = new View("form_recaptcha.html");
+ $view->public_key = $public_key;
+ return $view;
+ }
+
+ /**
+ * Validate this input based on the set rules.
+ *
+ * @return bool
+ */
+ public function validate() {
+ $input = Input::instance();
+ $challenge = $input->post("recaptcha_challenge_field", "", true);
+ $response = $input->post("recaptcha_response_field", "", true);
+ if (!empty($challenge)) {
+ $this->_error = recaptcha::is_recaptcha_valid(
+ $challenge, $response, module::get_var("recaptcha", "private_key"));
+ if (!empty($this->_error)) {
+ $this->add_error($this->_error, 1);
+ }
+ }
+ $this->is_valid = empty($this->_error);
+ return empty($this->_error);
+ }
+
+} \ No newline at end of file
diff --git a/modules/recaptcha/module.info b/modules/recaptcha/module.info
new file mode 100644
index 0000000..6806bb9
--- /dev/null
+++ b/modules/recaptcha/module.info
@@ -0,0 +1,7 @@
+name = "reCAPTCHA"
+description = "reCAPTCHA displays a graphical verification that protects the input form from abuse from 'bots,' or automated programs usually written to generate spam (http://recaptcha.net)."
+version = 1
+author_name = "Gallery Team"
+author_url = "http://codex.galleryproject.org/Gallery:Team"
+info_url = "http://codex.galleryproject.org/Gallery3:Modules:recaptcha"
+discuss_url = "http://galleryproject.org/forum_module_recaptcha"
diff --git a/modules/recaptcha/views/admin_recaptcha.html.php b/modules/recaptcha/views/admin_recaptcha.html.php
new file mode 100644
index 0000000..4f07fef
--- /dev/null
+++ b/modules/recaptcha/views/admin_recaptcha.html.php
@@ -0,0 +1,35 @@
+<?php defined("SYSPATH") or die("No direct script access.") ?>
+<div class="g-block">
+ <h1> <?= t("reCAPTCHA challenge filtering") ?> </h1>
+ <p>
+ <?= t("reCAPTCHA is a free CAPTCHA service that helps to digitize books, newspapers and old time radio shows. In order to use it, you need to sign up for a <a href=\"%domain_url\">reCAPTCHA Public/Private Key pair</a>, which is also free. Once registered, the challenge and response strings are evaluated at <a href=\"%recaptcha_url\">recaptcha.net</a> to determine if the form content has been entered by a bot.",
+ array("domain_url" => $form->get_key_url,
+ "recaptcha_url" => html::mark_clean("http://recaptcha.net"))) ?>
+ </p>
+
+ <div class="g-block-content">
+ <?= $form ?>
+
+ <? if ($public_key && $private_key): ?>
+ <div id="g-admin-recaptcha-test">
+ <h2> <?= t("reCAPTCHA test") ?> </h2>
+ <p>
+ <?= t("If you see a CAPTCHA form below, then reCAPTCHA is functioning properly.") ?>
+ </p>
+
+ <div id="g-recaptcha">
+ <script type="text/javascript" src="http://api.recaptcha.net/js/recaptcha_ajax.js"></script>
+ <script type="text/javascript">
+ Recaptcha.create("<?= $public_key ?>", "g-recaptcha", {
+ callback: Recaptcha.focus_response_field,
+ lang: "en",
+ custom_translations : { instructions_visual : <?= t("Type words to check:")->for_js() ?>},
+ theme: "white"
+ });
+ </script>
+ </div>
+ </div>
+ <? endif ?>
+
+ </div>
+</div>
diff --git a/modules/recaptcha/views/form_recaptcha.html.php b/modules/recaptcha/views/form_recaptcha.html.php
new file mode 100644
index 0000000..7481d00
--- /dev/null
+++ b/modules/recaptcha/views/form_recaptcha.html.php
@@ -0,0 +1,18 @@
+<?php defined("SYSPATH") or die("No direct script access.") ?>
+<div id="g-recaptcha"></div>
+<script type="text/javascript" src="<?= request::protocol() ?>://www.google.com/recaptcha/api/js/recaptcha_ajax.js">
+</script>
+<script type="text/javascript">
+ setTimeout(function() {
+ Recaptcha.create(
+ "<?= $public_key ?>",
+ "g-recaptcha",
+ {
+ theme: "white",
+ custom_translations : { instructions_visual : <?= t("Type words to check:")->for_js() ?>},
+ callback: Recaptcha.focus_response_field
+ }
+ );
+ }, 500);
+</script>
+