Package org.elasticsearch.plugins.security.filter

Source Code of org.elasticsearch.plugins.security.filter.ActionPathFilter

package org.elasticsearch.plugins.security.filter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.plugins.security.MalformedConfigurationException;
import org.elasticsearch.plugins.security.http.tomcat.TomcatHttpServerRestChannel;
import org.elasticsearch.plugins.security.http.tomcat.TomcatHttpServerRestRequest;
import org.elasticsearch.plugins.security.http.tomcat.TomcatUserRoleCallback;
import org.elasticsearch.plugins.security.service.SecurityService;
import org.elasticsearch.plugins.security.util.EditableRestRequest;
import org.elasticsearch.plugins.security.util.SecurityUtil;
import org.elasticsearch.rest.RestFilterChain;
import org.elasticsearch.rest.RestStatus;

public class ActionPathFilter extends SecureRestFilter {

  public ActionPathFilter(final SecurityService securityService) {
    super(securityService);

  }

  @Override
  public void processSecure(final TomcatHttpServerRestRequest request,
      final TomcatHttpServerRestChannel channel,
      final RestFilterChain filterChain) {

    if (SecurityUtil.stringContainsItemFromListAsTypeOrIndex(
        request.path(), SecurityUtil.BUILT_IN_ADMIN_COMMANDS)) {
      log.warn("Index- or Typename should not contains admin commands like "
          + Arrays.toString(SecurityUtil.BUILT_IN_ADMIN_COMMANDS));
    }

    if (SecurityUtil.stringContainsItemFromListAsTypeOrIndex(
        request.path(), securityService.isStrictModeEnabled()?SecurityUtil.BUILT_IN_READ_COMMANDS_STRICT : SecurityUtil.BUILT_IN_READ_COMMANDS_LAX)) {
      log.warn("Index- or Typename should not contains search commands like "
          + Arrays.toString(securityService.isStrictModeEnabled()?SecurityUtil.BUILT_IN_READ_COMMANDS_STRICT : SecurityUtil.BUILT_IN_READ_COMMANDS_LAX));
    }

    if (SecurityUtil.stringContainsItemFromListAsTypeOrIndex(
        request.path(), securityService.isStrictModeEnabled()?SecurityUtil.BUILT_IN_WRITE_COMMANDS_STRICT : SecurityUtil.BUILT_IN_WRITE_COMMANDS_LAX)) {
      log.warn("Index- or Typename should not contains write commands like "
          + Arrays.toString(securityService.isStrictModeEnabled()?SecurityUtil.BUILT_IN_WRITE_COMMANDS_STRICT : SecurityUtil.BUILT_IN_WRITE_COMMANDS_LAX));
    }

    try {

      final PermLevel permLevel = new PermLevelEvaluator(
          securityService.getXContentSecurityConfiguration(
              getType(), getId()))
      .evaluatePerm(
          SecurityUtil.getIndices(request),
          SecurityUtil.getTypes(request),
          getClientHostAddress(request),
          new TomcatUserRoleCallback(request
              .getHttpServletRequest(),securityService.getSettings().get("security.ssl.userattribute")));

      if (permLevel == PermLevel.NONE) {
        SecurityUtil.send(request, channel, RestStatus.FORBIDDEN,
            "No permission (at all)");
        return;
      }

      if (permLevel.ordinal() < PermLevel.ALL.ordinal()
          && SecurityUtil.isAdminRequest(request)) {
        SecurityUtil.send(request, channel, RestStatus.FORBIDDEN,
            "No permission (for admin actions)");
        return;
      }

      if (permLevel.ordinal() < PermLevel.READWRITE.ordinal()
          && SecurityUtil.isWriteRequest(request,securityService.isStrictModeEnabled())) {
        SecurityUtil.send(request, channel, RestStatus.FORBIDDEN,
            "No permission (for write actions)");
        return;
      }

      if (permLevel == PermLevel.READONLY
          && !SecurityUtil.isReadRequest(request,securityService.isStrictModeEnabled())) {
        SecurityUtil.send(request, channel, RestStatus.FORBIDDEN,
            "No permission (for read actions)");
        return;
      }
     
      // Ram Kotamarja - START
      // adding code to modify request modification before it hits elastic
      // search to apply the search filters
      modifiyKibanaRequest(request, channel);
      // Ram Kotamaraja - END
     

      filterChain.continueProcessing(request, channel);
      return;
    } catch (final MalformedConfigurationException e) {
      log.error("Cannot parse security configuration ", e);
      SecurityUtil.send(request, channel,
          RestStatus.INTERNAL_SERVER_ERROR,
          "Cannot parse security configuration");

      return;
    } catch (final Exception e) {
      log.error("Generic error: ", e);
      SecurityUtil.send(request, channel,
          RestStatus.INTERNAL_SERVER_ERROR,
          "Generic error, see log for details");

      return;
    }

  }
 
