]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blob - IkiWiki/Plugin/blogspam.pm
Merge branch 'master' of ssh://git.ikiwiki.info/srv/git/ikiwiki.info
[git.ikiwiki.info.git] / IkiWiki / Plugin / blogspam.pm
1 #!/usr/bin/perl
2 package IkiWiki::Plugin::blogspam;
4 use warnings;
5 use strict;
6 use IkiWiki 3.00;
8 my $defaulturl='http://test.blogspam.net:8888/';
10 sub import {
11         hook(type => "getsetup", id => "blogspam",  call => \&getsetup);
12         hook(type => "checkconfig", id => "blogspam", call => \&checkconfig);
13         hook(type => "checkcontent", id => "blogspam", call => \&checkcontent);
14 }
16 sub getsetup () {
17         return
18                 plugin => {
19                         safe => 1,
20                         rebuild => 0,
21                         section => "auth",
22                 },
23                 blogspam_pagespec => {
24                         type => 'pagespec',
25                         example => 'postcomment(*)',
26                         description => 'PageSpec of pages to check for spam',
27                         link => 'ikiwiki/PageSpec',
28                         safe => 1,
29                         rebuild => 0,
30                 },
31                 blogspam_options => {
32                         type => "string",
33                         example => "blacklist=1.2.3.4,blacklist=8.7.6.5,max-links=10",
34                         description => "options to send to blogspam server",
35                         link => "http://blogspam.net/api/testComment.html#options",
36                         safe => 1,
37                         rebuild => 0,
38                 },
39                 blogspam_server => {
40                         type => "string",
41                         default => $defaulturl,
42                         description => "blogspam server XML-RPC url",
43                         safe => 1,
44                         rebuild => 0,
45                 },
46 }
48 sub checkconfig () {
49         # This is done at checkconfig time because printing an error
50         # if the module is missing when a spam is posted would not
51         # let the admin know about the problem.
52         eval q{
53                 use RPC::XML;
54                 use RPC::XML::Client;
55         };
56         error $@ if $@;
57 }
59 sub checkcontent (@) {
60         my %params=@_;
61         my $session=$params{session};
62         
63         if (exists $config{blogspam_pagespec}) {
64                 return undef
65                         if ! pagespec_match($params{page}, $config{blogspam_pagespec},
66                                 location => $params{page});
67         }
69         my $url=$defaulturl;
70         $url = $config{blogspam_server} if exists $config{blogspam_server};
71         my $client = RPC::XML::Client->new($url);
73         my @options = split(",", $config{blogspam_options})
74                 if exists $config{blogspam_options};
76         # Allow short comments and whitespace-only edits, unless the user
77         # has overridden min-words themselves.
78         push @options, "min-words=0"
79                 unless grep /^min-words=/i, @options;
80         # Wiki pages can have a lot of urls, unless the user specifically
81         # wants to limit them.
82         push @options, "exclude=lotsaurls"
83                 unless grep /^max-links/i, @options;
84         # Unless the user specified a size check, disable such checking.
85         push @options, "exclude=size"
86                 unless grep /^(?:max|min)-size/i, @options;
87         # This test has absurd false positives on words like "alpha"
88         # and "buy".
89         push @options, "exclude=stopwords";
91         my %req=(
92                 ip => $session->remote_addr(),
93                 comment => defined $params{diff} ? $params{diff} : $params{content},
94                 subject => defined $params{subject} ? $params{subject} : "",
95                 name => defined $params{author} ? $params{author} : "",
96                 link => exists $params{url} ? $params{url} : "",
97                 options => join(",", @options),
98                 site => $config{url},
99                 version => "ikiwiki ".$IkiWiki::version,
100         );
101         my $res = $client->send_request('testComment', \%req);
103         if (! ref $res || ! defined $res->value) {
104                 debug("failed to get response from blogspam server ($url)");
105                 return undef;
106         }
107         elsif ($res->value =~ /^SPAM:(.*)/) {
108                 eval q{use Data::Dumper};
109                 debug("blogspam server reports ".$res->value.": ".Dumper(\%req));
110                 return gettext("Sorry, but that looks like spam to <a href=\"http://blogspam.net/\">blogspam</a>: ").$1;
111         }
112         elsif ($res->value ne 'OK') {
113                 debug("blogspam server failure: ".$res->value);
114                 return undef;
115         }
116         else {
117                 return undef;
118         }