Changeset 254 for captcha/trunk

Show
Ignore:
Timestamp:
10/03/06 17:57:03 (2 years ago)
Author:
ogawa
Message:

* Now can select enable or disable Captcha test per-blog basis
* Now can change the length of Captcha
* Now can be set a secret key for generating Captcha
* Captcha's output_folder can be placed under user-specific directory. Because, one can make plugins directory be executable but not readable (it might be usual for most web-hosting services?).

Location:
captcha/trunk/plugins/captcha
Files:
2 added
3 modified

Legend:

Unmodified
Added
Removed
  • captcha/trunk/plugins/captcha/captcha.pl

    r209 r254  
    1616use Authen::Captcha; 
    1717use base 'MT::Plugin'; 
    18 our $VERSION = '0.02'; 
     18our $VERSION = '0.10'; 
     19 
     20my $dirname = dirname(__FILE__); 
     21my $cgipath = MT::ConfigMgr->instance->CGIPath; 
     22$cgipath .= '/' unless $cgipath =~ m!/$!; 
    1923 
    2024my $plugin = __PACKAGE__->new({ 
    2125    name => 'Captcha', 
    2226    description => 'This plugin enables comment-posting with CAPTCHA test.', 
    23     doc_link => 'http://as-is.net/wiki/Captcha_Plugin', 
     27    doc_link => 'http://code.as-is.net/wiki/Captcha_Plugin', 
    2428    author_name => 'Hirotaka Ogawa', 
    2529    author_link => 'http://profile.typekey.com/ogawa/', 
    2630    version => $VERSION, 
    27     blog_config_template => \&config_tmpl, 
     31    blog_config_template => 'config.tmpl', 
    2832    settings => new MT::PluginSettings([ 
     33        ['captcha_enable', { Default => 0 }], 
    2934        ['captcha_ttl', { Default => 3600 }], 
     35        ['captcha_secret', { Default => '' }], 
     36        ['captcha_length', { Default => 5 }], 
     37        ['captcha_images_url', { Default => $cgipath . 'plugins/captcha/images/' }], 
     38        ['captcha_images_path', { Default => File::Spec->catdir($dirname, 'images') }], 
    3039    ]), 
    3140}); 
    3241MT->add_plugin($plugin); 
    3342 
    34 my $dirname = dirname(__FILE__); 
    3543my $captcha = Authen::Captcha->new( 
    36    data_folder => File::Spec->catdir($dirname, 'data'), 
    37    output_folder => File::Spec->catdir($dirname, 'images') 
     44   data_folder => File::Spec->catdir($dirname, 'data') 
    3845); 
    3946 
     
    4451    my ($eh, $app, $entry) = @_; 
    4552    my $blog = $entry->blog; 
     53 
     54    # check if commenter is logged on to typekey 
    4655    if ($blog->allow_reg_comments && $blog->effective_remote_auth_token) { 
    4756        my ($session_key, $commenter) = $app->_get_commenter_session(); 
     
    5362    my $md5 = $q->param('captcha_md5') or return 0; 
    5463 
    55     my $ttl = config('blog:' . $blog->id)->{captcha_ttl}; 
     64    # load config 
     65    my $cfg = config('blog:' . $blog->id); 
     66 
     67    # check if captcha-test disabled 
     68    return 1 unless $cfg->{captcha_enable}; 
     69 
     70    # configure Auth::Captcha 
     71    $captcha->output_folder($cfg->{captcha_images_path}); 
     72    $captcha->secret($cfg->{captcha_secret} || ''); 
     73 
     74    my $ttl = $cfg->{captcha_ttl}; 
    5675    $ttl = 3600 if $ttl !~ /^\d+$/; 
    5776    $captcha->expire($ttl); 
     
    6281sub captcha_js_url { 
    6382    my ($ctx, $args) = @_; 
     83    my $blog_id = $ctx->stash('blog')->id; 
    6484    my $path = MT::ConfigMgr->instance->CGIPath; 
    6585    $path .= '/' unless $path =~ m!/$!; 
    66     $path . 'plugins/captcha/captcha_js.cgi'; 
     86    $path . 'plugins/captcha/captcha_js.cgi?blog_id=' . $blog_id; 
     87} 
     88 
     89sub dump_settings { 
     90    my $plugin = shift; 
     91 
     92    my $conf = ''; 
     93    my @blogs = MT::Blog->load; 
     94    for my $blog (@blogs) { 
     95        my $config = $plugin->get_config_hash('blog:' . $blog->id); 
     96        next unless $config->{captcha_enable}; 
     97        $conf .= $blog->id . ',' . 
     98            $config->{captcha_ttl} . ',' . 
     99            $config->{captcha_secret} . ',' . 
     100            $config->{captcha_length} . ',' . 
     101            $config->{captcha_images_url} . ',' . 
     102            $config->{captcha_images_path} . "\n"; 
     103    } 
     104 
     105    my $cfg_file = File::Spec->catfile(dirname(__FILE__), 'data', 'config.txt'); 
     106    local(*FH); 
     107    open FH, ">$cfg_file" or die "Can't open File: $cfg_file\n"; 
     108    flock FH, 2; 
     109    print FH $conf; 
     110    close(FH); 
     111} 
     112 
     113sub save_config { 
     114    my $plugin = shift; 
     115    $plugin->SUPER::save_config(@_); 
     116    delete $plugin->{__config_obj}{$_[0]}; # invalidate cache 
     117    $plugin->dump_settings(); 
     118} 
     119 
     120sub reset_config { 
     121    my $plugin = shift; 
     122    $plugin->SUPER::reset_config(@_); 
     123    delete $plugin->{__config_obj}{$_[0]}; # invalidate cache 
     124    $plugin->dump_settings(); 
    67125} 
    68126 
     
    80138} 
    81139 
    82 sub config_tmpl { 
    83     my $tmpl = <<'EOT'; 
    84 <div class="setting"> 
    85   <div class="label"><label for="captcha_ttl"><MT_TRANS phrase="CAPTCHA TTL:"></label></div> 
    86   <div class="field"> 
    87     <input name="captcha_ttl" id ="captcha_ttl" size="5" value="<TMPL_VAR NAME=CAPTCHA_TTL ESCAPE=HTML>" /> <MT_TRANS phrase="seconds"> (max: 3600 seconds) 
    88   </div> 
    89 </div> 
    90 EOT 
    91 } 
    92  
    931401; 
  • captcha/trunk/plugins/captcha/captcha_js.cgi

    r209 r254  
    44# 
    55use Authen::Captcha; 
     6use File::Spec; 
     7use File::Basename; 
    68use CGI; 
    79 
    8 my $captcha = Authen::Captcha->new(data_folder => './data', 
    9                                    output_folder => './images', 
    10                                    expire => 3600); 
    11 my $captcha_length = 5; 
    12 my $captcha_img_width = 25 * $captcha_length; 
    13 my $captcha_img_height = 35; 
     10my $dirname = dirname(__FILE__); 
     11my $captcha = Authen::Captcha->new( 
     12   data_folder => File::Spec->catdir($dirname, 'data') 
     13); 
     14my $cfg_file = File::Spec->catfile($dirname, 'data', 'config.txt'); 
     15my $config; 
    1416 
    1517my $q = CGI->new; 
    16 gen_code($q); 
     18eval { 
     19    $config = read_config($cfg_file); 
     20    gen_code($q); 
     21}; 
     22if ($@) { 
     23    print $q->header("text/plain"), $@ if $@; 
     24} 
     25 
     26sub read_config { 
     27    my($cfg_file) = @_; 
     28    my $config; 
     29 
     30    local(*FH, $_, $/); 
     31    $/ = "\n"; 
     32    open FH, $cfg_file or die "Can't open File: $cfg_file\n"; 
     33    flock FH, 1; 
     34    while (<FH>) { 
     35        chomp; 
     36        my @c = split(',', $_); 
     37        next unless scalar @c == 6; 
     38        $config->{$c[0]} = { 
     39            captcha_ttl => $c[1], 
     40            captcha_secret => $c[2], 
     41            captcha_length => $c[3], 
     42            captcha_images_url => $c[4], 
     43            captcha_images_path => $c[5], 
     44        }; 
     45    } 
     46    close(FH); 
     47    $config; 
     48} 
    1749 
    1850sub gen_code { 
    1951    my $q = shift; 
    20     my $url = $q->url; 
    21     $url =~ s!/[^/]+$!!; 
     52    my $blog_id = $q->param('blog_id') || 1; 
     53    my $conf = $config->{$blog_id} or die "blog_id is not properly given."; 
     54 
     55    $captcha->expire($conf->{captcha_ttl} || 3600); 
     56    $captcha->secret($conf->{captcha_secret} || ''); 
     57    $captcha->output_folder($conf->{captcha_images_path}); 
     58 
     59    my $captcha_images_url = $conf->{captcha_images_url}; 
     60    $captcha_images_url .= '/' if $captcha_images_url !~ m!/$!; 
     61 
     62    my $captcha_length = $conf->{captcha_length} || 5; 
     63    my $captcha_img_width = 25 * $captcha_length; 
     64    my $captcha_img_height = 35; 
    2265 
    2366    my $captcha_md5 = $captcha->generate_code($captcha_length); 
     
    2972  document.writeln('<input type="hidden" name="captcha_md5" value="$captcha_md5" />'); 
    3073  document.writeln('<label for="comment-captcha">CAPTCHA&trade; Code:</label>'); 
    31   document.writeln('<img src="$url/images/$captcha_md5.png" width="$captcha_img_width" height="$captcha_img_height" alt="CAPTCHA Image" />'); 
     74  document.writeln('<img src="$captcha_images_url$captcha_md5.png" width="$captcha_img_width" height="$captcha_img_height" alt="CAPTCHA Image" />'); 
    3275  document.writeln('<input type="text" id="comment-captcha" name="captcha_code" value="" length="$captcha_length" maxlength="$captcha_length" />'); 
    3376  document.writeln('</div>'); 
  • captcha/trunk/plugins/captcha/captcha_js.fcgi

    r209 r254  
    44# 
    55use Authen::Captcha; 
     6use File::Spec; 
     7use File::Basename; 
    68use CGI::Fast; 
    79 
    8 my $captcha = Authen::Captcha->new(data_folder => './data', 
    9                                    output_folder => './images', 
    10                                    expire => 3600); 
    11 my $captcha_length = 5; 
    12 my $captcha_img_width = 25 * $captcha_length; 
    13 my $captcha_img_height = 35; 
     10my $dirname = dirname(__FILE__); 
     11my $captcha = Authen::Captcha->new( 
     12   data_folder => File::Spec->catdir($dirname, 'data') 
     13); 
     14my $cfg_file = File::Spec->catfile($dirname, 'data', 'config.txt'); 
     15my $config; 
    1416 
     17my $ctime = 0; 
    1518while (my $q = CGI::Fast->new) { 
    16     gen_code($q); 
     19    eval { 
     20        my $ctime_current = (stat($cfg_file))[9]; 
     21        if ($ctime_current > $ctime) { 
     22            $config = read_config($cfg_file); 
     23            $ctime = $ctime_current; 
     24        } 
     25        gen_code($q); 
     26    }; 
     27    print $q->header("text/plain"), $@ if $@; 
     28} 
     29 
     30sub read_config { 
     31    my($cfg_file) = @_; 
     32    my $config; 
     33 
     34    local(*FH, $_, $/); 
     35    $/ = "\n"; 
     36    open FH, $cfg_file or die "Can't open File: $cfg_file\n"; 
     37    flock FH, 1; 
     38    while (<FH>) { 
     39        chomp; 
     40        my @c = split(',', $_); 
     41        next unless scalar @c == 6; 
     42        $config->{$c[0]} = { 
     43            captcha_ttl => $c[1], 
     44            captcha_secret => $c[2], 
     45            captcha_length => $c[3], 
     46            captcha_images_url => $c[4], 
     47            captcha_images_path => $c[5], 
     48        }; 
     49    } 
     50    close(FH); 
     51    $config; 
    1752} 
    1853 
    1954sub gen_code { 
    2055    my $q = shift; 
    21     my $url = $q->url; 
    22     $url =~ s!/[^/]+$!!; 
     56    my $blog_id = $q->param('blog_id') || 1; 
     57    my $conf = $config->{$blog_id} or die "blog_id is not properly given."; 
     58 
     59    $captcha->expire($conf->{captcha_ttl} || 3600); 
     60    $captcha->secret($conf->{captcha_secret} || ''); 
     61    $captcha->output_folder($conf->{captcha_images_path}); 
     62 
     63    my $captcha_images_url = $conf->{captcha_images_url}; 
     64    $captcha_images_url .= '/' if $captcha_images_url !~ m!/$!; 
     65 
     66    my $captcha_length = $conf->{captcha_length} || 5; 
     67    my $captcha_img_width = 25 * $captcha_length; 
     68    my $captcha_img_height = 35; 
    2369 
    2470    my $captcha_md5 = $captcha->generate_code($captcha_length); 
     
    3076  document.writeln('<input type="hidden" name="captcha_md5" value="$captcha_md5" />'); 
    3177  document.writeln('<label for="comment-captcha">CAPTCHA&trade; Code:</label>'); 
    32   document.writeln('<img src="$url/images/$captcha_md5.png" width="$captcha_img_width" height="$captcha_img_height" alt="CAPTCHA Image" />'); 
     78  document.writeln('<img src="$captcha_images_url$captcha_md5.png" width="$captcha_img_width" height="$captcha_img_height" alt="CAPTCHA Image" />'); 
    3379  document.writeln('<input type="text" id="comment-captcha" name="captcha_code" value="" length="$captcha_length" maxlength="$captcha_length" />'); 
    3480  document.writeln('</div>');