X-Git-Url: https://iankelling.org/git/?p=iankelling.org;a=blobdiff_plain;f=_site%2Fcomment.rb;fp=_site%2Fcomment.rb;h=0000000000000000000000000000000000000000;hp=14f1152cb92ca13970971b4b212a4c21ff71b623;hb=3c09af9cc854c716d9f772d1c8c1e568cacc92b9;hpb=d0a5b73d2a275bfff5957961f2360df8966bee22 diff --git a/_site/comment.rb b/_site/comment.rb deleted file mode 100755 index 14f1152..0000000 --- a/_site/comment.rb +++ /dev/null @@ -1,332 +0,0 @@ -#!/usr/bin/env ruby -# encoding: utf-8 -# Copyright (C) 2016 Ian Kelling - -# 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, see . - -# debian sets LANG=C when starting apache2. -# the envoding comment above fixes the internal encoding afaik, -# Found this at -# https://stackoverflow.com/questions/20521371/set-utf-8-as-default-for-ruby-1-9-3 -# also note man ruby's -E arg. -Encoding.default_external = Encoding::UTF_8 - -require 'cgi' -require 'fileutils' -require 'time' -require 'sqlite3' - -require_relative '../b' -include B - -# constanty things -DEBUG = true -CAPTCHA = -> { - c = [] - x = (< 0 - c << x.pop(2) - end - c -}[] - -def do_captcha - captcha_q = CAPTCHA.sample[0] - puts "Content-type: text/html\n\n" - puts skel('comment.rb', "#{DN}/captcha", <blog / comment-captcha') -

Hello friend. I haven't read a post from #{IP}, and I only remember for a few months, so:

-

#{captcha_q}

- -
- - - - -
Your comment: - - -
-EOF - exit 0 -end - - -def fail(msg) - if DEBUG and msg - puts "Content-type: text/plain\n\n" - puts msg - else - redir - end - exit 0 -end - -def redir - File.write('/tmp/x', GOTO) - puts 'Status: 302 Found' - puts "Location: #{GOTO}#comment-section\n\n" - exit(0) -end - - -def bn(*args) - File.basename *args -end - - -###### begin error checking & arg parsing ###### -cgi = CGI.new -IP = cgi.remote_addr - -if cgi.has_key?('goto') - GOTO = cgi['goto'] -else - GOTO = '/' - fail['redir to /'] -end - -if (cgi.has_key?('url') && cgi['url'] != "") || ! cgi.has_key?('comment') - fail["comment not in form or url in form. cgi.params: #{cgi.params}"] -end - -COMMENT_TXT = cgi["comment"] - - -if COMMENT_TXT.length > 1000 or GOTO.length > 150 - fail['length of comment or goto is too great'] -end - - -captchad = false -if cgi.has_key?('answer') && cgi.has_key?('question') - if cgi['answer'].downcase !~ /^#{CAPTCHA.to_h[cgi['question']]}$/ - do_captcha - end - captchad = true -end - - --> { - found = false - Dir.foreach('blog') do |entry| - next if ['.','..'].any? { |f| f == entry } - if GOTO == 'blog/' + entry - found = true - break - end - end - fail['goto entry not found'] unless found -}[] -######### end error checking & arg parsing ######## - - -$db = db_init -state = nil -WHITELIST_CUTOFF = NOW - 4*DAY - - -####### begin: state for ips we've seen before ####### -[[5, 60], # 1 min - [10, 60*5], # 5 min - [20, 60*60], # 60 min - [30, 60*60*24], # 1 day - [60, 60*60*24*7]] # 1 week - .each do |max_posts, date| - - if $db.execute(<<-SQL, [NOW - date])[0][0] > max_posts - select count(*) from c - where date > ? and ip = '#{IP}' -SQL - state = 'rate_limited' - end -end - -state ||= 'suspect' if $db.execute(<<-SQL)[0][0] > 0 - select count(*) from c - where ip = '#{IP}' and ( -state = 'banned' or -state = 'rate_limited') -SQL - -unless state - older_date = NOW - DAY*2 - last_moderated = $db.execute(<<-SQL, [older_date])[-1][0] - select date from c - where ip = '#{IP}' and ( - state = 'moderated' or - (date < ? and (state = 'timed' or state = 'known'))) -SQL - last_good = $db.execute(<<-SQL, [older_date])[-1][0] - select date from c - where ip = '#{IP}' and ( - state = 'picked' or - (date < ? and (state = 'timed' or state = 'known'))) -SQL - if last_moderated && last_good - if last_good > last_moderated - state = 'known' - else - # these 2 waiting conditions are not actually needed, - # since waiting is the default, but meh. - state = 'waiting' - end - elsif last_moderated - state = 'waiting' - elsif last_good - state = 'known' - end -end -####### end: state for ips we've seen before ####### - -####### begin: whitelist checking ######### -glob = "../blog/#{'?'*'YYYY-MM-DD-'.length}#{bn GOTO, '.*'}.md" -md_file = Dir[glob][0] -unless state - b = bn(md_file,'.*') - post_date = Time.parse(b[0..DATE_LEN]).to_i - if post_date > WHITELIST_CUTOFF - state = 'timed' - end -end -###### end: whitelist checking ######## - -state ||= 'waiting' - -if state != 'known' && ! captchad - do_captcha -end - - -# states: -# timed -# # was posted a whitelist period, so automatically posted. -# # whitelist periods are per page times when legit comments are -# # much more likely than spam, so we automatically let comments through. - -# known -# # ip posted good comment before: either, one in picked state, or -# # a timed/known comment which is over 2 days old (I saw it and didn't remove -# # it) - -# picked -# # manually marked as a good comment, so publish it. - -# rate_limited -# # posting too much, consider them a spammer. - -# moderated -# # bad comment, but don't ban them - -# banned -# # all comments from this ip dead, new comment's dont even go into the db. - -# waiting -# # waiting for manual moderation, get's posted automatically if there -# # is none in 24 hours - -# suspect -# # had a bad post in the past. does not -# # automatically get posted in time without moderation. - - -# any of the manual states -date = $db.execute(<<-SQL)[0][0] -select max(date) from c where -state = 'moderated' or -state = 'banned' or -state = 'picked' -SQL - -# not the bad automatic states -query = <<-SQL -select count(*) from c where -state != 'rate_limited' and -state != 'suspect' -SQL - - -if date - new_count = $db.execute(query + 'and date > ?',date) -else - new_count = $db.execute(query) -end - -if new_count == 1 - require 'net/smtp' - def send_email(opts={}) - opts[:to] ||= ENV['USER'] - opts[:server] ||= 'localhost' - opts[:from] ||= ENV['USER'] - opts[:from_alias] ||= ENV['USER'] - opts[:subject] ||= "test subject" - opts[:body] ||= "" - - msg = < -To: <#{opts[:to]}> -Subject: #{opts[:subject]} - -#{opts[:body]} -END_OF_MESSAGE - - Net::SMTP.start(opts[:server]) do |smtp| - smtp.send_message msg, opts[:from], opts[:to] - end - end - send_email :subject => 'new comments on iankelling.org' -end - -$db.execute('insert into c values (NULL, ?, ?, ?, ?, ?)', - [state, - IP, - NOW, - GOTO, - COMMENT_TXT]) - -post(md_file) - -redir