Ejemplo n.º 1
0
  @Override
  public QueryResponse processPostQuery(QueryResponse input) throws StopProcessingException {
    if (input.getRequest() == null || input.getRequest().getProperties() == null) {
      throw new StopProcessingException(
          "Unable to filter contents of current message, no user Subject available.");
    }
    Subject subject = getSubject(input);

    List<Result> results = input.getResults();
    List<Result> newResults = new ArrayList<>(results.size());
    Metacard metacard;
    KeyValueCollectionPermission securityPermission =
        new KeyValueCollectionPermission(CollectionPermission.READ_ACTION);
    int filteredMetacards = 0;
    for (Result result : results) {
      metacard = result.getMetacard();
      Attribute attr = metacard.getAttribute(Metacard.SECURITY);
      if (!checkPermissions(attr, securityPermission, subject, CollectionPermission.READ_ACTION)) {
        for (FilterStrategy filterStrategy : filterStrategies.values()) {
          FilterResult filterResult = filterStrategy.process(input, metacard);
          if (filterResult.processed()) {
            if (filterResult.metacard() != null) {
              newResults.add(new ResultImpl(filterResult.metacard()));
            }
            break;
            // returned responses are ignored for queries
          }
        }
        filteredMetacards++;
      } else {
        newResults.add(result);
      }
    }

    LOGGER.info("Filtered {} metacards, returned {}", filteredMetacards, newResults.size());
    SecurityLogger.logInfo(
        "Filtered " + filteredMetacards + " metacards, returned " + newResults.size());

    input.getResults().clear();
    input.getResults().addAll(newResults);
    newResults.clear();
    return input;
  }
  /**
   * Overrides the implies method to handle checking for the existence of one attribute - the "match
   * one" scenario rather than the "match all" behavior of the overridden classes. Specifically,
   * this permission will imply another permission if that permission matches at least one of our
   * permission attributes.
   *
   * @param p the permission to check for behavior/functionality comparison.
   * @return {@code true} if this current instance <em>implies</em> the specified {@code Permission}
   *     argument, {@code false} otherwise.
   */
  @Override
  public boolean implies(Permission p) {
    if (permissionList.isEmpty()) {
      SecurityLogger.logDebug(
          PERMISSION_START_MSG
              + toString()
              + PERMISSION_NOT_IMPLIES_MSG
              + p.toString()
              + PERMISSION_END_MSG);
      return false;
    }

    if (p instanceof CollectionPermission) {
      for (Permission perm : ((CollectionPermission) p).getPermissionList()) {
        boolean result = false;
        for (Permission ourPerm : permissionList) {
          // we only care about the key value permission here, because that one can have
          // multiple values
          // mapped to a single key. In the case of "match one" we only need one of those
          // values to satisfy
          // the permission.
          if (ourPerm instanceof KeyValuePermission) {
            for (String value : ((KeyValuePermission) ourPerm).getValues()) {
              // Since this is "match one" we know that only one of these values needs
              // to match in order
              // for the entire permission at that key to be implied
              // So here we loop through all of the values assigned to that key and
              // create new
              // single valued key value permissions
              KeyValuePermission kvp =
                  new KeyValuePermission(((KeyValuePermission) ourPerm).getKey());
              kvp.addValue(value);
              if (perm.implies(kvp)) {
                result = true;
                break;
              }
            }
            // Currently we use key value permissions for everything. However, we still need
            // to be able to handle
            // permissions other than KV, so this else block will serve as the catch all for
            // everything else.
          } else {
            // Shiro permissions are always a "match all" condition so we need to flip
            // the implies to make it match one
            if (perm.implies(ourPerm)) {
              result = true;
              break;
            }
          }
        }
        if (!result) {
          SecurityLogger.logDebug(
              PERMISSION_START_MSG
                  + toString()
                  + PERMISSION_NOT_IMPLIES_MSG
                  + p.toString()
                  + PERMISSION_END_MSG);
          return false;
        }
      }
      SecurityLogger.logDebug(
          PERMISSION_START_MSG
              + toString()
              + PERMISSION_IMPLIES_MSG
              + p.toString()
              + PERMISSION_END_MSG);
      return true;
    }

    // default catch all permission check
    for (Permission permission : permissionList) {
      // Shiro permissions are always a "match all" condition so we need to flip the implies
      // to make it match one
      if (p.implies(permission)) {
        SecurityLogger.logDebug(
            PERMISSION_START_MSG
                + toString()
                + PERMISSION_IMPLIES_MSG
                + p.toString()
                + PERMISSION_END_MSG);
        return true;
      }
    }
    SecurityLogger.logDebug(
        PERMISSION_START_MSG
            + toString()
            + PERMISSION_NOT_IMPLIES_MSG
            + p.toString()
            + PERMISSION_END_MSG);
    return false;
  }
