package er.extensions.components._private;
import org.apache.commons.lang.CharEncoding;
import com.webobjects.appserver.WOAssociation;
import com.webobjects.appserver.WOComponent;
import com.webobjects.appserver.WOContext;
import com.webobjects.appserver.WOElement;
import com.webobjects.appserver.WORequest;
import com.webobjects.appserver.WOResponse;
import com.webobjects.appserver._private.WODynamicElementCreationException;
import com.webobjects.appserver._private.WOInput;
import com.webobjects.foundation.NSDictionary;
import er.extensions.foundation.ERXKeyValueCodingUtilities;
import er.extensions.foundation.ERXStringUtilities;
/**
* ERXWOPasswordField is just like WOPasswordField except that it
* doesn't show the actualy password as the value in the input. Instead,
* it replaces it with a "hidden value" (defaults to '_@secret@_'). When
* the form posts back, the value binding is only set if the posted value
* is different than the hidden value. If you view the source of your
* html page, you will only see the hidden value (which appears as *'s
* to the end-user anyway) rather than the actual value. This is not a
* substitute by any means for SSL. It just adds one small additional
* amount of security to your HTML.
*
* @binding value the actual password value (required)
* @binding hiddenValue the string to display when hidden (optional)
* @binding disabled whether or not the input field is disabled (optional)
* @binding name the name of the input field (optional)
* @binding readonly whether or not the input field is readonly (optional)
*
* @author mschrag
*/
public class ERXWOPasswordField extends WOInput {
private static final String HIDDEN_STRING = "_@secret@_";
private WOAssociation _hiddenValue;
private WOAssociation _hashValue;
private WOAssociation _readonly;
public ERXWOPasswordField(String name, NSDictionary associations, WOElement template) {
super("input", associations, null);
if (_value == null || !_value.isValueSettable()) {
throw new WODynamicElementCreationException("<ERXWOPasswordField> 'value' attribute not present or is a constant.");
}
_hiddenValue = _associations.removeObjectForKey("hiddenValue");
_hashValue = _associations.removeObjectForKey("hashValue");
_readonly = _associations.removeObjectForKey("readonly");
}
@Override
protected String type() {
return "password";
}
@Override
protected boolean isDisabledInContext(WOContext context) {
WOAssociation disabled = (WOAssociation) ERXKeyValueCodingUtilities.privateValueForKey(this, "_disabled");
return disabled != null && disabled.booleanValueInComponent(context.component());
}
protected boolean isReadonlyInContext(WOContext context) {
return _readonly != null && _readonly.booleanValueInComponent(context.component());
}
@Override
public void takeValuesFromRequest(WORequest request, WOContext context) {
WOComponent component = context.component();
if (!isDisabledInContext(context) && context.wasFormSubmitted() && !isReadonlyInContext(context)) {
String name = nameInContext(context, component);
if (name != null) {
String value = request.stringFormValueForKey(name);
if (value != null) {
String hiddenValue = hiddenValueInContext(context, component);
if (!value.equals(hiddenValue)) {
boolean hashValue = (_hashValue != null && _hashValue.booleanValueInComponent(component));
if (hashValue) {
value = ERXStringUtilities.md5Hex(value, CharEncoding.UTF_8);
}
_value.setValue(value, component);
}
}
}
}
}
protected String hiddenValueInContext(WOContext context, WOComponent component) {
String hiddenValue = null;
Object actualValue = _value.valueInComponent(component);
if (actualValue != null) {
if (_hiddenValue != null) {
hiddenValue = (String) _hiddenValue.valueInComponent(component);
}
if (hiddenValue == null) {
hiddenValue = ERXWOPasswordField.HIDDEN_STRING;
}
}
return hiddenValue;
}
@Override
protected void _appendValueAttributeToResponse(WOResponse response, WOContext context) {
WOComponent component = context.component();
String hiddenValue = hiddenValueInContext(context, component);
if (hiddenValue != null) {
response._appendTagAttributeAndValue("value", hiddenValue, true);
}
if (isReadonlyInContext(context)) {
response._appendTagAttributeAndValue("readonly", "readonly", false);
}
}
@Override
protected void _appendCloseTagToResponse(WOResponse response, WOContext context) {
}
}