/* 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.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.Set; import javax.servlet.ServletContext; import com.sun.xacml.EvaluationCtx; import com.sun.xacml.attr.AttributeValue; import com.sun.xacml.attr.BagAttribute; import com.sun.xacml.attr.DateAttribute; import com.sun.xacml.attr.DateTimeAttribute; import com.sun.xacml.attr.IntegerAttribute; import com.sun.xacml.attr.StringAttribute; import com.sun.xacml.attr.TimeAttribute; import com.sun.xacml.cond.EvaluationResult; import com.sun.xacml.ctx.Status; import org.apache.log4j.Logger; /** * @author Bill Niebel */ abstract class AttributeFinderModule extends com.sun.xacml.finder.AttributeFinderModule { /** Logger for this class. */ private static final Logger LOG = Logger.getLogger(AttributeFinderModule.class.getName()); private ServletContext servletContext = null; protected void setServletContext(ServletContext servletContext) { if (this.servletContext == null) { this.servletContext = servletContext; } } protected AttributeFinderModule() { URI temp; try { temp = new URI(StringAttribute.identifier); } catch (URISyntaxException e1) { temp = null; // TODO Auto-generated catch block e1.printStackTrace(); } STRING_ATTRIBUTE_URI = temp; } private Boolean instantiatedOk = null; protected final void setInstantiatedOk(boolean value) { LOG.debug("setInstantiatedOk() " + value); if (instantiatedOk == null) { instantiatedOk = new Boolean(value); } } @Override public boolean isDesignatorSupported() { LOG.debug("isDesignatorSupported() will return " + iAm() + " " + (instantiatedOk != null && instantiatedOk.booleanValue())); return instantiatedOk != null && instantiatedOk.booleanValue(); } private final boolean parmsOk(URI attributeType, URI attributeId, int designatorType) { LOG.debug("in parmsOk " + iAm()); if (!getSupportedDesignatorTypes() .contains(new Integer(designatorType))) { LOG.debug("AttributeFinder:parmsOk" + iAm() + " exit on " + "target not supported"); return false; } if (attributeType == null) { LOG.debug("AttributeFinder:parmsOk" + iAm() + " exit on " + "null attributeType"); return false; } if (attributeId == null) { LOG.debug("AttributeFinder:parmsOk" + iAm() + " exit on " + "null attributeId"); return false; } LOG.debug("AttributeFinder:parmsOk" + iAm() + " looking for " + attributeId.toString()); showRegisteredAttributes(); if (hasAttribute(attributeId.toString())) { if (!getAttributeType(attributeId.toString()).equals(attributeType .toString())) { LOG.debug("AttributeFinder:parmsOk" + iAm() + " exit on " + "attributeType incorrect for attributeId"); return false; } } else { if (!StringAttribute.identifier.equals(attributeType.toString())) { LOG.debug("AttributeFinder:parmsOk" + iAm() + " exit on " + "attributeType incorrect for attributeId"); return false; } } LOG.debug("exiting parmsOk normally " + iAm()); return true; } protected String iAm() { return this.getClass().getName(); } protected final Object getAttributeFromEvaluationResult(EvaluationResult attribute /* * URI * type, * URI * id, * URI * category, * EvaluationCtx * context */) { if (attribute.indeterminate()) { LOG.debug("AttributeFinder:getAttributeFromEvaluationCtx" + iAm() + " exit on " + "couldn't get resource attribute from xacml request " + "indeterminate"); return null; } if (attribute.getStatus() != null && !Status.STATUS_OK.equals(attribute.getStatus())) { LOG.debug("AttributeFinder:getAttributeFromEvaluationCtx" + iAm() + " exit on " + "couldn't get resource attribute from xacml request " + "bad status"); return null; } // (resourceAttribute.getStatus() == null) == everything is ok AttributeValue attributeValue = attribute.getAttributeValue(); if (!(attributeValue instanceof BagAttribute)) { LOG.debug("AttributeFinder:getAttributeFromEvaluationCtx" + iAm() + " exit on " + "couldn't get resource attribute from xacml request " + "no bag"); return null; } BagAttribute bag = (BagAttribute) attributeValue; if (1 != bag.size()) { LOG.debug("AttributeFinder:getAttributeFromEvaluationCtx" + iAm() + " exit on " + "couldn't get resource attribute from xacml request " + "wrong bag n=" + bag.size()); return null; } Iterator it = bag.iterator(); Object element = it.next(); if (element == null) { LOG.debug("AttributeFinder:getAttributeFromEvaluationCtx" + iAm() + " exit on " + "couldn't get resource attribute from xacml request " + "null returned"); return null; } if (it.hasNext()) { LOG.debug("AttributeFinder:getAttributeFromEvaluationCtx" + iAm() + " exit on " + "couldn't get resource attribute from xacml request " + "too many returned"); LOG.debug(element.toString()); while (it.hasNext()) { LOG.debug(it.next().toString()); } return null; } LOG.debug("AttributeFinder:getAttributeFromEvaluationCtx " + iAm() + " returning " + element.toString()); return element; } protected final HashSet attributesDenied = new HashSet(); private final Hashtable<String, URI> attributeIdUris = new Hashtable<String, URI>(); private final Hashtable<String, String> attributeTypes = new Hashtable<String, String>(); private final Hashtable<String, URI> attributeTypeUris = new Hashtable<String, URI>(); protected final void registerAttribute(String id, String type) throws URISyntaxException { LOG.debug("registering attribute " + iAm() + " " + id); attributeIdUris.put(id, new URI(id)); attributeTypeUris.put(id, new URI(type)); attributeTypes.put(id, type); } protected final URI getAttributeIdUri(String id) { return attributeIdUris.get(id); } protected final boolean hasAttribute(String id) { return attributeIdUris.containsKey(id); } private final void showRegisteredAttributes() { Iterator it = attributeIdUris.keySet().iterator(); while (it.hasNext()) { String key = (String) it.next(); LOG.debug("another registered attribute = " + iAm() + " " + key); } } protected final String getAttributeType(String id) { return attributeTypes.get(id); } protected final URI getAttributeTypeUri(String id) { return attributeTypeUris.get(id); } private static final Set NULLSET = new HashSet(); private final Set<Integer> supportedDesignatorTypes = new HashSet<Integer>(); protected final void registerSupportedDesignatorType(int designatorType) { LOG.debug("registerSupportedDesignatorType() " + iAm()); supportedDesignatorTypes.add(designatorType); } @Override public Set getSupportedDesignatorTypes() { if (instantiatedOk != null && instantiatedOk.booleanValue()) { LOG.debug("getSupportedDesignatorTypes() will return " + iAm() + " set of elements, n=" + supportedDesignatorTypes.size()); return supportedDesignatorTypes; } LOG.debug("getSupportedDesignatorTypes() will return " + iAm() + "NULLSET"); return NULLSET; } protected abstract boolean canHandleAdhoc(); private final boolean willService(URI attributeId) { String temp = attributeId.toString(); if (hasAttribute(temp)) { LOG.debug("willService() " + iAm() + " accept this known serviced attribute " + attributeId.toString()); return true; } if (!canHandleAdhoc()) { LOG.debug("willService() " + iAm() + " deny any adhoc attribute " + attributeId.toString()); return false; } if (attributesDenied.contains(temp)) { LOG.debug("willService() " + iAm() + " deny this known adhoc attribute " + attributeId.toString()); return false; } LOG.debug("willService() " + iAm() + " allow this unknown adhoc attribute " + attributeId.toString()); return true; } @Override public EvaluationResult findAttribute(URI attributeType, URI attributeId, URI issuer, URI category, EvaluationCtx context, int designatorType) { LOG.debug("AttributeFinder:findAttribute " + iAm()); LOG.debug("attributeType=[" + attributeType + "], attributeId=[" + attributeId + "]" + iAm()); if (!parmsOk(attributeType, attributeId, designatorType)) { LOG.debug("AttributeFinder:findAttribute" + " exit on " + "parms not ok" + iAm()); if (attributeType == null) { try { attributeType = new URI(StringAttribute.identifier); } catch (URISyntaxException e) { //we tried } } return new EvaluationResult(BagAttribute .createEmptyBag(attributeType)); } if (!willService(attributeId)) { LOG.debug("AttributeFinder:willService() " + iAm() + " returns false" + iAm()); return new EvaluationResult(BagAttribute .createEmptyBag(attributeType)); } if (category != null) { LOG.debug("++++++++++ AttributeFinder:findAttribute " + iAm() + " category=" + category.toString()); } LOG.debug("++++++++++ AttributeFinder:findAttribute " + iAm() + " designatorType=" + designatorType); LOG.debug("about to get temp " + iAm()); Object temp = getAttributeLocally(designatorType, attributeId.toASCIIString(), category, context); LOG.debug(iAm() + " got temp=" + temp); if (temp == null) { LOG.debug("AttributeFinder:findAttribute" + " exit on " + "attribute value not found" + iAm()); return new EvaluationResult(BagAttribute .createEmptyBag(attributeType)); } Set<AttributeValue> set = new HashSet<AttributeValue>(); if (temp instanceof String) { LOG.debug("AttributeFinder:findAttribute" + " will return a " + "String " + iAm()); if (attributeType.toString().equals(StringAttribute.identifier)) { set.add(new StringAttribute((String) temp)); } else if (attributeType.toString() .equals(DateTimeAttribute.identifier)) { DateTimeAttribute tempDateTimeAttribute; try { tempDateTimeAttribute = DateTimeAttribute.getInstance((String) temp); set.add(tempDateTimeAttribute); } catch (Throwable t) { } } else if (attributeType.toString() .equals(DateAttribute.identifier)) { DateAttribute tempDateAttribute; try { tempDateAttribute = DateAttribute.getInstance((String) temp); set.add(tempDateAttribute); } catch (Throwable t) { } } else if (attributeType.toString() .equals(TimeAttribute.identifier)) { TimeAttribute tempTimeAttribute; try { tempTimeAttribute = TimeAttribute.getInstance((String) temp); set.add(tempTimeAttribute); } catch (Throwable t) { } } else if (attributeType.toString() .equals(IntegerAttribute.identifier)) { IntegerAttribute tempIntegerAttribute; try { tempIntegerAttribute = IntegerAttribute.getInstance((String) temp); set.add(tempIntegerAttribute); } catch (Throwable t) { } } //xacml fixup //was set.add(new StringAttribute((String)temp)); } else if (temp instanceof String[]) { LOG.debug("AttributeFinder:findAttribute" + " will return a " + "String[] " + iAm()); for (int i = 0; i < ((String[]) temp).length; i++) { if (((String[]) temp)[i] == null) { continue; } if (attributeType.toString().equals(StringAttribute.identifier)) { set.add(new StringAttribute(((String[]) temp)[i])); } else if (attributeType.toString() .equals(DateTimeAttribute.identifier)) { LOG.debug("USING AS DATETIME:" + ((String[]) temp)[i]); DateTimeAttribute tempDateTimeAttribute; try { tempDateTimeAttribute = DateTimeAttribute .getInstance(((String[]) temp)[i]); set.add(tempDateTimeAttribute); } catch (Throwable t) { } } else if (attributeType.toString() .equals(DateAttribute.identifier)) { LOG.debug("USING AS DATE:" + ((String[]) temp)[i]); DateAttribute tempDateAttribute; try { tempDateAttribute = DateAttribute.getInstance(((String[]) temp)[i]); set.add(tempDateAttribute); } catch (Throwable t) { } } else if (attributeType.toString() .equals(TimeAttribute.identifier)) { LOG.debug("USING AS TIME:" + ((String[]) temp)[i]); TimeAttribute tempTimeAttribute; try { tempTimeAttribute = TimeAttribute.getInstance(((String[]) temp)[i]); set.add(tempTimeAttribute); } catch (Throwable t) { } } else if (attributeType.toString() .equals(IntegerAttribute.identifier)) { LOG.debug("USING AS INTEGER:" + ((String[]) temp)[i]); IntegerAttribute tempIntegerAttribute; try { tempIntegerAttribute = IntegerAttribute .getInstance(((String[]) temp)[i]); set.add(tempIntegerAttribute); } catch (Throwable t) { } } } } return new EvaluationResult(new BagAttribute(attributeType, set)); } protected final URI STRING_ATTRIBUTE_URI; abstract protected Object getAttributeLocally(int designatorType, String attributeId, URI resourceCategory, EvaluationCtx context); }