SVX日記
2012-07-07(Sat) tDiary用簡易CAPTCHA
・/usr/local/share/tdiary/misc/filter/tcaptcha.rb
# -*- coding: utf-8; -*-
require 'digest/md5'
module TDiary
module Filter
class TcaptchaFilter < Filter
def comment_filter( diary, comment )
common_key = 'abc' # 任意の文字列(プラグイン側と合わせる)
rw = @cgi.params['tcaptcha'].dup
dm = Digest::MD5.hexdigest((rw << common_key).sort.join(':'))
$stdout.sync = 1
if(result = (@cgi.params['tcaptcha_digest'][0] == dm))
# =begin # 強引なメッセージの出し方をするので、クッキーを食わせられなくなる
print "Content-Type: text/html\n\n"
print "<HTML><HEAD><META http-equiv='Content-Type' content='text/html; charset=UTF-8'></HEAD><BODY>\n"
print "<H1>Thank you for your comment</H1>\n"
print "<P>コメントありがとうございました。</P>\n"
sleep 5
# =end
else
print "Status: 406 Not Acceptable\n"
print "Content-Type: text/html\n\n"
print "<HTML><HEAD><META http-equiv='Content-Type' content='text/html; charset=UTF-8'></HEAD><BODY>\n"
print "<H1>Tiny CAPTCHA challenge failed</H1>\n"
print "<P>Tiny CAPTCHA 認証に失敗しました。</P>\n"
print "<FONT color='white'><!--\n" # 以降を強引に不可視にしようとする努力
sleep 5
raise 'Tiny CAPTCHA challenge failed'
end
comment.show = false # 要査閲にするなら
result
end
end
end
end
__END__
・/usr/local/share/tdiary/misc/plugin/tcaptcha.rb
# -*- coding: utf-8; -*-
require 'digest/md5'
def comment_body_label
common_key = 'abc' # 任意の文字列(フィルタ側と合わせる)
q = @options['tcaptcha.question'] ||= '質問: 鳥の鳴き声'
r = @options['tcaptcha.rights'] ||= ['チュンチュン', 'コケコッコ', 'ピヨピヨ', 'カァー', 'ホーホケキョ', 'ガァガァ']
w = @options['tcaptcha.wrongs'] ||= ['ワン', 'ニャー', 'ブゥブゥ', 'ヒヒーン', 'パォーン', 'ガォー']
rs = r.shuffle
rw = ([rs.shift] + (rs + w).shuffle[0, 5]).shuffle
dm = Digest::MD5.hexdigest(((r & rw) << common_key).sort.join(':'))
h = ''; id = 0; rw.each {|i|
h << "\t\t\t\t\t<INPUT type='checkbox' id='tc%d' name='tcaptcha' value='%s'><LABEL for='tc%d'>%s</LABEL>\n" % [id += 1, i, id, i]
}
h << "\t\t\t\t\t<INPUT type='hidden' name='tcaptcha_digest' value='%s'>\n" % dm
tcaptcha = <<-FORM
#{q}
#{h} </div>
<div class="textarea">
コメント
FORM
tcaptcha.chomp
end
def comment_body_label_short
'本文' # 未対応
end
__END__
どうも再訪問のカウントは、基本クッキーを使って回避しているらしいのだが、調べるとブラウザまでクッキーが届いていない。仕方ないので、counterプラグインのみならず、tDiary本体にもデバッグ行を入れまくり、動作をトレースする。すると、なんだかコメントスパム等に対するフィルタ処理の関係で、各プラグインが2回ずつ呼ばれるようになってしまっている。counterプラグインは関数定義だけでなく、ロードされただけで実行される処理を持っており、2回連続で呼ばれると副作用でクッキーを吐かなくなってしまうようだ。
www.itline.jp /usr/local/share/tdiary/misc/plugin # diff -U 4 counter.rb.org counter.rb
--- counter.rb.org 2012-04-29 20:27:26.000000000 +0900
+++ counter.rb 2012-07-08 02:44:54.290040583 +0900
@@ -476,16 +503,19 @@
def kiriban_today?
TDiaryCounter.kiriban_today?
end
+if($q_meet_again_q)
tdiary_counter_cookie = TDiaryCounter.run(@cache_path, @cgi, @options)
if tdiary_counter_cookie
if defined?(add_cookie)
add_cookie(tdiary_counter_cookie)
else
@cookie = tdiary_counter_cookie if tdiary_counter_cookie
end
end
+end
+$q_meet_again_q = true
def kiriban
if kiriban?
msg = @options["counter.kiriban_msg"] ? @options["counter.kiriban_msg"] : ""