/* 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;
import java.security.Principal;
import java.util.Hashtable;
import java.util.Map;
import java.util.Vector;
import javax.servlet.FilterConfig;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author Bill Niebel
*/
public abstract class BaseCaching
extends BaseContributing
implements CacheElementPopulator {
protected static Log log = LogFactory.getLog(BaseCaching.class);
//use additional indirection level to distinguish multiple uses of the same code for different filter instances
private static final Map superCache = new Hashtable();
protected final Cache getCache(String filterName) {
String method = "getCache()";
if (log.isDebugEnabled()) {
log.debug(enterExit(method));
}
return (Cache) superCache.get(filterName);
}
private final void putCache(String filterName, Cache cache) {
String method = "putCache()";
if (log.isDebugEnabled()) {
log.debug(enterExit(method));
}
superCache.put(filterName, cache);
}
@Override
public void init(FilterConfig filterConfig) {
String method = "init()";
if (log.isDebugEnabled()) {
log.debug(enter(method));
}
super.init(filterConfig);
inited = false;
if (!initErrors) {
Cache cache = getCache(FILTER_NAME);
if (cache == null) {
cache = getNewCache();
putCache(FILTER_NAME, cache);
}
}
if (initErrors) {
if (log.isErrorEnabled()) {
log
.error(format(method,
"cache not set up correctly; see previous error"));
}
}
inited = true;
if (log.isDebugEnabled()) {
log.debug(exit(method));
}
}
@Override
public void destroy() {
String method = "destroy()";
if (log.isDebugEnabled()) {
log.debug(enter(method));
}
super.destroy();
if (log.isDebugEnabled()) {
log.debug(exit(method));
}
}
protected Cache getNewCache() {
String method = "getNewCache()";
if (log.isDebugEnabled()) {
log.debug(enter(method));
}
Cache cache = new Cache(FILTER_NAME, "", //CACHE_KEY_SEPARATOR
LOOKUP_SUCCESS_TIMEOUT_UNIT,
LOOKUP_SUCCESS_TIMEOUT_DURATION,
AUTHN_FAILURE_TIMEOUT_UNIT,
AUTHN_FAILURE_TIMEOUT_DURATION,
LOOKUP_EXCEPTION_TIMEOUT_UNIT,
LOOKUP_EXCEPTION_TIMEOUT_DURATION,
this);
if (log.isDebugEnabled()) {
log.debug(exit(method));
}
return cache;
}
protected boolean SPONSORING = false;
public static final String LOOKUP_SUCCESS_TIMEOUT_UNIT_KEY =
"lookup-success-timeout-unit";
public static final String LOOKUP_SUCCESS_TIMEOUT_DURATION_KEY =
"lookup-success-timeout-duration";
public static final String AUTHN_FAILURE_TIMEOUT_UNIT_KEY =
"authn-failure-timeout-unit";
public static final String AUTHN_FAILURE_TIMEOUT_DURATION_KEY =
"authn-failure-timeout-duration";
public static final String LOOKUP_EXCEPTION_TIMEOUT_UNIT_KEY =
"lookup-exception-timeout-unit";
public static final String LOOKUP_EXCEPTION_TIMEOUT_DURATION_KEY =
"lookup-exception-timeout-duration";
//defaults
private final String LOOKUP_SUCCESS_TIMEOUT_UNIT_DEFAULT = "MINUTE";
private final int LOOKUP_SUCCESS_TIMEOUT_DURATION_DEFAULT = 10;
private final String AUTHN_FAILURE_TIMEOUT_UNIT_DEFAULT = "SECOND";
private final int AUTHN_FAILURE_TIMEOUT_DURATION_DEFAULT = 1;
private final String LOOKUP_EXCEPTION_TIMEOUT_UNIT_DEFAULT = "SECOND";
private final int LOOKUP_EXCEPTION_TIMEOUT_DURATION_DEFAULT = 1;
private String LOOKUP_SUCCESS_TIMEOUT_UNIT =
LOOKUP_SUCCESS_TIMEOUT_UNIT_DEFAULT;
private int LOOKUP_SUCCESS_TIMEOUT_DURATION =
LOOKUP_SUCCESS_TIMEOUT_DURATION_DEFAULT;
private String AUTHN_FAILURE_TIMEOUT_UNIT =
AUTHN_FAILURE_TIMEOUT_UNIT_DEFAULT;
private int AUTHN_FAILURE_TIMEOUT_DURATION =
AUTHN_FAILURE_TIMEOUT_DURATION_DEFAULT;
private String LOOKUP_EXCEPTION_TIMEOUT_UNIT =
LOOKUP_EXCEPTION_TIMEOUT_UNIT_DEFAULT;
private int LOOKUP_EXCEPTION_TIMEOUT_DURATION =
LOOKUP_EXCEPTION_TIMEOUT_DURATION_DEFAULT;
public String AUTHENTICATE_KEY = "authenticate";
public String AUTHENTICATED_USER_KEY = "associated-filters";
public String SPONSORED_USER_KEY = "surrogate-associated-filters";
@Override
protected void initThisSubclass(String key, String value) {
String method = "initThisSubclass()";
if (log.isDebugEnabled()) {
log.debug(enter(method));
}
boolean setLocally = false;
if (LOOKUP_SUCCESS_TIMEOUT_UNIT_KEY.equals(key)) {
LOOKUP_SUCCESS_TIMEOUT_UNIT = value;
setLocally = true;
} else if (LOOKUP_SUCCESS_TIMEOUT_DURATION_KEY.equals(key)) {
LOOKUP_SUCCESS_TIMEOUT_DURATION = Integer.parseInt(value);
setLocally = true;
} else if (AUTHN_FAILURE_TIMEOUT_UNIT_KEY.equals(key)) {
AUTHN_FAILURE_TIMEOUT_UNIT = value;
setLocally = true;
} else if (AUTHN_FAILURE_TIMEOUT_DURATION_KEY.equals(key)) {
AUTHN_FAILURE_TIMEOUT_DURATION = Integer.parseInt(value);
setLocally = true;
} else if (LOOKUP_EXCEPTION_TIMEOUT_UNIT_KEY.equals(key)) {
LOOKUP_EXCEPTION_TIMEOUT_UNIT = value;
setLocally = true;
} else if (LOOKUP_EXCEPTION_TIMEOUT_DURATION_KEY.equals(key)) {
LOOKUP_EXCEPTION_TIMEOUT_DURATION = Integer.parseInt(value);
setLocally = true;
} else if (AUTHENTICATE_KEY.equals(key)) {
try {
AUTHENTICATE = booleanValue(value);
} catch (Exception e) {
if (log.isErrorEnabled()) {
log.error(format(method,
"known parameter, bad value",
key,
value));
}
initErrors = true;
}
setLocally = true;
} else if (AUTHENTICATED_USER_KEY.equals(key)) {
String[] temp = value.split(",");
FILTERS_CONTRIBUTING_AUTHENTICATED_ATTRIBUTES =
new Vector(temp.length);
for (String element : temp) {
FILTERS_CONTRIBUTING_AUTHENTICATED_ATTRIBUTES.add(element);
}
setLocally = true;
} else if (SPONSORED_USER_KEY.equals(key)) {
log.error(format(method,
null,
"\"SPONSORED_USER_KEY\"",
SPONSORED_USER_KEY));
log
.error(format(method,
null,
"other filters associated with this filter for surrogates",
value));
String[] temp = value.split(",");
FILTERS_CONTRIBUTING_SPONSORED_ATTRIBUTES = new Vector(temp.length);
for (String element : temp) {
log.error(format(method, null, "adding", element));
FILTERS_CONTRIBUTING_SPONSORED_ATTRIBUTES.add(element);
}
setLocally = true;
} else {
if (log.isDebugEnabled()) {
log.debug(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));
}
}
@Override
protected boolean authenticate(boolean alreadyAuthenticated) {
boolean authenticate = AUTHENTICATE && !alreadyAuthenticated;
return authenticate;
}
@Override
public void authenticate(ExtendedHttpServletRequest extendedHttpServletRequest)
throws Exception {
String method = "authenticate()";
if (log.isDebugEnabled()) {
log.debug(enter(method));
}
try {
String userid = extendedHttpServletRequest.getUser();
if (log.isDebugEnabled()) {
log.debug(format(method, null, "userid", userid));
}
boolean authenticated = false;
if (userid != null && !"".equals(userid)) {
String password = extendedHttpServletRequest.getPassword();
if (log.isDebugEnabled()) {
log.debug(format(method, null, "password", password));
}
Cache cache = getCache(FILTER_NAME);
if (log.isDebugEnabled()) {
log.debug(format(method, "calling cache.authenticate()"));
}
Boolean result = cache.authenticate(this, userid, password);
authenticated = result != null && result.booleanValue();
if (authenticated) {
Principal authenticatingPrincipal =
new fedora.server.security.servletfilters.Principal(userid);
extendedHttpServletRequest
.setAuthenticated(authenticatingPrincipal,
FILTER_NAME);
if (log.isDebugEnabled()) {
log.debug(format(method, "set authenticated"));
}
}
if (log.isDebugEnabled()) {
log.debug(format(method, "calling audit", "user", userid));
}
cache.audit(userid);
}
} catch (Throwable th) {
showThrowable(th, log, "general " + method + " failure");
}
if (log.isDebugEnabled()) {
log.debug(exit(method));
}
}
public void contributeAttributes(ExtendedHttpServletRequest extendedHttpServletRequest,
String userid,
String password) throws Exception {
String method = "gatherAttributes()";
if (log.isDebugEnabled()) {
log.debug(enter(method));
}
if (!extendedHttpServletRequest.isAuthenticated()) {
throw new Exception();
}
try {
Cache cache = getCache(FILTER_NAME);
/*
* if (log.isDebugEnabled()) log.debug(format(method, "calling
* cache.getPredicates()")); Set predicates =
* cache.getPredicates(this, userid, password);
*/
if (log.isDebugEnabled()) {
log.debug(format(method, "calling cache.getNamedValues()"));
}
Map namedValues = cache.getNamedValues(this, userid, password);
//extendedHttpServletRequest.addRoles(FILTER_NAME, predicates);
extendedHttpServletRequest.addAttributes(FILTER_NAME, namedValues);
if (log.isDebugEnabled()) {
log.debug(format(method, "gatherAttributes calling audit"));
}
cache.audit(userid);
if (log.isDebugEnabled()) {
log.debug(format(method, "at end of gatherAttributes"));
}
} catch (Throwable th) {
showThrowable(th, log, "general " + method + " failure");
}
if (log.isDebugEnabled()) {
log.debug(exit(method));
}
}
@Override
public void contributeAuthenticatedAttributes(ExtendedHttpServletRequest extendedHttpServletRequest)
throws Exception {
String method = "gatherAuthenticatedAttributes()";
if (log.isDebugEnabled()) {
log.debug(enter(method));
}
if (extendedHttpServletRequest.getUserPrincipal() != null) {
String userid = extendedHttpServletRequest.getUser();
String password = extendedHttpServletRequest.getPassword();
contributeAttributes(extendedHttpServletRequest, userid, password);
}
if (log.isDebugEnabled()) {
log.debug(exit(method));
}
}
@Override
public void contributeSponsoredAttributes(ExtendedHttpServletRequest extendedHttpServletRequest)
throws Exception {
String method = "gatherSponsoredAttributes()";
if (log.isDebugEnabled()) {
log.debug(enter(method));
}
String sponsoredUser = extendedHttpServletRequest.getFromHeader();
if (sponsoredUser != null && !"".equals(sponsoredUser)) {
String password = "";
contributeAttributes(extendedHttpServletRequest,
sponsoredUser,
password);
}
if (log.isDebugEnabled()) {
log.debug(exit(method));
}
}
public void populateCacheElement(CacheElement cacheElement, String password) {
String method = "populateCacheElement()";
if (log.isWarnEnabled()) {
log.warn(format(method,
"must implement this method in filter subclass"));
}
}
}