Author: ajaquith
Date: Wed Jan 6 16:43:50 2010
New Revision: 896518
URL: http://svn.apache.org/viewvc?rev=896518&view=rev
Log:
Minor refactoring to content-inspection package to better support multi-field
inspections.
Removed:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/CaptchaInspector.java
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/AkismetInspector.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/BanListInspector.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/BotTrapInspector.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Change.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/ChangeRateInspector.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Inspection.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/InspectionInterruptedException.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/InspectionPlan.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Inspector.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/LinkCountInspector.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/PatternInspector.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/ReputationManager.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/SpamInspectionFactory.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/UserInspector.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/filters/SpamFilter.java
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/InspectionTest.java
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/ReputationManagerTest.java
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/SpamInspectionFactoryTest.java
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/AkismetInspector.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/AkismetInspector.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/AkismetInspector.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/AkismetInspector.java
Wed Jan 6 16:43:50 2010
@@ -32,17 +32,24 @@
{
m_akismetAPIKey = TextUtil.getStringProperty( config.getProperties(),
PROP_AKISMET_API_KEY, m_akismetAPIKey );
}
+
+ /**
+ * Always returns {...@link Scope#REQUEST}.
+ */
+ public Scope getScope()
+ {
+ return Scope.REQUEST;
+ }
/**
* Returns {...@link Finding.Result#FAILED} if Akismet determines the
change is
* spam; {...@code null} otherwise.
* @param inspection the current Inspection
- * @param content the content that is being inspected
- * @param change the subset of the content that represents the added or
+ * @param change the current contents, plus content that represents the
added or
* deleted text since the last change
* @return {...@link Finding.Result#FAILED} if the test fails; {...@code
null} otherwise
*/
- public Finding[] inspect( Inspection inspection, String content, Change
change )
+ public Finding[] inspect( Inspection inspection, Change change )
{
WikiContext context = inspection.getContext();
HttpServletRequest req = context.getHttpRequest();
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/BanListInspector.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/BanListInspector.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/BanListInspector.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/BanListInspector.java
Wed Jan 6 16:43:50 2010
@@ -15,6 +15,14 @@
*/
public class BanListInspector implements Inspector
{
+ /**
+ * Always returns {...@link Scope#REQUEST}.
+ */
+ public Scope getScope()
+ {
+ return Scope.REQUEST;
+ }
+
public void initialize( InspectionPlan config )
{
}
@@ -23,12 +31,11 @@
* Returns {...@link Finding.Result#FAILED} if the IP address is banned;
* {...@code null} otherwise.
* @param inspection the current Inspection
- * @param content the content that is being inspected
- * @param change the subset of the content that represents the added or
+ * @param change the current contents, plus content that represents the
added or
* deleted text since the last change
* @return {...@link Finding.Result#FAILED} if the test fails; {...@code
null} otherwise
*/
- public Finding[] inspect( Inspection inspection, String content, Change
change )
+ public Finding[] inspect( Inspection inspection, Change change )
{
ReputationManager banList =
inspection.getPlan().getReputationManager();
WikiContext context = inspection.getContext();
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/BotTrapInspector.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/BotTrapInspector.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/BotTrapInspector.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/BotTrapInspector.java
Wed Jan 6 16:43:50 2010
@@ -24,6 +24,14 @@
/** Request parameter containing the encoded payload. */
public static final String REQ_SPAM_PARAM = "__wikiCheck";
+ /**
+ * Always returns {...@link Scope#REQUEST}.
+ */
+ public Scope getScope()
+ {
+ return Scope.REQUEST;
+ }
+
public void initialize( InspectionPlan config )
{
}
@@ -32,12 +40,11 @@
* Returns {...@link Finding.Result#FAILED} if any of the spam parameters
are invalid;
* {...@code null} otherwise.
* @param inspection the current Inspection
- * @param content the content that is being inspected
- * @param change the subset of the content that represents the added or
+ * @param change the current contents, plus content that represents the
added or
* deleted text since the last change
* @return {...@link Finding.Result#FAILED} if the test fails; {...@code
null} otherwise
*/
- public Finding[] inspect( Inspection inspection, String content, Change
change )
+ public Finding[] inspect( Inspection inspection, Change change )
{
WikiContext context = inspection.getContext();
HttpServletRequest request = context.getHttpRequest();
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Change.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Change.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Change.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Change.java
Wed Jan 6 16:43:50 2010
@@ -11,12 +11,16 @@
import org.apache.wiki.api.WikiPage;
/**
- * Embodies the differences between two Strings, or between a proposed page
text
- * and the page's current value. This class is immutable and therefore
+ * Embodies the differences between two Strings, or between a proposed text
+ * and current value for a field. This class is immutable and therefore
* thread-safe.
*/
public class Change
{
+ private final String m_name;
+
+ private final String m_value;
+
private final String m_change;
private final int m_adds;
@@ -27,23 +31,25 @@
* Convenience method that returns a Change object representing a new text
* string. String {...@code newText} will be represented as a single add.
*
+ * @param name the name of the field that is being changed
* @param newText the new text
* @return the Change object
*/
- public static Change getChange( String newText )
+ public static Change getChange( String name, String newText )
{
- return new Change( 1, 0, newText );
+ return new Change( name, newText, 1, 0, newText );
}
/**
* Compares a proposed (new) text string against an existing (old) String,
* and returns a Change object representing any differences between the
two.
*
+ * @param name the name of the field that is being changed
* @param oldText the old text
* @param newText the new text
* @return the change, or the empty string if there is no difference
*/
- public static Change getChange( String oldText, String newText ) throws
DifferentiationFailedException
+ public static Change getChange( String name, String oldText, String
newText ) throws DifferentiationFailedException
{
if( oldText == null || newText == null )
{
@@ -57,7 +63,7 @@
if( rev == null || rev.size() == 0 )
{
- return new Change( 0, 0, null );
+ return new Change( name, newText, 0, 0, null );
}
int adds = 0;
@@ -82,13 +88,18 @@
removals++;
}
}
- return new Change( adds, removals, changes.toString() );
+ return new Change( name, newText, adds, removals, changes.toString() );
+ }
+
+ public String getName()
+ {
+ return m_name;
}
/**
* Compares a proposed text String for a page against the page's current
* content, and returns a Change object representing any differences
between
- * the two.
+ * the two. The field's name is {...@code page}.
*
* @param context the wiki context containing the page. This must be a
* page-related WikiContext
@@ -122,12 +133,14 @@
}
}
- return getChange( changes.toString(), newText );
+ return getChange( "page", changes.toString(), newText );
}
- private Change( int adds, int removals, String change )
+ private Change( String name, String newText, int adds, int removals,
String change )
{
super();
+ m_name = name;
+ m_value = newText;
m_adds = adds;
m_removals = removals;
m_change = change;
@@ -136,7 +149,7 @@
public boolean equals( Object o )
{
if( o instanceof Change )
- return m_change.equals( ((Change) o).m_change );
+ return m_name.equals( ((Change) o).m_name ) && m_change.equals(
((Change) o).m_change );
return false;
}
@@ -156,6 +169,15 @@
return m_removals;
}
+ /**
+ * Returns the current (i.e., new) value of the Change.
+ * @return the current value
+ */
+ public String getValue()
+ {
+ return m_value;
+ }
+
public int hashCode()
{
return m_change.hashCode() + 17;
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/ChangeRateInspector.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/ChangeRateInspector.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/ChangeRateInspector.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/ChangeRateInspector.java
Wed Jan 6 16:43:50 2010
@@ -38,6 +38,14 @@
*/
private int m_limitSimilarChanges = 2;
+ /**
+ * Always returns {...@link Scope#FIELD}.
+ */
+ public Scope getScope()
+ {
+ return Scope.FIELD;
+ }
+
public void initialize( InspectionPlan config )
{
Properties props = config.getProperties();
@@ -45,7 +53,7 @@
m_limitSimilarChanges = TextUtil.getIntegerProperty( props,
PROP_SIMILARCHANGES, m_limitSimilarChanges );
- log.info( "# Spam filter initialized. Temporary ban time " +
config.getReputationManager().getBanTime()
+ log.info( "Spam filter initialized. Temporary ban time " +
config.getReputationManager().getBanTime()
+ " mins, max page changes/minute: " +
m_limitSinglePageChanges );
}
@@ -53,12 +61,11 @@
* Returns {...@link Finding.Result#FAILED} if the user has recently
submitted too many
* aggregate or identical changes; {...@code null} otherwise.
* @param inspection the current Inspection
- * @param content the content that is being inspected
- * @param change the subset of the content that represents the added or
+ * @param change the current contents, plus content that represents the
added or
* deleted text since the last change
* @return {...@link Finding.Result#FAILED} if the test fails; {...@code
null} otherwise
*/
- public Finding[] inspect( Inspection inspection, String content, Change
change )
+ public Finding[] inspect( Inspection inspection, Change change )
{
HttpServletRequest req = inspection.getContext().getHttpRequest();
if( req == null )
@@ -81,7 +88,7 @@
}
// Has this change been seen before?
- if( host.getChange() != null && host.getChange().equals( change ) )
+ if( host.getChange() != null && host.getChange().equals(
change.getChange() ) )
{
changeCounter++;
}
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Inspection.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Inspection.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Inspection.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Inspection.java
Wed Jan 6 16:43:50 2010
@@ -4,6 +4,7 @@
import org.apache.wiki.WikiContext;
import org.apache.wiki.api.WikiPage;
+import org.apache.wiki.content.inspect.Inspector.Scope;
import org.apache.wiki.log.Logger;
import org.apache.wiki.log.LoggerFactory;
import org.apache.wiki.util.TextUtil;
@@ -165,69 +166,64 @@
}
/**
- * Executes the chain of Inspector objects for a supplied content String
- * and, optionally, the {...@link Change} object associated with it. All
scores
- * are initially reset to zero when this method executes.
- *
- * @param content the content String. If {...@code null}, this method
returns
- * silently.
- * @param change the Change represented by {...@code content}, relative to
a
- * previous version. If this parameter is {...@code null}, the
text
- * is considered "all new," and a Change object will be created
- * by calling {...@link Change#getChange(String)}.
+ * Executes the chain of Inspector objects for a supplied number of
+ * {...@link Change} objects. All scores are initially reset to zero when
this
+ * method executes. The Inspectors with {...@link Scope#REQUEST} execute
first,
+ * in order. Then the Inspectors with {...@link Scope#FIELD} execute, in
order,
+ * once per Target.
+ *
+ * @param changes one or more field changes; that is, a field-name,
+ * content and content-change tuple. If {...@code null}, this
method will
+ * execute only the Inspectors that have scope of
+ * {...@link Scope#REQUEST}.
*/
- public void inspect( String content, Change change )
+ public void inspect( Change... changes )
{
- if( content == null )
- {
- return;
- }
- if( change == null )
- {
- change = Change.getChange( content );
- }
-
m_scores.clear();
m_findings.clear();
Inspector[] inspectors = m_plan.getInspectors();
- InspectionListener currentListener = null;
+
try
{
+ // Execute the request-scoped inspectors
for( Inspector inspector : inspectors )
{
- float weight = m_plan.getWeight( inspector );
- Finding[] findings = inspector.inspect( this, content, change
);
- if( findings != null )
+ if( inspector.getScope() == Scope.REQUEST )
+ {
+ Finding[] findings = inspector.inspect( this, null );
+ processFindings( inspector, findings );
+ }
+ }
+
+ if( changes == null )
+ {
+ return;
+ }
+
+ // Execute the field-scoped inspectors
+ for( Change change : changes )
+ {
+ for( Inspector inspector : inspectors )
{
- for( Finding finding : findings )
+ if( inspector.getScope() == Scope.FIELD )
{
- // Increase/decrease score here
- Topic topic = finding.getTopic();
- updateScore( topic, finding, weight );
-
- // Notify any listeners that the score has changed
- List<InspectionListener> listeners = m_listeners.get(
topic );
- if( listeners != null )
- {
- for( InspectionListener listener : listeners )
- {
- currentListener = listener;
- listener.changedScore( this, finding );
- }
- }
- log( inspector, finding, weight );
+ Finding[] findings = inspector.inspect( this, change );
+ processFindings( inspector, findings );
}
}
}
}
catch( InspectionInterruptedException e )
{
- log.debug( "Inspection " + m_uid + " interrupted by " +
currentListener.getClass().getName() );
+ log.debug( "Inspection " + m_uid + " interrupted by " +
e.getSource().getClass().getName() );
}
- // Add the change to the ReputationManager's list of recent changes
+ // Add the changes to the ReputationManager's list of recent changes
ReputationManager mgr = m_plan.getReputationManager();
- mgr.addModifier( m_context.getHttpRequest(), change );
+ for( Change change : changes )
+ {
+ mgr.addModifier( m_context.getHttpRequest(), change );
+ }
}
/**
@@ -250,6 +246,37 @@
}
/**
+ * Processes any Findings that result from an Inspector's processing
+ * @param inspector the inspector that executed
+ * @param findings the findings it produced
+ * @throws InspectionInterruptedException if any listeners interrupt
processing
+ */
+ private void processFindings( Inspector inspector, Finding[] findings )
throws InspectionInterruptedException
+ {
+ float weight = m_plan.getWeight( inspector );
+ if( findings != null )
+ {
+ for( Finding finding : findings )
+ {
+ // Increase/decrease score here
+ Topic topic = finding.getTopic();
+ updateScore( topic, finding, weight );
+
+ // Notify any listeners that the score has changed
+ List<InspectionListener> listeners = m_listeners.get( topic );
+ if( listeners != null )
+ {
+ for( InspectionListener listener : listeners )
+ {
+ listener.changedScore( this, finding );
+ }
+ }
+ log( inspector, finding, weight );
+ }
+ }
+ }
+
+ /**
* Logs a Finding to the inspection log.
*
* @param finding the Finding to log
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/InspectionInterruptedException.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/InspectionInterruptedException.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/InspectionInterruptedException.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/InspectionInterruptedException.java
Wed Jan 6 16:43:50 2010
@@ -7,12 +7,21 @@
{
private static final long serialVersionUID = -2989289836320240924L;
+ private final InspectionListener m_source;
+
/**
* Constructs a new InspectionInterruptedException with a String message.
+ * @param source the source of the interruption
* @param message the message
*/
- public InspectionInterruptedException( String message )
+ public InspectionInterruptedException( InspectionListener source, String
message )
{
super( message );
+ m_source = source;
+ }
+
+ public InspectionListener getSource()
+ {
+ return m_source;
}
}
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/InspectionPlan.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/InspectionPlan.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/InspectionPlan.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/InspectionPlan.java
Wed Jan 6 16:43:50 2010
@@ -23,8 +23,11 @@
private final ReputationManager m_reputationManager;
- private Captcha m_captcha = null;
-
+ /**
+ * Returns the {...@link ReputationManager} associated with the
InspectionPlan.
+ *
+ * @return the reputation manager
+ */
public ReputationManager getReputationManager()
{
return m_reputationManager;
@@ -38,6 +41,15 @@
private final Map<Inspector, Float> m_inspectors;
+ /**
+ * Constructs a new InspectionPlan with a supplied set of properties for
+ * configuration. When the plan is instantiated, a new
+ * {...@link ReputationManager} will also be created. Its ban-time will be
set
+ * to the value specified in the properties file by key
+ * {...@link #PROP_BANTIME}.
+ *
+ * @param props the wiki properties
+ */
public InspectionPlan( Properties props )
{
super();
@@ -61,34 +73,40 @@
{
m_inspectors.put( inspector, Float.valueOf( weight ) );
inspector.initialize( this );
- if ( inspector instanceof CaptchaInspector )
- {
- m_captcha = ((CaptchaInspector)inspector).getCaptcha();
- }
}
/**
- * Returns the {...@link Captcha} object, if one was initialized by
- * a {...@link CaptchaInspector} passed to {...@link
#addInspector(Inspector, float)}.
- * @return the Captcha, or {...@code null} if not supplied or configured
+ * Returns the array of {...@link Inspector} objects that are part of the
+ * InspectionPlan. The order of the array reflects the order in which the
+ * Inspectors were added.
+ *
+ * @return the array, which may be zero-length if no Inspectors were added
+ * before calling this method
*/
- public Captcha getCaptcha()
- {
- return m_captcha;
- }
-
public Inspector[] getInspectors()
{
Set<Inspector> inspectors = m_inspectors.keySet();
return inspectors.toArray( new Inspector[inspectors.size()] );
}
+ /**
+ * Returns the weight for a particular Inspector. If no weight was assigned
+ * or if the inspector does not exist, returns {0f}.
+ *
+ * @param inspector the inspector whose weight is being sought
+ * @return the weight
+ */
public float getWeight( Inspector inspector )
{
Float weight = m_inspectors.get( inspector );
return weight == null ? 0f : weight.floatValue();
}
+ /**
+ * The wiki properties used to initialize the InspectionPlan.
+ *
+ * @return the properties
+ */
public Properties getProperties()
{
return m_props;
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Inspector.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Inspector.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Inspector.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Inspector.java
Wed Jan 6 16:43:50 2010
@@ -24,10 +24,30 @@
* {...@code null}.
*
* @param inspection the current Inspection
- * @param content the content that
- * @param change the subset of the content that represents the added or
+ * @param change the current contents, plus content that represents the
added or
* deleted text since the last change
* @return the Findings
*/
- public Finding[] inspect( Inspection inspection, String content, Change
change );
+ public Finding[] inspect( Inspection inspection, Change change );
+
+ /**
+ * Returns the {...@link Scope} of the inspector: per-field or per-request.
+ * Request-scoped inspectors are invoked just once for the entire request.
+ * Field-scoped inspectors are invoked on every field that is being
+ * protected.
+ */
+ public Scope getScope();
+
+ /**
+ * The scope of an inspector, which can operate on individual fields or for
+ * the entire request.
+ */
+ public enum Scope
+ {
+ /** Inspector that should be executed for every field. */
+ FIELD,
+
+ /** Inspector that should be executed just once per form. */
+ REQUEST
+ }
}
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/LinkCountInspector.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/LinkCountInspector.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/LinkCountInspector.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/LinkCountInspector.java
Wed Jan 6 16:43:50 2010
@@ -36,6 +36,14 @@
*/
private int m_maxUrls = 10;
+ /**
+ * Always returns {...@link Scope#FIELD}.
+ */
+ public Scope getScope()
+ {
+ return Scope.FIELD;
+ }
+
public void initialize( InspectionPlan config )
{
m_config = config;
@@ -56,12 +64,11 @@
* Returns {...@link Finding.Result#FAILED} if the proposed change
contains too many
* links; {...@code null} otherwise.
* @param inspection the current Inspection
- * @param content the content that is being inspected
- * @param change the subset of the content that represents the added or
+ * @param change the current contents, plus content that represents the
added or
* deleted text since the last change
* @return {...@link Finding.Result#FAILED} if the test fails; {...@code
null} otherwise
*/
- public Finding[] inspect( Inspection inspection, String content, Change
change )
+ public Finding[] inspect( Inspection inspection, Change change )
{
// Calculate the number of links in the addition.
String tstChange = change.toString();
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/PatternInspector.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/PatternInspector.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/PatternInspector.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/PatternInspector.java
Wed Jan 6 16:43:50 2010
@@ -45,6 +45,14 @@
private static final String LISTVAR = "spamwords";
+ /**
+ * Always returns {...@link Scope#FIELD}.
+ */
+ public Scope getScope()
+ {
+ return Scope.FIELD;
+ }
+
public void initialize( InspectionPlan config )
{
Properties properties = config.getProperties();
@@ -56,12 +64,11 @@
* Returns {...@link Finding.Result#FAILED} if any contents are contained
on
* the banned-word pattern blacklist; {...@code null} otherwise.
* @param inspection the current Inspection
- * @param content the content that is being inspected
- * @param change the subset of the content that represents the added or
+ * @param change the current contents, plus content that represents the
added or
* deleted text since the last change
* @return {...@link Finding.Result#FAILED} if the test fails; {...@code
null} otherwise
*/
- public Finding[] inspect( Inspection inspection, String content, Change
change )
+ public Finding[] inspect( Inspection inspection, Change change )
{
WikiContext context = inspection.getContext();
refreshBlacklists( context );
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/ReputationManager.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/ReputationManager.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/ReputationManager.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/ReputationManager.java
Wed Jan 6 16:43:50 2010
@@ -25,7 +25,7 @@
private final String m_address;
- private final Change m_change;
+ private final String m_change;
/**
* @param ipaddress
@@ -35,7 +35,7 @@
public Host( String ipaddress, Change change, int releaseTime )
{
m_address = ipaddress;
- m_change = change;
+ m_change = change == null ? null : change.getChange();
m_releaseTime = System.currentTimeMillis() + releaseTime * 60 *
1000L;
}
@@ -49,7 +49,7 @@
return m_address;
}
- public Change getChange()
+ public String getChange()
{
return m_change;
}
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/SpamInspectionFactory.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/SpamInspectionFactory.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/SpamInspectionFactory.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/SpamInspectionFactory.java
Wed Jan 6 16:43:50 2010
@@ -5,6 +5,7 @@
import java.util.Properties;
import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.WikiException;
import org.apache.wiki.log.Logger;
import org.apache.wiki.log.LoggerFactory;
@@ -12,7 +13,7 @@
* Factory for creating spam-related {...@link Inspection} and
* {...@link InspectionPlan} objects.
*/
-public class SpamInspectionFactory
+public final class SpamInspectionFactory
{
private static final Logger log = LoggerFactory.getLogger(
SpamInspectionFactory.class );
@@ -39,7 +40,7 @@
float currentScore = inspection.getScore( Topic.SPAM );
if( currentScore < m_limit )
{
- throw new InspectionInterruptedException( "Limit reached." );
+ throw new InspectionInterruptedException( this, "Limit
reached." );
}
}
}
@@ -65,14 +66,47 @@
/** Default limit at which we consider something to be spam. */
protected static final float DEFAULT_SCORE_LIMIT = -0.01f;
+ protected static final String DEFAULT_CAPTCHA_CLASS =
AsirraCaptcha.class.getName();
+
/**
* Default weight for Inspectors.
*/
protected static final float DEFAULT_WEIGHT = 0f;
+ protected static final String PROP_CAPTCHA_CLASS =
"jspwiki.captcha.implementation";
+
private static final Map<WikiEngine, InspectionPlan> c_plans = new
HashMap<WikiEngine, InspectionPlan>();
+ private static final Map<WikiEngine, Challenge> c_captchas = new
HashMap<WikiEngine,Challenge>();
+
private static final Map<WikiEngine, Float> c_spamLimits = new
HashMap<WikiEngine, Float>();
+
+ public static float defaultSpamLimit( WikiEngine engine )
+ {
+ Float limit = c_spamLimits.get( engine );
+ return limit == null ? DEFAULT_SCORE_LIMIT : limit.floatValue();
+ }
+
+ /**
+ * Looks up and returns the CAPTCHA ({...@link Challenge}) for a given
WikiEngine.
+ * If the CAPTCHA does not exist, it will be created. <em>Callers should
+ * check for {...@code null} values, which indicate a CAPTCHA was
+ * not configured.</em>
+ * @return the CAPTCHA, or {...@code null} if one was not specified
+ * in the wiki engine's properties (or not configured)
+ */
+ public static final Challenge getCaptcha( WikiEngine engine ) throws
WikiException
+ {
+ if ( c_captchas.containsKey( engine ) )
+ {
+ return c_captchas.get( engine );
+ }
+
+ // Lazily create
+ Challenge captcha = initCaptcha( engine.getWikiProperties() );
+ c_captchas.put( engine, captcha );
+ return captcha;
+ }
/**
* <p>
@@ -88,7 +122,6 @@
* <li>{...@link BotTrapInspector}</li>
* <li>{...@link AkismetInspector}</li>
* <li>{...@link PatternInspector}</li>
- * <li>{...@link CaptchaInspector}</li>
* </ul>
* <p>
* The weights for each Inspector will be determined by examining {...@code
@@ -118,10 +151,11 @@
plan.addInspector( new BotTrapInspector(), getWeight( props,
BotTrapInspector.class ) );
plan.addInspector( new AkismetInspector(), getWeight( props,
AkismetInspector.class ) );
plan.addInspector( new PatternInspector(), getWeight( props,
PatternInspector.class ) );
- plan.addInspector( new CaptchaInspector(), getWeight( props,
CaptchaInspector.class ) );
-
c_plans.put( engine, plan );
+ // Figure out the Challenge to use for this WikiEngine
+
+
// Get the default spam score limits
float limit = DEFAULT_SCORE_LIMIT;
String limitString = props.getProperty( PROP_SCORE_LIMIT,
String.valueOf( DEFAULT_SCORE_LIMIT ) );
@@ -160,10 +194,47 @@
return weight;
}
- public static float defaultSpamLimit( WikiEngine engine )
+ /**
+ * Returns a new instance of the configured CAPTCHA implementation class,
+ * if one was specified by the {...@link #PROP_CAPTCHA_CLASS} property. If
one
+ * was not specified, this method will attempt to initialize the class
+ * named by {...@link #DEFAULT_CAPTCHA_CLASS}. This method is guaranteed to
+ * return a no...@code null} value.
+ *
+ * @param props the properties to examine
+ * @return an initialized CAPTCHA implementing class
+ * @throws WikiException if the CAPTCHA implementation cannot be found or
+ * initialized for any reason; the original Exception will be wrapped
+ */
+ protected static Challenge initCaptcha( Properties props ) throws
WikiException
{
- Float limit = c_spamLimits.get( engine );
- return limit == null ? DEFAULT_SCORE_LIMIT : limit.floatValue();
- }
+ String captchaClassName = props.getProperty( PROP_CAPTCHA_CLASS,
DEFAULT_CAPTCHA_CLASS );
+ Class<?> captchaClass = null;
+ try
+ {
+ captchaClass = Class.forName( captchaClassName );
+ }
+ catch( ClassNotFoundException e )
+ {
+ String msg = "No CAPTCHA implementation found for class " +
captchaClassName;
+ log.error( msg, e );
+ throw new WikiException( msg, e );
+ }
+ Challenge captcha = null;
+ if( captchaClass != null )
+ {
+ try
+ {
+ captcha = (Challenge) captchaClass.newInstance();
+ }
+ catch( Exception e )
+ {
+ String msg = "Could not create CAPTCHA instance for class " +
captchaClassName;
+ log.error( msg, e );
+ throw new WikiException( msg, e );
+ }
+ }
+ return captcha;
+ }
}
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/UserInspector.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/UserInspector.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/UserInspector.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/UserInspector.java
Wed Jan 6 16:43:50 2010
@@ -22,6 +22,14 @@
*/
private boolean m_ignoreAuthenticated = false;
+ /**
+ * Always returns {...@link Scope#REQUEST}.
+ */
+ public Scope getScope()
+ {
+ return Scope.REQUEST;
+ }
+
public void initialize( InspectionPlan config )
{
Properties props = config.getProperties();
@@ -34,12 +42,11 @@
* {...@link Finding.Result#PASSED}. Otherwise, the method returns
{...@code null}
* but does not affect the score in any way.
* @param inspection the current Inspection
- * @param content the content that is being inspected
- * @param change the subset of the content that represents the added or
+ * @param change the current contents, plus content that represents the
added or
* deleted text since the last change
* @return {...@link Finding.Result#FAILED} if the test fails; {...@code
null} otherwise
*/
- public Finding[] inspect( Inspection inspection, String content, Change
change )
+ public Finding[] inspect( Inspection inspection, Change change )
{
WikiContext context = inspection.getContext();
if( context.hasAdminPermissions() )
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/filters/SpamFilter.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/filters/SpamFilter.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/filters/SpamFilter.java
(original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/filters/SpamFilter.java
Wed Jan 6 16:43:50 2010
@@ -150,7 +150,7 @@
Inspection inspection = new Inspection( context, m_plan );
float spamScoreLimit = SpamInspectionFactory.defaultSpamLimit(
m_engine );
SpamInspectionFactory.setSpamLimit( inspection, spamScoreLimit );
- inspection.inspect( content, change );
+ inspection.inspect( change );
float spamScore = inspection.getScore( Topic.SPAM );
context.setVariable( ATTR_SPAMFILTER_SCORE, spamScore );
@@ -184,7 +184,7 @@
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.NONE, "Challenge.jsp", "page=" +
ctx.getEngine().encodeName( ctx.getPage().getName() ) );
return ctx.getURL( WikiContext.VIEW, m_errorPage );
}
Modified:
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/InspectionTest.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/InspectionTest.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
---
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/InspectionTest.java
(original)
+++
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/InspectionTest.java
Wed Jan 6 16:43:50 2010
@@ -82,7 +82,7 @@
m_executed = true;
if( m_interrupt )
{
- throw new InspectionInterruptedException( "Interrupted by
TestInspectionListener." );
+ throw new InspectionInterruptedException( this, "Interrupted
by TestInspectionListener." );
}
}
@@ -111,10 +111,15 @@
{
}
- public Finding[] inspect( Inspection inspection, String content,
Change change )
+ public Finding[] inspect( Inspection inspection, Change change )
{
return new Finding[] { new Finding( m_topic, m_result,
m_result.toString() ) };
}
+
+ public Scope getScope()
+ {
+ return Scope.FIELD;
+ }
}
public void testInspectOneTopic() throws Exception
@@ -133,7 +138,7 @@
WikiPage page = m_engine.getFrontPage( ContentManager.DEFAULT_SPACE );
WikiContext context = m_engine.getWikiContextFactory().newViewContext(
page );
Inspection inspection = new Inspection( context, plan );
- inspection.inspect( "Sample text", null );
+ inspection.inspect( Change.getChange( "page", "Sample text" ) );
// Result should be 2: +4 -2 +0
assertEquals( 2.0f, inspection.getScore( Topic.SPAM ) );
@@ -157,7 +162,7 @@
WikiPage page = m_engine.getFrontPage( ContentManager.DEFAULT_SPACE );
WikiContext context = m_engine.getWikiContextFactory().newViewContext(
page );
Inspection inspection = new Inspection( context, plan );
- inspection.inspect( "Sample text", null );
+ inspection.inspect( Change.getChange( "page", "Sample text" ) );
// Result should be 2: +4 -2 +0
assertEquals( 2.0f, inspection.getScore( Topic.SPAM ) );
@@ -184,7 +189,7 @@
WikiPage page = m_engine.getFrontPage( ContentManager.DEFAULT_SPACE );
WikiContext context = m_engine.getWikiContextFactory().newViewContext(
page );
Inspection inspection = new Inspection( context, plan );
- inspection.inspect( "Sample text", null );
+ inspection.inspect( Change.getChange( "page", "Sample text" ) );
// Verify that the findings were added in order
Finding[] findings = inspection.getFindings( Topic.SPAM );
@@ -220,7 +225,7 @@
inspection.addListener( new Topic( "Topic2" ), listener2 );
// Run the inspection
- inspection.inspect( "Sample text", null );
+ inspection.inspect( Change.getChange( "page", "Sample text" ) );
// Verify that Spam listener fired, but Topic2 listener did not
assertTrue( listener.isExecuted() );
@@ -248,7 +253,7 @@
inspection.addListener( new Topic( "Topic2" ), listener2 );
// Run the inspection
- inspection.inspect( "Sample text", null );
+ inspection.inspect( Change.getChange( "page", "Sample text" ) );
// Verify that Spam listener fired, but Topic2 listener did not
assertTrue( listener.isExecuted() );
Modified:
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/ReputationManagerTest.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/ReputationManagerTest.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
---
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/ReputationManagerTest.java
(original)
+++
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/ReputationManagerTest.java
Wed Jan 6 16:43:50 2010
@@ -68,7 +68,7 @@
HttpServletRequest req = new MockHttpServletRequest( "/JSPWiki",
"/servlet" );
InspectionPlan plan = new InspectionPlan( m_props );
ReputationManager reputationManager = plan.getReputationManager();
- Change change = Change.getChange( "changed text" );
+ Change change = Change.getChange( "page", "changed text" );
reputationManager.addModifier( req, change );
assertEquals( 1, reputationManager.getModifiers().length );
Host host = reputationManager.getModifiers()[0];
@@ -76,10 +76,10 @@
assertNotNull( host.getAddedTime() );
assertNotNull( host.getReleaseTime() );
assertNotSame( host.getAddedTime(), host.getReleaseTime() );
- assertEquals( "changed text", host.getChange().getChange() );
+ assertEquals( "changed text", host.getChange() );
req = new MockHttpServletRequest( "/JSPWiki", "/servlet" );
- change = Change.getChange( "more changed text" );
+ change = Change.getChange( "page", "more changed text" );
reputationManager.addModifier( req, change );
assertEquals( 2, reputationManager.getModifiers().length );
}
Modified:
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/SpamInspectionFactoryTest.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/SpamInspectionFactoryTest.java?rev=896518&r1=896517&r2=896518&view=diff
==============================================================================
---
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/SpamInspectionFactoryTest.java
(original)
+++
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/SpamInspectionFactoryTest.java
Wed Jan 6 16:43:50 2010
@@ -91,7 +91,7 @@
// Running the inspection should cause the BanListInspector to fail
String newText = "Sample text";
- inspection.inspect( newText, null );
+ inspection.inspect( Change.getChange( "page", newText ) );
assertEquals( -2f, inspection.getScore( Topic.SPAM ) );
}
@@ -113,7 +113,7 @@
// Running inspection with simple text change should be fine
Inspection inspection = createInspection( request );
String newText = "Sample text";
- inspection.inspect( newText, null );
+ inspection.inspect( Change.getChange( "page", newText ) );
assertEquals( PERFECT_SCORE, inspection.getScore( Topic.SPAM ) );
// Now, make 100 more (slightly different) changes
@@ -121,7 +121,7 @@
{
inspection = createInspection( request );
newText = "Sample text change " + i;
- inspection.inspect( newText, null );
+ inspection.inspect( Change.getChange( "page", newText ) );
}
// Our change-rate check should fail
assertEquals( -4f, inspection.getScore( Topic.SPAM ) );
@@ -145,12 +145,12 @@
// Running inspection with simple text change should be fine
Inspection inspection = createInspection( request );
String newText = "Sample text";
- inspection.inspect( newText, null );
+ inspection.inspect( Change.getChange( "page", newText ) );
assertEquals( PERFECT_SCORE, inspection.getScore( Topic.SPAM ) );
// Now, make a change with 3 URLs in it (1 more than limit)
newText = "http://www.jspwiki.org mailto:[email protected]
https://www.freshcookies.org";
- inspection.inspect( newText, null );
+ inspection.inspect( Change.getChange( "page", newText ) );
// Link-count check should fail
assertEquals( -8f, inspection.getScore( Topic.SPAM ) );
@@ -174,7 +174,7 @@
// Running inspection with simple text change should be fine
Inspection inspection = createInspection( request );
String newText = "Sample text";
- inspection.inspect( newText, null );
+ inspection.inspect( Change.getChange( "page", newText ) );
assertEquals( PERFECT_SCORE, inspection.getScore( Topic.SPAM ) );
// Now, make 50 more identical changes
@@ -182,9 +182,9 @@
for( int i = 0; i < 50; i++ )
{
inspection = createInspection( request );
- inspection.inspect( newText, null );
+ inspection.inspect( Change.getChange( "page", newText ) );
}
- inspection.inspect( newText, null );
+ inspection.inspect( Change.getChange( "page", newText ) );
// Our similarity check should fail
assertEquals( -4f, inspection.getScore( Topic.SPAM ) );
}
@@ -211,20 +211,20 @@
// anything
Inspection inspection = createInspection( request );
String newText = "Sample text";
- inspection.inspect( newText, null );
+ inspection.inspect( Change.getChange( "page", newText ) );
assertEquals( PERFECT_SCORE, inspection.getScore( Topic.SPAM ) );
// Removing the UTF-8 token suggests we have a bot
request.getParameterMap().remove( BotTrapInspector.REQ_ENCODING_CHECK
);
inspection = createInspection( request );
- inspection.inspect( newText, null );
+ inspection.inspect( Change.getChange( "page", newText ) );
assertEquals( -16f, inspection.getScore( Topic.SPAM ) );
// Removing the encrypted spam param suggests we have a bot
setupSpamParams( request );
request.getParameterMap().remove( BotTrapInspector.REQ_SPAM_PARAM );
inspection = createInspection( request );
- inspection.inspect( newText, null );
+ inspection.inspect( Change.getChange( "page", newText ) );
assertEquals( -16f, inspection.getScore( Topic.SPAM ) );
// Supplying a non-null value for the first (trap) spam param should
@@ -232,19 +232,19 @@
setupSpamParams( request );
request.getParameterMap().put( BotTrapInspector.REQ_TRAP_PARAM, new
String[] { "botSuppliedValue" } );
inspection = createInspection( request );
- inspection.inspect( newText, null );
+ inspection.inspect( Change.getChange( "page", newText ) );
assertEquals( -16f, inspection.getScore( Topic.SPAM ) );
// Removing the second (token) spam param should trip it also
setupSpamParams( request );
request.getParameterMap().remove( "TOKENA" );
inspection = createInspection( request );
- inspection.inspect( newText, null );
+ inspection.inspect( Change.getChange( "page", newText ) );
assertEquals( -16f, inspection.getScore( Topic.SPAM ) );
// / Re-run the inspection with all parameters intact
setupSpamParams( request );
- inspection.inspect( newText, null );
+ inspection.inspect( Change.getChange( "page", newText ) );
assertEquals( PERFECT_SCORE, inspection.getScore( Topic.SPAM ) );
}