/* 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 org.fcrepo.server.security.servletfilters;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Bill Niebel
*/
public class Cache {
private static final Logger logger =
LoggerFactory.getLogger(Cache.class);
static boolean firstCall = true;
private final String cacheId;
private final String cacheAbbrev;
private final String CACHE_KEY_SEPARATOR;
private final String AUTH_SUCCESS_TIMEOUT_UNIT;
private final int AUTH_SUCCESS_TIMEOUT_DURATION;
private final String AUTH_FAILURE_TIMEOUT_UNIT;
private final int AUTH_FAILURE_TIMEOUT_DURATION;
private final String AUTH_EXCEPTION_TIMEOUT_UNIT;
private final int AUTH_EXCEPTION_TIMEOUT_DURATION;
private final CacheElementPopulator cacheElementPopulator;
public final String getCacheId() {
return cacheId;
}
public final String getCacheAbbrev() {
return cacheAbbrev;
}
public final String getCacheKeySeparator() {
return CACHE_KEY_SEPARATOR;
}
public final String getAuthSuccessTimeoutUnit() {
return AUTH_SUCCESS_TIMEOUT_UNIT;
}
public final int getAuthSuccessTimeoutDuration() {
return AUTH_SUCCESS_TIMEOUT_DURATION;
}
public final String getAuthFailureTimeoutUnit() {
return AUTH_FAILURE_TIMEOUT_UNIT;
}
public final int getAuthFailureTimeoutDuration() {
return AUTH_FAILURE_TIMEOUT_DURATION;
}
public final String getAuthExceptionTimeoutUnit() {
return AUTH_EXCEPTION_TIMEOUT_UNIT;
}
public final int getAuthExceptionTimeoutDuration() {
return AUTH_EXCEPTION_TIMEOUT_DURATION;
}
public final CacheElementPopulator getCacheElementPopulator() {
return cacheElementPopulator;
}
@SuppressWarnings("deprecation")
public Cache(String cacheId,
String CACHE_KEY_SEPARATOR,
String AUTH_SUCCESS_TIMEOUT_UNIT,
int AUTH_SUCCESS_TIMEOUT_DURATION,
String AUTH_FAILURE_TIMEOUT_UNIT,
int AUTH_FAILURE_TIMEOUT_DURATION,
String AUTH_EXCEPTION_TIMEOUT_UNIT,
int AUTH_EXCEPTION_TIMEOUT_DURATION,
CacheElementPopulator cacheElementPopulator) {
this.cacheId = cacheId;
this.CACHE_KEY_SEPARATOR = CACHE_KEY_SEPARATOR;
this.AUTH_SUCCESS_TIMEOUT_UNIT = AUTH_SUCCESS_TIMEOUT_UNIT;
this.AUTH_SUCCESS_TIMEOUT_DURATION = AUTH_SUCCESS_TIMEOUT_DURATION;
this.AUTH_FAILURE_TIMEOUT_UNIT = AUTH_FAILURE_TIMEOUT_UNIT;
this.AUTH_FAILURE_TIMEOUT_DURATION = AUTH_FAILURE_TIMEOUT_DURATION;
this.AUTH_EXCEPTION_TIMEOUT_UNIT = AUTH_EXCEPTION_TIMEOUT_UNIT;
this.AUTH_EXCEPTION_TIMEOUT_DURATION = AUTH_EXCEPTION_TIMEOUT_DURATION;
this.cacheElementPopulator = cacheElementPopulator;
cacheAbbrev = FilterSetup.getFilterNameAbbrev(getCacheId());
}
private final Map<String, CacheElement> cache = new Hashtable<String, CacheElement>();
public final void audit(String userid) {
String m = getCacheAbbrev() + " audit() ";
CacheElement cacheElement = getCacheElement(userid);
if (cacheElement == null) {
logger.debug(m + "cache element is null for " + userid);
} else {
cacheElement.audit();
}
}
private static final String getKey(String userid /*
* , String password,
* String
* cacheKeySeparator
*/) {
return userid /* + cacheKeySeparator + password */;
}
/*
* synchronize so that each access gets the same item instance (protect
* against overlapping calls) note that expiration logic of cache element
* changes the element's state -- elements are never removed from cache or
* replaced
*/
private final synchronized CacheElement getCacheElement(String userid) {
String m = getCacheAbbrev() + " getCacheElement() ";
CacheElement cacheElement = null;
String key = getKey(userid);
logger.debug(m + "key==" + key);
if (cache.containsKey(key)) {
logger.debug(m + "cache already has element");
} else {
logger.debug(m + "cache does not have element; create and put");
CacheElement itemtemp =
new CacheElement(userid, getCacheId(), getCacheAbbrev());
cache.put(key, itemtemp);
}
cacheElement = (CacheElement) cache.get(key);
if (cacheElement == null) {
logger.error(m + "cache does not contain element");
} else {
logger.debug(m + "element retrieved from cache successfully");
}
return cacheElement;
}
public static final void testAssert() {
try {
assert false;
logger.debug("asserts are not turned on");
} catch (Throwable t) {
logger.debug("asserts are turned on");
}
}
public final Boolean authenticate(CacheElementPopulator authenticator,
String userid,
String password) throws Throwable {
if (firstCall) {
testAssert();
firstCall = false;
}
String m = getCacheAbbrev() + " authenticate() ";
if (logger.isDebugEnabled()) {
logger.debug(m + "----------------------------------------------");
logger.debug(m + "> " + getCacheId() + " [" + userid + "] ["
+ password + "]");
} else {
logger.info("Authenticating user [{}]", userid);
}
CacheElement cacheElement = getCacheElement(userid /* , password */);
logger.debug("{}cacheElement=={}", m, cacheElement.getInstanceId());
Boolean authenticated = null;
try {
authenticated = cacheElement.authenticate(this, password);
} catch (Throwable t) {
logger.error("Error authenticating", t);
throw t;
}
logger.debug("{}< {}", m, authenticated);
return authenticated;
}
public final Map<String, Set<?>> getNamedValues(CacheElementPopulator authenticator,
String userid,
String password) throws Throwable {
if (firstCall) {
testAssert();
firstCall = false;
}
String m = getCacheAbbrev() + " getNamedValues() ";
if (logger.isDebugEnabled()) {
logger.debug(m + "----------------------------------------------");
logger.debug(m + "> " + getCacheId() + " [" + userid + "] ["
+ password + "]");
}
CacheElement cacheElement = getCacheElement(userid /* , password */);
logger.debug("{}cacheElement=={}", m, cacheElement.getInstanceId());
Map<String, Set<?>> namedValues = null;
try {
namedValues = cacheElement.getNamedValues(this, password);
} catch (Throwable t) {
logger.error("Error getting named values", t);
throw t;
}
logger.debug("{}< {}", m, namedValues);
return namedValues;
}
}