From 572c5819d656d63f6b87e8fc54d8f561d6c3b9e3 Mon Sep 17 00:00:00 2001 From: Byron Jones Date: Tue, 22 Apr 2014 22:56:28 +0800 Subject: Bug 936509: Automatically disable accounts based on the number of comments tagged as spam --- extensions/AntiSpam/Extension.pm | 73 ++++++++++++++++++++++ extensions/AntiSpam/lib/Config.pm | 54 ++++++++++++++++ .../en/default/admin/params/antispam.html.tmpl | 28 +++++++++ 3 files changed, 155 insertions(+) create mode 100644 extensions/AntiSpam/lib/Config.pm create mode 100644 extensions/AntiSpam/template/en/default/admin/params/antispam.html.tmpl diff --git a/extensions/AntiSpam/Extension.pm b/extensions/AntiSpam/Extension.pm index ef31a0b2d..40a637adc 100644 --- a/extensions/AntiSpam/Extension.pm +++ b/extensions/AntiSpam/Extension.pm @@ -125,6 +125,73 @@ sub _ip_blocking { } } +# +# spam user disabling +# + +sub comment_after_add_tag { + my ($self, $args) = @_; + return unless lc($args->{tag}) eq 'spam'; + my $comment = $args->{comment}; + my $author = $comment->author; + + # exclude disabled users + return if !$author->is_enabled; + + # exclude users by group + return if $author->in_group(Bugzilla->params->{antispam_spammer_exclude_group}); + + # exclude users who are no longer new + return if !$author->is_new; + + # exclude users who haven't made enough comments + my $spam_count = Bugzilla->params->{antispam_spammer_comment_count}; + return if $author->comment_count < $spam_count; + + # get user's comments + my $comments = Bugzilla->dbh->selectall_arrayref(" + SELECT longdescs.comment_id,longdescs_tags.id + FROM longdescs + LEFT JOIN longdescs_tags + ON longdescs_tags.comment_id = longdescs.comment_id + AND longdescs_tags.tag = 'spam' + WHERE longdescs.who = ? + ORDER BY longdescs.bug_when + ", undef, $author->id); + + # this comment is spam + my $comment_id = $comment->id; + foreach my $ra (@$comments) { + if ($ra->[0] == $comment_id) { + $ra->[1] = 1; + last; + } + } + + # throw away comment id and negate bool to make it a list of not-spam + $comments = [ map { $_->[1] ? 0 : 1 } @$comments ]; + + my $reason; + + # check if the first N comments are spam + if (!scalar(grep { $_ } @$comments[0..($spam_count - 1)])) { + $reason = "first $spam_count comments are spam"; + } + + # check if the last N comments are spam + elsif (!scalar(grep { $_ } @$comments[-$spam_count..-1])) { + $reason = "last $spam_count comments are spam"; + } + + # disable + if ($reason) { + $author->set_disabledtext(Bugzilla->params->{antispam_spammer_disable_text}); + $author->set_disable_mail(1); + $author->update(); + _syslog(sprintf("[audit] antispam disabled <%s>: %s", $author->login, $reason)); + } +} + # # hooks # @@ -171,6 +238,12 @@ sub editable_tables { }; } +sub config_add_panels { + my ($self, $args) = @_; + my $modules = $args->{panel_modules}; + $modules->{AntiSpam} = "Bugzilla::Extension::AntiSpam::Config"; +} + # # installation # diff --git a/extensions/AntiSpam/lib/Config.pm b/extensions/AntiSpam/lib/Config.pm new file mode 100644 index 000000000..dc3e2820f --- /dev/null +++ b/extensions/AntiSpam/lib/Config.pm @@ -0,0 +1,54 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::AntiSpam::Config; + +use strict; +use warnings; + +use Bugzilla::Config::Common; +use Bugzilla::Group; + +our $sortkey = 511; + +sub get_param_list { + my ($class) = @_; + + my @param_list = ( + { + name => 'antispam_spammer_exclude_group', + type => 's', + choices => \&_get_all_group_names, + default => 'canconfirm', + checker => \&check_group + }, + { + name => 'antispam_spammer_comment_count', + type => 't', + default => '3', + checker => \&check_numeric + }, + { + name => 'antispam_spammer_disable_text', + type => 'l', + default => + "This account has been automatically disabled as a result of a " . + "high number of spam comments.\n\nPlease contact the address at ". + "the end of this message if you believe this to be an error." + }, + ); + + return @param_list; +} + +sub _get_all_group_names { + my @group_names = map {$_->name} Bugzilla::Group->get_all; + unshift(@group_names, ''); + return \@group_names; +} + +1; diff --git a/extensions/AntiSpam/template/en/default/admin/params/antispam.html.tmpl b/extensions/AntiSpam/template/en/default/admin/params/antispam.html.tmpl new file mode 100644 index 000000000..45dae623a --- /dev/null +++ b/extensions/AntiSpam/template/en/default/admin/params/antispam.html.tmpl @@ -0,0 +1,28 @@ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + # + # This Source Code Form is "Incompatible With Secondary Licenses", as + # defined by the Mozilla Public License, v. 2.0. + #%] + +[% + title = "Anti-Spam" + desc = "Edit Anti-Spam Configuration" +%] + +[% param_descs = +{ + antispam_spammer_exclude_group => + "Users in this group will be excluded from automatic disabling." + + antispam_spammer_comment_count => + "If a user has made at least this many comments, and either their first " _ + "NNN comments or their last NNN comments have been tagged as spam, their " _ + "account will be automatically disabled." + + antispam_spammer_disable_text => + "This message will be displayed to the user when they try to log " _ + "in after their account is disabled." +} +%] -- cgit v1.2.3-24-g4f1b