I implemented a simple extension of the wicket PasswordTextField which provides you with an indication of the strength of the entered password (using regular expressions and returning “empty”, “weak”, “medium” or “strong”). Strong means at least 7 characters with mixed alphanumeric and non-alphanumeric characters. Medium means at least 6 characters with mixed alpha and non-alpha characters.
Originally I intended to make it a panel with a visual indicator (the usual spectrum from red through yellow to green), but then I figured that allowing the caller to make the styling decisions is better (if you want to display a spectrum, then add images to your styles and set the style on the component using an AttributeModifier – come to think of it, maybe I’ll do another post on how to do that…).
Anyway, here’s the component:
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.OnChangeAjaxBehavior;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
public abstract class PasswordTextFieldWithStrength extends PasswordTextField {
private static final long serialVersionUID = 1L;
public abstract void onUpdate(String passwordStrength, AjaxRequestTarget target);
public PasswordTextFieldWithStrength(String id) {
super(id);
add(new OnChangeAjaxBehavior() {
private static final long serialVersionUID = 1L;
@Override
protected void onUpdate(AjaxRequestTarget target) {
String strength = getPasswordStrength(PasswordTextFieldWithStrength.this.getDefaultModelObjectAsString());
PasswordTextFieldWithStrength.this.onUpdate(strength, target);
}
});
}
public String getStrength() {
return getPasswordStrength(getDefaultModelObjectAsString());
}
private String getPasswordStrength(String password) {
if (password.isEmpty())
return "empty";
String alphaPresent = ".*\w.*"; // at least one alpha character
String nonAlphanumericPresent = ".*[^a-zA-Z0-9].*"; // at least one non-alphanumeric character
String nonAlphaPresent = ".*[^a-zA-Z].*"; // at least one non-alpha character
if (password.matches(alphaPresent) && password.matches(nonAlphanumericPresent) && password.length() >= 7)
return "strong";
if (password.matches(alphaPresent) && password.matches(nonAlphaPresent) && password.length() >= 6)
return "medium";
return "weak";
}
}
And here’s how to use it:
// put a label on the form which will display the strength of the entered password
final Label passwordStrengthLabel = new Label("passwordStrength");
passwordStrengthLabel.setOutputMarkupId(true);
form.add(passwordStrengthLabel);
PasswordTextFieldWithStrength passwordField = new PasswordTextFieldWithStrength("password") {
private static final long serialVersionUID = 1L;
@Override
public void onUpdate(String strength, AjaxRequestTarget target) {
// strength will be one of "empty", "weak", "medium", "strong"
// you can put it into a label, use it as a key to load a localized string, use it to construct a style etc
passwordStrength = getLocalizer().getString("passwordStrength_" + strength, this);
target.addComponent(passwordStrengthLabel);
}
};
form.add(passwordField);