[Home]WikiPatches/BannedContent

UseModWiki | WikiPatches | RecentChanges | Preferences

Banning specific content such as spam is pretty easy. Just take the various routines used banning ip/hosts and stir.

These are my patches for the modified version of UseMod 0.92 I'm using. They work with 1.0 with minor modifications, a context diff is at the end of this page.

First, define the test:


  sub ContentIsBanned {
    my ($content) = @_;
    my ($data, $status);
    ($status, $data) = &ReadFile("$DataDir/spamlist");
    return 0  if (!$status);            # no file exists, so no ban
    $data =~ s/\r//g;                   # remove \r from end of lines
    foreach (split(/\n/, $data)) {
      next if ((/^\s*$/) || (/^#/));    # Skip empty, spaces, or comments
      return 1  if ($content =~ /$_/i); # return true, content is banned
    }
    return 0;                           # return false, content is not banned
  }

Next, call the test... insert the following into DoPost?, just under the if block that tests UserCanEdit


  if (&ContentIsBanned($string)) {
    # This is an internal interface--we don't need to explain
    &ReportError(Ts('Editing not allowed for %s.', $id));
    return;
  }

Next, we need a way to edit and update the spamlist... insert these just under DoEditBanned? and DoUpdateBanned?


  sub DoEditSpam {
    my ($spamList, $status);
  
    print &GetHeader("", "Editing Spam List", "");
    return  if (!&UserIsAdminOrError());
    ($status, $spamList) = &ReadFile("$DataDir/spamlist");
    $spamList = ""  if (!$status);
    print &GetFormStart();
    print GetHiddenValue("edit_spam", 1), "\n";
    print "<b>Banned content list:</b><br>\n";
    print "<p>Each entry is either a commented line (starting with #), ",
      "or a Perl regular expression";
    print &GetTextArea('spamlist', $spamList, 20, 50);
    print "<br>", $q->submit(-name=>'Save'), "\n";
    print "<hr>\n";
    print $q->endform;
    print &GetCommonFooter("");
    print &GetMinimumFooter();
  }
  
  #---------------------------------------------------------------------------------------
  
  sub DoUpdateSpam {
    my ($newList, $fname);
  
    print &GetHeader("", "Updating spam list", "");
    return  if (!&UserIsAdminOrError());
    $fname = "$DataDir/spamlist";
    $newList = &GetParam("spamlist", "#Empty file");
    if ($newList eq "") {
    print "<p>Empty spam list or error.";
    print "<p>Resubmit with at least one space character to remove.";
    } elsif ($newList =~ /^\s*$/s) {
    unlink($fname);
    print "<p>Removed spam list";
    } else {
    &WriteStringToFile($fname, $newList);
    print "<p>Updated spam list";
    }
    print &GetCommonFooter();
  }

and we need a link to click on to load that edit interface, so insert the following or similar into GetAdminBar?:


  $bartext .= &GetNavBarItem(&ScriptLink("action=editspam",T("Edit Spam List")),1);

and finally we need to patch DoOtherRequest to properly dispatch action=editspam and the update..

insert this bit just under the bit which dispatches on $action eq "editbanned"


    } elsif ($action eq "editspam") {
      &DoEditSpam();

and insert this bit a little bit further down, just under the if block with &GetParam("edit_ban,0)


  if (&GetParam("edit_spam", 0)) {
    &DoUpdateSpam();
    return;
  }


Now, you should have a Edit Spam List in your admin bar, which you can fill with PRE to test for spam words or spam links. There is no test on preview, just on posting, and the message displayed is terse and opaque so hopefully a dumb spammer will simply give up. Just be careful not to insert any regexp which is overly broad or you'll tick off your users.


Patch for 1.0

Here is a context diff for the above changes (with a minor change to differentiate banned hosts from banned content) against a virgin copy of UseMod 1.0:

*** wiki.pl@@/main/2    Fri Sep 12 13:38:17 2003
--- wiki.pl  Wed Jun 14 10:38:24 2006
***************
*** 2699,2704 ****
--- 2699,2719 ----
    return 0;
  }

+ # content banning from
+ # http://www.usemod.com/cgi-bin/wiki.pl?WikiPatches/BannedContent
+ sub ContentIsBanned {
+     my ($content) = @_;
+     my ($data, $status);
+     ($status, $data) = &ReadFile("$DataDir/spamlist");
+     return 0  if (!$status);            # no file exists, so no ban
+     $data =~ s/\r//g;                   # remove \r from end of lines
+     foreach (split(/\n/, $data)) {
+         next if ((/^\s*$/) || (/^\#/));   # Skip empty, spaces, or comments
+         return 1  if ($content =~ /$_/i); # return true, content is banned
+     }
+     return 0;                           # return false, content is not banned
+ }
+
  sub UserIsAdmin {
    my (@pwlist, $userPassword);

***************
*** 3107,3112 ****
--- 3122,3129 ----
        &DoEditPrefs();
      } elsif ($action eq "editbanned") {
        &DoEditBanned();
+     } elsif ($action eq "editspam") {
+       &DoEditSpam();
      } elsif ($action eq "editlinks") {
        &DoEditLinks();
      } elsif ($action eq "login") {
***************
*** 3141,3146 ****
--- 3158,3167 ----
      &DoUpdateBanned();
      return;
    }
+   if (&GetParam("edit_spam", 0)) {
+     &DoUpdateSpam();
+     return;
+   }
    if (&GetParam("enter_login", 0)) {
      &DoLogin();
      return;
***************
*** 3901,3906 ****
--- 3922,3933 ----
      &ReportError(Ts('Editing not allowed for %s.', $id));
      return;
    }
+
+   if (&ContentIsBanned($string)) {
+     # This is an internal interface--we don't need to explain
+     &ReportError(Ts('Editing not allowed for %s.', $id));
+     return;
+   }
    if (($id eq   'SampleUndefinedPage')    ||
        ($id eq T('SampleUndefinedPage'))   ||
        ($id eq   'Sample_Undefined_Page')  ||
***************
*** 4445,4450 ****
--- 4472,4520 ----
    print &GetCommonFooter();
  }

+ #------------------------------------------------------------------------
+ # content banning from
+ # http://www.usemod.com/cgi-bin/wiki.pl?WikiPatches/BannedContent
+ sub DoEditSpam {
+     my ($spamList, $status);
+
+     print &GetHeader("", "Editing Spam List", "");
+     return  if (!&UserIsAdminOrError());
+     ($status, $spamList) = &ReadFile("$DataDir/spamlist");
+     $spamList = ""  if (!$status);
+     print &GetFormStart();
+     print GetHiddenValue("edit_spam", 1), "\n";
+     print "<b>Banned content list:</b><br>\n";
+     print "<p>Each entry is either a commented line (starting with #), ",
+       "or a Perl regular expression";
+     print &GetTextArea('spamlist', $spamList, 20, 50);
+     print "<br>", $q->submit(-name=>'Save'), "\n";
+     print "<hr>\n";
+     print $q->endform;
+     print &GetCommonFooter("");
+     print &GetMinimumFooter();
+ }
+
+ sub DoUpdateSpam {
+     my ($newList, $fname);
+
+     print &GetHeader("", "Updating spam list", "");
+     return  if (!&UserIsAdminOrError());
+     $fname = "$DataDir/spamlist";
+     $newList = &GetParam("spamlist", "#Empty file");
+     if ($newList eq "") {
+         print "<p>Empty spam list or error.";
+         print "<p>Resubmit with at least one space character to remove.";
+     } elsif ($newList =~ /^\s*$/s) {
+         unlink($fname);
+         print "<p>Removed spam list";
+     } else {
+         &WriteStringToFile($fname, $newList);
+         print "<p>Updated spam list";
+     }
+     print &GetCommonFooter();
+   }
+
  # ==== Editing/Deleting pages and links ====
  sub DoEditLinks {
    print &GetHeader("", "Editing Links", "");
***************
*** 4854,4860 ****
      $result .= &GetPageLockLink($id, 1, T('Lock page'));
    }
    $result .= " | " . &GetDeleteLink($id, T('Delete this page'), 0);
!   $result .= " | " . &ScriptLink("action=editbanned", T("Edit Banned List"));
    $result .= " | " . &ScriptLink("action=maintain", T("Run Maintenance"));
    $result .= " | " . &ScriptLink("action=editlinks", T("Edit/Rename pages"));
    if (-f "$DataDir/noedit") {
--- 4924,4932 ----
      $result .= &GetPageLockLink($id, 1, T('Lock page'));
    }
    $result .= " | " . &GetDeleteLink($id, T('Delete this page'), 0);
!   $result .= " | " . &ScriptLink("action=editbanned", T("Edit Banned Hosts"));
!   $result .= " | " . &ScriptLink("action=editspam",
!                                  T("Edit Banned Content"));
    $result .= " | " . &ScriptLink("action=maintain", T("Run Maintenance"));
    $result .= " | " . &ScriptLink("action=editlinks", T("Edit/Rename pages"));
    if (-f "$DataDir/noedit") {


Update: I've been using this a while, and I made one modification, which is to allow an admin or editor to get around the content ban (in my case I had to ban http:// to get some relief from relentless spamming). I just added these two lines near the top of ContentIsBanned:

 # admins and editors can get around the ban
 return 0  if (&UserIsAdmin());
 return 0  if (&UserIsEditor());

-- Trent


UseModWiki | WikiPatches | RecentChanges | Preferences
Edit text of this page | View other revisions | Search MetaWiki
Last edited July 7, 2007 3:19 am by MarkusLude (diff)
Search: