@SuppressWarnings("unused") @Override public EvaluationResult findAttribute( String contextPath, URI attributeType, String contextSelector, Node root, EvaluationCtx context, String xpathVersion) { Node contextNode = null; NamespaceContext namespaceContext = null; System.out.println( "Context path ==> " + contextPath + " AttributeType ==> " + attributeType + " Context Selector ==> " + contextSelector + " Root Node name ==> " + root.getNodeName() + " root node type==> " + root.getNodeType() + " root node value==> " + root.getNodeValue() + " Context ==> " + context + " XPath version ==> " + xpathVersion); if (root == null) { System.out.println("Root node is null "); // root == null means there is not content element defined with the // attributes element // therefore complete request is evaluated. // get the DOM root of the request document contextNode = context.getRequestRoot(); } else if (contextSelector != null) { System.out.println("Content selector is not null "); // root != null means content element is there. we can find the // context node by // evaluating the contextSelector // 1st assume context node as the root // TODO - Check if the contextNode should be assigned to root contextNode = root; XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); // see if the request root is in a namespace String namespace = null; if (contextNode != null) { namespace = contextNode.getNamespaceURI(); System.out.println(" nameSpace ==> " + contextNode); } // name spaces are used, so we need to lookup the correct // prefix to use in the search string NamedNodeMap namedNodeMap = contextNode.getAttributes(); Map<String, String> nsMap = new HashMap<String, String>(); for (int i = 0; i < namedNodeMap.getLength(); i++) { Node n = namedNodeMap.item(i); // we found the matching namespace, so get the prefix // and then break out String prefix = DOMHelper.getLocalName(n); String nodeValue = n.getNodeValue(); System.out.println("nodeValue of nameaspace ==> " + nodeValue); nsMap.put(prefix, nodeValue); } // if there is not any namespace is defined for content element, // default XACML request // name space would be there. if (XACMLConstants.REQUEST_CONTEXT_3_0_IDENTIFIER.equals(namespace) || XACMLConstants.REQUEST_CONTEXT_2_0_IDENTIFIER.equals(namespace) || XACMLConstants.REQUEST_CONTEXT_1_0_IDENTIFIER.equals(namespace)) { nsMap.put("xacml", namespace); } namespaceContext = new DefaultNamespaceContext(nsMap); xpath.setNamespaceContext(namespaceContext); try { XPathExpression expression = xpath.compile(contextSelector); NodeList result = (NodeList) expression.evaluate(contextNode, XPathConstants.NODESET); if (result == null || result.getLength() == 0) { throw new Exception("No node is found from context selector id evaluation"); } else if (result.getLength() != 1) { throw new Exception("More than one node is found from context selector id evaluation"); } contextNode = result.item(0); } catch (Exception e) { List<String> codes = new ArrayList<String>(); codes.add(Status.STATUS_SYNTAX_ERROR); Status status = new Status(codes, e.getMessage()); return new EvaluationResult(status); } } else { contextNode = root; } XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); if (namespaceContext == null) { // see if the request root is in a namespace String namespace = null; if (contextNode != null) { namespace = contextNode.getNamespaceURI(); } // name spaces are used, so we need to lookup the correct // prefix to use in the search string NamedNodeMap namedNodeMap = contextNode.getAttributes(); Map<String, String> nsMap = new HashMap<String, String>(); for (int i = 0; i < namedNodeMap.getLength(); i++) { Node n = namedNodeMap.item(i); // we found the matching namespace, so get the prefix // and then break out String prefix = DOMHelper.getLocalName(n); String nodeValue = n.getNodeValue(); nsMap.put(prefix, nodeValue); } // if there is not any namespace is defined for content element, // default XACML request // name space would be there. if (XACMLConstants.REQUEST_CONTEXT_3_0_IDENTIFIER.equals(namespace) || XACMLConstants.REQUEST_CONTEXT_2_0_IDENTIFIER.equals(namespace) || XACMLConstants.REQUEST_CONTEXT_1_0_IDENTIFIER.equals(namespace)) { nsMap.put("xacml", namespace); } namespaceContext = new DefaultNamespaceContext(nsMap); } xpath.setNamespaceContext(namespaceContext); NodeList matches; try { XPathExpression expression = xpath.compile(contextPath); matches = (NodeList) expression.evaluate(contextNode, XPathConstants.NODESET); if (matches == null || matches.getLength() < 1) { throw new Exception("No node is found from xpath evaluation"); } } catch (XPathExpressionException e) { List<String> codes = new ArrayList<String>(); codes.add(Status.STATUS_SYNTAX_ERROR); Status status = new Status(codes, e.getMessage()); return new EvaluationResult(status); } catch (Exception e) { List<String> codes = new ArrayList<String>(); codes.add(Status.STATUS_SYNTAX_ERROR); Status status = new Status(codes, e.getMessage()); return new EvaluationResult(status); } if (matches.getLength() == 0) { // we didn't find anything, so we return an empty bag return new EvaluationResult(BagAttribute.createEmptyBag(attributeType)); } // there was at least one match, so try to generate the values try { ArrayList<AttributeValue> list = new ArrayList<AttributeValue>(); AttributeFactory attrFactory = Balana.getInstance().getAttributeFactory(); for (int i = 0; i < matches.getLength(); i++) { String text = null; Node node = matches.item(i); short nodeType = node.getNodeType(); // see if this is straight text, or a node with data under // it and then get the values accordingly if ((nodeType == Node.CDATA_SECTION_NODE) || (nodeType == Node.COMMENT_NODE) || (nodeType == Node.TEXT_NODE) || (nodeType == Node.ATTRIBUTE_NODE)) { // there is no child to this node text = node.getNodeValue(); } else { // the data is in a child node text = node.getFirstChild().getNodeValue(); } list.add(attrFactory.createValue(attributeType, text)); } return new EvaluationResult(new BagAttribute(attributeType, list)); } catch (ParsingException pe) { ArrayList<String> code = new ArrayList<String>(); code.add(Status.STATUS_PROCESSING_ERROR); return new EvaluationResult(new Status(code, pe.getMessage())); } catch (UnknownIdentifierException uie) { ArrayList<String> code = new ArrayList<String>(); code.add(Status.STATUS_PROCESSING_ERROR); return new EvaluationResult(new Status(code, "Unknown attribute type : " + attributeType)); } }
@Override public Set<String> findDescendantResources(String parentResourceId, EvaluationCtx context) throws Exception { EvaluationResult environment; String environmentId = null; Set<String> resourceNames = null; NodeList children = context.getRequestRoot().getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); if (child != null) { if (PDPConstants.ENVIRONMENT_ELEMENT.equals(child.getLocalName())) { if (child.getChildNodes() != null && child.getChildNodes().getLength() > 0) { environment = context.getAttribute( new URI(StringAttribute.identifier), new URI(PDPConstants.ENVIRONMENT_ID_DEFAULT), null, new URI(XACMLConstants.ENT_CATEGORY)); if (environment != null && environment.getAttributeValue() != null && environment.getAttributeValue().isBag()) { BagAttribute attr = (BagAttribute) environment.getAttributeValue(); environmentId = ((AttributeValue) attr.iterator().next()).encode(); } } } } } if (isAbstractResourceCacheEnabled) { IdentityCacheKey cacheKey; String key = PDPConstants.RESOURCE_DESCENDANTS + parentResourceId + (environmentId != null ? environmentId : ""); tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId(); cacheKey = new IdentityCacheKey(tenantId, key); IdentityCacheEntry cacheEntry = (IdentityCacheEntry) abstractResourceCache.getValueFromCache(cacheKey); if (cacheEntry != null) { String[] values = cacheEntry.getCacheEntryArray(); resourceNames = new HashSet<String>(Arrays.asList(values)); if (log.isDebugEnabled()) { log.debug("Carbon Resource Cache Hit"); } } if (resourceNames != null) { resourceNames = findDescendantResources(parentResourceId, environmentId); if (log.isDebugEnabled()) { log.debug("Carbon Resource Cache Miss"); } if (resourceNames != null && !resourceNames.isEmpty()) { cacheEntry = new IdentityCacheEntry(resourceNames.toArray(new String[resourceNames.size()])); abstractResourceCache.addToCache(cacheKey, cacheEntry); } } } else { resourceNames = findDescendantResources(parentResourceId, environmentId); } return resourceNames; }
/** * Converts DOM object to String. This is a helper method for creating cache key * * @param evaluationCtx EvaluationCtx * @return String Object * @throws TransformerException Exception throws if fails */ private String encodeContext(EvaluationCtx evaluationCtx) throws TransformerException { OutputStream stream = new ByteArrayOutputStream(); evaluationCtx.getRequestCtx().encode(stream); return stream.toString(); }