| 1 | # Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd. |
|---|
| 2 | # This program is distributed under the terms of the |
|---|
| 3 | # GNU General Public License, version 2. |
|---|
| 4 | # |
|---|
| 5 | # $Id: reCaptcha.pm 1174 2008-01-08 21:02:50Z bchoate $ |
|---|
| 6 | |
|---|
| 7 | # reCaptcha plugin for Movable Type |
|---|
| 8 | # Author: Six Apart (http://www.sixapart.com) |
|---|
| 9 | # Released under the Artistic and GPLv2 License |
|---|
| 10 | |
|---|
| 11 | package reCaptcha; |
|---|
| 12 | |
|---|
| 13 | use strict; |
|---|
| 14 | use warnings; |
|---|
| 15 | use base qw(MT::ErrorHandler); |
|---|
| 16 | |
|---|
| 17 | sub form_fields { |
|---|
| 18 | my $self = shift; |
|---|
| 19 | my ($blog_id) = @_; |
|---|
| 20 | |
|---|
| 21 | my $plugin = MT::Plugin::reCaptcha->instance; |
|---|
| 22 | my $config = $plugin->get_config_hash("blog:$blog_id"); |
|---|
| 23 | my $publickey = $config->{recaptcha_publickey}; |
|---|
| 24 | my $privatekey = $config->{recaptcha_privatekey}; |
|---|
| 25 | return q() unless $publickey && $privatekey; |
|---|
| 26 | |
|---|
| 27 | return <<FORM_FIELD; |
|---|
| 28 | <div id="recaptcha_script" style="display:block"> |
|---|
| 29 | <script type="text/javascript" |
|---|
| 30 | src="http://api.recaptcha.net/challenge?k=$publickey"> |
|---|
| 31 | </script> |
|---|
| 32 | |
|---|
| 33 | <noscript> |
|---|
| 34 | <iframe src="http://api.recaptcha.net/noscript?k=$publickey" |
|---|
| 35 | height="300" width="500" frameborder="0"></iframe><br> |
|---|
| 36 | <textarea name="recaptcha_challenge_field" rows="3" cols="40"> |
|---|
| 37 | </textarea> |
|---|
| 38 | <input type="hidden" name="recaptcha_response_field" |
|---|
| 39 | value="manual_challenge"> |
|---|
| 40 | </noscript> |
|---|
| 41 | </div> |
|---|
| 42 | <script type="text/javascript"> |
|---|
| 43 | if ( typeof(mtCaptchaVisible) != "undefined" ) |
|---|
| 44 | mtCaptchaVisible = true; |
|---|
| 45 | else if ( typeof(commenter_name) != "undefined" ) { |
|---|
| 46 | var div = document.getElementById("recaptcha_script"); |
|---|
| 47 | if (commenter_name) |
|---|
| 48 | div.style.display = "none"; |
|---|
| 49 | else |
|---|
| 50 | div.style.display = "block"; |
|---|
| 51 | } |
|---|
| 52 | </script> |
|---|
| 53 | FORM_FIELD |
|---|
| 54 | } |
|---|
| 55 | |
|---|
| 56 | sub validate_captcha { |
|---|
| 57 | my $self = shift; |
|---|
| 58 | my ($app) = @_; |
|---|
| 59 | my $entry_id = $app->param('entry_id') |
|---|
| 60 | or return 0; |
|---|
| 61 | |
|---|
| 62 | my $entry = $app->model('entry')->load($entry_id) |
|---|
| 63 | or return 0; |
|---|
| 64 | |
|---|
| 65 | my $blog_id = $entry->blog_id; |
|---|
| 66 | |
|---|
| 67 | my $config = MT::Plugin::reCaptcha->instance->get_config_hash("blog:$blog_id"); |
|---|
| 68 | my $privatekey = $config->{recaptcha_privatekey}; |
|---|
| 69 | |
|---|
| 70 | my $challenge = $app->param('recaptcha_challenge_field'); |
|---|
| 71 | my $response = $app->param('recaptcha_response_field'); |
|---|
| 72 | my $ua = $app->new_ua({ timeout => 15, max_size => undef }); |
|---|
| 73 | return 0 unless $ua; |
|---|
| 74 | |
|---|
| 75 | require HTTP::Request; |
|---|
| 76 | my $req = HTTP::Request->new(POST => 'http://api-verify.recaptcha.net/verify'); |
|---|
| 77 | $req->content_type("application/x-www-form-urlencoded"); |
|---|
| 78 | require MT::Util; |
|---|
| 79 | my $content = 'privatekey=' . MT::Util::encode_url($privatekey); |
|---|
| 80 | $content .= '&remoteip=' . MT::Util::encode_url($app->remote_ip); |
|---|
| 81 | $content .= '&challenge=' . MT::Util::encode_url($challenge); |
|---|
| 82 | $content .= '&response=' . MT::Util::encode_url($response); |
|---|
| 83 | $req->content($content); |
|---|
| 84 | my $res = $ua->request($req); |
|---|
| 85 | my $c = $res->content; |
|---|
| 86 | if (substr($res->code, 0, 1) eq '2') { |
|---|
| 87 | return 1 if $c =~ /^true\n/; |
|---|
| 88 | } |
|---|
| 89 | 0; |
|---|
| 90 | } |
|---|
| 91 | |
|---|
| 92 | sub generate_captcha { |
|---|
| 93 | #This won't be called since there is no link which requests to "generate_captcha" mode. |
|---|
| 94 | my $self = shift; |
|---|
| 95 | 1; |
|---|
| 96 | } |
|---|
| 97 | |
|---|
| 98 | 1; |
|---|