You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by ju...@apache.org on 2013/11/28 20:59:12 UTC
svn commit: r1546452 - in
/jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki:
filters/SpamFilter.java util/HttpUtil.java
Author: juanpablo
Date: Thu Nov 28 19:59:11 2013
New Revision: 1546452
URL: http://svn.apache.org/r1546452
Log:
* JSPWIKI-804: SpamFilter should support X-Forwarded-For header in the banlist
* also, formatted braces from those classes
Modified:
jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/filters/SpamFilter.java
jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/util/HttpUtil.java
Modified: jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/filters/SpamFilter.java
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/filters/SpamFilter.java?rev=1546452&r1=1546451&r2=1546452&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/filters/SpamFilter.java (original)
+++ jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/filters/SpamFilter.java Thu Nov 28 19:59:11 2013
@@ -18,8 +18,20 @@
*/
package org.apache.wiki.filters;
-import java.io.*;
-import java.util.*;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Random;
+import java.util.StringTokenizer;
+import java.util.Vector;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -29,8 +41,18 @@ import net.sf.akismet.Akismet;
import org.apache.commons.lang.time.StopWatch;
import org.apache.log4j.Logger;
-import org.apache.oro.text.regex.*;
-import org.apache.wiki.*;
+import org.apache.oro.text.regex.MalformedPatternException;
+import org.apache.oro.text.regex.MatchResult;
+import org.apache.oro.text.regex.Pattern;
+import org.apache.oro.text.regex.PatternCompiler;
+import org.apache.oro.text.regex.PatternMatcher;
+import org.apache.oro.text.regex.Perl5Compiler;
+import org.apache.oro.text.regex.Perl5Matcher;
+import org.apache.wiki.InternalWikiException;
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.WikiEngine;
+import org.apache.wiki.WikiPage;
+import org.apache.wiki.WikiProvider;
import org.apache.wiki.api.exceptions.RedirectException;
import org.apache.wiki.api.filters.BasicPageFilter;
import org.apache.wiki.attachment.Attachment;
@@ -38,6 +60,7 @@ import org.apache.wiki.auth.user.UserPro
import org.apache.wiki.providers.ProviderException;
import org.apache.wiki.ui.EditorManager;
import org.apache.wiki.util.FileUtil;
+import org.apache.wiki.util.HttpUtil;
import org.apache.wiki.util.TextUtil;
import org.suigeneris.jrcs.diff.Diff;
import org.suigeneris.jrcs.diff.DifferentiationFailedException;
@@ -48,6 +71,7 @@ import org.suigeneris.jrcs.diff.delta.De
import org.suigeneris.jrcs.diff.delta.Delta;
import org.suigeneris.jrcs.diff.myers.MyersDiff;
+
/**
* This is Herb, the JSPWiki spamfilter that can also do choke modifications.
*
@@ -77,9 +101,8 @@ import org.suigeneris.jrcs.diff.myers.My
*
* @since 2.1.112
*/
-public class SpamFilter
- extends BasicPageFilter
-{
+public class SpamFilter extends BasicPageFilter {
+
private static final String ATTR_SPAMFILTER_SCORE = "spamfilter.score";
private static final String REASON_REGEXP = "Regexp";
private static final String REASON_IP_BANNED_TEMPORARILY = "IPBannedTemporarily";
@@ -208,29 +231,19 @@ public class SpamFilter
* {@inheritDoc}
*/
@Override
- public void initialize( WikiEngine engine, Properties properties )
- {
- m_forbiddenWordsPage = properties.getProperty( PROP_WORDLIST,
- m_forbiddenWordsPage );
- m_errorPage = properties.getProperty( PROP_ERRORPAGE,
- m_errorPage );
-
+ public void initialize( WikiEngine engine, Properties properties ) {
+ m_forbiddenWordsPage = properties.getProperty( PROP_WORDLIST, m_forbiddenWordsPage );
+ m_errorPage = properties.getProperty( PROP_ERRORPAGE, m_errorPage );
m_limitSinglePageChanges = TextUtil.getIntegerProperty( properties,
PROP_PAGECHANGES,
m_limitSinglePageChanges );
-
+
m_limitSimilarChanges = TextUtil.getIntegerProperty( properties,
PROP_SIMILARCHANGES,
m_limitSimilarChanges );
- m_maxUrls = TextUtil.getIntegerProperty( properties,
- PROP_MAXURLS,
- m_maxUrls );
-
- m_banTime = TextUtil.getIntegerProperty( properties,
- PROP_BANTIME,
- m_banTime );
-
+ m_maxUrls = TextUtil.getIntegerProperty( properties, PROP_MAXURLS, m_maxUrls );
+ m_banTime = TextUtil.getIntegerProperty( properties, PROP_BANTIME, m_banTime );
m_blacklist = properties.getProperty( PROP_BLACKLIST, m_blacklist );
m_ignoreAuthenticated = TextUtil.getBooleanProperty( properties,
@@ -239,14 +252,11 @@ public class SpamFilter
m_useCaptcha = properties.getProperty( PROP_CAPTCHA, "" ).equals("asirra");
- try
- {
+ try {
m_urlPattern = m_compiler.compile( URL_REGEXP );
- }
- catch( MalformedPatternException e )
- {
- log.fatal("Internal error: Someone put in a faulty pattern.",e);
- throw new InternalWikiException("Faulty pattern.");
+ } catch( MalformedPatternException e ) {
+ log.fatal( "Internal error: Someone put in a faulty pattern.", e );
+ throw new InternalWikiException( "Faulty pattern." );
}
m_akismetAPIKey = TextUtil.getStringProperty( properties,
@@ -255,10 +265,10 @@ public class SpamFilter
m_stopAtFirstMatch = TextUtil.getStringProperty( properties,
PROP_FILTERSTRATEGY,
- STRATEGY_EAGER ).equals(STRATEGY_EAGER);
+ STRATEGY_EAGER ).equals( STRATEGY_EAGER );
- log.info("# Spam filter initialized. Temporary ban time "+m_banTime+
- " mins, max page changes/minute: "+m_limitSinglePageChanges );
+ log.info( "# Spam filter initialized. Temporary ban time " + m_banTime +
+ " mins, max page changes/minute: " + m_limitSinglePageChanges );
}
@@ -267,8 +277,7 @@ public class SpamFilter
private static final int ACCEPT = 1;
private static final int NOTE = 2;
- private static String log( WikiContext ctx, int type, String source, String message )
- {
+ private static String log( WikiContext ctx, int type, String source, String message ) {
message = TextUtil.replaceString( message, "\r\n", "\\r\\n" );
message = TextUtil.replaceString( message, "\"", "\\\"" );
@@ -276,10 +285,9 @@ public class SpamFilter
String page = ctx.getPage().getName();
String reason = "UNKNOWN";
- String addr = ctx.getHttpRequest() != null ? ctx.getHttpRequest().getRemoteAddr() : "-";
+ String addr = ctx.getHttpRequest() != null ? HttpUtil.getRemoteAddress( ctx.getHttpRequest() ) : "-";
- switch( type )
- {
+ switch( type ) {
case REJECT:
reason = "REJECTED";
break;
@@ -290,38 +298,30 @@ public class SpamFilter
reason = "NOTE";
break;
default:
- throw new InternalWikiException("Illegal type "+type);
+ throw new InternalWikiException( "Illegal type " + type );
}
-
- c_spamlog.info( reason+" "+source+" "+uid+" "+addr+" \""+page+"\" "+message );
+ c_spamlog.info( reason + " " + source + " " + uid + " " + addr + " \"" + page + "\" " + message );
return uid;
}
/** {@inheritDoc} */
- public String preSave( WikiContext context, String content )
- throws RedirectException
- {
+ public String preSave( WikiContext context, String content ) throws RedirectException {
cleanBanList();
- refreshBlacklists(context);
-
+ refreshBlacklists( context );
Change change = getChange( context, content );
- if(!ignoreThisUser(context))
- {
+ if( !ignoreThisUser( context ) ) {
checkBanList( context, change );
checkSinglePageChange( context, content, change );
- checkPatternList(context, content, change);
+ checkPatternList( context, content, change );
}
- if( !m_stopAtFirstMatch )
- {
- Integer score = (Integer)context.getVariable(ATTR_SPAMFILTER_SCORE);
+ if( !m_stopAtFirstMatch ) {
+ Integer score = ( Integer )context.getVariable( ATTR_SPAMFILTER_SCORE );
- if( score != null && score.intValue() >= m_scoreLimit )
- {
- throw new RedirectException( "Herb says you got too many points",
- getRedirectPage(context) );
+ if( score != null && score.intValue() >= m_scoreLimit ) {
+ throw new RedirectException( "Herb says you got too many points", getRedirectPage( context ) );
}
}
@@ -329,23 +329,21 @@ public class SpamFilter
return content;
}
- private void checkStrategy( WikiContext context, String error, String message )
- throws RedirectException
- {
- if( m_stopAtFirstMatch )
- {
- throw new RedirectException( message, getRedirectPage(context) );
+ private void checkStrategy( WikiContext context, String error, String message ) throws RedirectException {
+ if( m_stopAtFirstMatch ) {
+ throw new RedirectException( message, getRedirectPage( context ) );
}
- Integer score = (Integer)context.getVariable( ATTR_SPAMFILTER_SCORE );
-
- if( score != null )
- score = score+1;
- else
+ Integer score = ( Integer )context.getVariable( ATTR_SPAMFILTER_SCORE );
+ if( score != null ) {
+ score = score + 1;
+ } else {
score = 1;
+ }
context.setVariable( ATTR_SPAMFILTER_SCORE, score );
}
+
/**
* Parses a list of patterns and returns a Collection of compiled Pattern
* objects.
@@ -354,27 +352,20 @@ public class SpamFilter
* @param list
* @return A Collection of the Patterns that were found from the lists.
*/
- private Collection<Pattern> parseWordList( WikiPage source, String list )
- {
- ArrayList<Pattern> compiledpatterns = new ArrayList<Pattern>();
+ private Collection< Pattern > parseWordList( WikiPage source, String list ) {
+ ArrayList< Pattern > compiledpatterns = new ArrayList< Pattern >();
- if( list != null )
- {
+ if( list != null ) {
StringTokenizer tok = new StringTokenizer( list, " \t\n" );
- while( tok.hasMoreTokens() )
- {
+ while( tok.hasMoreTokens() ) {
String pattern = tok.nextToken();
- try
- {
+ try {
compiledpatterns.add( m_compiler.compile( pattern ) );
- }
- catch( MalformedPatternException e )
- {
- log.debug( "Malformed spam filter pattern "+pattern );
-
- source.setAttribute("error", "Malformed spam filter pattern "+pattern);
+ } catch( MalformedPatternException e ) {
+ log.debug( "Malformed spam filter pattern " + pattern );
+ source.setAttribute("error", "Malformed spam filter pattern " + pattern);
}
}
}
@@ -383,49 +374,35 @@ public class SpamFilter
}
/**
- * Takes a MT-Blacklist -formatted blacklist and returns a list of compiled
- * Pattern objects.
+ * Takes a MT-Blacklist -formatted blacklist and returns a list of compiled Pattern objects.
*
* @param list
* @return The parsed blacklist patterns.
*/
- private Collection<Pattern> parseBlacklist( String list )
- {
- ArrayList<Pattern> compiledpatterns = new ArrayList<Pattern>();
-
- if( list != null )
- {
- try
- {
- BufferedReader in = new BufferedReader( new StringReader(list) );
+ private Collection< Pattern > parseBlacklist( String list ) {
+ ArrayList< Pattern > compiledpatterns = new ArrayList< Pattern >();
+ if( list != null ) {
+ try {
+ BufferedReader in = new BufferedReader( new StringReader(list) );
String line;
-
- while( (line = in.readLine()) != null )
- {
+ while( (line = in.readLine() ) != null ) {
line = line.trim();
if( line.length() == 0 ) continue; // Empty line
if( line.startsWith("#") ) continue; // It's a comment
- int ws = line.indexOf(' ');
-
- if( ws == -1 ) ws = line.indexOf('\t');
-
- if( ws != -1 ) line = line.substring(0,ws);
+ int ws = line.indexOf( ' ' );
+ if( ws == -1 ) ws = line.indexOf( '\t' );
+ if( ws != -1 ) line = line.substring( 0, ws );
- try
- {
+ try {
compiledpatterns.add( m_compiler.compile( line ) );
- }
- catch( MalformedPatternException e )
- {
- log.debug( "Malformed spam filter pattern "+line );
+ } catch( MalformedPatternException e ) {
+ log.debug( "Malformed spam filter pattern " + line );
}
}
- }
- catch( IOException e )
- {
- log.info("Could not read patterns; returning what I got",e);
+ } catch( IOException e ) {
+ log.info( "Could not read patterns; returning what I got" , e );
}
}
@@ -440,31 +417,27 @@ public class SpamFilter
* @param content
* @throws RedirectException
*/
- private synchronized void checkSinglePageChange( WikiContext context, String content, Change change )
- throws RedirectException
- {
+ private synchronized void checkSinglePageChange( WikiContext context, String content, Change change )
+ throws RedirectException {
HttpServletRequest req = context.getHttpRequest();
- if( req != null )
- {
- String addr = req.getRemoteAddr();
+ if( req != null ) {
+ String addr = HttpUtil.getRemoteAddress( req );
int hostCounter = 0;
int changeCounter = 0;
- log.debug("Change is "+change.m_change);
+ log.debug( "Change is " + change.m_change );
- long time = System.currentTimeMillis()-60*1000L; // 1 minute
+ long time = System.currentTimeMillis() - 60*1000L; // 1 minute
- for( Iterator i = m_lastModifications.iterator(); i.hasNext(); )
- {
- Host host = (Host)i.next();
+ for( Iterator< Host > i = m_lastModifications.iterator(); i.hasNext(); ) {
+ Host host = i.next();
//
// Check if this item is invalid
//
- if( host.getAddedTime() < time )
- {
- log.debug("Removed host "+host.getAddress()+" from modification queue (expired)");
+ if( host.getAddedTime() < time ) {
+ log.debug( "Removed host " + host.getAddress() + " from modification queue (expired)" );
i.remove();
continue;
}
@@ -473,8 +446,7 @@ public class SpamFilter
// Check if this IP address has been seen before
//
- if( host.getAddress().equals(addr) )
- {
+ if( host.getAddress().equals( addr ) ) {
hostCounter++;
}
@@ -482,8 +454,7 @@ public class SpamFilter
// Check, if this change has been seen before
//
- if( host.getChange() != null && host.getChange().equals(change) )
- {
+ if( host.getChange() != null && host.getChange().equals( change ) ) {
changeCounter++;
}
}
@@ -491,74 +462,58 @@ public class SpamFilter
//
// Now, let's check against the limits.
//
- if( hostCounter >= m_limitSinglePageChanges )
- {
+ if( hostCounter >= m_limitSinglePageChanges ) {
Host host = new Host( addr, null );
-
m_temporaryBanList.add( host );
String uid = log( context, REJECT, REASON_TOO_MANY_MODIFICATIONS, change.m_change );
- log.info( "SPAM:TooManyModifications ("+uid+"). Added host "+addr+" to temporary ban list for doing too many modifications/minute" );
- checkStrategy( context, REASON_TOO_MANY_MODIFICATIONS, "Herb says you look like a spammer, and I trust Herb! (Incident code "+uid+")" );
+ log.info( "SPAM:TooManyModifications (" + uid + "). Added host " + addr + " to temporary ban list for doing too many modifications/minute" );
+ checkStrategy( context, REASON_TOO_MANY_MODIFICATIONS, "Herb says you look like a spammer, and I trust Herb! (Incident code " + uid + ")" );
}
- if( changeCounter >= m_limitSimilarChanges )
- {
+ if( changeCounter >= m_limitSimilarChanges ) {
Host host = new Host( addr, null );
-
m_temporaryBanList.add( host );
String uid = log( context, REJECT, REASON_SIMILAR_MODIFICATIONS, change.m_change );
-
- log.info("SPAM:SimilarModifications ("+uid+"). Added host "+addr+" to temporary ban list for doing too many similar modifications" );
+ log.info( "SPAM:SimilarModifications (" + uid + "). Added host " + addr + " to temporary ban list for doing too many similar modifications" );
checkStrategy( context, REASON_SIMILAR_MODIFICATIONS, "Herb says you look like a spammer, and I trust Herb! (Incident code "+uid+")");
}
//
// Calculate the number of links in the addition.
//
-
- String tstChange = change.toString();
+ String tstChange = change.toString();
int urlCounter = 0;
-
- while( m_matcher.contains(tstChange,m_urlPattern) )
- {
+ while( m_matcher.contains( tstChange,m_urlPattern ) ) {
MatchResult m = m_matcher.getMatch();
-
tstChange = tstChange.substring( m.endOffset(0) );
-
urlCounter++;
}
- if( urlCounter > m_maxUrls )
- {
+ if( urlCounter > m_maxUrls ) {
Host host = new Host( addr, null );
-
m_temporaryBanList.add( host );
String uid = log( context, REJECT, REASON_TOO_MANY_URLS, change.toString() );
-
- log.info("SPAM:TooManyUrls ("+uid+"). Added host "+addr+" to temporary ban list for adding too many URLs" );
- checkStrategy( context, REASON_TOO_MANY_URLS, "Herb says you look like a spammer, and I trust Herb! (Incident code "+uid+")" );
+ log.info( "SPAM:TooManyUrls (" + uid + "). Added host " + addr + " to temporary ban list for adding too many URLs" );
+ checkStrategy( context, REASON_TOO_MANY_URLS, "Herb says you look like a spammer, and I trust Herb! (Incident code " + uid + ")" );
}
//
// Check bot trap
//
-
checkBotTrap( context, change );
//
// Check UTF-8 mangling
//
-
checkUTF8( context, change );
//
// Do Akismet check. This is good to be the last, because this is the most
// expensive operation.
//
-
checkAkismet( context, change );
m_lastModifications.add( new Host( addr, change ) );
@@ -573,20 +528,14 @@ public class SpamFilter
* @param change
* @throws RedirectException
*/
- private void checkAkismet( WikiContext context, Change change )
- throws RedirectException
- {
- if( m_akismetAPIKey != null )
- {
- if( m_akismet == null )
- {
- log.info("Initializing Akismet spam protection.");
-
+ private void checkAkismet( WikiContext context, Change change ) throws RedirectException {
+ if( m_akismetAPIKey != null ) {
+ if( m_akismet == null ) {
+ log.info( "Initializing Akismet spam protection." );
m_akismet = new Akismet( m_akismetAPIKey, context.getEngine().getBaseURL() );
- if( !m_akismet.verifyAPIKey() )
- {
- log.error("Akismet API key cannot be verified. Please check your config.");
+ if( !m_akismet.verifyAPIKey() ) {
+ log.error( "Akismet API key cannot be verified. Please check your config." );
m_akismetAPIKey = null;
m_akismet = null;
}
@@ -598,23 +547,21 @@ public class SpamFilter
// Akismet will mark all empty statements as spam, so we'll just
// ignore them.
//
- if( change.m_adds == 0 && change.m_removals > 0 )
- {
+ if( change.m_adds == 0 && change.m_removals > 0 ) {
return;
}
- if( req != null && m_akismet != null )
- {
- log.debug("Calling Akismet to check for spam...");
+ if( req != null && m_akismet != null ) {
+ log.debug( "Calling Akismet to check for spam..." );
StopWatch sw = new StopWatch();
sw.start();
- String ipAddress = req.getRemoteAddr();
- String userAgent = req.getHeader("User-Agent");
+ String ipAddress = HttpUtil.getRemoteAddress( req );
+ String userAgent = req.getHeader( "User-Agent" );
String referrer = req.getHeader( "Referer");
String permalink = context.getViewURL( context.getPage().getName() );
- String commentType = context.getRequestContext().equals(WikiContext.COMMENT) ? "comment" : "edit";
+ String commentType = context.getRequestContext().equals( WikiContext.COMMENT ) ? "comment" : "edit";
String commentAuthor = context.getCurrentUser().getName();
String commentAuthorEmail = null;
String commentAuthorURL = null;
@@ -631,96 +578,74 @@ public class SpamFilter
null );
sw.stop();
+ log.debug( "Akismet request done in: " + sw );
- log.debug("Akismet request done in: "+sw);
-
- if( isSpam )
- {
+ if( isSpam ) {
// Host host = new Host( ipAddress, null );
-
// m_temporaryBanList.add( host );
String uid = log( context, REJECT, REASON_AKISMET, change.toString() );
-
- log.info("SPAM:Akismet ("+uid+"). Akismet thinks this change is spam; added host to temporary ban list.");
-
- checkStrategy( context, REASON_AKISMET, "Akismet tells Herb you're a spammer, Herb trusts Akismet, and I trust Herb! (Incident code "+uid+")");
+ log.info( "SPAM:Akismet (" + uid + "). Akismet thinks this change is spam; added host to temporary ban list." );
+ checkStrategy( context, REASON_AKISMET, "Akismet tells Herb you're a spammer, Herb trusts Akismet, and I trust Herb! (Incident code " + uid + ")" );
}
}
}
}
/**
- * Returns a static string which can be used to detect spambots which
- * just wildly fill in all the fields.
+ * Returns a static string which can be used to detect spambots which just wildly fill in all the fields.
*
- * @return A string
+ * @return A string
*/
- public static String getBotFieldName()
- {
+ public static String getBotFieldName() {
return "submit_auth";
}
/**
- * This checks whether an invisible field is available in the request, and
- * whether it's contents are suspected spam.
+ * This checks whether an invisible field is available in the request, and whether it's contents are suspected spam.
*
- * @param context
- * @param change
+ * @param context
+ * @param change
* @throws RedirectException
*/
- private void checkBotTrap( WikiContext context, Change change ) throws RedirectException
- {
+ private void checkBotTrap( WikiContext context, Change change ) throws RedirectException {
HttpServletRequest request = context.getHttpRequest();
- if( request != null )
- {
+ if( request != null ) {
String unspam = request.getParameter( getBotFieldName() );
- if( unspam != null && unspam.length() > 0 )
- {
+ if( unspam != null && unspam.length() > 0 ) {
String uid = log( context, REJECT, REASON_BOT_TRAP, change.toString() );
- log.info("SPAM:BotTrap ("+uid+"). Wildly behaving bot detected.");
-
- checkStrategy( context, REASON_BOT_TRAP, "Spamming attempt detected. (Incident code "+uid+")");
-
+ log.info( "SPAM:BotTrap (" + uid + "). Wildly behaving bot detected." );
+ checkStrategy( context, REASON_BOT_TRAP, "Spamming attempt detected. (Incident code " + uid + ")" );
}
}
}
- private void checkUTF8( WikiContext context, Change change ) throws RedirectException
- {
+ private void checkUTF8( WikiContext context, Change change ) throws RedirectException {
HttpServletRequest request = context.getHttpRequest();
- if( request != null )
- {
+ if( request != null ) {
String utf8field = request.getParameter( "encodingcheck" );
- if( utf8field != null && !utf8field.equals("\u3041") )
- {
+ if( utf8field != null && !utf8field.equals( "\u3041" ) ) {
String uid = log( context, REJECT, REASON_UTF8_TRAP, change.toString() );
- log.info("SPAM:UTF8Trap ("+uid+"). Wildly posting dumb bot detected.");
-
- checkStrategy( context, REASON_UTF8_TRAP, "Spamming attempt detected. (Incident code "+uid+")");
+ log.info( "SPAM:UTF8Trap (" + uid + "). Wildly posting dumb bot detected." );
+ checkStrategy( context, REASON_UTF8_TRAP, "Spamming attempt detected. (Incident code " + uid + ")" );
}
}
}
- /**
- * Goes through the ban list and cleans away any host which has expired from it.
- */
- private synchronized void cleanBanList()
- {
+ /** Goes through the ban list and cleans away any host which has expired from it. */
+ private synchronized void cleanBanList() {
long now = System.currentTimeMillis();
- for( Iterator i = m_temporaryBanList.iterator(); i.hasNext(); )
- {
- Host host = (Host)i.next();
-
- if( host.getReleaseTime() < now )
- {
- log.debug("Removed host "+host.getAddress()+" from temporary ban list (expired)");
+ for( Iterator< Host > i = m_temporaryBanList.iterator(); i.hasNext(); ) {
+ Host host = i.next();
+
+ if( host.getReleaseTime() < now ) {
+ log.debug( "Removed host " + host.getAddress() + " from temporary ban list (expired)" );
i.remove();
}
}
@@ -732,45 +657,33 @@ public class SpamFilter
* @param context
* @throws RedirectException
*/
-
- private void checkBanList( WikiContext context, Change change )
- throws RedirectException
- {
+ private void checkBanList( WikiContext context, Change change ) throws RedirectException {
HttpServletRequest req = context.getHttpRequest();
- if( req != null )
- {
- String remote = req.getRemoteAddr();
-
+ if( req != null ) {
+ String remote = HttpUtil.getRemoteAddress(req);
long now = System.currentTimeMillis();
- for( Iterator i = m_temporaryBanList.iterator(); i.hasNext(); )
- {
- Host host = (Host)i.next();
-
- if( host.getAddress().equals(remote) )
- {
- long timeleft = (host.getReleaseTime() - now) / 1000L;
+ for( Iterator< Host > i = m_temporaryBanList.iterator(); i.hasNext(); ) {
+ Host host = i.next();
- log( context, REJECT, REASON_IP_BANNED_TEMPORARILY, change.m_change );
+ if( host.getAddress().equals( remote ) ) {
+ long timeleft = ( host.getReleaseTime() - now ) / 1000L;
- checkStrategy( context, REASON_IP_BANNED_TEMPORARILY, "You have been temporarily banned from modifying this wiki. ("+timeleft+" seconds of ban left)");
+ log( context, REJECT, REASON_IP_BANNED_TEMPORARILY, change.m_change );
+ checkStrategy( context, REASON_IP_BANNED_TEMPORARILY, "You have been temporarily banned from modifying this wiki. (" + timeleft + " seconds of ban left)" );
}
}
}
-
}
/**
- * If the spam filter notices changes in the black list page, it will refresh
- * them automatically.
+ * If the spam filter notices changes in the black list page, it will refresh them automatically.
*
* @param context
*/
- private void refreshBlacklists( WikiContext context )
- {
- try
- {
+ private void refreshBlacklists( WikiContext context ) {
+ try {
WikiPage source = context.getEngine().getPage( m_forbiddenWordsPage );
Attachment att = context.getEngine().getAttachmentManager().getAttachmentInfo( context, m_blacklist );
@@ -779,62 +692,43 @@ public class SpamFilter
//
// Rebuild, if the page or the attachment has changed since.
//
- if( source != null )
- {
- if( m_spamPatterns == null || m_spamPatterns.isEmpty() || source.getLastModified().after(m_lastRebuild) )
- {
+ if( source != null ) {
+ if( m_spamPatterns == null || m_spamPatterns.isEmpty() || source.getLastModified().after( m_lastRebuild ) ) {
rebuild = true;
}
}
- if( att != null )
- {
- if( m_spamPatterns == null || m_spamPatterns.isEmpty() || att.getLastModified().after(m_lastRebuild) )
- {
+ if( att != null ) {
+ if( m_spamPatterns == null || m_spamPatterns.isEmpty() || att.getLastModified().after( m_lastRebuild ) ) {
rebuild = true;
}
}
-
//
// Do the actual rebuilding. For simplicity's sake, we always rebuild the complete
// filter list regardless of what changed.
//
-
- if( rebuild )
- {
+ if( rebuild ) {
m_lastRebuild = new Date();
-
m_spamPatterns = parseWordList( source,
- (source != null) ? (String)source.getAttribute( LISTVAR ) : null );
+ ( source != null ) ? ( String )source.getAttribute( LISTVAR ) : null );
- log.info("Spam filter reloaded - recognizing "+m_spamPatterns.size()+" patterns from page "+m_forbiddenWordsPage);
+ log.info( "Spam filter reloaded - recognizing " + m_spamPatterns.size() + " patterns from page " + m_forbiddenWordsPage );
- if( att != null )
- {
+ if( att != null ) {
InputStream in = context.getEngine().getAttachmentManager().getAttachmentStream(att);
-
StringWriter out = new StringWriter();
-
- FileUtil.copyContents( new InputStreamReader(in,"UTF-8"), out );
-
- Collection<Pattern> blackList = parseBlacklist( out.toString() );
-
- log.info("...recognizing additional "+blackList.size()+" patterns from blacklist "+m_blacklist);
-
+ FileUtil.copyContents( new InputStreamReader( in,"UTF-8" ), out );
+ Collection< Pattern > blackList = parseBlacklist( out.toString() );
+ log.info( "...recognizing additional " + blackList.size() + " patterns from blacklist " + m_blacklist );
m_spamPatterns.addAll( blackList );
}
}
+ } catch( IOException ex ) {
+ log.info( "Unable to read attachment data, continuing...", ex );
+ } catch( ProviderException ex ) {
+ log.info( "Failed to read spam filter attachment, continuing...", ex );
}
- catch( IOException ex )
- {
- log.info("Unable to read attachment data, continuing...",ex);
- }
- catch( ProviderException ex )
- {
- log.info("Failed to read spam filter attachment, continuing...",ex);
- }
-
}
/**
@@ -845,45 +739,39 @@ public class SpamFilter
* @param change
* @throws RedirectException
*/
- private void checkPatternList(WikiContext context, String content, Change change) throws RedirectException
- {
+ private void checkPatternList( WikiContext context, String content, Change change ) throws RedirectException {
//
// If we have no spam patterns defined, or we're trying to save
// the page containing the patterns, just return.
//
- if( m_spamPatterns == null || context.getPage().getName().equals( m_forbiddenWordsPage ) )
- {
+ if( m_spamPatterns == null || context.getPage().getName().equals( m_forbiddenWordsPage ) ) {
return;
}
String ch = change.toString();
-
- if( context.getHttpRequest() != null )
- ch += context.getHttpRequest().getRemoteAddr();
+ if( context.getHttpRequest() != null ) {
+ ch += HttpUtil.getRemoteAddress( context.getHttpRequest() );
+ }
- for( Pattern p : m_spamPatterns )
- {
+ for( Pattern p : m_spamPatterns ) {
// log.debug("Attempting to match page contents with "+p.getPattern());
- if( m_matcher.contains( ch, p ) )
- {
+ if( m_matcher.contains( ch, p ) ) {
//
// Spam filter has a match.
//
- String uid = log( context, REJECT, REASON_REGEXP+"("+p.getPattern()+")", ch);
+ String uid = log( context, REJECT, REASON_REGEXP + "(" + p.getPattern() + ")", ch );
- log.info("SPAM:Regexp ("+uid+"). Content matches the spam filter '"+p.getPattern()+"'");
-
- checkStrategy( context, REASON_REGEXP, "Herb says '"+p.getPattern()+"' is a bad spam word and I trust Herb! (Incident code "+uid+")");
+ log.info( "SPAM:Regexp (" + uid + "). Content matches the spam filter '" + p.getPattern() + "'" );
+ checkStrategy( context, REASON_REGEXP, "Herb says '" + p.getPattern() + "' is a bad spam word and I trust Herb! (Incident code " + uid + ")" );
}
}
}
- private void checkPatternList(WikiContext context, String content, String change ) throws RedirectException
- {
+ private void checkPatternList( WikiContext context, String content, String change ) throws RedirectException {
Change c = new Change();
c.m_change = change;
- checkPatternList(context,content,c);
+ checkPatternList( context, content, c );
}
/**
@@ -893,8 +781,7 @@ public class SpamFilter
* @param newText
* @return Empty string, if there is no change.
*/
- private static Change getChange( WikiContext context, String newText )
- {
+ private static Change getChange( WikiContext context, String newText ) {
WikiPage page = context.getPage();
StringBuffer change = new StringBuffer();
WikiEngine engine = context.getEngine();
@@ -902,62 +789,51 @@ public class SpamFilter
Change ch = new Change();
- try
- {
- String oldText = engine.getPureText(page.getName(), WikiProvider.LATEST_VERSION);
-
- String[] first = Diff.stringToArray(oldText);
- String[] second = Diff.stringToArray(newText);
- Revision rev = Diff.diff(first, second, new MyersDiff());
+ try {
+ String oldText = engine.getPureText( page.getName(), WikiProvider.LATEST_VERSION );
+
+ String[] first = Diff.stringToArray( oldText );
+ String[] second = Diff.stringToArray( newText );
+ Revision rev = Diff.diff( first, second, new MyersDiff() );
- if( rev == null || rev.size() == 0 )
- {
+ if( rev == null || rev.size() == 0 ) {
return ch;
}
- for( int i = 0; i < rev.size(); i++ )
- {
- Delta d = rev.getDelta(i);
+ for( int i = 0; i < rev.size(); i++ ) {
+ Delta d = rev.getDelta( i );
- if( d instanceof AddDelta )
- {
+ if( d instanceof AddDelta ) {
d.getRevised().toString( change, "", "\r\n" );
ch.m_adds++;
- }
- else if( d instanceof ChangeDelta )
- {
+
+ } else if( d instanceof ChangeDelta ) {
d.getRevised().toString( change, "", "\r\n" );
ch.m_adds++;
- }
- else if( d instanceof DeleteDelta )
- {
+
+ } else if( d instanceof DeleteDelta ) {
ch.m_removals++;
}
}
- }
- catch (DifferentiationFailedException e)
- {
+ } catch( DifferentiationFailedException e ) {
log.error( "Diff failed", e );
}
//
// Don't forget to include the change note, too
//
- String changeNote = (String)page.getAttribute(WikiPage.CHANGENOTE);
+ String changeNote = ( String )page.getAttribute( WikiPage.CHANGENOTE );
- if( changeNote != null )
- {
- change.append("\r\n");
- change.append(changeNote);
+ if( changeNote != null ) {
+ change.append( "\r\n" );
+ change.append( changeNote );
}
//
// And author as well
//
-
- if( page.getAuthor() != null )
- {
- change.append("\r\n"+page.getAuthor());
+ if( page.getAuthor() != null ) {
+ change.append( "\r\n" + page.getAuthor() );
}
ch.m_change = change.toString();
@@ -970,20 +846,16 @@ public class SpamFilter
* @param context
* @return True, if this users should be ignored.
*/
- private boolean ignoreThisUser(WikiContext context)
- {
- if( context.hasAdminPermissions() )
- {
+ private boolean ignoreThisUser( WikiContext context ) {
+ if( context.hasAdminPermissions() ) {
return true;
}
- if( m_ignoreAuthenticated && context.getWikiSession().isAuthenticated() )
- {
+ if( m_ignoreAuthenticated && context.getWikiSession().isAuthenticated() ) {
return true;
}
- if( context.getVariable("captcha") != null )
- {
+ if( context.getVariable( "captcha" ) != null ) {
return true;
}
@@ -995,32 +867,28 @@ public class SpamFilter
*
* @return A random string
*/
- private static String getUniqueID()
- {
- StringBuffer sb = new StringBuffer();
+ private static String getUniqueID() {
+ StringBuilder sb = new StringBuilder();
Random rand = new Random();
- for( int i = 0; i < 6; i++ )
- {
- char x = (char)('A'+rand.nextInt(26));
-
- sb.append(x);
+ for( int i = 0; i < 6; i++ ) {
+ char x = ( char )( 'A' + rand.nextInt( 26 ) );
+ sb.append( x );
}
return sb.toString();
}
/**
- * Returns a page to which we shall redirect, based on the current value
- * of the "captcha" parameter.
+ * Returns a page to which we shall redirect, based on the current value of the "captcha" parameter.
*
* @param ctx WikiContext
* @return An URL to redirect to
*/
- private String getRedirectPage( WikiContext ctx )
- {
- if( m_useCaptcha )
- return ctx.getURL( WikiContext.NONE, "Captcha.jsp", "page="+ctx.getEngine().encodeName(ctx.getPage().getName()) );
+ private String getRedirectPage( WikiContext ctx ) {
+ if( m_useCaptcha ) {
+ return ctx.getURL( WikiContext.NONE, "Captcha.jsp", "page="+ctx.getEngine().encodeName( ctx.getPage().getName() ) );
+ }
return ctx.getURL( WikiContext.VIEW, m_errorPage );
}
@@ -1033,16 +901,12 @@ public class SpamFilter
* @return False, if this userprofile is suspect and should not be allowed to be added.
* @since 2.6.1
*/
- public boolean isValidUserProfile( WikiContext context, UserProfile profile )
- {
- try
- {
+ public boolean isValidUserProfile( WikiContext context, UserProfile profile ) {
+ try {
checkPatternList( context, profile.getEmail(), profile.getEmail() );
checkPatternList( context, profile.getFullname(), profile.getFullname() );
checkPatternList( context, profile.getLoginName(), profile.getLoginName() );
- }
- catch( RedirectException e )
- {
+ } catch( RedirectException e ) {
log.info("Detected attempt to create a spammer user account (see above for rejection reason)");
return false;
}
@@ -1051,57 +915,47 @@ public class SpamFilter
}
/**
- * This method is used to calculate an unique code when submitting the page
- * to detect edit conflicts. It currently incorporates the last-modified
- * date of the page, and the IP address of the submitter.
+ * This method is used to calculate an unique code when submitting the page to detect edit conflicts.
+ * It currently incorporates the last-modified date of the page, and the IP address of the submitter.
*
* @param page The WikiPage under edit
* @param request The HTTP Request
* @since 2.6
* @return A hash value for this page and session
*/
- public static final String getSpamHash( WikiPage page, HttpServletRequest request )
- {
+ public static final String getSpamHash( WikiPage page, HttpServletRequest request ) {
long lastModified = 0;
- if( page.getLastModified() != null )
+ if( page.getLastModified() != null ) {
lastModified = page.getLastModified().getTime();
-
- long remote = request.getRemoteAddr().hashCode();
+ }
+ long remote = HttpUtil.getRemoteAddress( request ).hashCode();
return Long.toString( lastModified ^ remote );
}
/**
- * Returns the name of the hash field to be used in this request.
- * The value is unique per session, and once the session has expired,
- * you cannot edit anymore.
+ * Returns the name of the hash field to be used in this request. The value is unique per session, and once
+ * the session has expired, you cannot edit anymore.
*
* @param request The page request
* @return The name to be used in the hash field
* @since 2.6
*/
-
- public static final String getHashFieldName( HttpServletRequest request )
- {
+ public static final String getHashFieldName( HttpServletRequest request ) {
String hash = null;
- if( request.getSession() != null )
- {
- hash = (String)request.getSession().getAttribute("_hash");
+ if( request.getSession() != null ) {
+ hash = ( String )request.getSession().getAttribute( "_hash" );
- if( hash == null )
- {
+ if( hash == null ) {
hash = c_hashName;
-
request.getSession().setAttribute( "_hash", hash );
}
}
- if( c_hashName == null || c_lastUpdate < (System.currentTimeMillis() - HASH_DELAY*60*60*1000) )
- {
+ if( c_hashName == null || c_lastUpdate < ( System.currentTimeMillis() - HASH_DELAY * 60 * 60 * 1000 ) ) {
c_hashName = getUniqueID().toLowerCase();
-
c_lastUpdate = System.currentTimeMillis();
}
@@ -1110,13 +964,12 @@ public class SpamFilter
/**
- * This method checks if the hash value is still valid, i.e. if it exists at all. This
- * can occur in two cases: either this is a spam bot which is not adaptive, or it is
- * someone who has been editing one page for too long, and their session has expired.
+ * This method checks if the hash value is still valid, i.e. if it exists at all. This can occur in two cases:
+ * either this is a spam bot which is not adaptive, or it is someone who has been editing one page for too long,
+ * and their session has expired.
* <p>
- * This method puts a redirect to the http response field to page "SessionExpired"
- * and logs the incident in the spam log (it may or may not be spam, but it's rather likely
- * that it is).
+ * This method puts a redirect to the http response field to page "SessionExpired" and logs the incident in
+ * the spam log (it may or may not be spam, but it's rather likely that it is).
*
* @param context The WikiContext
* @param pageContext The JSP PageContext.
@@ -1124,22 +977,16 @@ public class SpamFilter
* @throws IOException If redirection fails
* @since 2.6
*/
- public static final boolean checkHash( WikiContext context, PageContext pageContext )
- throws IOException
- {
+ public static final boolean checkHash( WikiContext context, PageContext pageContext ) throws IOException {
String hashName = getHashFieldName( (HttpServletRequest)pageContext.getRequest() );
- if( pageContext.getRequest().getParameter(hashName) == null )
- {
- if( pageContext.getAttribute( hashName ) == null )
- {
+ if( pageContext.getRequest().getParameter(hashName) == null ) {
+ if( pageContext.getAttribute( hashName ) == null ) {
Change change = getChange( context, EditorManager.getEditedText( pageContext ) );
-
log( context, REJECT, "MissingHash", change.m_change );
- String redirect = context.getURL(WikiContext.VIEW,"SessionExpired");
- ((HttpServletResponse)pageContext.getResponse()).sendRedirect( redirect );
-
+ String redirect = context.getURL( WikiContext.VIEW,"SessionExpired" );
+ ( ( HttpServletResponse )pageContext.getResponse() ).sendRedirect( redirect );
return false;
}
}
@@ -1148,89 +995,81 @@ public class SpamFilter
}
/**
- * This helper method adds all the input fields to your editor that the SpamFilter requires
- * to check for spam. This <i>must</i> be in your editor form if you intend to use
- * the SpamFilter.
+ * This helper method adds all the input fields to your editor that the SpamFilter requires
+ * to check for spam. This <i>must</i> be in your editor form if you intend to use the SpamFilter.
*
- * @param pageContext The PageContext
- * @return A HTML string which contains input fields for the SpamFilter.
+ * @param pageContext The PageContext
+ * @return A HTML string which contains input fields for the SpamFilter.
*/
- public static final String insertInputFields( PageContext pageContext )
- {
- WikiContext ctx = WikiContext.findContext(pageContext);
+ public static final String insertInputFields( PageContext pageContext ) {
+ WikiContext ctx = WikiContext.findContext( pageContext );
WikiEngine engine = ctx.getEngine();
- StringBuffer sb = new StringBuffer();
- if (engine.getContentEncoding().equals("UTF-8"))
- {
- sb.append("<input name='encodingcheck' type='hidden' value='\u3041' />\n");
+ StringBuilder sb = new StringBuilder();
+ if( engine.getContentEncoding().equals( "UTF-8" ) ) {
+ sb.append( "<input name='encodingcheck' type='hidden' value='\u3041' />\n" );
}
return sb.toString();
}
+
/**
* A local class for storing host information.
*
* @since
*/
- private class Host
- {
- private long m_addedTime = System.currentTimeMillis();
- private long m_releaseTime;
- private String m_address;
- private Change m_change;
+ private class Host {
+
+ private long m_addedTime = System.currentTimeMillis();
+ private long m_releaseTime;
+ private String m_address;
+ private Change m_change;
- public String getAddress()
- {
+ public String getAddress() {
return m_address;
}
- public long getReleaseTime()
- {
+ public long getReleaseTime() {
return m_releaseTime;
}
- public long getAddedTime()
- {
+ public long getAddedTime() {
return m_addedTime;
}
- public Change getChange()
- {
+ public Change getChange() {
return m_change;
}
- public Host( String ipaddress, Change change )
- {
+ public Host( String ipaddress, Change change ) {
m_address = ipaddress;
m_change = change;
-
m_releaseTime = System.currentTimeMillis() + m_banTime * 60 * 1000L;
}
+
}
- private static class Change
- {
+ private static class Change {
+
public String m_change;
public int m_adds;
public int m_removals;
- public String toString()
- {
+ public String toString() {
return m_change;
}
- public boolean equals(Object o)
- {
- if( o instanceof Change )
- return m_change.equals( ((Change)o).m_change);
-
+ public boolean equals( Object o ) {
+ if( o instanceof Change ) {
+ return m_change.equals( ( ( Change )o ).m_change );
+ }
return false;
}
- public int hashCode()
- {
- return m_change.hashCode()+17;
+ public int hashCode() {
+ return m_change.hashCode() + 17;
}
+
}
+
}
Modified: jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/util/HttpUtil.java
URL: http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/util/HttpUtil.java?rev=1546452&r1=1546451&r2=1546452&view=diff
==============================================================================
--- jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/util/HttpUtil.java (original)
+++ jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/util/HttpUtil.java Thu Nov 28 19:59:11 2013
@@ -26,25 +26,35 @@ import java.util.Date;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
+import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
-
import org.apache.wiki.WikiPage;
+
/**
* Contains useful utilities for some common HTTP tasks.
*
* @since 2.1.61.
*/
-public final class HttpUtil
-{
+public final class HttpUtil {
+
static Logger log = Logger.getLogger( HttpUtil.class );
+ /** Private constructor to prevent direct instantiation. */
+ private HttpUtil() {
+ }
+
/**
- * Private constructor to prevent direct instantiation.
+ * returns the remote address by looking into {@code x-forwarded-for} header or, if unavailable,
+ * into {@link HttpServletRequest#getRemoteAddr()}.
+ *
+ * @param req http request
+ * @return remote address associated to the request.
*/
- private HttpUtil()
- {
- }
+ public static String getRemoteAddress( HttpServletRequest req ) {
+ return StringUtils.isNotEmpty ( req.getHeader( "x-forwarded-for" ) ) ? req.getHeader( "x-forwarded-for" ) :
+ req.getRemoteAddr();
+ }
/**
* Attempts to retrieve the given cookie value from the request.
@@ -58,23 +68,17 @@ public final class HttpUtil
* @return Value of the cookie, or null, if there is no such cookie.
*/
- public static String retrieveCookieValue( HttpServletRequest request, String cookieName )
- {
+ public static String retrieveCookieValue( HttpServletRequest request, String cookieName ) {
Cookie[] cookies = request.getCookies();
- if( cookies != null )
- {
- for( int i = 0; i < cookies.length; i++ )
- {
- if( cookies[i].getName().equals( cookieName ) )
- {
+ if( cookies != null ) {
+ for( int i = 0; i < cookies.length; i++ ) {
+ if( cookies[i].getName().equals( cookieName ) ) {
String value = cookies[i].getValue();
- if ( value.length() == 0 )
- {
+ if( value.length() == 0 ) {
return null;
}
- if ( value.charAt( 0 ) == '"' && value.charAt( value.length() - 1 ) == '"')
- {
+ if( value.charAt( 0 ) == '"' && value.charAt( value.length() - 1 ) == '"' ) {
value = value.substring( 1, value.length() - 1 );
}
return value;
@@ -93,9 +97,8 @@ public final class HttpUtil
* @param p The page for which the ETag should be created.
* @return A String depiction of an ETag.
*/
- public static String createETag( WikiPage p )
- {
- return Long.toString(p.getName().hashCode() ^ p.getLastModified().getTime());
+ public static String createETag( WikiPage p ) {
+ return Long.toString( p.getName().hashCode() ^ p.getLastModified().getTime() );
}
/**
@@ -104,9 +107,7 @@ public final class HttpUtil
* @param page the wiki page to check for
* @return the result of the check
*/
- public static boolean checkFor304( HttpServletRequest req,
- WikiPage page )
- {
+ public static boolean checkFor304( HttpServletRequest req, WikiPage page ) {
//
// We'll do some handling for CONDITIONAL GET (and return a 304)
// If the client has set the following headers, do not try for a 304.
@@ -115,13 +116,10 @@ public final class HttpUtil
// cache-control: no-cache
//
- if( "no-cache".equalsIgnoreCase(req.getHeader("Pragma"))
- || "no-cache".equalsIgnoreCase(req.getHeader("cache-control")))
- {
+ if( "no-cache".equalsIgnoreCase( req.getHeader( "Pragma" ) )
+ || "no-cache".equalsIgnoreCase( req.getHeader( "cache-control" ) ) ) {
// Wants specifically a fresh copy
- }
- else
- {
+ } else {
//
// HTTP 1.1 ETags go first
//
@@ -129,8 +127,7 @@ public final class HttpUtil
String eTag = req.getHeader( "If-None-Match" );
- if( eTag != null && eTag.equals(thisTag) )
- {
+ if( eTag != null && eTag.equals(thisTag) ) {
return true;
}
@@ -140,45 +137,33 @@ public final class HttpUtil
DateFormat rfcDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
Date lastModified = page.getLastModified();
- try
- {
- long ifModifiedSince = req.getDateHeader("If-Modified-Since");
+ try {
+ long ifModifiedSince = req.getDateHeader( "If-Modified-Since" );
//log.info("ifModifiedSince:"+ifModifiedSince);
- if( ifModifiedSince != -1 )
- {
+ if( ifModifiedSince != -1 ) {
long lastModifiedTime = lastModified.getTime();
//log.info("lastModifiedTime:" + lastModifiedTime);
- if( lastModifiedTime <= ifModifiedSince )
- {
+ if( lastModifiedTime <= ifModifiedSince ) {
return true;
}
- }
- else
- {
- try
- {
+ } else {
+ try {
String s = req.getHeader("If-Modified-Since");
- if( s != null )
- {
+ if( s != null ) {
Date ifModifiedSinceDate = rfcDateFormat.parse(s);
//log.info("ifModifiedSinceDate:" + ifModifiedSinceDate);
- if( lastModified.before(ifModifiedSinceDate) )
- {
+ if( lastModified.before(ifModifiedSinceDate) ) {
return true;
}
}
- }
- catch (ParseException e)
- {
+ } catch (ParseException e) {
log.warn(e.getLocalizedMessage(), e);
}
}
- }
- catch( IllegalArgumentException e )
- {
+ } catch( IllegalArgumentException e ) {
// Illegal date/time header format.
// We fail quietly, and return false.
// FIXME: Should really move to ETags.
@@ -191,29 +176,27 @@ public final class HttpUtil
/**
* Attempts to form a valid URI based on the string given. Currently
* it can guess email addresses (mailto:). If nothing else is given,
- * it assumes it to be a http:// url.
+ * it assumes it to be an http:// url.
*
* @param uri URI to take a poke at
* @return Possibly a valid URI
* @since 2.2.8
*/
- public static String guessValidURI( String uri )
- {
- if( uri.indexOf('@') != -1 )
- {
- if( !uri.startsWith("mailto:") )
- {
+ public static String guessValidURI( String uri ) {
+ if( uri.indexOf( '@' ) != -1 ) {
+ if( !uri.startsWith( "mailto:" ) ) {
// Assume this is an email address
-
- uri = "mailto:"+uri;
+ uri = "mailto:" + uri;
}
- }
- else if( uri.length() > 0 && !((uri.startsWith("http://") || uri.startsWith("https://")) ))
- {
- uri = "http://"+uri;
+ } else if( notBeginningWithHttpOrHttps( uri ) ) {
+ uri = "http://" + uri;
}
return uri;
}
+ static boolean notBeginningWithHttpOrHttps( String uri ) {
+ return uri.length() > 0 && !( ( uri.startsWith("http://" ) || uri.startsWith( "https://" ) ) );
+ }
+
}
Re: svn commit: r1546452 - in /jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki:
filters/SpamFilter.java util/HttpUtil.java
Posted by Juan Pablo Santos RodrÃguez <ju...@gmail.com>.
Hi Harry,
the http spec [#1] states that http headers are case insensitive:
4.2 Message Headers
[...]Each header field consists of a name followed by a colon (":")
and the field value.
Field names are case-insensitive.[...]
so it shouldn't be a problem. @work we're used to lowercased-headers so I
didn't think much of it when committing the change.. Anyway, the wikipedia
link at JSPWIKI-804 states that the general format for the name is the
capitalized one, so I'll commit that change in a second, just to not make
that code look weird.
br,
juan pablo
[#1]: http://www.ietf.org/rfc/rfc2616.txt
On Thu, Nov 28, 2013 at 9:59 PM, Harry Metske <ha...@gmail.com>wrote:
> JP,
>
> not sure if this will work though, the header is "*X-Forwarded-For" , *not
> *
> "**x-forwarded-for" *?
>
> kind regards,
> Harry
>
>
>
>
> On 28 November 2013 20:59, <ju...@apache.org> wrote:
>
> > Author: juanpablo
> > Date: Thu Nov 28 19:59:11 2013
> > New Revision: 1546452
> >
> > URL: http://svn.apache.org/r1546452
> > Log:
> > * JSPWIKI-804: SpamFilter should support X-Forwarded-For header in the
> > banlist
> >
> > * also, formatted braces from those classes
> >
> > Modified:
> >
> >
> jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/filters/SpamFilter.java
> >
> >
> jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/util/HttpUtil.java
> >
> > Modified:
> >
> jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/filters/SpamFilter.java
> > URL:
> >
> http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/filters/SpamFilter.java?rev=1546452&r1=1546451&r2=1546452&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/filters/SpamFilter.java
> > (original)
> > +++
> >
> jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/filters/SpamFilter.java
> > Thu Nov 28 19:59:11 2013
> > @@ -18,8 +18,20 @@
> > */
> > package org.apache.wiki.filters;
> >
> > -import java.io.*;
> > -import java.util.*;
> > +import java.io.BufferedReader;
> > +import java.io.IOException;
> > +import java.io.InputStream;
> > +import java.io.InputStreamReader;
> > +import java.io.StringReader;
> > +import java.io.StringWriter;
> > +import java.util.ArrayList;
> > +import java.util.Collection;
> > +import java.util.Date;
> > +import java.util.Iterator;
> > +import java.util.Properties;
> > +import java.util.Random;
> > +import java.util.StringTokenizer;
> > +import java.util.Vector;
> >
> > import javax.servlet.http.HttpServletRequest;
> > import javax.servlet.http.HttpServletResponse;
> > @@ -29,8 +41,18 @@ import net.sf.akismet.Akismet;
> >
> > import org.apache.commons.lang.time.StopWatch;
> > import org.apache.log4j.Logger;
> > -import org.apache.oro.text.regex.*;
> > -import org.apache.wiki.*;
> > +import org.apache.oro.text.regex.MalformedPatternException;
> > +import org.apache.oro.text.regex.MatchResult;
> > +import org.apache.oro.text.regex.Pattern;
> > +import org.apache.oro.text.regex.PatternCompiler;
> > +import org.apache.oro.text.regex.PatternMatcher;
> > +import org.apache.oro.text.regex.Perl5Compiler;
> > +import org.apache.oro.text.regex.Perl5Matcher;
> > +import org.apache.wiki.InternalWikiException;
> > +import org.apache.wiki.WikiContext;
> > +import org.apache.wiki.WikiEngine;
> > +import org.apache.wiki.WikiPage;
> > +import org.apache.wiki.WikiProvider;
> > import org.apache.wiki.api.exceptions.RedirectException;
> > import org.apache.wiki.api.filters.BasicPageFilter;
> > import org.apache.wiki.attachment.Attachment;
> > @@ -38,6 +60,7 @@ import org.apache.wiki.auth.user.UserPro
> > import org.apache.wiki.providers.ProviderException;
> > import org.apache.wiki.ui.EditorManager;
> > import org.apache.wiki.util.FileUtil;
> > +import org.apache.wiki.util.HttpUtil;
> > import org.apache.wiki.util.TextUtil;
> > import org.suigeneris.jrcs.diff.Diff;
> > import org.suigeneris.jrcs.diff.DifferentiationFailedException;
> > @@ -48,6 +71,7 @@ import org.suigeneris.jrcs.diff.delta.De
> > import org.suigeneris.jrcs.diff.delta.Delta;
> > import org.suigeneris.jrcs.diff.myers.MyersDiff;
> >
> > +
> > /**
> > * This is Herb, the JSPWiki spamfilter that can also do choke
> > modifications.
> > *
> > @@ -77,9 +101,8 @@ import org.suigeneris.jrcs.diff.myers.My
> > *
> > * @since 2.1.112
> > */
> > -public class SpamFilter
> > - extends BasicPageFilter
> > -{
> > +public class SpamFilter extends BasicPageFilter {
> > +
> > private static final String ATTR_SPAMFILTER_SCORE =
> > "spamfilter.score";
> > private static final String REASON_REGEXP = "Regexp";
> > private static final String REASON_IP_BANNED_TEMPORARILY =
> > "IPBannedTemporarily";
> > @@ -208,29 +231,19 @@ public class SpamFilter
> > * {@inheritDoc}
> > */
> > @Override
> > - public void initialize( WikiEngine engine, Properties properties )
> > - {
> > - m_forbiddenWordsPage = properties.getProperty( PROP_WORDLIST,
> > -
> > m_forbiddenWordsPage );
> > - m_errorPage = properties.getProperty( PROP_ERRORPAGE,
> > - m_errorPage );
> > -
> > + public void initialize( WikiEngine engine, Properties properties ) {
> > + m_forbiddenWordsPage = properties.getProperty( PROP_WORDLIST,
> > m_forbiddenWordsPage );
> > + m_errorPage = properties.getProperty( PROP_ERRORPAGE,
> m_errorPage
> > );
> > m_limitSinglePageChanges = TextUtil.getIntegerProperty(
> > properties,
> >
> > PROP_PAGECHANGES,
> >
> > m_limitSinglePageChanges );
> > -
> > +
> > m_limitSimilarChanges = TextUtil.getIntegerProperty( properties,
> >
> > PROP_SIMILARCHANGES,
> >
> > m_limitSimilarChanges );
> >
> > - m_maxUrls = TextUtil.getIntegerProperty( properties,
> > - PROP_MAXURLS,
> > - m_maxUrls );
> > -
> > - m_banTime = TextUtil.getIntegerProperty( properties,
> > - PROP_BANTIME,
> > - m_banTime );
> > -
> > + m_maxUrls = TextUtil.getIntegerProperty( properties,
> > PROP_MAXURLS, m_maxUrls );
> > + m_banTime = TextUtil.getIntegerProperty( properties,
> > PROP_BANTIME, m_banTime );
> > m_blacklist = properties.getProperty( PROP_BLACKLIST,
> m_blacklist
> > );
> >
> > m_ignoreAuthenticated = TextUtil.getBooleanProperty( properties,
> > @@ -239,14 +252,11 @@ public class SpamFilter
> >
> > m_useCaptcha = properties.getProperty( PROP_CAPTCHA, ""
> > ).equals("asirra");
> >
> > - try
> > - {
> > + try {
> > m_urlPattern = m_compiler.compile( URL_REGEXP );
> > - }
> > - catch( MalformedPatternException e )
> > - {
> > - log.fatal("Internal error: Someone put in a faulty
> > pattern.",e);
> > - throw new InternalWikiException("Faulty pattern.");
> > + } catch( MalformedPatternException e ) {
> > + log.fatal( "Internal error: Someone put in a faulty
> > pattern.", e );
> > + throw new InternalWikiException( "Faulty pattern." );
> > }
> >
> > m_akismetAPIKey = TextUtil.getStringProperty( properties,
> > @@ -255,10 +265,10 @@ public class SpamFilter
> >
> > m_stopAtFirstMatch = TextUtil.getStringProperty( properties,
> >
> > PROP_FILTERSTRATEGY,
> > - STRATEGY_EAGER
> > ).equals(STRATEGY_EAGER);
> > + STRATEGY_EAGER
> > ).equals( STRATEGY_EAGER );
> >
> > - log.info("# Spam filter initialized. Temporary ban time
> > "+m_banTime+
> > - " mins, max page changes/minute:
> > "+m_limitSinglePageChanges );
> > + log.info( "# Spam filter initialized. Temporary ban time " +
> > m_banTime +
> > + " mins, max page changes/minute: " +
> > m_limitSinglePageChanges );
> >
> >
> > }
> > @@ -267,8 +277,7 @@ public class SpamFilter
> > private static final int ACCEPT = 1;
> > private static final int NOTE = 2;
> >
> > - private static String log( WikiContext ctx, int type, String source,
> > String message )
> > - {
> > + private static String log( WikiContext ctx, int type, String source,
> > String message ) {
> > message = TextUtil.replaceString( message, "\r\n", "\\r\\n" );
> > message = TextUtil.replaceString( message, "\"", "\\\"" );
> >
> > @@ -276,10 +285,9 @@ public class SpamFilter
> >
> > String page = ctx.getPage().getName();
> > String reason = "UNKNOWN";
> > - String addr = ctx.getHttpRequest() != null ?
> > ctx.getHttpRequest().getRemoteAddr() : "-";
> > + String addr = ctx.getHttpRequest() != null ?
> > HttpUtil.getRemoteAddress( ctx.getHttpRequest() ) : "-";
> >
> > - switch( type )
> > - {
> > + switch( type ) {
> > case REJECT:
> > reason = "REJECTED";
> > break;
> > @@ -290,38 +298,30 @@ public class SpamFilter
> > reason = "NOTE";
> > break;
> > default:
> > - throw new InternalWikiException("Illegal type "+type);
> > + throw new InternalWikiException( "Illegal type " + type
> );
> > }
> > -
> > - c_spamlog.info( reason+" "+source+" "+uid+" "+addr+"
> > \""+page+"\" "+message );
> > + c_spamlog.info( reason + " " + source + " " + uid + " " + addr
> +
> > " \"" + page + "\" " + message );
> >
> > return uid;
> > }
> >
> > /** {@inheritDoc} */
> > - public String preSave( WikiContext context, String content )
> > - throws RedirectException
> > - {
> > + public String preSave( WikiContext context, String content ) throws
> > RedirectException {
> > cleanBanList();
> > - refreshBlacklists(context);
> > -
> > + refreshBlacklists( context );
> > Change change = getChange( context, content );
> >
> > - if(!ignoreThisUser(context))
> > - {
> > + if( !ignoreThisUser( context ) ) {
> > checkBanList( context, change );
> > checkSinglePageChange( context, content, change );
> > - checkPatternList(context, content, change);
> > + checkPatternList( context, content, change );
> > }
> >
> > - if( !m_stopAtFirstMatch )
> > - {
> > - Integer score =
> > (Integer)context.getVariable(ATTR_SPAMFILTER_SCORE);
> > + if( !m_stopAtFirstMatch ) {
> > + Integer score = ( Integer )context.getVariable(
> > ATTR_SPAMFILTER_SCORE );
> >
> > - if( score != null && score.intValue() >= m_scoreLimit )
> > - {
> > - throw new RedirectException( "Herb says you got too many
> > points",
> > - getRedirectPage(context) );
> > + if( score != null && score.intValue() >= m_scoreLimit ) {
> > + throw new RedirectException( "Herb says you got too many
> > points", getRedirectPage( context ) );
> > }
> > }
> >
> > @@ -329,23 +329,21 @@ public class SpamFilter
> > return content;
> > }
> >
> > - private void checkStrategy( WikiContext context, String error,
> String
> > message )
> > - throws RedirectException
> > - {
> > - if( m_stopAtFirstMatch )
> > - {
> > - throw new RedirectException( message,
> > getRedirectPage(context) );
> > + private void checkStrategy( WikiContext context, String error,
> String
> > message ) throws RedirectException {
> > + if( m_stopAtFirstMatch ) {
> > + throw new RedirectException( message, getRedirectPage(
> > context ) );
> > }
> >
> > - Integer score = (Integer)context.getVariable(
> > ATTR_SPAMFILTER_SCORE );
> > -
> > - if( score != null )
> > - score = score+1;
> > - else
> > + Integer score = ( Integer )context.getVariable(
> > ATTR_SPAMFILTER_SCORE );
> > + if( score != null ) {
> > + score = score + 1;
> > + } else {
> > score = 1;
> > + }
> >
> > context.setVariable( ATTR_SPAMFILTER_SCORE, score );
> > }
> > +
> > /**
> > * Parses a list of patterns and returns a Collection of compiled
> > Pattern
> > * objects.
> > @@ -354,27 +352,20 @@ public class SpamFilter
> > * @param list
> > * @return A Collection of the Patterns that were found from the
> > lists.
> > */
> > - private Collection<Pattern> parseWordList( WikiPage source, String
> > list )
> > - {
> > - ArrayList<Pattern> compiledpatterns = new ArrayList<Pattern>();
> > + private Collection< Pattern > parseWordList( WikiPage source, String
> > list ) {
> > + ArrayList< Pattern > compiledpatterns = new ArrayList< Pattern
> > >();
> >
> > - if( list != null )
> > - {
> > + if( list != null ) {
> > StringTokenizer tok = new StringTokenizer( list, " \t\n" );
> >
> > - while( tok.hasMoreTokens() )
> > - {
> > + while( tok.hasMoreTokens() ) {
> > String pattern = tok.nextToken();
> >
> > - try
> > - {
> > + try {
> > compiledpatterns.add( m_compiler.compile( pattern )
> );
> > - }
> > - catch( MalformedPatternException e )
> > - {
> > - log.debug( "Malformed spam filter pattern "+pattern
> );
> > -
> > - source.setAttribute("error", "Malformed spam filter
> > pattern "+pattern);
> > + } catch( MalformedPatternException e ) {
> > + log.debug( "Malformed spam filter pattern " +
> pattern
> > );
> > + source.setAttribute("error", "Malformed spam filter
> > pattern " + pattern);
> > }
> > }
> > }
> > @@ -383,49 +374,35 @@ public class SpamFilter
> > }
> >
> > /**
> > - * Takes a MT-Blacklist -formatted blacklist and returns a list of
> > compiled
> > - * Pattern objects.
> > + * Takes a MT-Blacklist -formatted blacklist and returns a list of
> > compiled Pattern objects.
> > *
> > * @param list
> > * @return The parsed blacklist patterns.
> > */
> > - private Collection<Pattern> parseBlacklist( String list )
> > - {
> > - ArrayList<Pattern> compiledpatterns = new ArrayList<Pattern>();
> > -
> > - if( list != null )
> > - {
> > - try
> > - {
> > - BufferedReader in = new BufferedReader( new
> > StringReader(list) );
> > + private Collection< Pattern > parseBlacklist( String list ) {
> > + ArrayList< Pattern > compiledpatterns = new ArrayList< Pattern
> > >();
> >
> > + if( list != null ) {
> > + try {
> > + BufferedReader in = new BufferedReader( new
> > StringReader(list) );
> > String line;
> > -
> > - while( (line = in.readLine()) != null )
> > - {
> > + while( (line = in.readLine() ) != null ) {
> > line = line.trim();
> > if( line.length() == 0 ) continue; // Empty line
> > if( line.startsWith("#") ) continue; // It's a
> comment
> >
> > - int ws = line.indexOf(' ');
> > -
> > - if( ws == -1 ) ws = line.indexOf('\t');
> > -
> > - if( ws != -1 ) line = line.substring(0,ws);
> > + int ws = line.indexOf( ' ' );
> > + if( ws == -1 ) ws = line.indexOf( '\t' );
> > + if( ws != -1 ) line = line.substring( 0, ws );
> >
> > - try
> > - {
> > + try {
> > compiledpatterns.add( m_compiler.compile( line )
> > );
> > - }
> > - catch( MalformedPatternException e )
> > - {
> > - log.debug( "Malformed spam filter pattern "+line
> > );
> > + } catch( MalformedPatternException e ) {
> > + log.debug( "Malformed spam filter pattern " +
> > line );
> > }
> > }
> > - }
> > - catch( IOException e )
> > - {
> > - log.info("Could not read patterns; returning what I
> > got",e);
> > + } catch( IOException e ) {
> > + log.info( "Could not read patterns; returning what I
> > got" , e );
> > }
> > }
> >
> > @@ -440,31 +417,27 @@ public class SpamFilter
> > * @param content
> > * @throws RedirectException
> > */
> > - private synchronized void checkSinglePageChange( WikiContext
> context,
> > String content, Change change )
> > - throws RedirectException
> > - {
> > + private synchronized void checkSinglePageChange( WikiContext
> context,
> > String content, Change change )
> > + throws RedirectException {
> > HttpServletRequest req = context.getHttpRequest();
> >
> > - if( req != null )
> > - {
> > - String addr = req.getRemoteAddr();
> > + if( req != null ) {
> > + String addr = HttpUtil.getRemoteAddress( req );
> > int hostCounter = 0;
> > int changeCounter = 0;
> >
> > - log.debug("Change is "+change.m_change);
> > + log.debug( "Change is " + change.m_change );
> >
> > - long time = System.currentTimeMillis()-60*1000L; // 1 minute
> > + long time = System.currentTimeMillis() - 60*1000L; // 1
> minute
> >
> > - for( Iterator i = m_lastModifications.iterator();
> > i.hasNext(); )
> > - {
> > - Host host = (Host)i.next();
> > + for( Iterator< Host > i = m_lastModifications.iterator();
> > i.hasNext(); ) {
> > + Host host = i.next();
> >
> > //
> > // Check if this item is invalid
> > //
> > - if( host.getAddedTime() < time )
> > - {
> > - log.debug("Removed host "+host.getAddress()+" from
> > modification queue (expired)");
> > + if( host.getAddedTime() < time ) {
> > + log.debug( "Removed host " + host.getAddress() + "
> > from modification queue (expired)" );
> > i.remove();
> > continue;
> > }
> > @@ -473,8 +446,7 @@ public class SpamFilter
> > // Check if this IP address has been seen before
> > //
> >
> > - if( host.getAddress().equals(addr) )
> > - {
> > + if( host.getAddress().equals( addr ) ) {
> > hostCounter++;
> > }
> >
> > @@ -482,8 +454,7 @@ public class SpamFilter
> > // Check, if this change has been seen before
> > //
> >
> > - if( host.getChange() != null &&
> > host.getChange().equals(change) )
> > - {
> > + if( host.getChange() != null && host.getChange().equals(
> > change ) ) {
> > changeCounter++;
> > }
> > }
> > @@ -491,74 +462,58 @@ public class SpamFilter
> > //
> > // Now, let's check against the limits.
> > //
> > - if( hostCounter >= m_limitSinglePageChanges )
> > - {
> > + if( hostCounter >= m_limitSinglePageChanges ) {
> > Host host = new Host( addr, null );
> > -
> > m_temporaryBanList.add( host );
> >
> > String uid = log( context, REJECT,
> > REASON_TOO_MANY_MODIFICATIONS, change.m_change );
> > - log.info( "SPAM:TooManyModifications ("+uid+"). Added
> > host "+addr+" to temporary ban list for doing too many
> > modifications/minute" );
> > - checkStrategy( context, REASON_TOO_MANY_MODIFICATIONS,
> > "Herb says you look like a spammer, and I trust Herb! (Incident code
> > "+uid+")" );
> > + log.info( "SPAM:TooManyModifications (" + uid + ").
> > Added host " + addr + " to temporary ban list for doing too many
> > modifications/minute" );
> > + checkStrategy( context, REASON_TOO_MANY_MODIFICATIONS,
> > "Herb says you look like a spammer, and I trust Herb! (Incident code " +
> > uid + ")" );
> > }
> >
> > - if( changeCounter >= m_limitSimilarChanges )
> > - {
> > + if( changeCounter >= m_limitSimilarChanges ) {
> > Host host = new Host( addr, null );
> > -
> > m_temporaryBanList.add( host );
> >
> > String uid = log( context, REJECT,
> > REASON_SIMILAR_MODIFICATIONS, change.m_change );
> > -
> > - log.info("SPAM:SimilarModifications ("+uid+"). Added
> > host "+addr+" to temporary ban list for doing too many similar
> > modifications" );
> > + log.info( "SPAM:SimilarModifications (" + uid + ").
> > Added host " + addr + " to temporary ban list for doing too many similar
> > modifications" );
> > checkStrategy( context, REASON_SIMILAR_MODIFICATIONS,
> > "Herb says you look like a spammer, and I trust Herb! (Incident code
> > "+uid+")");
> > }
> >
> > //
> > // Calculate the number of links in the addition.
> > //
> > -
> > - String tstChange = change.toString();
> > + String tstChange = change.toString();
> > int urlCounter = 0;
> > -
> > - while( m_matcher.contains(tstChange,m_urlPattern) )
> > - {
> > + while( m_matcher.contains( tstChange,m_urlPattern ) ) {
> > MatchResult m = m_matcher.getMatch();
> > -
> > tstChange = tstChange.substring( m.endOffset(0) );
> > -
> > urlCounter++;
> > }
> >
> > - if( urlCounter > m_maxUrls )
> > - {
> > + if( urlCounter > m_maxUrls ) {
> > Host host = new Host( addr, null );
> > -
> > m_temporaryBanList.add( host );
> >
> > String uid = log( context, REJECT, REASON_TOO_MANY_URLS,
> > change.toString() );
> > -
> > - log.info("SPAM:TooManyUrls ("+uid+"). Added host
> > "+addr+" to temporary ban list for adding too many URLs" );
> > - checkStrategy( context, REASON_TOO_MANY_URLS, "Herb says
> > you look like a spammer, and I trust Herb! (Incident code "+uid+")" );
> > + log.info( "SPAM:TooManyUrls (" + uid + "). Added host "
> > + addr + " to temporary ban list for adding too many URLs" );
> > + checkStrategy( context, REASON_TOO_MANY_URLS, "Herb says
> > you look like a spammer, and I trust Herb! (Incident code " + uid + ")"
> );
> > }
> >
> > //
> > // Check bot trap
> > //
> > -
> > checkBotTrap( context, change );
> >
> > //
> > // Check UTF-8 mangling
> > //
> > -
> > checkUTF8( context, change );
> >
> > //
> > // Do Akismet check. This is good to be the last, because
> > this is the most
> > // expensive operation.
> > //
> > -
> > checkAkismet( context, change );
> >
> > m_lastModifications.add( new Host( addr, change ) );
> > @@ -573,20 +528,14 @@ public class SpamFilter
> > * @param change
> > * @throws RedirectException
> > */
> > - private void checkAkismet( WikiContext context, Change change )
> > - throws RedirectException
> > - {
> > - if( m_akismetAPIKey != null )
> > - {
> > - if( m_akismet == null )
> > - {
> > - log.info("Initializing Akismet spam protection.");
> > -
> > + private void checkAkismet( WikiContext context, Change change )
> > throws RedirectException {
> > + if( m_akismetAPIKey != null ) {
> > + if( m_akismet == null ) {
> > + log.info( "Initializing Akismet spam protection." );
> > m_akismet = new Akismet( m_akismetAPIKey,
> > context.getEngine().getBaseURL() );
> >
> > - if( !m_akismet.verifyAPIKey() )
> > - {
> > - log.error("Akismet API key cannot be verified.
> > Please check your config.");
> > + if( !m_akismet.verifyAPIKey() ) {
> > + log.error( "Akismet API key cannot be verified.
> > Please check your config." );
> > m_akismetAPIKey = null;
> > m_akismet = null;
> > }
> > @@ -598,23 +547,21 @@ public class SpamFilter
> > // Akismet will mark all empty statements as spam, so we'll
> > just
> > // ignore them.
> > //
> > - if( change.m_adds == 0 && change.m_removals > 0 )
> > - {
> > + if( change.m_adds == 0 && change.m_removals > 0 ) {
> > return;
> > }
> >
> > - if( req != null && m_akismet != null )
> > - {
> > - log.debug("Calling Akismet to check for spam...");
> > + if( req != null && m_akismet != null ) {
> > + log.debug( "Calling Akismet to check for spam..." );
> >
> > StopWatch sw = new StopWatch();
> > sw.start();
> >
> > - String ipAddress = req.getRemoteAddr();
> > - String userAgent = req.getHeader("User-Agent");
> > + String ipAddress = HttpUtil.getRemoteAddress( req );
> > + String userAgent = req.getHeader( "User-Agent" );
> > String referrer = req.getHeader( "Referer");
> > String permalink = context.getViewURL(
> > context.getPage().getName() );
> > - String commentType =
> > context.getRequestContext().equals(WikiContext.COMMENT) ? "comment" :
> > "edit";
> > + String commentType =
> > context.getRequestContext().equals( WikiContext.COMMENT ) ? "comment" :
> > "edit";
> > String commentAuthor =
> context.getCurrentUser().getName();
> > String commentAuthorEmail = null;
> > String commentAuthorURL = null;
> > @@ -631,96 +578,74 @@ public class SpamFilter
> > null );
> >
> > sw.stop();
> > + log.debug( "Akismet request done in: " + sw );
> >
> > - log.debug("Akismet request done in: "+sw);
> > -
> > - if( isSpam )
> > - {
> > + if( isSpam ) {
> > // Host host = new Host( ipAddress, null );
> > -
> > // m_temporaryBanList.add( host );
> >
> > String uid = log( context, REJECT, REASON_AKISMET,
> > change.toString() );
> > -
> > - log.info("SPAM:Akismet ("+uid+"). Akismet thinks
> > this change is spam; added host to temporary ban list.");
> > -
> > - checkStrategy( context, REASON_AKISMET, "Akismet
> > tells Herb you're a spammer, Herb trusts Akismet, and I trust Herb!
> > (Incident code "+uid+")");
> > + log.info( "SPAM:Akismet (" + uid + "). Akismet
> > thinks this change is spam; added host to temporary ban list." );
> > + checkStrategy( context, REASON_AKISMET, "Akismet
> > tells Herb you're a spammer, Herb trusts Akismet, and I trust Herb!
> > (Incident code " + uid + ")" );
> > }
> > }
> > }
> > }
> >
> > /**
> > - * Returns a static string which can be used to detect spambots
> which
> > - * just wildly fill in all the fields.
> > + * Returns a static string which can be used to detect spambots
> which
> > just wildly fill in all the fields.
> > *
> > - * @return A string
> > + * @return A string
> > */
> > - public static String getBotFieldName()
> > - {
> > + public static String getBotFieldName() {
> > return "submit_auth";
> > }
> >
> > /**
> > - * This checks whether an invisible field is available in the
> > request, and
> > - * whether it's contents are suspected spam.
> > + * This checks whether an invisible field is available in the
> > request, and whether it's contents are suspected spam.
> > *
> > - * @param context
> > - * @param change
> > + * @param context
> > + * @param change
> > * @throws RedirectException
> > */
> > - private void checkBotTrap( WikiContext context, Change change )
> > throws RedirectException
> > - {
> > + private void checkBotTrap( WikiContext context, Change change )
> > throws RedirectException {
> > HttpServletRequest request = context.getHttpRequest();
> >
> > - if( request != null )
> > - {
> > + if( request != null ) {
> > String unspam = request.getParameter( getBotFieldName() );
> > - if( unspam != null && unspam.length() > 0 )
> > - {
> > + if( unspam != null && unspam.length() > 0 ) {
> > String uid = log( context, REJECT, REASON_BOT_TRAP,
> > change.toString() );
> >
> > - log.info("SPAM:BotTrap ("+uid+"). Wildly behaving bot
> > detected.");
> > -
> > - checkStrategy( context, REASON_BOT_TRAP, "Spamming
> > attempt detected. (Incident code "+uid+")");
> > -
> > + log.info( "SPAM:BotTrap (" + uid + "). Wildly behaving
> > bot detected." );
> > + checkStrategy( context, REASON_BOT_TRAP, "Spamming
> > attempt detected. (Incident code " + uid + ")" );
> > }
> > }
> > }
> >
> > - private void checkUTF8( WikiContext context, Change change ) throws
> > RedirectException
> > - {
> > + private void checkUTF8( WikiContext context, Change change ) throws
> > RedirectException {
> > HttpServletRequest request = context.getHttpRequest();
> >
> > - if( request != null )
> > - {
> > + if( request != null ) {
> > String utf8field = request.getParameter( "encodingcheck" );
> >
> > - if( utf8field != null && !utf8field.equals("\u3041") )
> > - {
> > + if( utf8field != null && !utf8field.equals( "\u3041" ) ) {
> > String uid = log( context, REJECT, REASON_UTF8_TRAP,
> > change.toString() );
> >
> > - log.info("SPAM:UTF8Trap ("+uid+"). Wildly posting dumb
> > bot detected.");
> > -
> > - checkStrategy( context, REASON_UTF8_TRAP, "Spamming
> > attempt detected. (Incident code "+uid+")");
> > + log.info( "SPAM:UTF8Trap (" + uid + "). Wildly posting
> > dumb bot detected." );
> > + checkStrategy( context, REASON_UTF8_TRAP, "Spamming
> > attempt detected. (Incident code " + uid + ")" );
> > }
> > }
> > }
> >
> > - /**
> > - * Goes through the ban list and cleans away any host which has
> > expired from it.
> > - */
> > - private synchronized void cleanBanList()
> > - {
> > + /** Goes through the ban list and cleans away any host which has
> > expired from it. */
> > + private synchronized void cleanBanList() {
> > long now = System.currentTimeMillis();
> >
> > - for( Iterator i = m_temporaryBanList.iterator(); i.hasNext(); )
> > - {
> > - Host host = (Host)i.next();
> > -
> > - if( host.getReleaseTime() < now )
> > - {
> > - log.debug("Removed host "+host.getAddress()+" from
> > temporary ban list (expired)");
> > + for( Iterator< Host > i = m_temporaryBanList.iterator();
> > i.hasNext(); ) {
> > + Host host = i.next();
> > +
> > + if( host.getReleaseTime() < now ) {
> > + log.debug( "Removed host " + host.getAddress() + " from
> > temporary ban list (expired)" );
> > i.remove();
> > }
> > }
> > @@ -732,45 +657,33 @@ public class SpamFilter
> > * @param context
> > * @throws RedirectException
> > */
> > -
> > - private void checkBanList( WikiContext context, Change change )
> > - throws RedirectException
> > - {
> > + private void checkBanList( WikiContext context, Change change )
> > throws RedirectException {
> > HttpServletRequest req = context.getHttpRequest();
> >
> > - if( req != null )
> > - {
> > - String remote = req.getRemoteAddr();
> > -
> > + if( req != null ) {
> > + String remote = HttpUtil.getRemoteAddress(req);
> > long now = System.currentTimeMillis();
> >
> > - for( Iterator i = m_temporaryBanList.iterator();
> i.hasNext();
> > )
> > - {
> > - Host host = (Host)i.next();
> > -
> > - if( host.getAddress().equals(remote) )
> > - {
> > - long timeleft = (host.getReleaseTime() - now) /
> 1000L;
> > + for( Iterator< Host > i = m_temporaryBanList.iterator();
> > i.hasNext(); ) {
> > + Host host = i.next();
> >
> > - log( context, REJECT, REASON_IP_BANNED_TEMPORARILY,
> > change.m_change );
> > + if( host.getAddress().equals( remote ) ) {
> > + long timeleft = ( host.getReleaseTime() - now ) /
> > 1000L;
> >
> > - checkStrategy( context,
> REASON_IP_BANNED_TEMPORARILY,
> > "You have been temporarily banned from modifying this wiki. ("+timeleft+"
> > seconds of ban left)");
> > + log( context, REJECT, REASON_IP_BANNED_TEMPORARILY,
> > change.m_change );
> > + checkStrategy( context,
> REASON_IP_BANNED_TEMPORARILY,
> > "You have been temporarily banned from modifying this wiki. (" +
> timeleft +
> > " seconds of ban left)" );
> > }
> > }
> > }
> > -
> > }
> >
> > /**
> > - * If the spam filter notices changes in the black list page, it
> > will refresh
> > - * them automatically.
> > + * If the spam filter notices changes in the black list page, it
> > will refresh them automatically.
> > *
> > * @param context
> > */
> > - private void refreshBlacklists( WikiContext context )
> > - {
> > - try
> > - {
> > + private void refreshBlacklists( WikiContext context ) {
> > + try {
> > WikiPage source = context.getEngine().getPage(
> > m_forbiddenWordsPage );
> > Attachment att =
> > context.getEngine().getAttachmentManager().getAttachmentInfo( context,
> > m_blacklist );
> >
> > @@ -779,62 +692,43 @@ public class SpamFilter
> > //
> > // Rebuild, if the page or the attachment has changed
> since.
> > //
> > - if( source != null )
> > - {
> > - if( m_spamPatterns == null || m_spamPatterns.isEmpty()
> ||
> > source.getLastModified().after(m_lastRebuild) )
> > - {
> > + if( source != null ) {
> > + if( m_spamPatterns == null || m_spamPatterns.isEmpty()
> ||
> > source.getLastModified().after( m_lastRebuild ) ) {
> > rebuild = true;
> > }
> > }
> >
> > - if( att != null )
> > - {
> > - if( m_spamPatterns == null || m_spamPatterns.isEmpty()
> ||
> > att.getLastModified().after(m_lastRebuild) )
> > - {
> > + if( att != null ) {
> > + if( m_spamPatterns == null || m_spamPatterns.isEmpty()
> ||
> > att.getLastModified().after( m_lastRebuild ) ) {
> > rebuild = true;
> > }
> > }
> >
> > -
> > //
> > // Do the actual rebuilding. For simplicity's sake, we
> > always rebuild the complete
> > // filter list regardless of what changed.
> > //
> > -
> > - if( rebuild )
> > - {
> > + if( rebuild ) {
> > m_lastRebuild = new Date();
> > -
> > m_spamPatterns = parseWordList( source,
> > - (source != null) ?
> > (String)source.getAttribute( LISTVAR ) : null );
> > + ( source != null ) ? (
> > String )source.getAttribute( LISTVAR ) : null );
> >
> > - log.info("Spam filter reloaded - recognizing
> > "+m_spamPatterns.size()+" patterns from page "+m_forbiddenWordsPage);
> > + log.info( "Spam filter reloaded - recognizing " +
> > m_spamPatterns.size() + " patterns from page " + m_forbiddenWordsPage );
> >
> > - if( att != null )
> > - {
> > + if( att != null ) {
> > InputStream in =
> > context.getEngine().getAttachmentManager().getAttachmentStream(att);
> > -
> > StringWriter out = new StringWriter();
> > -
> > - FileUtil.copyContents( new
> > InputStreamReader(in,"UTF-8"), out );
> > -
> > - Collection<Pattern> blackList = parseBlacklist(
> > out.toString() );
> > -
> > - log.info("...recognizing additional
> > "+blackList.size()+" patterns from blacklist "+m_blacklist);
> > -
> > + FileUtil.copyContents( new InputStreamReader(
> > in,"UTF-8" ), out );
> > + Collection< Pattern > blackList = parseBlacklist(
> > out.toString() );
> > + log.info( "...recognizing additional " +
> > blackList.size() + " patterns from blacklist " + m_blacklist );
> > m_spamPatterns.addAll( blackList );
> > }
> > }
> > + } catch( IOException ex ) {
> > + log.info( "Unable to read attachment data, continuing...",
> > ex );
> > + } catch( ProviderException ex ) {
> > + log.info( "Failed to read spam filter attachment,
> > continuing...", ex );
> > }
> > - catch( IOException ex )
> > - {
> > - log.info("Unable to read attachment data,
> continuing...",ex);
> > - }
> > - catch( ProviderException ex )
> > - {
> > - log.info("Failed to read spam filter attachment,
> > continuing...",ex);
> > - }
> > -
> > }
> >
> > /**
> > @@ -845,45 +739,39 @@ public class SpamFilter
> > * @param change
> > * @throws RedirectException
> > */
> > - private void checkPatternList(WikiContext context, String content,
> > Change change) throws RedirectException
> > - {
> > + private void checkPatternList( WikiContext context, String content,
> > Change change ) throws RedirectException {
> > //
> > // If we have no spam patterns defined, or we're trying to save
> > // the page containing the patterns, just return.
> > //
> > - if( m_spamPatterns == null ||
> context.getPage().getName().equals(
> > m_forbiddenWordsPage ) )
> > - {
> > + if( m_spamPatterns == null ||
> context.getPage().getName().equals(
> > m_forbiddenWordsPage ) ) {
> > return;
> > }
> >
> > String ch = change.toString();
> > -
> > - if( context.getHttpRequest() != null )
> > - ch += context.getHttpRequest().getRemoteAddr();
> > + if( context.getHttpRequest() != null ) {
> > + ch += HttpUtil.getRemoteAddress( context.getHttpRequest() );
> > + }
> >
> > - for( Pattern p : m_spamPatterns )
> > - {
> > + for( Pattern p : m_spamPatterns ) {
> > // log.debug("Attempting to match page contents with
> > "+p.getPattern());
> >
> > - if( m_matcher.contains( ch, p ) )
> > - {
> > + if( m_matcher.contains( ch, p ) ) {
> > //
> > // Spam filter has a match.
> > //
> > - String uid = log( context, REJECT,
> > REASON_REGEXP+"("+p.getPattern()+")", ch);
> > + String uid = log( context, REJECT, REASON_REGEXP + "(" +
> > p.getPattern() + ")", ch );
> >
> > - log.info("SPAM:Regexp ("+uid+"). Content matches the
> > spam filter '"+p.getPattern()+"'");
> > -
> > - checkStrategy( context, REASON_REGEXP, "Herb says
> > '"+p.getPattern()+"' is a bad spam word and I trust Herb! (Incident code
> > "+uid+")");
> > + log.info( "SPAM:Regexp (" + uid + "). Content matches
> > the spam filter '" + p.getPattern() + "'" );
> > + checkStrategy( context, REASON_REGEXP, "Herb says '" +
> > p.getPattern() + "' is a bad spam word and I trust Herb! (Incident code
> " +
> > uid + ")" );
> > }
> > }
> > }
> >
> > - private void checkPatternList(WikiContext context, String content,
> > String change ) throws RedirectException
> > - {
> > + private void checkPatternList( WikiContext context, String content,
> > String change ) throws RedirectException {
> > Change c = new Change();
> > c.m_change = change;
> > - checkPatternList(context,content,c);
> > + checkPatternList( context, content, c );
> > }
> >
> > /**
> > @@ -893,8 +781,7 @@ public class SpamFilter
> > * @param newText
> > * @return Empty string, if there is no change.
> > */
> > - private static Change getChange( WikiContext context, String
> newText )
> > - {
> > + private static Change getChange( WikiContext context, String newText
> > ) {
> > WikiPage page = context.getPage();
> > StringBuffer change = new StringBuffer();
> > WikiEngine engine = context.getEngine();
> > @@ -902,62 +789,51 @@ public class SpamFilter
> >
> > Change ch = new Change();
> >
> > - try
> > - {
> > - String oldText = engine.getPureText(page.getName(),
> > WikiProvider.LATEST_VERSION);
> > -
> > - String[] first = Diff.stringToArray(oldText);
> > - String[] second = Diff.stringToArray(newText);
> > - Revision rev = Diff.diff(first, second, new MyersDiff());
> > + try {
> > + String oldText = engine.getPureText( page.getName(),
> > WikiProvider.LATEST_VERSION );
> > +
> > + String[] first = Diff.stringToArray( oldText );
> > + String[] second = Diff.stringToArray( newText );
> > + Revision rev = Diff.diff( first, second, new MyersDiff() );
> >
> > - if( rev == null || rev.size() == 0 )
> > - {
> > + if( rev == null || rev.size() == 0 ) {
> > return ch;
> > }
> >
> > - for( int i = 0; i < rev.size(); i++ )
> > - {
> > - Delta d = rev.getDelta(i);
> > + for( int i = 0; i < rev.size(); i++ ) {
> > + Delta d = rev.getDelta( i );
> >
> > - if( d instanceof AddDelta )
> > - {
> > + if( d instanceof AddDelta ) {
> > d.getRevised().toString( change, "", "\r\n" );
> > ch.m_adds++;
> > - }
> > - else if( d instanceof ChangeDelta )
> > - {
> > +
> > + } else if( d instanceof ChangeDelta ) {
> > d.getRevised().toString( change, "", "\r\n" );
> > ch.m_adds++;
> > - }
> > - else if( d instanceof DeleteDelta )
> > - {
> > +
> > + } else if( d instanceof DeleteDelta ) {
> > ch.m_removals++;
> > }
> > }
> > - }
> > - catch (DifferentiationFailedException e)
> > - {
> > + } catch( DifferentiationFailedException e ) {
> > log.error( "Diff failed", e );
> > }
> >
> > //
> > // Don't forget to include the change note, too
> > //
> > - String changeNote =
> > (String)page.getAttribute(WikiPage.CHANGENOTE);
> > + String changeNote = ( String )page.getAttribute(
> > WikiPage.CHANGENOTE );
> >
> > - if( changeNote != null )
> > - {
> > - change.append("\r\n");
> > - change.append(changeNote);
> > + if( changeNote != null ) {
> > + change.append( "\r\n" );
> > + change.append( changeNote );
> > }
> >
> > //
> > // And author as well
> > //
> > -
> > - if( page.getAuthor() != null )
> > - {
> > - change.append("\r\n"+page.getAuthor());
> > + if( page.getAuthor() != null ) {
> > + change.append( "\r\n" + page.getAuthor() );
> > }
> >
> > ch.m_change = change.toString();
> > @@ -970,20 +846,16 @@ public class SpamFilter
> > * @param context
> > * @return True, if this users should be ignored.
> > */
> > - private boolean ignoreThisUser(WikiContext context)
> > - {
> > - if( context.hasAdminPermissions() )
> > - {
> > + private boolean ignoreThisUser( WikiContext context ) {
> > + if( context.hasAdminPermissions() ) {
> > return true;
> > }
> >
> > - if( m_ignoreAuthenticated &&
> > context.getWikiSession().isAuthenticated() )
> > - {
> > + if( m_ignoreAuthenticated &&
> > context.getWikiSession().isAuthenticated() ) {
> > return true;
> > }
> >
> > - if( context.getVariable("captcha") != null )
> > - {
> > + if( context.getVariable( "captcha" ) != null ) {
> > return true;
> > }
> >
> > @@ -995,32 +867,28 @@ public class SpamFilter
> > *
> > * @return A random string
> > */
> > - private static String getUniqueID()
> > - {
> > - StringBuffer sb = new StringBuffer();
> > + private static String getUniqueID() {
> > + StringBuilder sb = new StringBuilder();
> > Random rand = new Random();
> >
> > - for( int i = 0; i < 6; i++ )
> > - {
> > - char x = (char)('A'+rand.nextInt(26));
> > -
> > - sb.append(x);
> > + for( int i = 0; i < 6; i++ ) {
> > + char x = ( char )( 'A' + rand.nextInt( 26 ) );
> > + sb.append( x );
> > }
> >
> > return sb.toString();
> > }
> >
> > /**
> > - * Returns a page to which we shall redirect, based on the current
> > value
> > - * of the "captcha" parameter.
> > + * Returns a page to which we shall redirect, based on the current
> > value of the "captcha" parameter.
> > *
> > * @param ctx WikiContext
> > * @return An URL to redirect to
> > */
> > - private String getRedirectPage( WikiContext ctx )
> > - {
> > - if( m_useCaptcha )
> > - return ctx.getURL( WikiContext.NONE, "Captcha.jsp",
> > "page="+ctx.getEngine().encodeName(ctx.getPage().getName()) );
> > + private String getRedirectPage( WikiContext ctx ) {
> > + if( m_useCaptcha ) {
> > + return ctx.getURL( WikiContext.NONE, "Captcha.jsp",
> > "page="+ctx.getEngine().encodeName( ctx.getPage().getName() ) );
> > + }
> >
> > return ctx.getURL( WikiContext.VIEW, m_errorPage );
> > }
> > @@ -1033,16 +901,12 @@ public class SpamFilter
> > * @return False, if this userprofile is suspect and should not be
> > allowed to be added.
> > * @since 2.6.1
> > */
> > - public boolean isValidUserProfile( WikiContext context, UserProfile
> > profile )
> > - {
> > - try
> > - {
> > + public boolean isValidUserProfile( WikiContext context, UserProfile
> > profile ) {
> > + try {
> > checkPatternList( context, profile.getEmail(),
> > profile.getEmail() );
> > checkPatternList( context, profile.getFullname(),
> > profile.getFullname() );
> > checkPatternList( context, profile.getLoginName(),
> > profile.getLoginName() );
> > - }
> > - catch( RedirectException e )
> > - {
> > + } catch( RedirectException e ) {
> > log.info("Detected attempt to create a spammer user account
> > (see above for rejection reason)");
> > return false;
> > }
> > @@ -1051,57 +915,47 @@ public class SpamFilter
> > }
> >
> > /**
> > - * This method is used to calculate an unique code when submitting
> > the page
> > - * to detect edit conflicts. It currently incorporates the
> > last-modified
> > - * date of the page, and the IP address of the submitter.
> > + * This method is used to calculate an unique code when submitting
> > the page to detect edit conflicts.
> > + * It currently incorporates the last-modified date of the page,
> and
> > the IP address of the submitter.
> > *
> > * @param page The WikiPage under edit
> > * @param request The HTTP Request
> > * @since 2.6
> > * @return A hash value for this page and session
> > */
> > - public static final String getSpamHash( WikiPage page,
> > HttpServletRequest request )
> > - {
> > + public static final String getSpamHash( WikiPage page,
> > HttpServletRequest request ) {
> > long lastModified = 0;
> >
> > - if( page.getLastModified() != null )
> > + if( page.getLastModified() != null ) {
> > lastModified = page.getLastModified().getTime();
> > -
> > - long remote = request.getRemoteAddr().hashCode();
> > + }
> > + long remote = HttpUtil.getRemoteAddress( request ).hashCode();
> >
> > return Long.toString( lastModified ^ remote );
> > }
> >
> > /**
> > - * Returns the name of the hash field to be used in this request.
> > - * The value is unique per session, and once the session has
> expired,
> > - * you cannot edit anymore.
> > + * Returns the name of the hash field to be used in this request.
> > The value is unique per session, and once
> > + * the session has expired, you cannot edit anymore.
> > *
> > * @param request The page request
> > * @return The name to be used in the hash field
> > * @since 2.6
> > */
> > -
> > - public static final String getHashFieldName( HttpServletRequest
> > request )
> > - {
> > + public static final String getHashFieldName( HttpServletRequest
> > request ) {
> > String hash = null;
> >
> > - if( request.getSession() != null )
> > - {
> > - hash = (String)request.getSession().getAttribute("_hash");
> > + if( request.getSession() != null ) {
> > + hash = ( String )request.getSession().getAttribute( "_hash"
> );
> >
> > - if( hash == null )
> > - {
> > + if( hash == null ) {
> > hash = c_hashName;
> > -
> > request.getSession().setAttribute( "_hash", hash );
> > }
> > }
> >
> > - if( c_hashName == null || c_lastUpdate <
> > (System.currentTimeMillis() - HASH_DELAY*60*60*1000) )
> > - {
> > + if( c_hashName == null || c_lastUpdate < (
> > System.currentTimeMillis() - HASH_DELAY * 60 * 60 * 1000 ) ) {
> > c_hashName = getUniqueID().toLowerCase();
> > -
> > c_lastUpdate = System.currentTimeMillis();
> > }
> >
> > @@ -1110,13 +964,12 @@ public class SpamFilter
> >
> >
> > /**
> > - * This method checks if the hash value is still valid, i.e. if it
> > exists at all. This
> > - * can occur in two cases: either this is a spam bot which is not
> > adaptive, or it is
> > - * someone who has been editing one page for too long, and their
> > session has expired.
> > + * This method checks if the hash value is still valid, i.e. if it
> > exists at all. This can occur in two cases:
> > + * either this is a spam bot which is not adaptive, or it is
> someone
> > who has been editing one page for too long,
> > + * and their session has expired.
> > * <p>
> > - * This method puts a redirect to the http response field to page
> > "SessionExpired"
> > - * and logs the incident in the spam log (it may or may not be
> spam,
> > but it's rather likely
> > - * that it is).
> > + * This method puts a redirect to the http response field to page
> > "SessionExpired" and logs the incident in
> > + * the spam log (it may or may not be spam, but it's rather likely
> > that it is).
> > *
> > * @param context The WikiContext
> > * @param pageContext The JSP PageContext.
> > @@ -1124,22 +977,16 @@ public class SpamFilter
> > * @throws IOException If redirection fails
> > * @since 2.6
> > */
> > - public static final boolean checkHash( WikiContext context,
> > PageContext pageContext )
> > - throws IOException
> > - {
> > + public static final boolean checkHash( WikiContext context,
> > PageContext pageContext ) throws IOException {
> > String hashName = getHashFieldName(
> > (HttpServletRequest)pageContext.getRequest() );
> >
> > - if( pageContext.getRequest().getParameter(hashName) == null )
> > - {
> > - if( pageContext.getAttribute( hashName ) == null )
> > - {
> > + if( pageContext.getRequest().getParameter(hashName) == null ) {
> > + if( pageContext.getAttribute( hashName ) == null ) {
> > Change change = getChange( context,
> > EditorManager.getEditedText( pageContext ) );
> > -
> > log( context, REJECT, "MissingHash", change.m_change );
> >
> > - String redirect =
> > context.getURL(WikiContext.VIEW,"SessionExpired");
> > -
> > ((HttpServletResponse)pageContext.getResponse()).sendRedirect( redirect
> );
> > -
> > + String redirect = context.getURL(
> > WikiContext.VIEW,"SessionExpired" );
> > + ( ( HttpServletResponse )pageContext.getResponse()
> > ).sendRedirect( redirect );
> > return false;
> > }
> > }
> > @@ -1148,89 +995,81 @@ public class SpamFilter
> > }
> >
> > /**
> > - * This helper method adds all the input fields to your editor that
> > the SpamFilter requires
> > - * to check for spam. This <i>must</i> be in your editor form if
> > you intend to use
> > - * the SpamFilter.
> > + * This helper method adds all the input fields to your editor that
> > the SpamFilter requires
> > + * to check for spam. This <i>must</i> be in your editor form if
> you
> > intend to use the SpamFilter.
> > *
> > - * @param pageContext The PageContext
> > - * @return A HTML string which contains input fields for the
> > SpamFilter.
> > + * @param pageContext The PageContext
> > + * @return A HTML string which contains input fields for the
> > SpamFilter.
> > */
> > - public static final String insertInputFields( PageContext
> pageContext
> > )
> > - {
> > - WikiContext ctx = WikiContext.findContext(pageContext);
> > + public static final String insertInputFields( PageContext
> pageContext
> > ) {
> > + WikiContext ctx = WikiContext.findContext( pageContext );
> > WikiEngine engine = ctx.getEngine();
> >
> > - StringBuffer sb = new StringBuffer();
> > - if (engine.getContentEncoding().equals("UTF-8"))
> > - {
> > - sb.append("<input name='encodingcheck' type='hidden'
> > value='\u3041' />\n");
> > + StringBuilder sb = new StringBuilder();
> > + if( engine.getContentEncoding().equals( "UTF-8" ) ) {
> > + sb.append( "<input name='encodingcheck' type='hidden'
> > value='\u3041' />\n" );
> > }
> >
> > return sb.toString();
> > }
> > +
> > /**
> > * A local class for storing host information.
> > *
> > * @since
> > */
> > - private class Host
> > - {
> > - private long m_addedTime = System.currentTimeMillis();
> > - private long m_releaseTime;
> > - private String m_address;
> > - private Change m_change;
> > + private class Host {
> > +
> > + private long m_addedTime = System.currentTimeMillis();
> > + private long m_releaseTime;
> > + private String m_address;
> > + private Change m_change;
> >
> > - public String getAddress()
> > - {
> > + public String getAddress() {
> > return m_address;
> > }
> >
> > - public long getReleaseTime()
> > - {
> > + public long getReleaseTime() {
> > return m_releaseTime;
> > }
> >
> > - public long getAddedTime()
> > - {
> > + public long getAddedTime() {
> > return m_addedTime;
> > }
> >
> > - public Change getChange()
> > - {
> > + public Change getChange() {
> > return m_change;
> > }
> >
> > - public Host( String ipaddress, Change change )
> > - {
> > + public Host( String ipaddress, Change change ) {
> > m_address = ipaddress;
> > m_change = change;
> > -
> > m_releaseTime = System.currentTimeMillis() + m_banTime * 60
> *
> > 1000L;
> > }
> > +
> > }
> >
> > - private static class Change
> > - {
> > + private static class Change {
> > +
> > public String m_change;
> > public int m_adds;
> > public int m_removals;
> >
> > - public String toString()
> > - {
> > + public String toString() {
> > return m_change;
> > }
> >
> > - public boolean equals(Object o)
> > - {
> > - if( o instanceof Change )
> > - return m_change.equals( ((Change)o).m_change);
> > -
> > + public boolean equals( Object o ) {
> > + if( o instanceof Change ) {
> > + return m_change.equals( ( ( Change )o ).m_change );
> > + }
> > return false;
> > }
> >
> > - public int hashCode()
> > - {
> > - return m_change.hashCode()+17;
> > + public int hashCode() {
> > + return m_change.hashCode() + 17;
> > }
> > +
> > }
> > +
> > }
> >
> > Modified:
> >
> jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/util/HttpUtil.java
> > URL:
> >
> http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/util/HttpUtil.java?rev=1546452&r1=1546451&r2=1546452&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/util/HttpUtil.java
> > (original)
> > +++
> >
> jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/util/HttpUtil.java
> > Thu Nov 28 19:59:11 2013
> > @@ -26,25 +26,35 @@ import java.util.Date;
> > import javax.servlet.http.Cookie;
> > import javax.servlet.http.HttpServletRequest;
> >
> > +import org.apache.commons.lang.StringUtils;
> > import org.apache.log4j.Logger;
> > -
> > import org.apache.wiki.WikiPage;
> >
> > +
> > /**
> > * Contains useful utilities for some common HTTP tasks.
> > *
> > * @since 2.1.61.
> > */
> > -public final class HttpUtil
> > -{
> > +public final class HttpUtil {
> > +
> > static Logger log = Logger.getLogger( HttpUtil.class );
> >
> > + /** Private constructor to prevent direct instantiation. */
> > + private HttpUtil() {
> > + }
> > +
> > /**
> > - * Private constructor to prevent direct instantiation.
> > + * returns the remote address by looking into {@code
> x-forwarded-for}
> > header or, if unavailable,
> > + * into {@link HttpServletRequest#getRemoteAddr()}.
> > + *
> > + * @param req http request
> > + * @return remote address associated to the request.
> > */
> > - private HttpUtil()
> > - {
> > - }
> > + public static String getRemoteAddress( HttpServletRequest req ) {
> > + return StringUtils.isNotEmpty ( req.getHeader(
> > "x-forwarded-for" ) ) ? req.getHeader( "x-forwarded-for" ) :
> > +
> > req.getRemoteAddr();
> > + }
> >
> > /**
> > * Attempts to retrieve the given cookie value from the request.
> > @@ -58,23 +68,17 @@ public final class HttpUtil
> > * @return Value of the cookie, or null, if there is no such
> cookie.
> > */
> >
> > - public static String retrieveCookieValue( HttpServletRequest
> request,
> > String cookieName )
> > - {
> > + public static String retrieveCookieValue( HttpServletRequest
> request,
> > String cookieName ) {
> > Cookie[] cookies = request.getCookies();
> >
> > - if( cookies != null )
> > - {
> > - for( int i = 0; i < cookies.length; i++ )
> > - {
> > - if( cookies[i].getName().equals( cookieName ) )
> > - {
> > + if( cookies != null ) {
> > + for( int i = 0; i < cookies.length; i++ ) {
> > + if( cookies[i].getName().equals( cookieName ) ) {
> > String value = cookies[i].getValue();
> > - if ( value.length() == 0 )
> > - {
> > + if( value.length() == 0 ) {
> > return null;
> > }
> > - if ( value.charAt( 0 ) == '"' && value.charAt(
> > value.length() - 1 ) == '"')
> > - {
> > + if( value.charAt( 0 ) == '"' && value.charAt(
> > value.length() - 1 ) == '"' ) {
> > value = value.substring( 1, value.length() - 1
> );
> > }
> > return value;
> > @@ -93,9 +97,8 @@ public final class HttpUtil
> > * @param p The page for which the ETag should be created.
> > * @return A String depiction of an ETag.
> > */
> > - public static String createETag( WikiPage p )
> > - {
> > - return Long.toString(p.getName().hashCode() ^
> > p.getLastModified().getTime());
> > + public static String createETag( WikiPage p ) {
> > + return Long.toString( p.getName().hashCode() ^
> > p.getLastModified().getTime() );
> > }
> >
> > /**
> > @@ -104,9 +107,7 @@ public final class HttpUtil
> > * @param page the wiki page to check for
> > * @return the result of the check
> > */
> > - public static boolean checkFor304( HttpServletRequest req,
> > - WikiPage page )
> > - {
> > + public static boolean checkFor304( HttpServletRequest req, WikiPage
> > page ) {
> > //
> > // We'll do some handling for CONDITIONAL GET (and return a
> 304)
> > // If the client has set the following headers, do not try for
> a
> > 304.
> > @@ -115,13 +116,10 @@ public final class HttpUtil
> > // cache-control: no-cache
> > //
> >
> > - if( "no-cache".equalsIgnoreCase(req.getHeader("Pragma"))
> > - ||
> > "no-cache".equalsIgnoreCase(req.getHeader("cache-control")))
> > - {
> > + if( "no-cache".equalsIgnoreCase( req.getHeader( "Pragma" ) )
> > + || "no-cache".equalsIgnoreCase( req.getHeader(
> > "cache-control" ) ) ) {
> > // Wants specifically a fresh copy
> > - }
> > - else
> > - {
> > + } else {
> > //
> > // HTTP 1.1 ETags go first
> > //
> > @@ -129,8 +127,7 @@ public final class HttpUtil
> >
> > String eTag = req.getHeader( "If-None-Match" );
> >
> > - if( eTag != null && eTag.equals(thisTag) )
> > - {
> > + if( eTag != null && eTag.equals(thisTag) ) {
> > return true;
> > }
> >
> > @@ -140,45 +137,33 @@ public final class HttpUtil
> > DateFormat rfcDateFormat = new SimpleDateFormat("EEE, dd MMM
> > yyyy HH:mm:ss z");
> > Date lastModified = page.getLastModified();
> >
> > - try
> > - {
> > - long ifModifiedSince =
> > req.getDateHeader("If-Modified-Since");
> > + try {
> > + long ifModifiedSince = req.getDateHeader(
> > "If-Modified-Since" );
> >
> > //log.info("ifModifiedSince:"+ifModifiedSince);
> > - if( ifModifiedSince != -1 )
> > - {
> > + if( ifModifiedSince != -1 ) {
> > long lastModifiedTime = lastModified.getTime();
> >
> > //log.info("lastModifiedTime:" + lastModifiedTime);
> > - if( lastModifiedTime <= ifModifiedSince )
> > - {
> > + if( lastModifiedTime <= ifModifiedSince ) {
> > return true;
> > }
> > - }
> > - else
> > - {
> > - try
> > - {
> > + } else {
> > + try {
> > String s = req.getHeader("If-Modified-Since");
> >
> > - if( s != null )
> > - {
> > + if( s != null ) {
> > Date ifModifiedSinceDate =
> > rfcDateFormat.parse(s);
> > //log.info("ifModifiedSinceDate:" +
> > ifModifiedSinceDate);
> > - if(
> lastModified.before(ifModifiedSinceDate) )
> > - {
> > + if( lastModified.before(ifModifiedSinceDate)
> > ) {
> > return true;
> > }
> > }
> > - }
> > - catch (ParseException e)
> > - {
> > + } catch (ParseException e) {
> > log.warn(e.getLocalizedMessage(), e);
> > }
> > }
> > - }
> > - catch( IllegalArgumentException e )
> > - {
> > + } catch( IllegalArgumentException e ) {
> > // Illegal date/time header format.
> > // We fail quietly, and return false.
> > // FIXME: Should really move to ETags.
> > @@ -191,29 +176,27 @@ public final class HttpUtil
> > /**
> > * Attempts to form a valid URI based on the string given.
> Currently
> > * it can guess email addresses (mailto:). If nothing else is
> > given,
> > - * it assumes it to be a http:// url.
> > + * it assumes it to be an http:// url.
> > *
> > * @param uri URI to take a poke at
> > * @return Possibly a valid URI
> > * @since 2.2.8
> > */
> > - public static String guessValidURI( String uri )
> > - {
> > - if( uri.indexOf('@') != -1 )
> > - {
> > - if( !uri.startsWith("mailto:") )
> > - {
> > + public static String guessValidURI( String uri ) {
> > + if( uri.indexOf( '@' ) != -1 ) {
> > + if( !uri.startsWith( "mailto:" ) ) {
> > // Assume this is an email address
> > -
> > - uri = "mailto:"+uri;
> > + uri = "mailto:" + uri;
> > }
> > - }
> > - else if( uri.length() > 0 && !((uri.startsWith("http://") ||
> > uri.startsWith("https://")) ))
> > - {
> > - uri = "http://"+uri;
> > + } else if( notBeginningWithHttpOrHttps( uri ) ) {
> > + uri = "http://" + uri;
> > }
> >
> > return uri;
> > }
> >
> > + static boolean notBeginningWithHttpOrHttps( String uri ) {
> > + return uri.length() > 0 && !( ( uri.startsWith("http://"
> > ) || uri.startsWith( "https://" ) ) );
> > + }
> > +
> > }
> >
> >
> >
>
Re: svn commit: r1546452 - in /jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki:
filters/SpamFilter.java util/HttpUtil.java
Posted by Harry Metske <ha...@gmail.com>.
JP,
not sure if this will work though, the header is "*X-Forwarded-For" , *not *
"**x-forwarded-for" *?
kind regards,
Harry
On 28 November 2013 20:59, <ju...@apache.org> wrote:
> Author: juanpablo
> Date: Thu Nov 28 19:59:11 2013
> New Revision: 1546452
>
> URL: http://svn.apache.org/r1546452
> Log:
> * JSPWIKI-804: SpamFilter should support X-Forwarded-For header in the
> banlist
>
> * also, formatted braces from those classes
>
> Modified:
>
> jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/filters/SpamFilter.java
>
> jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/util/HttpUtil.java
>
> Modified:
> jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/filters/SpamFilter.java
> URL:
> http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/filters/SpamFilter.java?rev=1546452&r1=1546451&r2=1546452&view=diff
>
> ==============================================================================
> ---
> jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/filters/SpamFilter.java
> (original)
> +++
> jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/filters/SpamFilter.java
> Thu Nov 28 19:59:11 2013
> @@ -18,8 +18,20 @@
> */
> package org.apache.wiki.filters;
>
> -import java.io.*;
> -import java.util.*;
> +import java.io.BufferedReader;
> +import java.io.IOException;
> +import java.io.InputStream;
> +import java.io.InputStreamReader;
> +import java.io.StringReader;
> +import java.io.StringWriter;
> +import java.util.ArrayList;
> +import java.util.Collection;
> +import java.util.Date;
> +import java.util.Iterator;
> +import java.util.Properties;
> +import java.util.Random;
> +import java.util.StringTokenizer;
> +import java.util.Vector;
>
> import javax.servlet.http.HttpServletRequest;
> import javax.servlet.http.HttpServletResponse;
> @@ -29,8 +41,18 @@ import net.sf.akismet.Akismet;
>
> import org.apache.commons.lang.time.StopWatch;
> import org.apache.log4j.Logger;
> -import org.apache.oro.text.regex.*;
> -import org.apache.wiki.*;
> +import org.apache.oro.text.regex.MalformedPatternException;
> +import org.apache.oro.text.regex.MatchResult;
> +import org.apache.oro.text.regex.Pattern;
> +import org.apache.oro.text.regex.PatternCompiler;
> +import org.apache.oro.text.regex.PatternMatcher;
> +import org.apache.oro.text.regex.Perl5Compiler;
> +import org.apache.oro.text.regex.Perl5Matcher;
> +import org.apache.wiki.InternalWikiException;
> +import org.apache.wiki.WikiContext;
> +import org.apache.wiki.WikiEngine;
> +import org.apache.wiki.WikiPage;
> +import org.apache.wiki.WikiProvider;
> import org.apache.wiki.api.exceptions.RedirectException;
> import org.apache.wiki.api.filters.BasicPageFilter;
> import org.apache.wiki.attachment.Attachment;
> @@ -38,6 +60,7 @@ import org.apache.wiki.auth.user.UserPro
> import org.apache.wiki.providers.ProviderException;
> import org.apache.wiki.ui.EditorManager;
> import org.apache.wiki.util.FileUtil;
> +import org.apache.wiki.util.HttpUtil;
> import org.apache.wiki.util.TextUtil;
> import org.suigeneris.jrcs.diff.Diff;
> import org.suigeneris.jrcs.diff.DifferentiationFailedException;
> @@ -48,6 +71,7 @@ import org.suigeneris.jrcs.diff.delta.De
> import org.suigeneris.jrcs.diff.delta.Delta;
> import org.suigeneris.jrcs.diff.myers.MyersDiff;
>
> +
> /**
> * This is Herb, the JSPWiki spamfilter that can also do choke
> modifications.
> *
> @@ -77,9 +101,8 @@ import org.suigeneris.jrcs.diff.myers.My
> *
> * @since 2.1.112
> */
> -public class SpamFilter
> - extends BasicPageFilter
> -{
> +public class SpamFilter extends BasicPageFilter {
> +
> private static final String ATTR_SPAMFILTER_SCORE =
> "spamfilter.score";
> private static final String REASON_REGEXP = "Regexp";
> private static final String REASON_IP_BANNED_TEMPORARILY =
> "IPBannedTemporarily";
> @@ -208,29 +231,19 @@ public class SpamFilter
> * {@inheritDoc}
> */
> @Override
> - public void initialize( WikiEngine engine, Properties properties )
> - {
> - m_forbiddenWordsPage = properties.getProperty( PROP_WORDLIST,
> -
> m_forbiddenWordsPage );
> - m_errorPage = properties.getProperty( PROP_ERRORPAGE,
> - m_errorPage );
> -
> + public void initialize( WikiEngine engine, Properties properties ) {
> + m_forbiddenWordsPage = properties.getProperty( PROP_WORDLIST,
> m_forbiddenWordsPage );
> + m_errorPage = properties.getProperty( PROP_ERRORPAGE, m_errorPage
> );
> m_limitSinglePageChanges = TextUtil.getIntegerProperty(
> properties,
>
> PROP_PAGECHANGES,
>
> m_limitSinglePageChanges );
> -
> +
> m_limitSimilarChanges = TextUtil.getIntegerProperty( properties,
>
> PROP_SIMILARCHANGES,
>
> m_limitSimilarChanges );
>
> - m_maxUrls = TextUtil.getIntegerProperty( properties,
> - PROP_MAXURLS,
> - m_maxUrls );
> -
> - m_banTime = TextUtil.getIntegerProperty( properties,
> - PROP_BANTIME,
> - m_banTime );
> -
> + m_maxUrls = TextUtil.getIntegerProperty( properties,
> PROP_MAXURLS, m_maxUrls );
> + m_banTime = TextUtil.getIntegerProperty( properties,
> PROP_BANTIME, m_banTime );
> m_blacklist = properties.getProperty( PROP_BLACKLIST, m_blacklist
> );
>
> m_ignoreAuthenticated = TextUtil.getBooleanProperty( properties,
> @@ -239,14 +252,11 @@ public class SpamFilter
>
> m_useCaptcha = properties.getProperty( PROP_CAPTCHA, ""
> ).equals("asirra");
>
> - try
> - {
> + try {
> m_urlPattern = m_compiler.compile( URL_REGEXP );
> - }
> - catch( MalformedPatternException e )
> - {
> - log.fatal("Internal error: Someone put in a faulty
> pattern.",e);
> - throw new InternalWikiException("Faulty pattern.");
> + } catch( MalformedPatternException e ) {
> + log.fatal( "Internal error: Someone put in a faulty
> pattern.", e );
> + throw new InternalWikiException( "Faulty pattern." );
> }
>
> m_akismetAPIKey = TextUtil.getStringProperty( properties,
> @@ -255,10 +265,10 @@ public class SpamFilter
>
> m_stopAtFirstMatch = TextUtil.getStringProperty( properties,
>
> PROP_FILTERSTRATEGY,
> - STRATEGY_EAGER
> ).equals(STRATEGY_EAGER);
> + STRATEGY_EAGER
> ).equals( STRATEGY_EAGER );
>
> - log.info("# Spam filter initialized. Temporary ban time
> "+m_banTime+
> - " mins, max page changes/minute:
> "+m_limitSinglePageChanges );
> + log.info( "# Spam filter initialized. Temporary ban time " +
> m_banTime +
> + " mins, max page changes/minute: " +
> m_limitSinglePageChanges );
>
>
> }
> @@ -267,8 +277,7 @@ public class SpamFilter
> private static final int ACCEPT = 1;
> private static final int NOTE = 2;
>
> - private static String log( WikiContext ctx, int type, String source,
> String message )
> - {
> + private static String log( WikiContext ctx, int type, String source,
> String message ) {
> message = TextUtil.replaceString( message, "\r\n", "\\r\\n" );
> message = TextUtil.replaceString( message, "\"", "\\\"" );
>
> @@ -276,10 +285,9 @@ public class SpamFilter
>
> String page = ctx.getPage().getName();
> String reason = "UNKNOWN";
> - String addr = ctx.getHttpRequest() != null ?
> ctx.getHttpRequest().getRemoteAddr() : "-";
> + String addr = ctx.getHttpRequest() != null ?
> HttpUtil.getRemoteAddress( ctx.getHttpRequest() ) : "-";
>
> - switch( type )
> - {
> + switch( type ) {
> case REJECT:
> reason = "REJECTED";
> break;
> @@ -290,38 +298,30 @@ public class SpamFilter
> reason = "NOTE";
> break;
> default:
> - throw new InternalWikiException("Illegal type "+type);
> + throw new InternalWikiException( "Illegal type " + type );
> }
> -
> - c_spamlog.info( reason+" "+source+" "+uid+" "+addr+"
> \""+page+"\" "+message );
> + c_spamlog.info( reason + " " + source + " " + uid + " " + addr +
> " \"" + page + "\" " + message );
>
> return uid;
> }
>
> /** {@inheritDoc} */
> - public String preSave( WikiContext context, String content )
> - throws RedirectException
> - {
> + public String preSave( WikiContext context, String content ) throws
> RedirectException {
> cleanBanList();
> - refreshBlacklists(context);
> -
> + refreshBlacklists( context );
> Change change = getChange( context, content );
>
> - if(!ignoreThisUser(context))
> - {
> + if( !ignoreThisUser( context ) ) {
> checkBanList( context, change );
> checkSinglePageChange( context, content, change );
> - checkPatternList(context, content, change);
> + checkPatternList( context, content, change );
> }
>
> - if( !m_stopAtFirstMatch )
> - {
> - Integer score =
> (Integer)context.getVariable(ATTR_SPAMFILTER_SCORE);
> + if( !m_stopAtFirstMatch ) {
> + Integer score = ( Integer )context.getVariable(
> ATTR_SPAMFILTER_SCORE );
>
> - if( score != null && score.intValue() >= m_scoreLimit )
> - {
> - throw new RedirectException( "Herb says you got too many
> points",
> - getRedirectPage(context) );
> + if( score != null && score.intValue() >= m_scoreLimit ) {
> + throw new RedirectException( "Herb says you got too many
> points", getRedirectPage( context ) );
> }
> }
>
> @@ -329,23 +329,21 @@ public class SpamFilter
> return content;
> }
>
> - private void checkStrategy( WikiContext context, String error, String
> message )
> - throws RedirectException
> - {
> - if( m_stopAtFirstMatch )
> - {
> - throw new RedirectException( message,
> getRedirectPage(context) );
> + private void checkStrategy( WikiContext context, String error, String
> message ) throws RedirectException {
> + if( m_stopAtFirstMatch ) {
> + throw new RedirectException( message, getRedirectPage(
> context ) );
> }
>
> - Integer score = (Integer)context.getVariable(
> ATTR_SPAMFILTER_SCORE );
> -
> - if( score != null )
> - score = score+1;
> - else
> + Integer score = ( Integer )context.getVariable(
> ATTR_SPAMFILTER_SCORE );
> + if( score != null ) {
> + score = score + 1;
> + } else {
> score = 1;
> + }
>
> context.setVariable( ATTR_SPAMFILTER_SCORE, score );
> }
> +
> /**
> * Parses a list of patterns and returns a Collection of compiled
> Pattern
> * objects.
> @@ -354,27 +352,20 @@ public class SpamFilter
> * @param list
> * @return A Collection of the Patterns that were found from the
> lists.
> */
> - private Collection<Pattern> parseWordList( WikiPage source, String
> list )
> - {
> - ArrayList<Pattern> compiledpatterns = new ArrayList<Pattern>();
> + private Collection< Pattern > parseWordList( WikiPage source, String
> list ) {
> + ArrayList< Pattern > compiledpatterns = new ArrayList< Pattern
> >();
>
> - if( list != null )
> - {
> + if( list != null ) {
> StringTokenizer tok = new StringTokenizer( list, " \t\n" );
>
> - while( tok.hasMoreTokens() )
> - {
> + while( tok.hasMoreTokens() ) {
> String pattern = tok.nextToken();
>
> - try
> - {
> + try {
> compiledpatterns.add( m_compiler.compile( pattern ) );
> - }
> - catch( MalformedPatternException e )
> - {
> - log.debug( "Malformed spam filter pattern "+pattern );
> -
> - source.setAttribute("error", "Malformed spam filter
> pattern "+pattern);
> + } catch( MalformedPatternException e ) {
> + log.debug( "Malformed spam filter pattern " + pattern
> );
> + source.setAttribute("error", "Malformed spam filter
> pattern " + pattern);
> }
> }
> }
> @@ -383,49 +374,35 @@ public class SpamFilter
> }
>
> /**
> - * Takes a MT-Blacklist -formatted blacklist and returns a list of
> compiled
> - * Pattern objects.
> + * Takes a MT-Blacklist -formatted blacklist and returns a list of
> compiled Pattern objects.
> *
> * @param list
> * @return The parsed blacklist patterns.
> */
> - private Collection<Pattern> parseBlacklist( String list )
> - {
> - ArrayList<Pattern> compiledpatterns = new ArrayList<Pattern>();
> -
> - if( list != null )
> - {
> - try
> - {
> - BufferedReader in = new BufferedReader( new
> StringReader(list) );
> + private Collection< Pattern > parseBlacklist( String list ) {
> + ArrayList< Pattern > compiledpatterns = new ArrayList< Pattern
> >();
>
> + if( list != null ) {
> + try {
> + BufferedReader in = new BufferedReader( new
> StringReader(list) );
> String line;
> -
> - while( (line = in.readLine()) != null )
> - {
> + while( (line = in.readLine() ) != null ) {
> line = line.trim();
> if( line.length() == 0 ) continue; // Empty line
> if( line.startsWith("#") ) continue; // It's a comment
>
> - int ws = line.indexOf(' ');
> -
> - if( ws == -1 ) ws = line.indexOf('\t');
> -
> - if( ws != -1 ) line = line.substring(0,ws);
> + int ws = line.indexOf( ' ' );
> + if( ws == -1 ) ws = line.indexOf( '\t' );
> + if( ws != -1 ) line = line.substring( 0, ws );
>
> - try
> - {
> + try {
> compiledpatterns.add( m_compiler.compile( line )
> );
> - }
> - catch( MalformedPatternException e )
> - {
> - log.debug( "Malformed spam filter pattern "+line
> );
> + } catch( MalformedPatternException e ) {
> + log.debug( "Malformed spam filter pattern " +
> line );
> }
> }
> - }
> - catch( IOException e )
> - {
> - log.info("Could not read patterns; returning what I
> got",e);
> + } catch( IOException e ) {
> + log.info( "Could not read patterns; returning what I
> got" , e );
> }
> }
>
> @@ -440,31 +417,27 @@ public class SpamFilter
> * @param content
> * @throws RedirectException
> */
> - private synchronized void checkSinglePageChange( WikiContext context,
> String content, Change change )
> - throws RedirectException
> - {
> + private synchronized void checkSinglePageChange( WikiContext context,
> String content, Change change )
> + throws RedirectException {
> HttpServletRequest req = context.getHttpRequest();
>
> - if( req != null )
> - {
> - String addr = req.getRemoteAddr();
> + if( req != null ) {
> + String addr = HttpUtil.getRemoteAddress( req );
> int hostCounter = 0;
> int changeCounter = 0;
>
> - log.debug("Change is "+change.m_change);
> + log.debug( "Change is " + change.m_change );
>
> - long time = System.currentTimeMillis()-60*1000L; // 1 minute
> + long time = System.currentTimeMillis() - 60*1000L; // 1 minute
>
> - for( Iterator i = m_lastModifications.iterator();
> i.hasNext(); )
> - {
> - Host host = (Host)i.next();
> + for( Iterator< Host > i = m_lastModifications.iterator();
> i.hasNext(); ) {
> + Host host = i.next();
>
> //
> // Check if this item is invalid
> //
> - if( host.getAddedTime() < time )
> - {
> - log.debug("Removed host "+host.getAddress()+" from
> modification queue (expired)");
> + if( host.getAddedTime() < time ) {
> + log.debug( "Removed host " + host.getAddress() + "
> from modification queue (expired)" );
> i.remove();
> continue;
> }
> @@ -473,8 +446,7 @@ public class SpamFilter
> // Check if this IP address has been seen before
> //
>
> - if( host.getAddress().equals(addr) )
> - {
> + if( host.getAddress().equals( addr ) ) {
> hostCounter++;
> }
>
> @@ -482,8 +454,7 @@ public class SpamFilter
> // Check, if this change has been seen before
> //
>
> - if( host.getChange() != null &&
> host.getChange().equals(change) )
> - {
> + if( host.getChange() != null && host.getChange().equals(
> change ) ) {
> changeCounter++;
> }
> }
> @@ -491,74 +462,58 @@ public class SpamFilter
> //
> // Now, let's check against the limits.
> //
> - if( hostCounter >= m_limitSinglePageChanges )
> - {
> + if( hostCounter >= m_limitSinglePageChanges ) {
> Host host = new Host( addr, null );
> -
> m_temporaryBanList.add( host );
>
> String uid = log( context, REJECT,
> REASON_TOO_MANY_MODIFICATIONS, change.m_change );
> - log.info( "SPAM:TooManyModifications ("+uid+"). Added
> host "+addr+" to temporary ban list for doing too many
> modifications/minute" );
> - checkStrategy( context, REASON_TOO_MANY_MODIFICATIONS,
> "Herb says you look like a spammer, and I trust Herb! (Incident code
> "+uid+")" );
> + log.info( "SPAM:TooManyModifications (" + uid + ").
> Added host " + addr + " to temporary ban list for doing too many
> modifications/minute" );
> + checkStrategy( context, REASON_TOO_MANY_MODIFICATIONS,
> "Herb says you look like a spammer, and I trust Herb! (Incident code " +
> uid + ")" );
> }
>
> - if( changeCounter >= m_limitSimilarChanges )
> - {
> + if( changeCounter >= m_limitSimilarChanges ) {
> Host host = new Host( addr, null );
> -
> m_temporaryBanList.add( host );
>
> String uid = log( context, REJECT,
> REASON_SIMILAR_MODIFICATIONS, change.m_change );
> -
> - log.info("SPAM:SimilarModifications ("+uid+"). Added
> host "+addr+" to temporary ban list for doing too many similar
> modifications" );
> + log.info( "SPAM:SimilarModifications (" + uid + ").
> Added host " + addr + " to temporary ban list for doing too many similar
> modifications" );
> checkStrategy( context, REASON_SIMILAR_MODIFICATIONS,
> "Herb says you look like a spammer, and I trust Herb! (Incident code
> "+uid+")");
> }
>
> //
> // Calculate the number of links in the addition.
> //
> -
> - String tstChange = change.toString();
> + String tstChange = change.toString();
> int urlCounter = 0;
> -
> - while( m_matcher.contains(tstChange,m_urlPattern) )
> - {
> + while( m_matcher.contains( tstChange,m_urlPattern ) ) {
> MatchResult m = m_matcher.getMatch();
> -
> tstChange = tstChange.substring( m.endOffset(0) );
> -
> urlCounter++;
> }
>
> - if( urlCounter > m_maxUrls )
> - {
> + if( urlCounter > m_maxUrls ) {
> Host host = new Host( addr, null );
> -
> m_temporaryBanList.add( host );
>
> String uid = log( context, REJECT, REASON_TOO_MANY_URLS,
> change.toString() );
> -
> - log.info("SPAM:TooManyUrls ("+uid+"). Added host
> "+addr+" to temporary ban list for adding too many URLs" );
> - checkStrategy( context, REASON_TOO_MANY_URLS, "Herb says
> you look like a spammer, and I trust Herb! (Incident code "+uid+")" );
> + log.info( "SPAM:TooManyUrls (" + uid + "). Added host "
> + addr + " to temporary ban list for adding too many URLs" );
> + checkStrategy( context, REASON_TOO_MANY_URLS, "Herb says
> you look like a spammer, and I trust Herb! (Incident code " + uid + ")" );
> }
>
> //
> // Check bot trap
> //
> -
> checkBotTrap( context, change );
>
> //
> // Check UTF-8 mangling
> //
> -
> checkUTF8( context, change );
>
> //
> // Do Akismet check. This is good to be the last, because
> this is the most
> // expensive operation.
> //
> -
> checkAkismet( context, change );
>
> m_lastModifications.add( new Host( addr, change ) );
> @@ -573,20 +528,14 @@ public class SpamFilter
> * @param change
> * @throws RedirectException
> */
> - private void checkAkismet( WikiContext context, Change change )
> - throws RedirectException
> - {
> - if( m_akismetAPIKey != null )
> - {
> - if( m_akismet == null )
> - {
> - log.info("Initializing Akismet spam protection.");
> -
> + private void checkAkismet( WikiContext context, Change change )
> throws RedirectException {
> + if( m_akismetAPIKey != null ) {
> + if( m_akismet == null ) {
> + log.info( "Initializing Akismet spam protection." );
> m_akismet = new Akismet( m_akismetAPIKey,
> context.getEngine().getBaseURL() );
>
> - if( !m_akismet.verifyAPIKey() )
> - {
> - log.error("Akismet API key cannot be verified.
> Please check your config.");
> + if( !m_akismet.verifyAPIKey() ) {
> + log.error( "Akismet API key cannot be verified.
> Please check your config." );
> m_akismetAPIKey = null;
> m_akismet = null;
> }
> @@ -598,23 +547,21 @@ public class SpamFilter
> // Akismet will mark all empty statements as spam, so we'll
> just
> // ignore them.
> //
> - if( change.m_adds == 0 && change.m_removals > 0 )
> - {
> + if( change.m_adds == 0 && change.m_removals > 0 ) {
> return;
> }
>
> - if( req != null && m_akismet != null )
> - {
> - log.debug("Calling Akismet to check for spam...");
> + if( req != null && m_akismet != null ) {
> + log.debug( "Calling Akismet to check for spam..." );
>
> StopWatch sw = new StopWatch();
> sw.start();
>
> - String ipAddress = req.getRemoteAddr();
> - String userAgent = req.getHeader("User-Agent");
> + String ipAddress = HttpUtil.getRemoteAddress( req );
> + String userAgent = req.getHeader( "User-Agent" );
> String referrer = req.getHeader( "Referer");
> String permalink = context.getViewURL(
> context.getPage().getName() );
> - String commentType =
> context.getRequestContext().equals(WikiContext.COMMENT) ? "comment" :
> "edit";
> + String commentType =
> context.getRequestContext().equals( WikiContext.COMMENT ) ? "comment" :
> "edit";
> String commentAuthor = context.getCurrentUser().getName();
> String commentAuthorEmail = null;
> String commentAuthorURL = null;
> @@ -631,96 +578,74 @@ public class SpamFilter
> null );
>
> sw.stop();
> + log.debug( "Akismet request done in: " + sw );
>
> - log.debug("Akismet request done in: "+sw);
> -
> - if( isSpam )
> - {
> + if( isSpam ) {
> // Host host = new Host( ipAddress, null );
> -
> // m_temporaryBanList.add( host );
>
> String uid = log( context, REJECT, REASON_AKISMET,
> change.toString() );
> -
> - log.info("SPAM:Akismet ("+uid+"). Akismet thinks
> this change is spam; added host to temporary ban list.");
> -
> - checkStrategy( context, REASON_AKISMET, "Akismet
> tells Herb you're a spammer, Herb trusts Akismet, and I trust Herb!
> (Incident code "+uid+")");
> + log.info( "SPAM:Akismet (" + uid + "). Akismet
> thinks this change is spam; added host to temporary ban list." );
> + checkStrategy( context, REASON_AKISMET, "Akismet
> tells Herb you're a spammer, Herb trusts Akismet, and I trust Herb!
> (Incident code " + uid + ")" );
> }
> }
> }
> }
>
> /**
> - * Returns a static string which can be used to detect spambots which
> - * just wildly fill in all the fields.
> + * Returns a static string which can be used to detect spambots which
> just wildly fill in all the fields.
> *
> - * @return A string
> + * @return A string
> */
> - public static String getBotFieldName()
> - {
> + public static String getBotFieldName() {
> return "submit_auth";
> }
>
> /**
> - * This checks whether an invisible field is available in the
> request, and
> - * whether it's contents are suspected spam.
> + * This checks whether an invisible field is available in the
> request, and whether it's contents are suspected spam.
> *
> - * @param context
> - * @param change
> + * @param context
> + * @param change
> * @throws RedirectException
> */
> - private void checkBotTrap( WikiContext context, Change change )
> throws RedirectException
> - {
> + private void checkBotTrap( WikiContext context, Change change )
> throws RedirectException {
> HttpServletRequest request = context.getHttpRequest();
>
> - if( request != null )
> - {
> + if( request != null ) {
> String unspam = request.getParameter( getBotFieldName() );
> - if( unspam != null && unspam.length() > 0 )
> - {
> + if( unspam != null && unspam.length() > 0 ) {
> String uid = log( context, REJECT, REASON_BOT_TRAP,
> change.toString() );
>
> - log.info("SPAM:BotTrap ("+uid+"). Wildly behaving bot
> detected.");
> -
> - checkStrategy( context, REASON_BOT_TRAP, "Spamming
> attempt detected. (Incident code "+uid+")");
> -
> + log.info( "SPAM:BotTrap (" + uid + "). Wildly behaving
> bot detected." );
> + checkStrategy( context, REASON_BOT_TRAP, "Spamming
> attempt detected. (Incident code " + uid + ")" );
> }
> }
> }
>
> - private void checkUTF8( WikiContext context, Change change ) throws
> RedirectException
> - {
> + private void checkUTF8( WikiContext context, Change change ) throws
> RedirectException {
> HttpServletRequest request = context.getHttpRequest();
>
> - if( request != null )
> - {
> + if( request != null ) {
> String utf8field = request.getParameter( "encodingcheck" );
>
> - if( utf8field != null && !utf8field.equals("\u3041") )
> - {
> + if( utf8field != null && !utf8field.equals( "\u3041" ) ) {
> String uid = log( context, REJECT, REASON_UTF8_TRAP,
> change.toString() );
>
> - log.info("SPAM:UTF8Trap ("+uid+"). Wildly posting dumb
> bot detected.");
> -
> - checkStrategy( context, REASON_UTF8_TRAP, "Spamming
> attempt detected. (Incident code "+uid+")");
> + log.info( "SPAM:UTF8Trap (" + uid + "). Wildly posting
> dumb bot detected." );
> + checkStrategy( context, REASON_UTF8_TRAP, "Spamming
> attempt detected. (Incident code " + uid + ")" );
> }
> }
> }
>
> - /**
> - * Goes through the ban list and cleans away any host which has
> expired from it.
> - */
> - private synchronized void cleanBanList()
> - {
> + /** Goes through the ban list and cleans away any host which has
> expired from it. */
> + private synchronized void cleanBanList() {
> long now = System.currentTimeMillis();
>
> - for( Iterator i = m_temporaryBanList.iterator(); i.hasNext(); )
> - {
> - Host host = (Host)i.next();
> -
> - if( host.getReleaseTime() < now )
> - {
> - log.debug("Removed host "+host.getAddress()+" from
> temporary ban list (expired)");
> + for( Iterator< Host > i = m_temporaryBanList.iterator();
> i.hasNext(); ) {
> + Host host = i.next();
> +
> + if( host.getReleaseTime() < now ) {
> + log.debug( "Removed host " + host.getAddress() + " from
> temporary ban list (expired)" );
> i.remove();
> }
> }
> @@ -732,45 +657,33 @@ public class SpamFilter
> * @param context
> * @throws RedirectException
> */
> -
> - private void checkBanList( WikiContext context, Change change )
> - throws RedirectException
> - {
> + private void checkBanList( WikiContext context, Change change )
> throws RedirectException {
> HttpServletRequest req = context.getHttpRequest();
>
> - if( req != null )
> - {
> - String remote = req.getRemoteAddr();
> -
> + if( req != null ) {
> + String remote = HttpUtil.getRemoteAddress(req);
> long now = System.currentTimeMillis();
>
> - for( Iterator i = m_temporaryBanList.iterator(); i.hasNext();
> )
> - {
> - Host host = (Host)i.next();
> -
> - if( host.getAddress().equals(remote) )
> - {
> - long timeleft = (host.getReleaseTime() - now) / 1000L;
> + for( Iterator< Host > i = m_temporaryBanList.iterator();
> i.hasNext(); ) {
> + Host host = i.next();
>
> - log( context, REJECT, REASON_IP_BANNED_TEMPORARILY,
> change.m_change );
> + if( host.getAddress().equals( remote ) ) {
> + long timeleft = ( host.getReleaseTime() - now ) /
> 1000L;
>
> - checkStrategy( context, REASON_IP_BANNED_TEMPORARILY,
> "You have been temporarily banned from modifying this wiki. ("+timeleft+"
> seconds of ban left)");
> + log( context, REJECT, REASON_IP_BANNED_TEMPORARILY,
> change.m_change );
> + checkStrategy( context, REASON_IP_BANNED_TEMPORARILY,
> "You have been temporarily banned from modifying this wiki. (" + timeleft +
> " seconds of ban left)" );
> }
> }
> }
> -
> }
>
> /**
> - * If the spam filter notices changes in the black list page, it
> will refresh
> - * them automatically.
> + * If the spam filter notices changes in the black list page, it
> will refresh them automatically.
> *
> * @param context
> */
> - private void refreshBlacklists( WikiContext context )
> - {
> - try
> - {
> + private void refreshBlacklists( WikiContext context ) {
> + try {
> WikiPage source = context.getEngine().getPage(
> m_forbiddenWordsPage );
> Attachment att =
> context.getEngine().getAttachmentManager().getAttachmentInfo( context,
> m_blacklist );
>
> @@ -779,62 +692,43 @@ public class SpamFilter
> //
> // Rebuild, if the page or the attachment has changed since.
> //
> - if( source != null )
> - {
> - if( m_spamPatterns == null || m_spamPatterns.isEmpty() ||
> source.getLastModified().after(m_lastRebuild) )
> - {
> + if( source != null ) {
> + if( m_spamPatterns == null || m_spamPatterns.isEmpty() ||
> source.getLastModified().after( m_lastRebuild ) ) {
> rebuild = true;
> }
> }
>
> - if( att != null )
> - {
> - if( m_spamPatterns == null || m_spamPatterns.isEmpty() ||
> att.getLastModified().after(m_lastRebuild) )
> - {
> + if( att != null ) {
> + if( m_spamPatterns == null || m_spamPatterns.isEmpty() ||
> att.getLastModified().after( m_lastRebuild ) ) {
> rebuild = true;
> }
> }
>
> -
> //
> // Do the actual rebuilding. For simplicity's sake, we
> always rebuild the complete
> // filter list regardless of what changed.
> //
> -
> - if( rebuild )
> - {
> + if( rebuild ) {
> m_lastRebuild = new Date();
> -
> m_spamPatterns = parseWordList( source,
> - (source != null) ?
> (String)source.getAttribute( LISTVAR ) : null );
> + ( source != null ) ? (
> String )source.getAttribute( LISTVAR ) : null );
>
> - log.info("Spam filter reloaded - recognizing
> "+m_spamPatterns.size()+" patterns from page "+m_forbiddenWordsPage);
> + log.info( "Spam filter reloaded - recognizing " +
> m_spamPatterns.size() + " patterns from page " + m_forbiddenWordsPage );
>
> - if( att != null )
> - {
> + if( att != null ) {
> InputStream in =
> context.getEngine().getAttachmentManager().getAttachmentStream(att);
> -
> StringWriter out = new StringWriter();
> -
> - FileUtil.copyContents( new
> InputStreamReader(in,"UTF-8"), out );
> -
> - Collection<Pattern> blackList = parseBlacklist(
> out.toString() );
> -
> - log.info("...recognizing additional
> "+blackList.size()+" patterns from blacklist "+m_blacklist);
> -
> + FileUtil.copyContents( new InputStreamReader(
> in,"UTF-8" ), out );
> + Collection< Pattern > blackList = parseBlacklist(
> out.toString() );
> + log.info( "...recognizing additional " +
> blackList.size() + " patterns from blacklist " + m_blacklist );
> m_spamPatterns.addAll( blackList );
> }
> }
> + } catch( IOException ex ) {
> + log.info( "Unable to read attachment data, continuing...",
> ex );
> + } catch( ProviderException ex ) {
> + log.info( "Failed to read spam filter attachment,
> continuing...", ex );
> }
> - catch( IOException ex )
> - {
> - log.info("Unable to read attachment data, continuing...",ex);
> - }
> - catch( ProviderException ex )
> - {
> - log.info("Failed to read spam filter attachment,
> continuing...",ex);
> - }
> -
> }
>
> /**
> @@ -845,45 +739,39 @@ public class SpamFilter
> * @param change
> * @throws RedirectException
> */
> - private void checkPatternList(WikiContext context, String content,
> Change change) throws RedirectException
> - {
> + private void checkPatternList( WikiContext context, String content,
> Change change ) throws RedirectException {
> //
> // If we have no spam patterns defined, or we're trying to save
> // the page containing the patterns, just return.
> //
> - if( m_spamPatterns == null || context.getPage().getName().equals(
> m_forbiddenWordsPage ) )
> - {
> + if( m_spamPatterns == null || context.getPage().getName().equals(
> m_forbiddenWordsPage ) ) {
> return;
> }
>
> String ch = change.toString();
> -
> - if( context.getHttpRequest() != null )
> - ch += context.getHttpRequest().getRemoteAddr();
> + if( context.getHttpRequest() != null ) {
> + ch += HttpUtil.getRemoteAddress( context.getHttpRequest() );
> + }
>
> - for( Pattern p : m_spamPatterns )
> - {
> + for( Pattern p : m_spamPatterns ) {
> // log.debug("Attempting to match page contents with
> "+p.getPattern());
>
> - if( m_matcher.contains( ch, p ) )
> - {
> + if( m_matcher.contains( ch, p ) ) {
> //
> // Spam filter has a match.
> //
> - String uid = log( context, REJECT,
> REASON_REGEXP+"("+p.getPattern()+")", ch);
> + String uid = log( context, REJECT, REASON_REGEXP + "(" +
> p.getPattern() + ")", ch );
>
> - log.info("SPAM:Regexp ("+uid+"). Content matches the
> spam filter '"+p.getPattern()+"'");
> -
> - checkStrategy( context, REASON_REGEXP, "Herb says
> '"+p.getPattern()+"' is a bad spam word and I trust Herb! (Incident code
> "+uid+")");
> + log.info( "SPAM:Regexp (" + uid + "). Content matches
> the spam filter '" + p.getPattern() + "'" );
> + checkStrategy( context, REASON_REGEXP, "Herb says '" +
> p.getPattern() + "' is a bad spam word and I trust Herb! (Incident code " +
> uid + ")" );
> }
> }
> }
>
> - private void checkPatternList(WikiContext context, String content,
> String change ) throws RedirectException
> - {
> + private void checkPatternList( WikiContext context, String content,
> String change ) throws RedirectException {
> Change c = new Change();
> c.m_change = change;
> - checkPatternList(context,content,c);
> + checkPatternList( context, content, c );
> }
>
> /**
> @@ -893,8 +781,7 @@ public class SpamFilter
> * @param newText
> * @return Empty string, if there is no change.
> */
> - private static Change getChange( WikiContext context, String newText )
> - {
> + private static Change getChange( WikiContext context, String newText
> ) {
> WikiPage page = context.getPage();
> StringBuffer change = new StringBuffer();
> WikiEngine engine = context.getEngine();
> @@ -902,62 +789,51 @@ public class SpamFilter
>
> Change ch = new Change();
>
> - try
> - {
> - String oldText = engine.getPureText(page.getName(),
> WikiProvider.LATEST_VERSION);
> -
> - String[] first = Diff.stringToArray(oldText);
> - String[] second = Diff.stringToArray(newText);
> - Revision rev = Diff.diff(first, second, new MyersDiff());
> + try {
> + String oldText = engine.getPureText( page.getName(),
> WikiProvider.LATEST_VERSION );
> +
> + String[] first = Diff.stringToArray( oldText );
> + String[] second = Diff.stringToArray( newText );
> + Revision rev = Diff.diff( first, second, new MyersDiff() );
>
> - if( rev == null || rev.size() == 0 )
> - {
> + if( rev == null || rev.size() == 0 ) {
> return ch;
> }
>
> - for( int i = 0; i < rev.size(); i++ )
> - {
> - Delta d = rev.getDelta(i);
> + for( int i = 0; i < rev.size(); i++ ) {
> + Delta d = rev.getDelta( i );
>
> - if( d instanceof AddDelta )
> - {
> + if( d instanceof AddDelta ) {
> d.getRevised().toString( change, "", "\r\n" );
> ch.m_adds++;
> - }
> - else if( d instanceof ChangeDelta )
> - {
> +
> + } else if( d instanceof ChangeDelta ) {
> d.getRevised().toString( change, "", "\r\n" );
> ch.m_adds++;
> - }
> - else if( d instanceof DeleteDelta )
> - {
> +
> + } else if( d instanceof DeleteDelta ) {
> ch.m_removals++;
> }
> }
> - }
> - catch (DifferentiationFailedException e)
> - {
> + } catch( DifferentiationFailedException e ) {
> log.error( "Diff failed", e );
> }
>
> //
> // Don't forget to include the change note, too
> //
> - String changeNote =
> (String)page.getAttribute(WikiPage.CHANGENOTE);
> + String changeNote = ( String )page.getAttribute(
> WikiPage.CHANGENOTE );
>
> - if( changeNote != null )
> - {
> - change.append("\r\n");
> - change.append(changeNote);
> + if( changeNote != null ) {
> + change.append( "\r\n" );
> + change.append( changeNote );
> }
>
> //
> // And author as well
> //
> -
> - if( page.getAuthor() != null )
> - {
> - change.append("\r\n"+page.getAuthor());
> + if( page.getAuthor() != null ) {
> + change.append( "\r\n" + page.getAuthor() );
> }
>
> ch.m_change = change.toString();
> @@ -970,20 +846,16 @@ public class SpamFilter
> * @param context
> * @return True, if this users should be ignored.
> */
> - private boolean ignoreThisUser(WikiContext context)
> - {
> - if( context.hasAdminPermissions() )
> - {
> + private boolean ignoreThisUser( WikiContext context ) {
> + if( context.hasAdminPermissions() ) {
> return true;
> }
>
> - if( m_ignoreAuthenticated &&
> context.getWikiSession().isAuthenticated() )
> - {
> + if( m_ignoreAuthenticated &&
> context.getWikiSession().isAuthenticated() ) {
> return true;
> }
>
> - if( context.getVariable("captcha") != null )
> - {
> + if( context.getVariable( "captcha" ) != null ) {
> return true;
> }
>
> @@ -995,32 +867,28 @@ public class SpamFilter
> *
> * @return A random string
> */
> - private static String getUniqueID()
> - {
> - StringBuffer sb = new StringBuffer();
> + private static String getUniqueID() {
> + StringBuilder sb = new StringBuilder();
> Random rand = new Random();
>
> - for( int i = 0; i < 6; i++ )
> - {
> - char x = (char)('A'+rand.nextInt(26));
> -
> - sb.append(x);
> + for( int i = 0; i < 6; i++ ) {
> + char x = ( char )( 'A' + rand.nextInt( 26 ) );
> + sb.append( x );
> }
>
> return sb.toString();
> }
>
> /**
> - * Returns a page to which we shall redirect, based on the current
> value
> - * of the "captcha" parameter.
> + * Returns a page to which we shall redirect, based on the current
> value of the "captcha" parameter.
> *
> * @param ctx WikiContext
> * @return An URL to redirect to
> */
> - private String getRedirectPage( WikiContext ctx )
> - {
> - if( m_useCaptcha )
> - return ctx.getURL( WikiContext.NONE, "Captcha.jsp",
> "page="+ctx.getEngine().encodeName(ctx.getPage().getName()) );
> + private String getRedirectPage( WikiContext ctx ) {
> + if( m_useCaptcha ) {
> + return ctx.getURL( WikiContext.NONE, "Captcha.jsp",
> "page="+ctx.getEngine().encodeName( ctx.getPage().getName() ) );
> + }
>
> return ctx.getURL( WikiContext.VIEW, m_errorPage );
> }
> @@ -1033,16 +901,12 @@ public class SpamFilter
> * @return False, if this userprofile is suspect and should not be
> allowed to be added.
> * @since 2.6.1
> */
> - public boolean isValidUserProfile( WikiContext context, UserProfile
> profile )
> - {
> - try
> - {
> + public boolean isValidUserProfile( WikiContext context, UserProfile
> profile ) {
> + try {
> checkPatternList( context, profile.getEmail(),
> profile.getEmail() );
> checkPatternList( context, profile.getFullname(),
> profile.getFullname() );
> checkPatternList( context, profile.getLoginName(),
> profile.getLoginName() );
> - }
> - catch( RedirectException e )
> - {
> + } catch( RedirectException e ) {
> log.info("Detected attempt to create a spammer user account
> (see above for rejection reason)");
> return false;
> }
> @@ -1051,57 +915,47 @@ public class SpamFilter
> }
>
> /**
> - * This method is used to calculate an unique code when submitting
> the page
> - * to detect edit conflicts. It currently incorporates the
> last-modified
> - * date of the page, and the IP address of the submitter.
> + * This method is used to calculate an unique code when submitting
> the page to detect edit conflicts.
> + * It currently incorporates the last-modified date of the page, and
> the IP address of the submitter.
> *
> * @param page The WikiPage under edit
> * @param request The HTTP Request
> * @since 2.6
> * @return A hash value for this page and session
> */
> - public static final String getSpamHash( WikiPage page,
> HttpServletRequest request )
> - {
> + public static final String getSpamHash( WikiPage page,
> HttpServletRequest request ) {
> long lastModified = 0;
>
> - if( page.getLastModified() != null )
> + if( page.getLastModified() != null ) {
> lastModified = page.getLastModified().getTime();
> -
> - long remote = request.getRemoteAddr().hashCode();
> + }
> + long remote = HttpUtil.getRemoteAddress( request ).hashCode();
>
> return Long.toString( lastModified ^ remote );
> }
>
> /**
> - * Returns the name of the hash field to be used in this request.
> - * The value is unique per session, and once the session has expired,
> - * you cannot edit anymore.
> + * Returns the name of the hash field to be used in this request.
> The value is unique per session, and once
> + * the session has expired, you cannot edit anymore.
> *
> * @param request The page request
> * @return The name to be used in the hash field
> * @since 2.6
> */
> -
> - public static final String getHashFieldName( HttpServletRequest
> request )
> - {
> + public static final String getHashFieldName( HttpServletRequest
> request ) {
> String hash = null;
>
> - if( request.getSession() != null )
> - {
> - hash = (String)request.getSession().getAttribute("_hash");
> + if( request.getSession() != null ) {
> + hash = ( String )request.getSession().getAttribute( "_hash" );
>
> - if( hash == null )
> - {
> + if( hash == null ) {
> hash = c_hashName;
> -
> request.getSession().setAttribute( "_hash", hash );
> }
> }
>
> - if( c_hashName == null || c_lastUpdate <
> (System.currentTimeMillis() - HASH_DELAY*60*60*1000) )
> - {
> + if( c_hashName == null || c_lastUpdate < (
> System.currentTimeMillis() - HASH_DELAY * 60 * 60 * 1000 ) ) {
> c_hashName = getUniqueID().toLowerCase();
> -
> c_lastUpdate = System.currentTimeMillis();
> }
>
> @@ -1110,13 +964,12 @@ public class SpamFilter
>
>
> /**
> - * This method checks if the hash value is still valid, i.e. if it
> exists at all. This
> - * can occur in two cases: either this is a spam bot which is not
> adaptive, or it is
> - * someone who has been editing one page for too long, and their
> session has expired.
> + * This method checks if the hash value is still valid, i.e. if it
> exists at all. This can occur in two cases:
> + * either this is a spam bot which is not adaptive, or it is someone
> who has been editing one page for too long,
> + * and their session has expired.
> * <p>
> - * This method puts a redirect to the http response field to page
> "SessionExpired"
> - * and logs the incident in the spam log (it may or may not be spam,
> but it's rather likely
> - * that it is).
> + * This method puts a redirect to the http response field to page
> "SessionExpired" and logs the incident in
> + * the spam log (it may or may not be spam, but it's rather likely
> that it is).
> *
> * @param context The WikiContext
> * @param pageContext The JSP PageContext.
> @@ -1124,22 +977,16 @@ public class SpamFilter
> * @throws IOException If redirection fails
> * @since 2.6
> */
> - public static final boolean checkHash( WikiContext context,
> PageContext pageContext )
> - throws IOException
> - {
> + public static final boolean checkHash( WikiContext context,
> PageContext pageContext ) throws IOException {
> String hashName = getHashFieldName(
> (HttpServletRequest)pageContext.getRequest() );
>
> - if( pageContext.getRequest().getParameter(hashName) == null )
> - {
> - if( pageContext.getAttribute( hashName ) == null )
> - {
> + if( pageContext.getRequest().getParameter(hashName) == null ) {
> + if( pageContext.getAttribute( hashName ) == null ) {
> Change change = getChange( context,
> EditorManager.getEditedText( pageContext ) );
> -
> log( context, REJECT, "MissingHash", change.m_change );
>
> - String redirect =
> context.getURL(WikiContext.VIEW,"SessionExpired");
> -
> ((HttpServletResponse)pageContext.getResponse()).sendRedirect( redirect );
> -
> + String redirect = context.getURL(
> WikiContext.VIEW,"SessionExpired" );
> + ( ( HttpServletResponse )pageContext.getResponse()
> ).sendRedirect( redirect );
> return false;
> }
> }
> @@ -1148,89 +995,81 @@ public class SpamFilter
> }
>
> /**
> - * This helper method adds all the input fields to your editor that
> the SpamFilter requires
> - * to check for spam. This <i>must</i> be in your editor form if
> you intend to use
> - * the SpamFilter.
> + * This helper method adds all the input fields to your editor that
> the SpamFilter requires
> + * to check for spam. This <i>must</i> be in your editor form if you
> intend to use the SpamFilter.
> *
> - * @param pageContext The PageContext
> - * @return A HTML string which contains input fields for the
> SpamFilter.
> + * @param pageContext The PageContext
> + * @return A HTML string which contains input fields for the
> SpamFilter.
> */
> - public static final String insertInputFields( PageContext pageContext
> )
> - {
> - WikiContext ctx = WikiContext.findContext(pageContext);
> + public static final String insertInputFields( PageContext pageContext
> ) {
> + WikiContext ctx = WikiContext.findContext( pageContext );
> WikiEngine engine = ctx.getEngine();
>
> - StringBuffer sb = new StringBuffer();
> - if (engine.getContentEncoding().equals("UTF-8"))
> - {
> - sb.append("<input name='encodingcheck' type='hidden'
> value='\u3041' />\n");
> + StringBuilder sb = new StringBuilder();
> + if( engine.getContentEncoding().equals( "UTF-8" ) ) {
> + sb.append( "<input name='encodingcheck' type='hidden'
> value='\u3041' />\n" );
> }
>
> return sb.toString();
> }
> +
> /**
> * A local class for storing host information.
> *
> * @since
> */
> - private class Host
> - {
> - private long m_addedTime = System.currentTimeMillis();
> - private long m_releaseTime;
> - private String m_address;
> - private Change m_change;
> + private class Host {
> +
> + private long m_addedTime = System.currentTimeMillis();
> + private long m_releaseTime;
> + private String m_address;
> + private Change m_change;
>
> - public String getAddress()
> - {
> + public String getAddress() {
> return m_address;
> }
>
> - public long getReleaseTime()
> - {
> + public long getReleaseTime() {
> return m_releaseTime;
> }
>
> - public long getAddedTime()
> - {
> + public long getAddedTime() {
> return m_addedTime;
> }
>
> - public Change getChange()
> - {
> + public Change getChange() {
> return m_change;
> }
>
> - public Host( String ipaddress, Change change )
> - {
> + public Host( String ipaddress, Change change ) {
> m_address = ipaddress;
> m_change = change;
> -
> m_releaseTime = System.currentTimeMillis() + m_banTime * 60 *
> 1000L;
> }
> +
> }
>
> - private static class Change
> - {
> + private static class Change {
> +
> public String m_change;
> public int m_adds;
> public int m_removals;
>
> - public String toString()
> - {
> + public String toString() {
> return m_change;
> }
>
> - public boolean equals(Object o)
> - {
> - if( o instanceof Change )
> - return m_change.equals( ((Change)o).m_change);
> -
> + public boolean equals( Object o ) {
> + if( o instanceof Change ) {
> + return m_change.equals( ( ( Change )o ).m_change );
> + }
> return false;
> }
>
> - public int hashCode()
> - {
> - return m_change.hashCode()+17;
> + public int hashCode() {
> + return m_change.hashCode() + 17;
> }
> +
> }
> +
> }
>
> Modified:
> jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/util/HttpUtil.java
> URL:
> http://svn.apache.org/viewvc/jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/util/HttpUtil.java?rev=1546452&r1=1546451&r2=1546452&view=diff
>
> ==============================================================================
> ---
> jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/util/HttpUtil.java
> (original)
> +++
> jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/util/HttpUtil.java
> Thu Nov 28 19:59:11 2013
> @@ -26,25 +26,35 @@ import java.util.Date;
> import javax.servlet.http.Cookie;
> import javax.servlet.http.HttpServletRequest;
>
> +import org.apache.commons.lang.StringUtils;
> import org.apache.log4j.Logger;
> -
> import org.apache.wiki.WikiPage;
>
> +
> /**
> * Contains useful utilities for some common HTTP tasks.
> *
> * @since 2.1.61.
> */
> -public final class HttpUtil
> -{
> +public final class HttpUtil {
> +
> static Logger log = Logger.getLogger( HttpUtil.class );
>
> + /** Private constructor to prevent direct instantiation. */
> + private HttpUtil() {
> + }
> +
> /**
> - * Private constructor to prevent direct instantiation.
> + * returns the remote address by looking into {@code x-forwarded-for}
> header or, if unavailable,
> + * into {@link HttpServletRequest#getRemoteAddr()}.
> + *
> + * @param req http request
> + * @return remote address associated to the request.
> */
> - private HttpUtil()
> - {
> - }
> + public static String getRemoteAddress( HttpServletRequest req ) {
> + return StringUtils.isNotEmpty ( req.getHeader(
> "x-forwarded-for" ) ) ? req.getHeader( "x-forwarded-for" ) :
> +
> req.getRemoteAddr();
> + }
>
> /**
> * Attempts to retrieve the given cookie value from the request.
> @@ -58,23 +68,17 @@ public final class HttpUtil
> * @return Value of the cookie, or null, if there is no such cookie.
> */
>
> - public static String retrieveCookieValue( HttpServletRequest request,
> String cookieName )
> - {
> + public static String retrieveCookieValue( HttpServletRequest request,
> String cookieName ) {
> Cookie[] cookies = request.getCookies();
>
> - if( cookies != null )
> - {
> - for( int i = 0; i < cookies.length; i++ )
> - {
> - if( cookies[i].getName().equals( cookieName ) )
> - {
> + if( cookies != null ) {
> + for( int i = 0; i < cookies.length; i++ ) {
> + if( cookies[i].getName().equals( cookieName ) ) {
> String value = cookies[i].getValue();
> - if ( value.length() == 0 )
> - {
> + if( value.length() == 0 ) {
> return null;
> }
> - if ( value.charAt( 0 ) == '"' && value.charAt(
> value.length() - 1 ) == '"')
> - {
> + if( value.charAt( 0 ) == '"' && value.charAt(
> value.length() - 1 ) == '"' ) {
> value = value.substring( 1, value.length() - 1 );
> }
> return value;
> @@ -93,9 +97,8 @@ public final class HttpUtil
> * @param p The page for which the ETag should be created.
> * @return A String depiction of an ETag.
> */
> - public static String createETag( WikiPage p )
> - {
> - return Long.toString(p.getName().hashCode() ^
> p.getLastModified().getTime());
> + public static String createETag( WikiPage p ) {
> + return Long.toString( p.getName().hashCode() ^
> p.getLastModified().getTime() );
> }
>
> /**
> @@ -104,9 +107,7 @@ public final class HttpUtil
> * @param page the wiki page to check for
> * @return the result of the check
> */
> - public static boolean checkFor304( HttpServletRequest req,
> - WikiPage page )
> - {
> + public static boolean checkFor304( HttpServletRequest req, WikiPage
> page ) {
> //
> // We'll do some handling for CONDITIONAL GET (and return a 304)
> // If the client has set the following headers, do not try for a
> 304.
> @@ -115,13 +116,10 @@ public final class HttpUtil
> // cache-control: no-cache
> //
>
> - if( "no-cache".equalsIgnoreCase(req.getHeader("Pragma"))
> - ||
> "no-cache".equalsIgnoreCase(req.getHeader("cache-control")))
> - {
> + if( "no-cache".equalsIgnoreCase( req.getHeader( "Pragma" ) )
> + || "no-cache".equalsIgnoreCase( req.getHeader(
> "cache-control" ) ) ) {
> // Wants specifically a fresh copy
> - }
> - else
> - {
> + } else {
> //
> // HTTP 1.1 ETags go first
> //
> @@ -129,8 +127,7 @@ public final class HttpUtil
>
> String eTag = req.getHeader( "If-None-Match" );
>
> - if( eTag != null && eTag.equals(thisTag) )
> - {
> + if( eTag != null && eTag.equals(thisTag) ) {
> return true;
> }
>
> @@ -140,45 +137,33 @@ public final class HttpUtil
> DateFormat rfcDateFormat = new SimpleDateFormat("EEE, dd MMM
> yyyy HH:mm:ss z");
> Date lastModified = page.getLastModified();
>
> - try
> - {
> - long ifModifiedSince =
> req.getDateHeader("If-Modified-Since");
> + try {
> + long ifModifiedSince = req.getDateHeader(
> "If-Modified-Since" );
>
> //log.info("ifModifiedSince:"+ifModifiedSince);
> - if( ifModifiedSince != -1 )
> - {
> + if( ifModifiedSince != -1 ) {
> long lastModifiedTime = lastModified.getTime();
>
> //log.info("lastModifiedTime:" + lastModifiedTime);
> - if( lastModifiedTime <= ifModifiedSince )
> - {
> + if( lastModifiedTime <= ifModifiedSince ) {
> return true;
> }
> - }
> - else
> - {
> - try
> - {
> + } else {
> + try {
> String s = req.getHeader("If-Modified-Since");
>
> - if( s != null )
> - {
> + if( s != null ) {
> Date ifModifiedSinceDate =
> rfcDateFormat.parse(s);
> //log.info("ifModifiedSinceDate:" +
> ifModifiedSinceDate);
> - if( lastModified.before(ifModifiedSinceDate) )
> - {
> + if( lastModified.before(ifModifiedSinceDate)
> ) {
> return true;
> }
> }
> - }
> - catch (ParseException e)
> - {
> + } catch (ParseException e) {
> log.warn(e.getLocalizedMessage(), e);
> }
> }
> - }
> - catch( IllegalArgumentException e )
> - {
> + } catch( IllegalArgumentException e ) {
> // Illegal date/time header format.
> // We fail quietly, and return false.
> // FIXME: Should really move to ETags.
> @@ -191,29 +176,27 @@ public final class HttpUtil
> /**
> * Attempts to form a valid URI based on the string given. Currently
> * it can guess email addresses (mailto:). If nothing else is
> given,
> - * it assumes it to be a http:// url.
> + * it assumes it to be an http:// url.
> *
> * @param uri URI to take a poke at
> * @return Possibly a valid URI
> * @since 2.2.8
> */
> - public static String guessValidURI( String uri )
> - {
> - if( uri.indexOf('@') != -1 )
> - {
> - if( !uri.startsWith("mailto:") )
> - {
> + public static String guessValidURI( String uri ) {
> + if( uri.indexOf( '@' ) != -1 ) {
> + if( !uri.startsWith( "mailto:" ) ) {
> // Assume this is an email address
> -
> - uri = "mailto:"+uri;
> + uri = "mailto:" + uri;
> }
> - }
> - else if( uri.length() > 0 && !((uri.startsWith("http://") ||
> uri.startsWith("https://")) ))
> - {
> - uri = "http://"+uri;
> + } else if( notBeginningWithHttpOrHttps( uri ) ) {
> + uri = "http://" + uri;
> }
>
> return uri;
> }
>
> + static boolean notBeginningWithHttpOrHttps( String uri ) {
> + return uri.length() > 0 && !( ( uri.startsWith("http://"
> ) || uri.startsWith( "https://" ) ) );
> + }
> +
> }
>
>
>