@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;
  }
Ejemplo n.º 3
0
 /**
  * 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();
 }