Skip to content

Commit

Permalink
Item461: port& clean AntiSpamPlugin?
Browse files Browse the repository at this point in the history
Converstion and simplification as we don't need to support broken versions of twiki anymore


git-svn-id: http://svn.foswiki.org/trunk/AntiWikiSpamPlugin@1335 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
SvenDowideit authored and SvenDowideit committed Dec 14, 2008
1 parent 7041b42 commit 30aef66
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 115 deletions.
254 changes: 140 additions & 114 deletions lib/Foswiki/Plugins/AntiWikiSpamPlugin.pm
Expand Up @@ -10,7 +10,7 @@
# 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, published at
# GNU General Public License for more details, published at
# http://www.gnu.org/copyleft/gpl.html
#

Expand Down Expand Up @@ -40,9 +40,9 @@ $VERSION = '$Rev$';
# of the version number in PLUGINDESCRIPTIONS.
$RELEASE = '1.2';

$pluginName = 'AntiWikiSpamPlugin'; # Name of this Plugin
$pluginName = 'AntiWikiSpamPlugin'; # Name of this Plugin

$debug = 1; # toggle me
$debug = 1; # toggle me

=pod
Expand All @@ -57,16 +57,17 @@ not used for plugins specific functionality at present
=cut

sub initPlugin {
my( $topic, $web, $user, $installWeb ) = @_;
my ( $topic, $web, $user, $installWeb ) = @_;

# check for Plugins.pm versions
if( $Foswiki::Plugins::VERSION < 1.026 ) {
Foswiki::Func::writeWarning( "Version mismatch between $pluginName and Plugins.pm" );
if ( $Foswiki::Plugins::VERSION < 1.026 ) {
Foswiki::Func::writeWarning(
"Version mismatch between $pluginName and Plugins.pm");
return 0;
}

#forceUpdate
Foswiki::Func::registerRESTHandler('forceUpdate', \&forceUpdate);
Foswiki::Func::registerRESTHandler( 'forceUpdate', \&forceUpdate );

# Plugin correctly initialized
return 1;
Expand All @@ -81,7 +82,8 @@ write debug output if the debug flag is set
=cut

sub writeDebug {
Foswiki::Func::writeDebug( "- $pluginName - ".$_[0]) if $debug;
Foswiki::Func::writeDebug( "- $pluginName - " . $_[0] ) if $debug;
return;
}

=pod
Expand All @@ -99,6 +101,7 @@ __NOTE:__ meta-data is embedded in $text (using %META: tags)
=cut

sub beforeSaveHandler {

# do not uncomment, use $_[0], $_[1]... instead
### my ( $text, $topic, $web ) = @_;

Expand All @@ -107,7 +110,8 @@ sub beforeSaveHandler {

writeDebug("beforeSaveHandler( $_[2].$_[1] )");
downloadRegexUpdate();
checkText($_[2], $_[1], $_[0]);
checkText( $_[2], $_[1], $_[0] );
return;
}

=pod
Expand All @@ -118,26 +122,34 @@ checks attachments for javascript exploits and spam
=cut

sub beforeAttachmentSaveHandler
{
sub beforeAttachmentSaveHandler {
### my ( $attachmentAttr, $topic, $web ) = @_; # do not uncomment, use $_[0], $_[1]... instead
my $attachmentName = $_[0]->{"attachment"};
my $tmpFilename = $_[0]->{"tmpFilename"};
my $text = Foswiki::Func::readFile( $tmpFilename );
my $text = Foswiki::Func::readFile($tmpFilename);

#from BlackListPlugin
# check for evil eval() spam in <script>
if( $text =~ /<script.*?eval *\(.*?<\/script>/gis ) { #TODO: there's got to be a better way to do this.
Foswiki::Func::writeWarning("detected possible javascript exploit at attachment in in $_[2].$_[1]");
throw Foswiki::OopsException( 'attention', def=>'attach_error',
params => 'The attachment has been rejected as it contains a possible javascript eval exploit.');
if ( $text =~ /<script.*?eval *\(.*?<\/script>/gis )
{ #TODO: there's got to be a better way to do this.
Foswiki::Func::writeWarning(
"detected possible javascript exploit at attachment in in $_[2].$_[1]"
);
throw Foswiki::OopsException(
'attention',
def => 'attach_error',
web => $_[2],
topic => $_[1],
params =>
'The attachment has been rejected as it contains a possible javascript eval exploit.'
);
}

downloadRegexUpdate();
checkText($_[2], $_[1], $text);
checkText( $_[2], $_[1], $text );
return;
}


=pod
---++ forceUpdate($session) -> $text
Expand All @@ -149,31 +161,34 @@ can be used to force an update of the spam list
=cut

sub forceUpdate {
writeDebug('about to forceUpdate');
downloadRegexUpdate(1);
writeDebug('forceUpdate complete');
writeDebug('about to forceUpdate');
downloadRegexUpdate(1);
writeDebug('forceUpdate complete');

return ${pluginName}.': SharedSpamList forceUpdate complete ';
return ${pluginName} . ': SharedSpamList forceUpdate complete ';
}

sub saveWorkFile($$) {
sub saveWorkFile {
my $fileName = shift;
my $text = shift;
my $text = shift;

my $workarea = Foswiki::Func::getWorkArea($pluginName);
Foswiki::Func::saveFile($workarea.'/'.$fileName , $text);
Foswiki::Func::saveFile( $workarea . '/' . $fileName, $text );
return;
}
sub readWorkFile($) {

sub readWorkFile {
my $fileName = shift;

my $workarea = Foswiki::Func::getWorkArea($pluginName);
return Foswiki::Func::readFile($workarea.'/'.$fileName);
return Foswiki::Func::readFile( $workarea . '/' . $fileName );
}
sub fileExists($) {

sub fileExists {
my $fileName = shift;

my $workarea = Foswiki::Func::getWorkArea($pluginName);
return (-e $workarea.'/'.$fileName);
return ( -e $workarea . '/' . $fileName );
}

=pod
Expand All @@ -185,84 +200,87 @@ downloads a new set of regexes if it is time to do so
=cut

sub downloadRegexUpdate {
my $forceFlag = shift;

unless ($forceFlag) {
my $timesUp;
my $topicExists = fileExists(${pluginName}.'_regexs');
if ($topicExists) {
my $getListTimeOut = Foswiki::Func::getPluginPreferencesValue( 'GETLISTTIMEOUT' ) || 61;
#has it been more than $getListTimeOut minutes since the last get?
my $lastTimeWeCheckedForUpdate = readWorkFile(${pluginName}.'_timeOfLastCheck');
writeDebug("time > ($lastTimeWeCheckedForUpdate + ($getListTimeOut * 60))");
$timesUp = time > ($lastTimeWeCheckedForUpdate + ($getListTimeOut * 60));
my $forceFlag = shift;

unless ($forceFlag) {
my $timesUp;
my $topicExists = fileExists( ${pluginName} . '_regexs' );
if ($topicExists) {
my $getListTimeOut =
Foswiki::Func::getPluginPreferencesValue('GETLISTTIMEOUT') || 61;

#has it been more than $getListTimeOut minutes since the last get?
my $lastTimeWeCheckedForUpdate =
readWorkFile( ${pluginName} . '_timeOfLastCheck' );
writeDebug(
"time > ($lastTimeWeCheckedForUpdate + ($getListTimeOut * 60))"
);
$timesUp =
time > ( $lastTimeWeCheckedForUpdate + ( $getListTimeOut * 60 ) );
}
return unless ($timesUp || !$topicExists);
}
return unless $timesUp || !$topicExists;
}

writeDebug("downloading new spam data");
my $lock = readWorkFile(${pluginName}.'_lock'); # SMELL: that's no good way to do locking
if ( $lock eq '' ) {
writeDebug("downloading new spam data");
saveWorkFile(${pluginName}.'_lock', 'lock');
my $listUrl = Foswiki::Func::getPluginPreferencesValue( 'ANTISPAMREGEXLISTURL' );
my $list = includeUrl($listUrl);
if (defined ($list)) {
#writeDebug("$list");
saveWorkFile(${pluginName}.'_regexs', $list);
saveWorkFile(${pluginName}.'_timeOfLastCheck', time);
}
saveWorkFile(${pluginName}.'_lock', '');
} else {
writeDebug("downloading new spam data");
}
}

=pod
---++ includeUrl()

simplified version of INCLUDE
=cut

sub includeUrl($) {
my $theUrl = shift;

return Foswiki::Func::getExternalResource($theUrl)->content();
writeDebug("downloading new spam data");
my $lock =
readWorkFile( ${pluginName} . '_lock' )
; # SMELL: that's no good way to do locking
if ( $lock eq '' ) {
writeDebug("downloading new spam data");
saveWorkFile( ${pluginName} . '_lock', 'lock' );
my $listUrl =
Foswiki::Func::getPluginPreferencesValue('ANTISPAMREGEXLISTURL');
my $list = Foswiki::Func::getExternalResource($listUrl)->content();
if ( defined($list) ) {

#writeDebug("$list");
saveWorkFile( ${pluginName} . '_regexs', $list );
saveWorkFile( ${pluginName} . '_timeOfLastCheck', time );
}
saveWorkFile( ${pluginName} . '_lock', '' );
}
else {
writeDebug("downloading new spam data");
}
return;
}

=pod
---++ checkText($text)
---++ checkText($web, $topic, $text)
check a text for spam; throws an oops exception if so
=cut

sub checkText {
# my ($web, $topic, $text) = @_;
my $web = shift;
my $topic = shift;

writeDebug("checkText($web.$topic, ... )");

# do localspamlist first
my $regexWeb;
my $regexTopic = Foswiki::Func::getPluginPreferencesValue( 'LOCALANTISPAMREGEXLISTTOPIC' );
my $twikiWeb = Foswiki::Func::getTwikiWebname();
($regexWeb, $regexTopic) = Foswiki::Func::normalizeWebTopicName($twikiWeb, $regexTopic);
if (Foswiki::Func::topicExists($regexWeb, $regexTopic) ) {
if (($topic eq $regexTopic) && ($web eq $regexWeb)) {
return; #don't check the anti-spam topic
}
my ( $meta, $regexs) = Foswiki::Func::readTopic($regexWeb, $regexTopic);
checkTextUsingRegex($web, $topic, $regexs, $_[0]);
}

# use the share spam regexs
my $regexs = readWorkFile(${pluginName}.'_regexs');
checkTextUsingRegex($web, $topic, $regexs, $_[0]);

# my ($web, $topic, $text) = @_;
my $web = shift;
my $topic = shift;

writeDebug("checkText($web.$topic, ... )");

# do localspamlist first
my $regexWeb;
my $regexTopic =
Foswiki::Func::getPluginPreferencesValue('LOCALANTISPAMREGEXLISTTOPIC');
my $twikiWeb = Foswiki::Func::getTwikiWebname();
( $regexWeb, $regexTopic ) =
Foswiki::Func::normalizeWebTopicName( $twikiWeb, $regexTopic );
if ( Foswiki::Func::topicExists( $regexWeb, $regexTopic ) ) {
if ( ( $topic eq $regexTopic ) && ( $web eq $regexWeb ) ) {
return; #don't check the anti-spam topic
}
my ( $meta, $regexs ) =
Foswiki::Func::readTopic( $regexWeb, $regexTopic );
checkTextUsingRegex( $web, $topic, $regexs, $_[0] );
}

# use the share spam regexs
my $regexs = readWorkFile( ${pluginName} . '_regexs' );
checkTextUsingRegex( $web, $topic, $regexs, $_[0] );
return;
}

=pod
Expand All @@ -275,27 +293,35 @@ check a text for spam using a given regex; throws an oops exception if it detect

sub checkTextUsingRegex {
#my ($web, $topic, $regexs, $text) = @_;
my $web = shift;
my $web = shift;
my $topic = shift;

#load text as a set of regex's, and eval
foreach my $regexLine (split(/\n/, $_[0])) {
foreach my $regexLine ( split( /\n/, $_[0] ) ) {
$regexLine =~ /([^#]*)\s*#?/;
my $regex = $1;
$regex =~ s/^\s+//;
$regex =~ s/\s+$//;
if ($regex ne '') {
if ( $regex ne '' ) {
if ( $_[1] =~ /$regex/i ) {
Foswiki::Func::writeWarning("detected spam at $web.$topic (regex=$regex)");
Foswiki::Func::writeWarning(
"detected spam at $web.$topic (regex=$regex)");

# TODO: make this a nicer error, or make its own template
throw Foswiki::OopsException( 'attention', def=>'save_error',
params => "The topic $web.$topic has been rejected as it may contain spam.");
throw Foswiki::OopsException(
'attention',
def => 'save_error',
web => $web,
topic => $topic,
params =>
"The text of topic $web.$topic has been rejected as it may contain spam."
);
}
}
}
return;
}


=pod
---++ getCgiAction() -> $script
Expand All @@ -305,20 +331,20 @@ our version of getting the script action
=cut

sub getCgiAction {
my $pathInfo = $ENV{'PATH_INFO'} || '';
my $theAction = $ENV{'REQUEST_URI'} || '';
if ( $theAction =~ /^.*?\/([^\/]+)$pathInfo.*$/ ) {
$theAction = $1;
}
else {
$theAction = 'view';
}

my $pathInfo = $ENV{'PATH_INFO'} || '';
my $theAction = $ENV{'REQUEST_URI'} || '';
if ($theAction =~ /^.*?\/([^\/]+)$pathInfo.*$/) {
$theAction = $1;
} else {
$theAction = 'view';
}

#writeDebug("PATH_INFO=$ENV{'PATH_INFO'}");
#writeDebug("REQUEST_URI=$ENV{'REQUEST_URI'}");
#writeDebug("theAction=$theAction");
#writeDebug("PATH_INFO=$ENV{'PATH_INFO'}");
#writeDebug("REQUEST_URI=$ENV{'REQUEST_URI'}");
#writeDebug("theAction=$theAction");

return $theAction;
return $theAction;
}

1;
2 changes: 1 addition & 1 deletion lib/Foswiki/Plugins/AntiWikiSpamPlugin/MANIFEST
@@ -1,2 +1,2 @@
data/Foswiki/AntiWikiSpamPlugin.txt NEW
data/System/AntiWikiSpamPlugin.txt NEW
lib/Foswiki/Plugins/AntiWikiSpamPlugin.pm NEW

0 comments on commit 30aef66

Please sign in to comment.