/* The contents of this file are subject to the license and copyright terms
* detailed in the license directory at the root of the source tree (also
* available online at http://fedora-commons.org/license/).
*/
package fedora.server.security.servletfilters.pubcookie;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.httpclient.Cookie;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import fedora.server.security.servletfilters.BaseCaching;
import fedora.server.security.servletfilters.CacheElement;
/**
* @author Bill Niebel
*/
public class FilterPubcookie
extends BaseCaching {
protected static Log log = LogFactory.getLog(FilterPubcookie.class);
private static final Map NO_REQUEST_PARAMETERS = new HashMap();
private static final Cookie[] NO_COOKIES = new Cookie[0];
public static final String PUBCOOKIE_NAME_KEY = "pubcookie-name";
public static final String PUBCOOKIE_LOGINPAGE_URL_KEY =
"pubcookie-loginpage-url";
public static final String PUBCOOKIE_LOGINPAGE_FORM_NAME_KEY =
"pubcookie-loginpage-form-name";
public static final String PUBCOOKIE_LOGINPAGE_INPUT_NAME_USERID_KEY =
"pubcookie-loginpage-input-name-userid";
public static final String PUBCOOKIE_LOGINPAGE_INPUT_NAME_PASSWORD_KEY =
"pubcookie-loginpage-input-name-password";
public static final String TRUSTSTORE_LOCATION_KEY =
"javax.net.ssl.trustStore";
public static final String TRUSTSTORE_PASSWORD_KEY =
"javax.net.ssl.trustStorePassword";
public static final String KEYSTORE_LOCATION_KEY = "javax.net.ssl.keyStore";
public static final String KEYSTORE_PASSWORD_KEY =
"javax.net.ssl.keyStorePassword";
private String PUBCOOKIE_NAME = "";
private String PUBCOOKIE_LOGINPAGE_URL = "";
private String PUBCOOKIE_LOGINPAGE_FORM_NAME = "";
private String PUBCOOKIE_LOGINPAGE_INPUT_NAME_USERID = "";
private String PUBCOOKIE_LOGINPAGE_INPUT_NAME_PASSWORD = "";
private String TRUSTSTORE_LOCATION = null;
private String TRUSTSTORE_PASSWORD = null;
@Override
public void destroy() {
String method = "destroy()";
if (log.isDebugEnabled()) {
log.debug(enter(method));
}
super.destroy();
if (log.isDebugEnabled()) {
log.debug(exit(method));
}
}
@Override
protected void initThisSubclass(String key, String value) {
String method = "initThisSubclass()";
if (log.isDebugEnabled()) {
log.debug(enter(method));
}
boolean setLocally = false;
if (PUBCOOKIE_NAME_KEY.equals(key)) {
PUBCOOKIE_NAME = value;
setLocally = true;
} else if (PUBCOOKIE_LOGINPAGE_URL_KEY.equals(key)) {
PUBCOOKIE_LOGINPAGE_URL = value;
setLocally = true;
} else if (PUBCOOKIE_LOGINPAGE_FORM_NAME_KEY.equals(key)) {
PUBCOOKIE_LOGINPAGE_FORM_NAME = value;
setLocally = true;
} else if (PUBCOOKIE_LOGINPAGE_INPUT_NAME_USERID_KEY.equals(key)) {
PUBCOOKIE_LOGINPAGE_INPUT_NAME_USERID = value;
setLocally = true;
} else if (PUBCOOKIE_LOGINPAGE_INPUT_NAME_PASSWORD_KEY.equals(key)) {
PUBCOOKIE_LOGINPAGE_INPUT_NAME_PASSWORD = value;
setLocally = true;
} else if (TRUSTSTORE_LOCATION_KEY.equals(key)) {
TRUSTSTORE_LOCATION = value;
setLocally = true;
} else if (TRUSTSTORE_PASSWORD_KEY.equals(key)) {
TRUSTSTORE_PASSWORD = value;
setLocally = true;
} else {
if (log.isErrorEnabled()) {
log.error(format(method, "deferring to super"));
}
super.initThisSubclass(key, value);
}
if (setLocally) {
if (log.isInfoEnabled()) {
log.info(format(method, "known parameter", key, value));
}
}
if (log.isDebugEnabled()) {
log.debug(exit(method));
}
}
private final String getAction(Node parent,
String pubcookieLoginpageFormName) {
String method = "getAction()";
if (log.isDebugEnabled()) {
log.debug(enter(method));
}
String action = "";
NodeList children = parent.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
String tag = child.getNodeName();
if ("form".equalsIgnoreCase(tag)) {
NamedNodeMap attributes = child.getAttributes();
Node nameNode = attributes.getNamedItem("name");
String name = nameNode.getNodeValue();
Node actionNode = attributes.getNamedItem("action");
if (pubcookieLoginpageFormName.equalsIgnoreCase(name)
&& actionNode != null) {
action = actionNode.getNodeValue();
break;
}
}
action = getAction(child, pubcookieLoginpageFormName);
if (!"".equals(action)) {
break;
}
}
if (log.isDebugEnabled()) {
log.debug(exit(method));
}
return action;
}
//initial, setup call
private final Map getFormFields(Node parent) {
String method = "getFormFields(Node parent)";
if (log.isDebugEnabled()) {
log.debug(enter(method));
}
Map formfields = new Hashtable();
getFormFields(parent, formfields);
if (log.isDebugEnabled()) {
log.debug(exit(method));
}
return formfields;
}
//inner, recursive call
private final void getFormFields(Node parent, Map formfields) {
String method = "getFormFields(Node parent, Map formfields)";
if (log.isDebugEnabled()) {
log.debug(enter(method));
}
NodeList children = parent.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
String tag = child.getNodeName();
if ("input".equalsIgnoreCase(tag)) {
NamedNodeMap attributes = child.getAttributes();
Node typeNode = attributes.getNamedItem("type");
String type = typeNode.getNodeValue();
Node nameNode = attributes.getNamedItem("name");
String name = nameNode.getNodeValue();
Node valueNode = attributes.getNamedItem("value");
String value = "";
if (valueNode != null) {
value = valueNode.getNodeValue();
}
if ("hidden".equalsIgnoreCase(type) && value != null) {
if (log.isDebugEnabled()) {
log
.debug(format("capturing hidden fields",
name,
value));
}
formfields.put(name, value);
}
}
getFormFields(child, formfields);
}
if (log.isDebugEnabled()) {
log.debug(exit(method));
}
}
@Override
public void populateCacheElement(CacheElement cacheElement, String password) {
String method = "populateCacheElement()";
if (log.isDebugEnabled()) {
log.debug(enter(method));
}
Boolean authenticated = null;
ConnectPubcookie tidyConnect = new ConnectPubcookie();
if (log.isDebugEnabled()) {
log.debug(format(method, "b4 first connect()", "tidyConnect"));
log.debug(tidyConnect);
log.debug(format(method,
null,
"PUBCOOKIE_LOGINPAGE_URL",
PUBCOOKIE_LOGINPAGE_URL));
}
tidyConnect.connect(PUBCOOKIE_LOGINPAGE_URL,
NO_REQUEST_PARAMETERS,
NO_COOKIES,
TRUSTSTORE_LOCATION,
TRUSTSTORE_PASSWORD);
if (!tidyConnect.completedFully()) {
if (log.isInfoEnabled()) {
log.info(format(method, "form page did not load"));
}
} else {
Cookie[] formpageCookies = tidyConnect.getResponseCookies();
Node formpageDocument = tidyConnect.getResponseDocument();
String action =
getAction(formpageDocument, PUBCOOKIE_LOGINPAGE_FORM_NAME);
if (log.isDebugEnabled()) {
log.debug(format(method, "action", action));
}
Map formpageFields = getFormFields(formpageDocument);
Iterator iter = null;
if (log.isDebugEnabled()) {
iter = formpageFields.keySet().iterator();
while (iter.hasNext()) {
String key = (String) iter.next();
log.debug(format(method, null, key, (String) formpageFields
.get(key)));
}
}
formpageFields.put(PUBCOOKIE_LOGINPAGE_INPUT_NAME_USERID,
cacheElement.getUserid());
formpageFields.put(PUBCOOKIE_LOGINPAGE_INPUT_NAME_PASSWORD,
password);
if (log.isDebugEnabled()) {
iter = formpageFields.keySet().iterator();
while (iter.hasNext()) {
String key = (String) iter.next();
log.debug(format(method,
" form field after",
key,
(String) formpageFields.get(key)));
}
}
tidyConnect = new ConnectPubcookie();
if (log.isDebugEnabled()) {
log.debug(format(method, "b4 second connect()"));
}
tidyConnect.connect(action,
formpageFields,
formpageCookies,
TRUSTSTORE_LOCATION,
TRUSTSTORE_PASSWORD);
if (!tidyConnect.completedFully()) {
if (log.isDebugEnabled()) {
log.debug(format(method, "result page did not load"));
}
} else {
Cookie[] resultpageCookies = tidyConnect.getResponseCookies();
if (log.isDebugEnabled()) {
log.debug(format(method, " cookies receieved", "n", Integer
.toString(resultpageCookies.length)));
}
for (Cookie cookie : resultpageCookies) {
if (log.isDebugEnabled()) {
log.debug(format(method,
"another cookie",
"cookie name" + cookie.getName()));
log.debug(format(method,
"another cookie",
"length",
Integer.toString(cookie.getName()
.length())));
}
if (PUBCOOKIE_NAME.equals(cookie.getName())) {
if (log.isInfoEnabled()) {
log.debug(format(method,
" found pubcookie login cookie"));
}
authenticated = Boolean.TRUE;
break;
}
}
if (authenticated == null) {
authenticated = Boolean.FALSE;
} else {
if (!authenticated.booleanValue()) {
if (log.isDebugEnabled()) {
log
.debug(format(method,
"didn't find a pubcookie login cookie"));
}
}
}
}
cacheElement.populate(authenticated, null, null, null);
}
if (log.isDebugEnabled()) {
log.debug(exit(method));
}
}
}