@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));
    }
  }
Ejemplo n.º 2
0
  /*
   * (non-Javadoc)
   *
   * @see org.wso2.balana.finder.AttributeFinderModule#findAttribute(java.net.URI, java.net.URI,
   * java.net.URI, java.net.URI, org.wso2.balana.EvaluationCtx, int)
   */
  public EvaluationResult findAttribute(
      URI attributeType, URI attributeId, String issuer, URI category, EvaluationCtx context) {

    List<AttributeValue> attrBag = new ArrayList<AttributeValue>();
    // Get the list of attribute finders who are registered with this particular attribute.
    List<PIPAttributeFinder> finders = attrFinders.get(attributeId.toString());

    if (finders == null || finders.size() == 0) {
      //          there is a API for refresh attribute finder so remove this
      //			try {
      //				refreshAttributeFindersForNewAttributeId();
      //			} catch (Exception e) {
      //				log.warn("Error while refreshing attribute finders");
      //			}
      finders = attrFinders.get(attributeId.toString());
      if (finders == null || finders.size() == 0) {
        log.info("No attribute designators defined for the attribute " + attributeId.toString());
        return new EvaluationResult(BagAttribute.createEmptyBag(attributeType));
      }
    }

    try {

      for (Iterator iterator = finders.iterator(); iterator.hasNext(); ) {
        PIPAttributeFinder pipAttributeFinder = (PIPAttributeFinder) iterator.next();
        if (log.isDebugEnabled()) {
          log.debug(
              String.format(
                  "Finding attributes with the PIP attribute handler %1$s",
                  pipAttributeFinder.getClass()));
        }

        Set<String> attrs = null;
        String key = null;

        if (attributeFinderCache != null && !pipAttributeFinder.overrideDefaultCache()) {

          key =
              attributeType.toString()
                  + attributeId.toString()
                  + category.toString()
                  + encodeContext(context);

          if (issuer != null) {
            key += issuer;
          }

          if (key != null) {
            attrs = attributeFinderCache.getFromCache(tenantId, key);
          }
        }

        if (attrs == null) {
          if (log.isDebugEnabled()) {
            log.debug("Carbon Attribute Cache Miss");
          }
          attrs =
              pipAttributeFinder.getAttributeValues(
                  attributeType, attributeId, category, issuer, context);
          if (attributeFinderCache != null
              && key != null
              && !pipAttributeFinder.overrideDefaultCache()) {
            attributeFinderCache.addToCache(tenantId, key, attrs);
          }
        } else {
          if (log.isDebugEnabled()) {
            log.debug("Carbon Attribute Cache Hit");
          }
        }

        if (attrs != null) {
          for (Iterator iterAttr = attrs.iterator(); iterAttr.hasNext(); ) {
            final String attr = (String) iterAttr.next();
            AttributeValue attribute =
                EntitlementUtil.getAttributeValue(attr, attributeType.toString());
            attrBag.add(attribute);
          }
        }
      }
    } catch (ParsingException e) {
      log.error("Error while parsing attribute values from EvaluationCtx : " + e);
      ArrayList<String> code = new ArrayList<String>();
      code.add(Status.STATUS_MISSING_ATTRIBUTE);
      Status status =
          new Status(
              code, "Error while parsing attribute values from EvaluationCtx : " + e.getMessage());
      return new EvaluationResult(status);
    } catch (ParseException e) {
      e.printStackTrace();
      log.error("Error while parsing attribute values from EvaluationCtx : " + e);
      ArrayList<String> code = new ArrayList<String>();
      code.add(Status.STATUS_MISSING_ATTRIBUTE);
      Status status =
          new Status(
              code, "Error while parsing attribute values from EvaluationCtx : " + e.getMessage());
      return new EvaluationResult(status);
    } catch (URISyntaxException e) {
      log.error("Error while parsing attribute values from EvaluationCtx : " + e);
      ArrayList<String> code = new ArrayList<String>();
      code.add(Status.STATUS_MISSING_ATTRIBUTE);
      Status status =
          new Status(
              code, "Error while parsing attribute values from EvaluationCtx :" + e.getMessage());
      return new EvaluationResult(status);
    } catch (Exception e) {
      log.error("Error while retrieving attribute values from PIP  attribute finder : " + e);
      ArrayList<String> code = new ArrayList<String>();
      code.add(Status.STATUS_MISSING_ATTRIBUTE);
      Status status =
          new Status(
              code,
              "Error while retrieving attribute values from PIP"
                  + " attribute finder : "
                  + e.getMessage());
      return new EvaluationResult(status);
    }
    return new EvaluationResult(new BagAttribute(attributeType, attrBag));
  }