Author: ajaquith
Date: Sat Jan 9 06:25:54 2010
New Revision: 897385
URL: http://svn.apache.org/viewvc?rev=897385&view=rev
Log:
Checked in PasswordChallenge, which renders the input for the <SpamProtect
challenge="password"> option. CAPTCHA added to CreateProfile.jsp.
Added:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Captcha.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/PasswordChallenge.java
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/PasswordChallengeTest.java
Modified:
incubator/jspwiki/trunk/ChangeLog
incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources.properties
incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/templates/default.properties
incubator/jspwiki/trunk/src/WebContent/templates/default/ProfileTab.jsp
incubator/jspwiki/trunk/src/java/org/apache/wiki/Release.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/action/UserProfileActionBean.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/AsirraCaptcha.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Change.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/SpamInspectionPlan.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/SpamProtectTag.java
incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/SpamInterceptor.java
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/AllTests.java
incubator/jspwiki/trunk/tests/java/org/apache/wiki/ui/stripes/SpamInterceptorTest.java
Modified: incubator/jspwiki/trunk/ChangeLog
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/ChangeLog?rev=897385&r1=897384&r2=897385&view=diff
==============================================================================
--- incubator/jspwiki/trunk/ChangeLog (original)
+++ incubator/jspwiki/trunk/ChangeLog Sat Jan 9 06:25:54 2010
@@ -1,3 +1,11 @@
+2010-01-09 Andrew Jaquith <ajaquith AT apache DOT org>
+
+ * 3.0.0-svn-198
+
+ * Checked in PasswordChallenge, which renders the
+ input for the <SpamProtect challenge="password">
+ option. CAPTCHA added to CreateProfile.jsp.
+
2010-01-08 Andrew Jaquith <ajaquith AT apache DOT org>
* 3.0.0-svn-197
Modified:
incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources.properties
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources.properties?rev=897385&r1=897384&r2=897385&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources.properties
(original)
+++
incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/CoreResources.properties
Sat Jan 9 06:25:54 2010
@@ -376,3 +376,5 @@
org.apache.wiki.content.inspect.AsirraCaptcha.description=If you are human,
please select all of the cats from the images below.
#Formerly named captcha.asirra.adopt.me.
org.apache.wiki.content.inspect.AsirraCaptcha.adoptMe=Adopt me
+org.apache.wiki.content.inspect.PasswordChallenge.description = To confirm
your changes, enter your password.
+captcha = CAPTCHA test
\ No newline at end of file
Modified:
incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/templates/default.properties
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/templates/default.properties?rev=897385&r1=897384&r2=897385&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/templates/default.properties
(original)
+++
incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/templates/default.properties
Sat Jan 9 06:25:54 2010
@@ -533,4 +533,4 @@
#Formerly named newgroup.members.description.
members.description=The membership for this group. Enter each user’s
name or wiki name, separated by carriage returns.
install.approver.saveWikiPage.description=Name of the role or wiki group that
can approve page changes. If users can change pages themselves without
approval, leave this blank. Specify the role "SU" if you want the superuser to
approve all page changes.
-install.approver.createUserProfile.description=Name of the role or wiki group
that can approve new wiki profiles. If users can self-enroll without approval,
leave this blank. Specify the role "SU" if you want the superuser to approve
all new accounts.
\ No newline at end of file
+install.approver.createUserProfile.description=Name of the role or wiki group
that can approve new wiki profiles. If users can self-enroll without approval,
leave this blank. Specify the role "SU" if you want the superuser to approve
all new accounts.
Modified:
incubator/jspwiki/trunk/src/WebContent/templates/default/ProfileTab.jsp
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/templates/default/ProfileTab.jsp?rev=897385&r1=897384&r2=897385&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/templates/default/ProfileTab.jsp
(original)
+++ incubator/jspwiki/trunk/src/WebContent/templates/default/ProfileTab.jsp Sat
Jan 9 06:25:54 2010
@@ -138,6 +138,17 @@
</tr>
</wiki:UserProfile>
+ <%-- Spam protection: password confirmation or CAPTCHA --%>
+ <tr>
+ <td><s:label for="captcha" /></td>
+ <td>
+ <wiki:UserCheck status="notAuthenticated">
+ <wiki:SpamProtect challenge="captcha" />
+ </wiki:UserCheck>
+ </td>
+ </tr>
+
+ <%-- Save changes --%>
<tr>
<td> </td>
<td>
Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/Release.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/Release.java?rev=897385&r1=897384&r2=897385&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/Release.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/Release.java Sat Jan 9
06:25:54 2010
@@ -77,7 +77,7 @@
* <p>
* If the build identifier is empty, it is not added.
*/
- public static final String BUILD = "197";
+ public static final String BUILD = "198";
/**
* This is the generic version string you should use
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/action/UserProfileActionBean.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/action/UserProfileActionBean.java?rev=897385&r1=897384&r2=897385&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/action/UserProfileActionBean.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/action/UserProfileActionBean.java
Sat Jan 9 06:25:54 2010
@@ -23,6 +23,10 @@
import java.security.Principal;
+import net.sourceforge.stripes.action.*;
+import net.sourceforge.stripes.controller.LifecycleStage;
+import net.sourceforge.stripes.validation.*;
+
import org.apache.wiki.WikiEngine;
import org.apache.wiki.WikiSession;
import org.apache.wiki.auth.AuthenticationManager;
@@ -35,14 +39,11 @@
import org.apache.wiki.log.Logger;
import org.apache.wiki.log.LoggerFactory;
import org.apache.wiki.ui.stripes.HandlerPermission;
+import org.apache.wiki.ui.stripes.SpamProtect;
import org.apache.wiki.ui.stripes.WikiActionBeanContext;
import org.apache.wiki.ui.stripes.WikiRequestContext;
import org.apache.wiki.workflow.DecisionRequiredException;
-import net.sourceforge.stripes.action.*;
-import net.sourceforge.stripes.controller.LifecycleStage;
-import net.sourceforge.stripes.validation.*;
-
/**
*/
@@ -112,6 +113,7 @@
*/
@HandlesEvent( "save" )
@HandlerPermission( permissionClass = WikiPermission.class, target =
"${context.engine.applicationName}", actions =
WikiPermission.EDIT_PROFILE_ACTION )
+ @SpamProtect
public Resolution save()
{
WikiActionBeanContext context = getContext();
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/AsirraCaptcha.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/AsirraCaptcha.java?rev=897385&r1=897384&r2=897385&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/AsirraCaptcha.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/AsirraCaptcha.java
Sat Jan 9 06:25:54 2010
@@ -92,7 +92,7 @@
* Asirra JavaScript.
* </p>
*/
-public class AsirraCaptcha implements Challenge
+public class AsirraCaptcha implements Captcha
{
/**
* Convenience class that encapsulates the image of a pet,
Added:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Captcha.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Captcha.java?rev=897385&view=auto
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Captcha.java
(added)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/Captcha.java
Sat Jan 9 06:25:54 2010
@@ -0,0 +1,8 @@
+package org.apache.wiki.content.inspect;
+
+/**
+ * Marker interface that indicates a Challenge is a CAPTCHA.
+ */
+public interface Captcha extends Challenge
+{
+}
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=897385&r1=897384&r2=897385&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
Sat Jan 9 06:25:54 2010
@@ -7,8 +7,8 @@
import org.apache.commons.jrcs.diff.myers.MyersDiff;
import org.apache.wiki.WikiContext;
import org.apache.wiki.WikiEngine;
-import org.apache.wiki.WikiProvider;
import org.apache.wiki.api.WikiPage;
+import org.apache.wiki.providers.ProviderException;
/**
* Embodies the differences between two Strings, or between a proposed text
@@ -105,6 +105,7 @@
* page-related WikiContext
* @param newText the new text
* @return Empty string, if there is no change.
+ * @throws DifferentiationFailedException if the page contents could not
be retrieved or diffed
*/
public static Change getPageChange( WikiContext context, String newText )
throws DifferentiationFailedException
{
@@ -115,7 +116,16 @@
// Get current page version
if( engine.pageExists( page.getName() ) )
{
- String oldText = engine.getPureText( page.getName(),
WikiProvider.LATEST_VERSION );
+ String oldText;
+ try
+ {
+ oldText = page.getContentAsString();
+ }
+ catch( ProviderException e )
+ {
+ e.printStackTrace();
+ throw new DifferentiationFailedException( "Differentiation
failed: " + e.getMessage() );
+ }
changes.append( oldText );
// Don't forget to include the change note, too
Added:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/PasswordChallenge.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/PasswordChallenge.java?rev=897385&view=auto
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/PasswordChallenge.java
(added)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/PasswordChallenge.java
Sat Jan 9 06:25:54 2010
@@ -0,0 +1,78 @@
+package org.apache.wiki.content.inspect;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import org.apache.wiki.WikiSession;
+import org.apache.wiki.auth.AuthenticationManager;
+import org.apache.wiki.auth.user.UserDatabase;
+import org.apache.wiki.i18n.InternationalizationManager;
+import org.apache.wiki.ui.stripes.WikiActionBeanContext;
+
+/**
+ * Challenge class that verifies that a user's password is correct. This
+ * challenge can only be used when JSPWiki built-in authentication is used. No
+ * form elements will be rendered by {...@link
#formContent(WikiActionBeanContext)}
+ * if container authentication is in effect, and
+ * {...@link #check(WikiActionBeanContext)} will return {...@code true} in
this case.
+ */
+public class PasswordChallenge implements Challenge
+{
+
+ /**
+ * Validates the user's password based on the contents of the request
+ * parameter {...@code j_password}. If the user is not authenticated, or if
+ * container authentication is configured, this method will always return
+ * {...@code false}.
+ */
+ public boolean check( WikiActionBeanContext context ) throws IOException
+ {
+ AuthenticationManager authMgr =
context.getEngine().getAuthenticationManager();
+ WikiSession wikiSession = context.getWikiSession();
+ if( !wikiSession.isAuthenticated() ||
authMgr.isContainerAuthenticated() )
+ {
+ return false;
+ }
+
+ // Get the user's password
+ String loginName = wikiSession.getLoginPrincipal().getName();
+ String password = context.getRequest().getParameter( "j_password" );
+ if ( loginName == null || password == null )
+ {
+ return false;
+ }
+
+ UserDatabase db =
context.getEngine().getUserManager().getUserDatabase();
+ return db.validatePassword( loginName, password );
+ }
+
+ private static final String PASSWORD_DESCRIPTION_KEY =
"org.apache.wiki.content.inspect.PasswordChallenge.description";
+
+ private static final String PASSWORD_KEY = "password";
+
+ /**
+ * Generates a password <code><input></code> tag called {...@code
+ * j_password} to capture the user's password.
+ */
+ public String formContent( WikiActionBeanContext context ) throws
IOException
+ {
+ boolean isContainerAuthentication =
context.getEngine().getAuthenticationManager().isContainerAuthenticated();
+ if( isContainerAuthentication )
+ {
+ return null;
+ }
+
+ // Get the localized text
+ Locale locale = context.getLocale();
+ InternationalizationManager i18n =
context.getEngine().getInternationalizationManager();
+ String description = i18n.get(
InternationalizationManager.CORE_BUNDLE, locale, PASSWORD_DESCRIPTION_KEY );
+ String password = i18n.get( InternationalizationManager.CORE_BUNDLE,
locale, PASSWORD_KEY );
+
+ StringBuilder b = new StringBuilder();
+ b.append( "<div class=\"password\">" + description + "</div>" );
+ b.append( "<label for=\"j_password\" value=\"" + password + "\" />\n"
);
+ b.append( "<input name=\"j_password\" id=\"j_password\"
type=\"password\" />\n" );
+ return b.toString();
+ }
+
+}
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/SpamInspectionPlan.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/SpamInspectionPlan.java?rev=897385&r1=897384&r2=897385&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/SpamInspectionPlan.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/content/inspect/SpamInspectionPlan.java
Sat Jan 9 06:25:54 2010
@@ -1,8 +1,8 @@
package org.apache.wiki.content.inspect;
-import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
+import java.util.WeakHashMap;
import org.apache.wiki.WikiEngine;
import org.apache.wiki.api.WikiException;
@@ -10,8 +10,8 @@
import org.apache.wiki.log.LoggerFactory;
/**
- * Factory for creating spam-related {...@link Inspection} and
- * {...@link InspectionPlan} objects.
+ * Spam-oriented {...@link InspectionPlan} that includes a static factory
method
+ * for retrieving the SpamInspectionPlan for a supplied WikiEngine.
*/
public final class SpamInspectionPlan extends InspectionPlan
{
@@ -37,52 +37,8 @@
protected static final String PROP_CAPTCHA_CLASS =
"jspwiki.captcha.implementation";
- private static final Map<WikiEngine, SpamInspectionPlan> c_plans = new
HashMap<WikiEngine, SpamInspectionPlan>();
+ private static final Map<WikiEngine, SpamInspectionPlan> c_plans = new
WeakHashMap<WikiEngine, SpamInspectionPlan>();
- private final Challenge m_captcha;
-
- private final float m_limit;
-
- /**
- * Private constructor to prevent direct instantiation.
- * @throws WikiException if the SpamInspectionPlan cannot be
- * initialized for any reason; the original Exception will be wrapped
- */
- private SpamInspectionPlan( Properties properties ) throws WikiException
- {
- super( properties );
-
- // Configure the CAPTCHA
- m_captcha = initCaptcha( properties );
-
- // Get the default spam score limits
- float limit = DEFAULT_SCORE_LIMIT;
- String limitString = properties.getProperty( PROP_SCORE_LIMIT,
String.valueOf( DEFAULT_SCORE_LIMIT ) );
- try
- {
- limit = Float.parseFloat( limitString );
- }
- catch( NumberFormatException e )
- {
- log.error( "Property value " + PROP_SCORE_LIMIT + " did not parse
to a float. Using " + DEFAULT_SCORE_LIMIT );
- }
- m_limit = limit;
- }
-
- public float getSpamLimit()
- {
- return m_limit;
- }
-
- /**
- * Returns the CAPTCHA ({...@link Challenge}) for a the SpamInspectionPlan.
- * @return the CAPTCHA
- */
- public Challenge getCaptcha() throws WikiException
- {
- return m_captcha;
- }
-
/**
* <p>
* Looks up and returns the spam InspectionPlan for a given WikiEngine. If
@@ -132,28 +88,6 @@
}
/**
- * Determines the desired weight for an Inspector class, based on looking
up
- * the value in the WikiEngine Properties
- * @param props the properties used to initialize the WikiEngine
- * @param inspectorClass the Inspector class
- * @return if found, the desired weight; if not, returns {...@link
#DEFAULT_WEIGHT}
- */
- protected float getWeight( Properties props, Class<? extends Inspector>
inspectorClass )
- {
- String key = PROP_INSPECTOR_WEIGHT_PREFIX +
inspectorClass.getCanonicalName();
- float weight = DEFAULT_WEIGHT;
- String weightString = props.getProperty( key, String.valueOf(
DEFAULT_WEIGHT ) );
- try
- {
- weight = Float.parseFloat( weightString );
- }
- catch( NumberFormatException e )
- {
- }
- return weight;
- }
-
- /**
* 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
@@ -165,7 +99,7 @@
* @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
+ protected static Captcha initCaptcha( Properties props ) throws
WikiException
{
String captchaClassName = props.getProperty( PROP_CAPTCHA_CLASS,
DEFAULT_CAPTCHA_CLASS );
Class<?> captchaClass = null;
@@ -180,12 +114,12 @@
throw new WikiException( msg, e );
}
- Challenge captcha = null;
+ Captcha captcha = null;
if( captchaClass != null )
{
try
{
- captcha = (Challenge) captchaClass.newInstance();
+ captcha = (Captcha) captchaClass.newInstance();
}
catch( Exception e )
{
@@ -196,4 +130,70 @@
}
return captcha;
}
+
+ private final Captcha m_captcha;
+
+ private final float m_limit;
+
+ /**
+ * Private constructor to prevent direct instantiation.
+ * @throws WikiException if the SpamInspectionPlan cannot be
+ * initialized for any reason; the original Exception will be wrapped
+ */
+ private SpamInspectionPlan( Properties properties ) throws WikiException
+ {
+ super( properties );
+
+ // Configure the CAPTCHA
+ m_captcha = initCaptcha( properties );
+
+ // Get the default spam score limits
+ float limit = DEFAULT_SCORE_LIMIT;
+ String limitString = properties.getProperty( PROP_SCORE_LIMIT,
String.valueOf( DEFAULT_SCORE_LIMIT ) );
+ try
+ {
+ limit = Float.parseFloat( limitString );
+ }
+ catch( NumberFormatException e )
+ {
+ log.error( "Property value " + PROP_SCORE_LIMIT + " did not parse
to a float. Using " + DEFAULT_SCORE_LIMIT );
+ }
+ m_limit = limit;
+ }
+
+ /**
+ * Returns the CAPTCHA ({...@link Challenge}) for a the SpamInspectionPlan.
+ * @return the CAPTCHA
+ */
+ public Captcha getCaptcha() throws WikiException
+ {
+ return m_captcha;
+ }
+
+ public float getSpamLimit()
+ {
+ return m_limit;
+ }
+
+ /**
+ * Determines the desired weight for an Inspector class, based on looking
up
+ * the value in the WikiEngine Properties
+ * @param props the properties used to initialize the WikiEngine
+ * @param inspectorClass the Inspector class
+ * @return if found, the desired weight; if not, returns {...@link
#DEFAULT_WEIGHT}
+ */
+ protected float getWeight( Properties props, Class<? extends Inspector>
inspectorClass )
+ {
+ String key = PROP_INSPECTOR_WEIGHT_PREFIX +
inspectorClass.getCanonicalName();
+ float weight = DEFAULT_WEIGHT;
+ String weightString = props.getProperty( key, String.valueOf(
DEFAULT_WEIGHT ) );
+ try
+ {
+ weight = Float.parseFloat( weightString );
+ }
+ catch( NumberFormatException e )
+ {
+ }
+ return weight;
+ }
}
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/SpamProtectTag.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/SpamProtectTag.java?rev=897385&r1=897384&r2=897385&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/SpamProtectTag.java
(original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/SpamProtectTag.java
Sat Jan 9 06:25:54 2010
@@ -36,9 +36,7 @@
import org.apache.wiki.WikiEngine;
import org.apache.wiki.api.WikiException;
-import org.apache.wiki.content.inspect.BotTrapInspector;
-import org.apache.wiki.content.inspect.Challenge;
-import org.apache.wiki.content.inspect.SpamInspectionPlan;
+import org.apache.wiki.content.inspect.*;
import org.apache.wiki.filters.SpamFilter;
import org.apache.wiki.ui.stripes.SpamInterceptor;
import org.apache.wiki.ui.stripes.WikiActionBeanContext;
@@ -109,6 +107,8 @@
private static final Random RANDOM = new SecureRandom();
+ private static final Challenge PASSWORD_CHALLENGE = new
PasswordChallenge();
+
/**
* Writes the Challenge form content and spam parameters to the current
* PageContext's JSPWriter. If a Challenge is not needed, it will not be
@@ -157,7 +157,10 @@
}
else if( CHALLENGE_PASSWORD.equals( challenge.toLowerCase() ) )
{
- m_challenge = Challenge.State.PASSWORD_PRESENTED;
+ if (
!m_wikiContext.getEngine().getAuthenticationManager().isContainerAuthenticated()
)
+ {
+ m_challenge = Challenge.State.PASSWORD_PRESENTED;
+ }
}
else
{
@@ -223,25 +226,26 @@
{
WikiEngine engine = m_wikiContext.getEngine();
SpamInspectionPlan plan = SpamInspectionPlan.getInspectionPlan( engine
);
+ WikiActionBeanContext actionBeanContext =
m_wikiActionBean.getContext();
String challengeContent = null;
switch( m_challenge )
{
case PASSWORD_PRESENTED: {
- // Not implemented yet
+ challengeContent = PASSWORD_CHALLENGE.formContent(
actionBeanContext );
break;
}
case CAPTCHA_PRESENTED: {
- Challenge captcha = plan.getCaptcha();
- challengeContent = captcha.formContent(
m_wikiActionBean.getContext() );
+ Captcha captcha = plan.getCaptcha();
+ challengeContent = captcha.formContent( actionBeanContext );
break;
}
case CHALLENGE_NOT_PRESENTED: {
- if( isSpamDetected( (WikiActionBeanContext)m_wikiContext ) )
+ if( isSpamDetected( actionBeanContext ) )
{
m_challenge = Challenge.State.CAPTCHA_PRESENTED;
- Challenge captcha = plan.getCaptcha();
- challengeContent = captcha.formContent(
m_wikiActionBean.getContext() );
+ Captcha captcha = plan.getCaptcha();
+ challengeContent = captcha.formContent( actionBeanContext
);
}
break;
}
Modified:
incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/SpamInterceptor.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/SpamInterceptor.java?rev=897385&r1=897384&r2=897385&view=diff
==============================================================================
---
incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/SpamInterceptor.java
(original)
+++
incubator/jspwiki/trunk/src/java/org/apache/wiki/ui/stripes/SpamInterceptor.java
Sat Jan 9 06:25:54 2010
@@ -89,6 +89,8 @@
private static final Logger log = LoggerFactory.getLogger(
SpamInterceptor.class );
+ private static final Challenge PASSWORD_CHALLENGE = new
PasswordChallenge();
+
/**
* Introspects an ActionBean and returns the value for one or more supplied
* properties. Any properties not found will be cheerfully ignored.
@@ -160,8 +162,13 @@
case PASSWORD_PRESENTED: {
// Password challenge was requested
- // Not implemented yet
checkForSpam( actionBean, eventInfo );
+ if ( !PASSWORD_CHALLENGE.check( actionBean.getContext() ) )
+ {
+ ValidationError error = new LocalizableError(
"login.error.password" );
+
actionBean.getContext().getValidationErrors().addGlobalError( error );
+ return actionBean.getContext().getSourcePageResolution();
+ }
break;
}
Modified:
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/AllTests.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/AllTests.java?rev=897385&r1=897384&r2=897385&view=diff
==============================================================================
---
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/AllTests.java
(original)
+++
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/AllTests.java
Sat Jan 9 06:25:54 2010
@@ -38,6 +38,7 @@
suite.addTest( InspectionPlanTest.suite() );
suite.addTest( InspectionTest.suite() );
+ suite.addTest( PasswordChallengeTest.suite() );
suite.addTest( ReputationManagerTest.suite() );
suite.addTest( SpamInspectionPlanTest.suite() );
Added:
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/PasswordChallengeTest.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/PasswordChallengeTest.java?rev=897385&view=auto
==============================================================================
---
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/PasswordChallengeTest.java
(added)
+++
incubator/jspwiki/trunk/tests/java/org/apache/wiki/content/inspect/PasswordChallengeTest.java
Sat Jan 9 06:25:54 2010
@@ -0,0 +1,107 @@
+/*
+ JSPWiki - a JSP-based WikiWiki clone.
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+package org.apache.wiki.content.inspect;
+
+import java.util.Properties;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import net.sourceforge.stripes.mock.MockRoundtrip;
+
+import org.apache.wiki.TestEngine;
+import org.apache.wiki.action.ViewActionBean;
+import org.apache.wiki.auth.Users;
+import org.apache.wiki.ui.stripes.WikiActionBeanContext;
+
+/**
+ */
+public class PasswordChallengeTest extends TestCase
+{
+ private TestEngine m_engine;
+
+ public static Test suite()
+ {
+ return new TestSuite( PasswordChallengeTest.class );
+ }
+
+ public void setUp()
+ {
+ // Start the WikiEngine, and stash reference
+ Properties props = new Properties();
+ try
+ {
+ props.load( TestEngine.findTestProperties() );
+ m_engine = new TestEngine( props );
+ }
+ catch( Exception e )
+ {
+ throw new RuntimeException( "Could not set up TestEngine: " +
e.getMessage() );
+ }
+ }
+
+ public void tearDown()
+ {
+ m_engine.shutdown();
+ }
+
+ public void testNotAuthenticated() throws Exception
+ {
+ // Start with an authenticated user
+ MockRoundtrip trip = m_engine.guestTrip( ViewActionBean.class );
+ trip.addParameter( "j_password", Users.JANNE_PASS );
+ trip.execute();
+ ViewActionBean bean = trip.getActionBean( ViewActionBean.class );
+ WikiActionBeanContext context = bean.getContext();
+ PasswordChallenge challenge = new PasswordChallenge();
+
+ // No j_password parameter: should be false
+ assertFalse( challenge.check( context ) );
+ }
+
+ public void testNoPasswordParameter() throws Exception
+ {
+ // Start with an authenticated user
+ MockRoundtrip trip = m_engine.authenticatedTrip( Users.JANNE,
Users.JANNE_PASS, ViewActionBean.class );
+ trip.execute();
+ ViewActionBean bean = trip.getActionBean( ViewActionBean.class );
+ WikiActionBeanContext context = bean.getContext();
+ PasswordChallenge challenge = new PasswordChallenge();
+
+ // No j_password parameter: should be false
+ assertFalse( challenge.check( context ) );
+ }
+
+ public void testPassword() throws Exception
+ {
+ // Start with an authenticated user
+ MockRoundtrip trip = m_engine.authenticatedTrip( Users.JANNE,
Users.JANNE_PASS, ViewActionBean.class );
+ trip.addParameter( "j_password", Users.JANNE_PASS );
+ trip.execute();
+ ViewActionBean bean = trip.getActionBean( ViewActionBean.class );
+ WikiActionBeanContext context = bean.getContext();
+ PasswordChallenge challenge = new PasswordChallenge();
+
+ // No j_password parameter: should be false
+ assertTrue( challenge.check( context ) );
+ }
+}
Modified:
incubator/jspwiki/trunk/tests/java/org/apache/wiki/ui/stripes/SpamInterceptorTest.java
URL:
http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/java/org/apache/wiki/ui/stripes/SpamInterceptorTest.java?rev=897385&r1=897384&r2=897385&view=diff
==============================================================================
---
incubator/jspwiki/trunk/tests/java/org/apache/wiki/ui/stripes/SpamInterceptorTest.java
(original)
+++
incubator/jspwiki/trunk/tests/java/org/apache/wiki/ui/stripes/SpamInterceptorTest.java
Sat Jan 9 06:25:54 2010
@@ -32,12 +32,11 @@
import org.apache.wiki.TestEngine;
import org.apache.wiki.action.TestActionBean;
+import org.apache.wiki.auth.Users;
import org.apache.wiki.content.inspect.BotTrapInspector;
import org.apache.wiki.content.inspect.Challenge;
import org.apache.wiki.tags.SpamProtectTag;
-import com.sun.tools.javac.util.Context;
-
public class SpamInterceptorTest extends TestCase
{
public static Test suite()
@@ -251,6 +250,86 @@
assertEquals( bean.getContext().getSourcePage(), trip.getDestination()
);
}
+ public void testPasswordChallenge() throws Exception
+ {
+ // Add the trap + token params
+ MockRoundtrip trip = m_engine.authenticatedTrip( Users.JANNE,
Users.JANNE_PASS, TestActionBean.class );
+ trip.addParameter( BotTrapInspector.REQ_TRAP_PARAM, new String[0] );
+ trip.addParameter( "TOKENA", trip.getRequest().getSession().getId() );
+ trip.addParameter( BotTrapInspector.REQ_SPAM_PARAM,
CryptoUtil.encrypt( "TOKENA" ) );
+ trip.addParameter( "j_password", Users.JANNE_PASS );
+
+ // Add the challenge param
+ String challengeParam = CryptoUtil.encrypt(
Challenge.State.PASSWORD_PRESENTED.name() );
+ trip.addParameter( SpamInterceptor.CHALLENGE_REQUEST_PARAM,
challengeParam );
+
+ // Add the UTF-8 token
+ trip.addParameter( BotTrapInspector.REQ_ENCODING_CHECK, "\u3041" );
+
+ // Verify that we got the ActionBean...
+ trip.execute( "test" );
+ TestActionBean bean = trip.getActionBean( TestActionBean.class );
+ assertEquals( null, bean.getPage() );
+
+ // ...and that we passed the challenge check
+ assertEquals( 0, trip.getValidationErrors().size() );
+ assertFalse( SpamProtectTag.isSpamDetected( bean.getContext() ) );
+ assertEquals( null, trip.getDestination() );
+ }
+
+ public void testPasswordChallengeAnonymous() throws Exception
+ {
+ // Add the trap + token params
+ MockRoundtrip trip = m_engine.guestTrip( TestActionBean.class );
+ trip.addParameter( BotTrapInspector.REQ_TRAP_PARAM, new String[0] );
+ trip.addParameter( "TOKENA", trip.getRequest().getSession().getId() );
+ trip.addParameter( BotTrapInspector.REQ_SPAM_PARAM,
CryptoUtil.encrypt( "TOKENA" ) );
+ trip.addParameter( "j_password", Users.JANNE_PASS );
+
+ // Add the challenge param
+ String challengeParam = CryptoUtil.encrypt(
Challenge.State.PASSWORD_PRESENTED.name() );
+ trip.addParameter( SpamInterceptor.CHALLENGE_REQUEST_PARAM,
challengeParam );
+
+ // Add the UTF-8 token
+ trip.addParameter( BotTrapInspector.REQ_ENCODING_CHECK, "\u3041" );
+
+ // Verify that we got the ActionBean...
+ trip.execute( "test" );
+ TestActionBean bean = trip.getActionBean( TestActionBean.class );
+ assertEquals( null, bean.getPage() );
+
+ // ...but that we failed the challenge check
+ assertEquals( 1, trip.getValidationErrors().size() );
+ assertFalse( SpamProtectTag.isSpamDetected( bean.getContext() ) );
+ assertEquals( bean.getContext().getSourcePage(), trip.getDestination()
);
+ }
+
+ public void testPasswordChallengeNoPassword() throws Exception
+ {
+ // Add the trap + token params
+ MockRoundtrip trip = m_engine.authenticatedTrip( Users.JANNE,
Users.JANNE_PASS, TestActionBean.class );
+ trip.addParameter( BotTrapInspector.REQ_TRAP_PARAM, new String[0] );
+ trip.addParameter( "TOKENA", trip.getRequest().getSession().getId() );
+ trip.addParameter( BotTrapInspector.REQ_SPAM_PARAM,
CryptoUtil.encrypt( "TOKENA" ) );
+
+ // Add the challenge param
+ String challengeParam = CryptoUtil.encrypt(
Challenge.State.PASSWORD_PRESENTED.name() );
+ trip.addParameter( SpamInterceptor.CHALLENGE_REQUEST_PARAM,
challengeParam );
+
+ // Add the UTF-8 token
+ trip.addParameter( BotTrapInspector.REQ_ENCODING_CHECK, "\u3041" );
+
+ // Verify that we got the ActionBean...
+ trip.execute( "test" );
+ TestActionBean bean = trip.getActionBean( TestActionBean.class );
+ assertEquals( null, bean.getPage() );
+
+ // ...but that we failed the challenge check
+ assertEquals( 1, trip.getValidationErrors().size() );
+ assertFalse( SpamProtectTag.isSpamDetected( bean.getContext() ) );
+ assertEquals( bean.getContext().getSourcePage(), trip.getDestination()
);
+ }
+
public void testToken() throws Exception
{
// Add the trap + token + challenge params