/* 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;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Hashtable;
import com.sun.xacml.EvaluationCtx;
import com.sun.xacml.attr.AttributeDesignator;
import com.sun.xacml.attr.StringAttribute;
import com.sun.xacml.cond.EvaluationResult;
import org.apache.log4j.Logger;
import fedora.common.Constants;
import fedora.server.Context;
/**
* @author Bill Niebel
*/
class ContextAttributeFinderModule
extends AttributeFinderModule {
/** Logger for this class. */
private static final Logger LOG =
Logger.getLogger(ContextAttributeFinderModule.class.getName());
@Override
protected boolean canHandleAdhoc() {
return true;
}
static private final ContextAttributeFinderModule singleton =
new ContextAttributeFinderModule();
private final Hashtable contexts = new Hashtable();
private ContextAttributeFinderModule() {
super();
try {
registerSupportedDesignatorType(AttributeDesignator.SUBJECT_TARGET);
registerSupportedDesignatorType(AttributeDesignator.ACTION_TARGET); //<<??????
registerSupportedDesignatorType(AttributeDesignator.RESOURCE_TARGET); //<<?????
registerSupportedDesignatorType(AttributeDesignator.ENVIRONMENT_TARGET);
registerAttribute(Constants.ENVIRONMENT.CURRENT_DATE_TIME.uri,
Constants.ENVIRONMENT.CURRENT_DATE_TIME.datatype);
registerAttribute(Constants.ENVIRONMENT.CURRENT_DATE.uri,
Constants.ENVIRONMENT.CURRENT_DATE.datatype);
registerAttribute(Constants.ENVIRONMENT.CURRENT_TIME.uri,
Constants.ENVIRONMENT.CURRENT_TIME.datatype);
registerAttribute(Constants.HTTP_REQUEST.PROTOCOL.uri,
Constants.HTTP_REQUEST.PROTOCOL.datatype);
registerAttribute(Constants.HTTP_REQUEST.SCHEME.uri,
Constants.HTTP_REQUEST.SCHEME.datatype);
registerAttribute(Constants.HTTP_REQUEST.SECURITY.uri,
Constants.HTTP_REQUEST.SECURITY.datatype);
registerAttribute(Constants.HTTP_REQUEST.AUTHTYPE.uri,
Constants.HTTP_REQUEST.AUTHTYPE.datatype);
registerAttribute(Constants.HTTP_REQUEST.METHOD.uri,
Constants.HTTP_REQUEST.METHOD.datatype);
registerAttribute(Constants.HTTP_REQUEST.SESSION_ENCODING.uri,
Constants.HTTP_REQUEST.SESSION_ENCODING.datatype);
registerAttribute(Constants.HTTP_REQUEST.SESSION_STATUS.uri,
Constants.HTTP_REQUEST.SESSION_STATUS.datatype);
registerAttribute(Constants.HTTP_REQUEST.CONTENT_LENGTH.uri,
Constants.HTTP_REQUEST.CONTENT_LENGTH.datatype);
registerAttribute(Constants.HTTP_REQUEST.CONTENT_TYPE.uri,
Constants.HTTP_REQUEST.CONTENT_TYPE.datatype);
registerAttribute(Constants.HTTP_REQUEST.CLIENT_FQDN.uri,
Constants.HTTP_REQUEST.CLIENT_FQDN.datatype);
registerAttribute(Constants.HTTP_REQUEST.CLIENT_IP_ADDRESS.uri,
Constants.HTTP_REQUEST.CLIENT_IP_ADDRESS.datatype);
registerAttribute(Constants.HTTP_REQUEST.SERVER_FQDN.uri,
Constants.HTTP_REQUEST.SERVER_FQDN.datatype);
registerAttribute(Constants.HTTP_REQUEST.SERVER_IP_ADDRESS.uri,
Constants.HTTP_REQUEST.SERVER_IP_ADDRESS.datatype);
registerAttribute(Constants.HTTP_REQUEST.SERVER_PORT.uri,
Constants.HTTP_REQUEST.SERVER_PORT.datatype);
attributesDenied.add(PolicyEnforcementPoint.XACML_SUBJECT_ID);
attributesDenied.add(PolicyEnforcementPoint.XACML_ACTION_ID);
attributesDenied.add(PolicyEnforcementPoint.XACML_RESOURCE_ID);
attributesDenied.add(Constants.ACTION.CONTEXT_ID.uri);
attributesDenied.add(Constants.SUBJECT.LOGIN_ID.uri);
attributesDenied.add(Constants.ACTION.ID.uri);
attributesDenied.add(Constants.ACTION.API.uri);
setInstantiatedOk(true);
} catch (URISyntaxException e1) {
setInstantiatedOk(false);
}
}
static public final ContextAttributeFinderModule getInstance() {
return singleton;
}
private final String getContextId(EvaluationCtx context) {
URI contextIdType = null;
URI contextIdId = null;
try {
contextIdType = new URI(StringAttribute.identifier);
} catch (URISyntaxException e) {
LOG.debug("ContextAttributeFinder:getContextId" + " exit on "
+ "couldn't make URI for contextId type");
}
try {
contextIdId = new URI(Constants.ACTION.CONTEXT_ID.uri);
} catch (URISyntaxException e) {
LOG.debug("ContextAttributeFinder:getContextId" + " exit on "
+ "couldn't make URI for contextId itself");
}
LOG.debug("ContextAttributeFinder:findAttribute"
+ " about to call getAttributeFromEvaluationCtx");
EvaluationResult attribute =
context.getActionAttribute(contextIdType, contextIdId, null);
Object element = getAttributeFromEvaluationResult(attribute);
if (element == null) {
LOG.debug("ContextAttributeFinder:getContextId" + " exit on "
+ "can't get contextId on request callback");
return null;
}
if (!(element instanceof StringAttribute)) {
LOG.debug("ContextAttributeFinder:getContextId" + " exit on "
+ "couldn't get contextId from xacml request "
+ "non-string returned");
return null;
}
String contextId = ((StringAttribute) element).getValue();
if (contextId == null) {
LOG.debug("ContextAttributeFinder:getContextId" + " exit on "
+ "null contextId");
return null;
}
if (!validContextId(contextId)) {
LOG.debug("ContextAttributeFinder:getContextId" + " exit on "
+ "invalid context-id");
return null;
}
return contextId;
}
private final boolean validContextId(String contextId) {
if (contextId == null) {
return false;
}
if ("".equals(contextId)) {
return false;
}
if (" ".equals(contextId)) {
return false;
}
return true;
}
@Override
protected final Object getAttributeLocally(int designatorType,
String attributeId,
URI resourceCategory,
EvaluationCtx ctx) {
LOG.debug("getAttributeLocally context");
String contextId = getContextId(ctx);
LOG.debug("contextId=" + contextId + " attributeId=" + attributeId);
Context context = (Context) contexts.get(contextId);
LOG.debug("got context");
Object values = null;
LOG.debug("designatorType" + designatorType);
switch (designatorType) {
case AttributeDesignator.SUBJECT_TARGET:
if (0 > context.nSubjectValues(attributeId)) {
values = null;
} else {
LOG.debug("getting n values for " + attributeId + "="
+ context.nSubjectValues(attributeId));
switch (context.nSubjectValues(attributeId)) {
case 0:
values = null;
/*
* values = new String[1]; ((String[])values)[0] =
* Authorization.UNDEFINED;
*/
break;
case 1:
values = new String[1];
((String[]) values)[0] =
context.getSubjectValue(attributeId);
break;
default:
values = context.getSubjectValues(attributeId);
}
if (values == null) {
LOG.debug("RETURNING NO VALUES FOR " + attributeId);
} else {
StringBuffer sb = new StringBuffer();
sb.append("RETURNING " + ((String[]) values).length
+ " VALUES FOR " + attributeId + " ==");
for (int i = 0; i < ((String[]) values).length; i++) {
sb.append(" " + ((String[]) values)[i]);
}
LOG.debug(sb);
}
}
break;
case AttributeDesignator.ACTION_TARGET:
if (0 > context.nActionValues(attributeId)) {
values = null;
} else {
switch (context.nActionValues(attributeId)) {
case 0:
values = null;
/*
* values = new String[1]; ((String[])values)[0] =
* Authorization.UNDEFINED;
*/
break;
case 1:
values = new String[1];
((String[]) values)[0] =
context.getActionValue(attributeId);
break;
default:
values = context.getActionValues(attributeId);
}
}
break;
case AttributeDesignator.RESOURCE_TARGET:
if (0 > context.nResourceValues(attributeId)) {
values = null;
} else {
switch (context.nResourceValues(attributeId)) {
case 0:
values = null;
/*
* values = new String[1]; ((String[])values)[0] =
* Authorization.UNDEFINED;
*/
break;
case 1:
values = new String[1];
((String[]) values)[0] =
context.getResourceValue(attributeId);
break;
default:
values = context.getResourceValues(attributeId);
}
}
break;
case AttributeDesignator.ENVIRONMENT_TARGET:
if (0 > context.nEnvironmentValues(attributeId)) {
values = null;
} else {
switch (context.nEnvironmentValues(attributeId)) {
case 0:
values = null;
/*
* values = new String[1]; ((String[])values)[0] =
* Authorization.UNDEFINED;
*/
break;
case 1:
values = new String[1];
((String[]) values)[0] =
context.getEnvironmentValue(attributeId);
break;
default:
values = context.getEnvironmentValues(attributeId);
}
}
break;
default:
}
if (values instanceof String) {
LOG.debug("getAttributeLocally string value=" + (String) values);
} else if (values instanceof String[]) {
LOG.debug("getAttributeLocally string values=" + values);
for (int i = 0; i < ((String[]) values).length; i++) {
LOG.debug("another string value=" + ((String[]) values)[i]);
}
} else {
LOG.debug("getAttributeLocally object value=" + values);
}
return values;
}
final void registerContext(Object key, Context value) {
LOG.debug("registering " + key);
contexts.put(key, value);
}
final void unregisterContext(Object key) {
LOG.debug("unregistering " + key);
contexts.remove(key);
}
}