diff options
Diffstat (limited to 'modules/recaptcha')
-rw-r--r-- | modules/recaptcha/controllers/admin_recaptcha.php | 105 | ||||
-rw-r--r-- | modules/recaptcha/helpers/recaptcha.php | 177 | ||||
-rw-r--r-- | modules/recaptcha/helpers/recaptcha_installer.php | 35 | ||||
-rw-r--r-- | modules/recaptcha/helpers/recaptcha_menu.php | 28 | ||||
-rw-r--r-- | modules/recaptcha/module.info | 3 | ||||
-rw-r--r-- | modules/recaptcha/views/admin_recaptcha.html.php | 53 |
6 files changed, 401 insertions, 0 deletions
diff --git a/modules/recaptcha/controllers/admin_recaptcha.php b/modules/recaptcha/controllers/admin_recaptcha.php new file mode 100644 index 00000000..0f05a82b --- /dev/null +++ b/modules/recaptcha/controllers/admin_recaptcha.php @@ -0,0 +1,105 @@ +<?php defined("SYSPATH") or die("No direct script access."); +/** + * Gallery - a web based photo album viewer and editor + * Copyright (C) 2000-2008 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(); + $old_public_key = module::get_var("recaptcha", "public_key"); + $old_private_key = module::get_var("recaptcha", "private_key"); + if (request::method() == "post") { + + $valid_key = $form->validate(); + if ($valid_key) { + $valid_key = recaptcha::is_recaptcha_valid($form, + $form->configure_recaptcha->private_key->value); + if (empty($valid_key) && $form->captcha_error == "invalid-site-private-key") { + $form->configure_recaptcha->private_key->add_error("invalid", 1); + unset($form->captcha_error); + } + } + if ($valid_key) { + $new_public_key = $form->configure_recaptcha->public_key->value; + $new_private_key = $form->configure_recaptcha->private_key->value; + + $updated = false; + if ($this->_update_key("public_key", $old_public_key, $new_public_key) || + $this->_update_key("private_key", $old_private_key, $new_private_key)) { + message::success(t("Recaptcha Configured")); + } + recaptcha::check_config(); + } + } else { + $valid_key = !empty($old_public_key) && !empty($old_private_key); + } + + recaptcha::check_config(); + $view = new Admin_View("admin.html"); + $view->content = new View("admin_recaptcha.html"); + $view->content->valid_key = $valid_key; + $view->content->form = $form; + print $view; + } + + private function _update_key($type, $old_key, $new_key) { + $changed = true; + if ($old_key && !$new_key) { + log::success(sprintf(t("Your Recaptcha %s has been cleared."), strtr($type, "_", " "))); + } else if ($old_key && $new_key && $old_key != $new_key) { + log::success(sprintf(t("Your Recaptcha %s has been changed."), strtr($type, "_", " "))); + } else if (!$old_key && $new_key) { + log::success(sprintf(t("Your Recaptcha %s has been saved."), strtr($type, "_", " "))); + } else { + $changed = false; + } + if ($changed) { + module::set_var("recaptcha", $key, $new_key); + } + + } + + public function gethtml($public_key, $error=null) { + $http_request = "GET /challenge?k=$public_key HTTP/1.0\r\n"; + $response = ""; + if( false == ( $fs = @fsockopen("api.recaptcha.net", 80, $errno, $errstr, 10) ) ) { + throw new Exception("@todo COULD NOT OPEN SOCKET"); + } + $errorpart = empty($error) ? "" : "&error=$error"; + fputs($fs, "GET /challenge?k=$public_key&ajax=1$errorpart HTTP/1.0\r\n"); + fputs($fs, "Host: api.recaptcha.net\r\n"); + fputs($fs, "Connection: Close\r\n\r\n"); + while (!feof($fs)) { + $response .= fgets($fs, 1160); // One TCP-IP packet + } + fclose($fs); + $response = explode("\r\n\r\n", $response, 2); + + if (strpos($response[1], "document.write") === 0) { + header("HTTP/1.1 400 BAD REQUEST"); + if (preg_match("#.*\'(.*)\'#", $response[1], $matches)) { + $msg = $matches[1]; + } else { + $msg = _t("Unable to determine error message"); + } + print $msg; + } else { + header("HTTP/1.1 200 OK"); + print json_encode(array("result" => "success", "script" => $response[1])); + } + } +} diff --git a/modules/recaptcha/helpers/recaptcha.php b/modules/recaptcha/helpers/recaptcha.php new file mode 100644 index 00000000..69361e23 --- /dev/null +++ b/modules/recaptcha/helpers/recaptcha.php @@ -0,0 +1,177 @@ +<?php defined("SYSPATH") or die("No direct script access."); +/** + * Gallery - a web based photo album viewer and editor + * Copyright (C) 2000-2008 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 { + /** + * The reCAPTCHA server URL"s + */ + const API_SERVER = "http://api.recaptcha.net"; + const API_SECURE_SERVER = "https://api-secure.recaptcha.net"; + const VERIFY_SERVER = "api-verify.recaptcha.net"; + + /** + * RecaptchaOptions + */ + private $options = array(); + + static function get_configure_form() { + $form = new Forge("admin/recaptcha", "", "post"); + $group = $form->group("configure_recaptcha") + ->label(t("Configure Recaptcha")); + $group->hidden("orig_public_key") + ->value(module::get_var()); + $group->input("public_key") + ->label(t("Public Key")) + ->value(module::get_var("recaptcha", "public_key")) + ->rules("required|length[40]"); + $group->public_key->error_messages("invalid", t("The public key you provided is invalid.")); + $group->input("private_key") + ->label(t("Private Key")) + ->value(module::get_var("recaptcha", "private_key")) + ->rules("required|length[40]"); + $group->private_key->error_messages("invalid", t("The private key you provided is invalid.")); + $group->submit("")->value(t("Save")); + $site_domain = urlencode(stripslashes($_SERVER["HTTP_HOST"])); + $form->recaptcha_site = self::API_SERVER; + $form->recaptcha_ssl_site = self::API_SECURE_SERVER; + $form->get_key_url = "http://recaptcha.net/api/getkey?domain=$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" => url::site("admin/recaptcha"))), + "recaptcha_config"); + } else { + site_status::clear("recaptcha_config"); + } + } + + /** + * Gets the challenge HTML (javascript and non-javascript version). + * This is called from the browser, and the resulting reCAPTCHA HTML widget + * is embedded within the HTML form it was called from. + * @param string $pubkey The public key to use in the challenge + * @param string $error The error given by reCAPTCHA (optional, default is null) + * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false) + * @param string $lang Any supported language code + * @return string - The HTML to be embedded in the user"s form. + */ + static function get_challenge_html($pubkey, $error = NULL, $use_ssl = false) { + if (empty($pubkey)) { + throw new Exception("@todo NEED KEY <a href=\"http://recaptcha.net/api/getkey\">" . + "http://recaptcha.net/api/getkey</a>"); + } + + $lang = Kohana::config("locale.root_locale"); + $server = $use_ssl ? self::API_SECURE_SERVER : self::API_SERVER; + $errorpart = ""; + if ($error) { + $errorpart = "&error=". $error; + } + return (count(self::$options) > 0 ? "<script type=\"text/javascript\">" . + "var RecaptchaOptions = {lang:'$lang'};</script>" : "") . + "<script type=\"text/javascript\" src=\"$server/challenge?k=" . + "{$pubkey}$errorpart \"></script>" . $noscript; + } + + /** + * Form validation call back for captcha validation + * @param string $form + * @return true if valid, false if not + */ + static function is_recaptcha_valid($form, $private_key=null) { + $input = Input::instance(); + + if (empty($private_key)) { + $private_key = module::get_var("recaptcha", "private_key"); + } + Kohana::log("debug", $private_key); + $remoteip = $_SERVER["REMOTE_ADDR"] ; + $challenge = $input->post("recaptcha_challenge_field", "", true); + $response = $input->post("recaptcha_response_field", "", true); + + //discard spam submissions + if (empty($challenge) || empty($response)) { + $form->captcha_error = "incorrect-captcha-sol"; + return false; + } + $response = self::_http_post(self::VERIFY_SERVER, "/verify", + array ("privatekey" => $private_key, + "remoteip" => $remoteip, + "challenge" => $challenge, + "response" => $response)); + + $answers = explode ("\n", $response [1]); + if (trim ($answers [0]) == "true") { + return true; + } else { + $form->captcha_error = $answers[1]; + Kohana::log("debug", print_r($answers, 1)); + return false; + } + } + + /** + * 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_installer.php b/modules/recaptcha/helpers/recaptcha_installer.php new file mode 100644 index 00000000..f4f63739 --- /dev/null +++ b/modules/recaptcha/helpers/recaptcha_installer.php @@ -0,0 +1,35 @@ +<?php defined("SYSPATH") or die("No direct script access."); +/** + * Gallery - a web based photo album viewer and editor + * Copyright (C) 2000-2008 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 install() { + $version = module::get_version("recaptcha"); + + if ($version == 0) { + module::set_version("recaptcha", 1); + } + + recaptcha::check_config(); + } + + static function uninstall() { + site_status::clear("recaptcha_config"); + module::delete("recaptcha"); + } +} diff --git a/modules/recaptcha/helpers/recaptcha_menu.php b/modules/recaptcha/helpers/recaptcha_menu.php new file mode 100644 index 00000000..59cb9d84 --- /dev/null +++ b/modules/recaptcha/helpers/recaptcha_menu.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-2008 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_menu_Core { + static function admin($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/module.info b/modules/recaptcha/module.info new file mode 100644 index 00000000..134ae31c --- /dev/null +++ b/modules/recaptcha/module.info @@ -0,0 +1,3 @@ +name = Recaptcha +description = "<a href="http://recaptcha.net">Recaptcha</a> displays a graphical verification that protects the input form from abuse from "bots," or automated programs usually written to generate spam." +version = 1 diff --git a/modules/recaptcha/views/admin_recaptcha.html.php b/modules/recaptcha/views/admin_recaptcha.html.php new file mode 100644 index 00000000..ebba31d5 --- /dev/null +++ b/modules/recaptcha/views/admin_recaptcha.html.php @@ -0,0 +1,53 @@ +<?php defined("SYSPATH") or die("No direct script access.") ?> +<script type="text/javascript" src="http://api.recaptcha.net/js/recaptcha_ajax.js"></script> +<script> +var site = (document.location.protocol == "http:") ? "<?= $form->recaptcha_site ?>" : "<?= $form->recaptcha_ssl_site ?>"; +var RecaptchaOptions = {lang: 'en'}; + +$("#gAdminRecaptcha form").ready(function() { + $("#gAdminRecaptcha form ul li:last-child").before("<li id=recaptcha_div />"); + $("#public_key").change(function() { + showRecaptcha($(this).val()); + }); + var original = $("#public_key").val(); + if (original != "") { + showRecaptcha(original); + } +}); + +function showRecaptcha(public_key) { + if (public_key != "") { + Recaptcha.widget = document.getElementById("recaptcha_div"); + $.ajax({url: "<?= url::site("admin/recaptcha/gethtml") ?>/" + public_key <? if (!empty($form->captcha_error)): ?> + "/<?= $form->captcha_error ?>" <? endif ?> , + dataType: "json", + cache: false, + error: function(request, textStatus, errorThrown) { + var public_key = $("#gAdminRecaptcha form ul li:first-child"); + public_key.addClass("gError"); + $("#gAdminRecaptcha form ul li:first-child p").replaceWith(""); + public_key.append('<p class="gError">' + request.responseText + "</p>"); + }, + success: function(data, textStatus) { + var public_key = $("#gAdminRecaptcha form ul li:first-child"); + public_key.removeClass("gError"); + $("#gAdminRecaptcha form ul li:first-child p").replaceWith(""); + $("#recaptcha_div").html("<script type='text/javascript'>" + data.script + "</script" + ">"); + } + }); + } else { + if (Recaptcha.widget != undefined) { + Recaptcha.destroy(); + } + } +} + +</script> + +<div id="gAdminRecaptcha"> + <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. automated spam filtering service. In order to use it, you need to sign up for a <a href=\"{$form->get_key_url}\">ReCaptcha Public/Private Key pair</a>, which is also free. Once registered, the the challenge and response strings are evaluated at <a href=\"http://recaptcha.net\">recaptcha.net</a> to determine if the form content has been entered by a bot.") ?> + </p> + + <?= $form ?> +</div> |