  /**
   * Method added to modify the request on the fly to
   * allow it to process generic queries coming from kibana by
   * validating against the security framework (contributed by Ram Kotamaraja)
   * @param request
   */
  private void modifiyKibanaRequest(
      final TomcatHttpServerRestRequest request,
      final TomcatHttpServerRestChannel channel) {

    List<String> reqTypesList = SecurityUtil.getTypes(request);
    if (reqTypesList != null && !reqTypesList.isEmpty()
        && reqTypesList.size() > 0) {
      // This means, there is a type specified in the request and so there
      // is not need to do anything as the framework will take care of the
      // type level security
      log.debug("Not modifying the request (for kibana) as there is one or more types already associated with the request");
      reqTypesList = null;
      return;
    }

    String kibanaPermLevel = null;
    try {
      kibanaPermLevel = securityService.getXContentSecurityConfiguration(
          getType(), getKibanaId());
    } catch (Exception e) {
      log.debug("No Kibana configuration found, so continuing the rest of the process: "+e.getMessage());
      return;
    }

    List<String> kibanaTypesList = null;
    List<String> authorizedTypesList = new ArrayList<String>();
    try {
      if (kibanaPermLevel != null && kibanaPermLevel.length() > 0) {
        kibanaTypesList = securityService.getKibanaTypes(SecurityUtil
            .getIndices(request));
      }

      final String reqContent = request.content().toUtf8();
      String modifiedContent = reqContent;

      // checking where the original request has any types
      List<String> requestTypes = SecurityUtil.getTypes(request);

      // If original request has any requests, then skip the logic below
      // as
      // permission evaluation has to be done based on that specific type
      if (requestTypes == null || requestTypes.isEmpty()
          || requestTypes.size() == 0) {
        if (kibanaTypesList != null) {

          // determine authorized types list
         

          Iterator<String> kibanaTypesItr = kibanaTypesList
              .iterator();

          while (kibanaTypesItr.hasNext()) {

            List<String> kibanaType = new ArrayList<String>();
            kibanaType.add((String) kibanaTypesItr.next());
            final PermLevel permLevel = new PermLevelEvaluator(
                securityService
                    .getXContentSecurityConfiguration(
                        getType(), getId()))
                .evaluatePerm(
                    SecurityUtil.getIndices(request),
                    // SecurityUtil.getTypes(request),
                    kibanaType,
                    getClientHostAddress(request),
                    new TomcatUserRoleCallback(
                        request.getHttpServletRequest(),
                        securityService
                            .getSettings()
                            .get("security.ssl.userattribute")));

            log.debug("Kibana perm level = "+permLevel);

            if (!permLevel.equals(PermLevel.NONE)) {
              authorizedTypesList.addAll(kibanaType);
            }
          }

         

          log.debug("Processing kibana types  "+ kibanaTypesList);
          log.debug("request Content =  "+ reqContent);

          String kibanaFilterStarter = "\"must\":[";
          int beginIndex = reqContent.indexOf(kibanaFilterStarter);
         
          if (beginIndex > 0) {
            String preReqContent = reqContent.substring(0,
                beginIndex + kibanaFilterStarter.length());
            String postReqContent = reqContent.substring(beginIndex
                + kibanaFilterStarter.length());

            modifiedContent = preReqContent
                + "{\"or\": {\"filters\":[";

            if (authorizedTypesList != null) {
              Iterator<String> authorizedTypesItr = authorizedTypesList
                  .iterator();
              while (authorizedTypesItr.hasNext()) {
                modifiedContent += "{\"type\":{\"value\":\""
                    + authorizedTypesItr.next().toString()
                    + "\"}},";
              }
              modifiedContent = modifiedContent.substring(0,
                  modifiedContent.length() - 1);
            }

            modifiedContent += "]}}," + postReqContent;
            log.debug("modified request content = " + modifiedContent);
                       
            request.setContent(new BytesArray(modifiedContent));
            request.setAttribute(TomcatHttpServerRestRequest.REQUEST_CONTENT_ATTRIBUTE, request.getContent());

          }
        }
      }
    } catch (MalformedConfigurationException e) {
      log.error("Cannot parse security configuration ", e);
      SecurityUtil.send(request, channel,
          RestStatus.INTERNAL_SERVER_ERROR,
          "Cannot parse security configuration");

      return;
    } catch (Exception e) {
      log.error("Generic error: ", e);
      SecurityUtil.send(request, channel,
          RestStatus.INTERNAL_SERVER_ERROR,
          "Generic error, see log for details");

      return;
    }

  }

  /**
   * Method to return the default id (contributed by Ram Kotamaraja)
   * @return String - default id string
   */
   protected String getKibanaId() {
        return "kibana";
     }

  @Override
  protected String getType() {

    return "actionpathfilter";
  }

  @Override
  protected String getId() {

    return "actionpathfilter";
  }

}
TOP

Related Classes of org.elasticsearch.plugins.security.filter.ActionPathFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.