Ejemplo n.º 3
0
  @Override
  public boolean[] isPermitted(PrincipalCollection subjectPrincipal, List<Permission> permissions) {
    boolean[] results = new boolean[permissions.size()];
    AuthorizationInfo info = getAuthorizationInfo(subjectPrincipal);
    Permission curPermission;
    boolean curResponse;
    String curAction;
    for (int i = 0; i < permissions.size(); i++) {
      curPermission = permissions.get(i);
      if (curPermission instanceof ActionPermission) {
        curAction = ((ActionPermission) curPermission).getAction();
        logger.debug(
            "Checking if {} has access to perform a {} action",
            subjectPrincipal.getPrimaryPrincipal(),
            curAction);

        SecurityLogger.logInfo(
            "Checking if ["
                + subjectPrincipal.getPrimaryPrincipal()
                + "] has access to perform a ["
                + curAction
                + "] action");

        logger.debug("Received authZ info, creating XACML request.");
        RequestType curRequest =
            createActionXACMLRequest(
                (String) subjectPrincipal.getPrimaryPrincipal(), info, curAction);
        logger.debug("Created XACML request, calling PDP.");

        curResponse = isPermitted(curRequest);
        logger.debug("Received response from PDP, returning {}.", curResponse);
        results[i] = curResponse;
      } else if (curPermission instanceof KeyValueCollectionPermission) {
        logger.debug(
            "Checking if {} has access to current metacard",
            subjectPrincipal.getPrimaryPrincipal());

        SecurityLogger.logInfo(
            "Checking if ["
                + subjectPrincipal.getPrimaryPrincipal()
                + "] has access to view current metacard");

        logger.debug("Received authZ info, creating XACML request.");
        RequestType curRequest =
            createRedactXACMLRequest(
                (String) subjectPrincipal.getPrimaryPrincipal(),
                info,
                (KeyValueCollectionPermission) curPermission);
        logger.debug("Created XACML request, calling PDP.");

        curResponse = isPermitted(curRequest);
        logger.debug("Received response from PDP, returning {}.", curResponse);
        results[i] = curResponse;
      } else if (curPermission instanceof KeyValuePermission) {
        // Need to refactor this into a private method with the above condition
        // This is to handle the case where there is a single KeyValuePermission
        logger.debug(
            "Checking if {} has access to current metacard",
            subjectPrincipal.getPrimaryPrincipal());

        SecurityLogger.logInfo(
            "Checking if ["
                + subjectPrincipal.getPrimaryPrincipal()
                + "] has access to view current metacard");
        KeyValueCollectionPermission keyValueCollectionPermission =
            new KeyValueCollectionPermission((KeyValuePermission) curPermission);
        logger.debug("Received authZ info, creating XACML request.");
        RequestType curRequest =
            createRedactXACMLRequest(
                (String) subjectPrincipal.getPrimaryPrincipal(),
                info,
                keyValueCollectionPermission);
        logger.debug("Created XACML request, calling PDP.");

        curResponse = isPermitted(curRequest);
        logger.debug("Received response from PDP, returning {}.", curResponse);
        results[i] = curResponse;
      } else {
        logger.warn(
            "Could not check permissions with {}, permission being requested MUST be an ActionPermission or RedactionPermission",
            curPermission);
        results[i] = false;
      }
    }
    return results;
  }
Ejemplo n.º 4
0
    QuerySources initializeSources(
        QueryOperations queryOps, QueryRequest queryRequest, Set<String> sourceIds) {
      if (queryRequest.isEnterprise()) { // Check if it's an enterprise query
        addConnectedSources = true;
        addCatalogProvider = queryOps.hasCatalogProvider();

        if (sourceIds != null && !sourceIds.isEmpty()) {
          LOGGER.debug("Enterprise Query also included specific sites which will now be ignored");
          sourceIds.clear();
        }

        // add all the federated sources
        Set<String> notPermittedSources = new HashSet<>();
        for (FederatedSource source : frameworkProperties.getFederatedSources().values()) {
          boolean canAccessSource = queryOps.canAccessSource(source, queryRequest);
          if (!canAccessSource) {
            notPermittedSources.add(source.getId());
          }
          if (queryOps.sourceOperations.isSourceAvailable(source) && canAccessSource) {
            sourcesToQuery.add(source);
          } else {
            exceptions.add(queryOps.createUnavailableProcessingDetails(source));
          }
        }
        if (!notPermittedSources.isEmpty()) {
          SecurityLogger.audit(
              "Subject is not permitted to access sources {}", notPermittedSources);
        }

      } else if (CollectionUtils.isNotEmpty(sourceIds)) {
        // it's a targeted federated query
        if (queryOps.includesLocalSources(sourceIds)) {
          LOGGER.debug("Local source is included in sourceIds");
          addConnectedSources =
              CollectionUtils.isNotEmpty(frameworkProperties.getConnectedSources());
          addCatalogProvider = queryOps.hasCatalogProvider();
          sourceIds.remove(queryOps.getId());
          sourceIds.remove(null);
          sourceIds.remove("");
        }

        // See if we still have sources to look up by name
        if (!sourceIds.isEmpty()) {
          Set<String> notPermittedSources = new HashSet<>();
          for (String id : sourceIds) {
            LOGGER.debug("Looking up source ID = {}", id);
            boolean sourceFound = false;
            if (frameworkProperties.getFederatedSources().containsKey(id)) {
              sourceFound = true;
              boolean canAccessSource =
                  queryOps.canAccessSource(
                      frameworkProperties.getFederatedSources().get(id), queryRequest);
              if (!canAccessSource) {
                notPermittedSources.add(frameworkProperties.getFederatedSources().get(id).getId());
              }
              if (frameworkProperties.getFederatedSources().get(id).isAvailable()
                  && canAccessSource) {
                sourcesToQuery.add(frameworkProperties.getFederatedSources().get(id));
              } else {
                exceptions.add(
                    queryOps.createUnavailableProcessingDetails(
                        frameworkProperties.getFederatedSources().get(id)));
              }
            }

            if (!sourceFound) {
              exceptions.add(
                  new ProcessingDetailsImpl(
                      id, new SourceUnavailableException("Source id is not found")));
            }
          }
          if (!notPermittedSources.isEmpty()) {
            SecurityLogger.audit(
                "Subject is not permitted to access sources {}", notPermittedSources);
          }
        }
      } else {
        // default to local sources
        addConnectedSources = CollectionUtils.isNotEmpty(frameworkProperties.getConnectedSources());
        addCatalogProvider = queryOps.hasCatalogProvider();
      }

      return this;
    }