/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.hadoop.security.http;

import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This filter provides protection against cross site request forgery (CSRF)
 * attacks for REST APIs. Enabling this filter on an endpoint results in the
 * requirement of all client to send a particular (configurable) HTTP header
 * with every request. In the absense of this header the filter will reject the
 * attempt as a bad request.
 */
@InterfaceAudience.Public
@InterfaceStability.Evolving
public class RestCsrfPreventionFilter implements Filter {

  private static final Logger LOG =
      LoggerFactory.getLogger(RestCsrfPreventionFilter.class);

  public static final String HEADER_USER_AGENT = "User-Agent";
  public static final String BROWSER_USER_AGENT_PARAM =
      "browser-useragents-regex";
  public static final String CUSTOM_HEADER_PARAM = "custom-header";
  public static final String CUSTOM_METHODS_TO_IGNORE_PARAM =
      "methods-to-ignore";
  static final String  BROWSER_USER_AGENTS_DEFAULT = "^Mozilla.*,^Opera.*";
  public static final String HEADER_DEFAULT = "X-XSRF-HEADER";
  static final String  METHODS_TO_IGNORE_DEFAULT = "GET,OPTIONS,HEAD,TRACE";
  private String  headerName = HEADER_DEFAULT;
  private Set<String> methodsToIgnore = null;
  private Set<Pattern> browserUserAgents;

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    String customHeader = filterConfig.getInitParameter(CUSTOM_HEADER_PARAM);
    if (customHeader != null) {
      headerName = customHeader;
    }
    String customMethodsToIgnore =
        filterConfig.getInitParameter(CUSTOM_METHODS_TO_IGNORE_PARAM);
    if (customMethodsToIgnore != null) {
      parseMethodsToIgnore(customMethodsToIgnore);
    } else {
      parseMethodsToIgnore(METHODS_TO_IGNORE_DEFAULT);
    }

    String agents = filterConfig.getInitParameter(BROWSER_USER_AGENT_PARAM);
    if (agents == null) {
      agents = BROWSER_USER_AGENTS_DEFAULT;
    }
    parseBrowserUserAgents(agents);
    LOG.info("Adding cross-site request forgery (CSRF) protection, "
        + "headerName = {}, methodsToIgnore = {}, browserUserAgents = {}",
        headerName, methodsToIgnore, browserUserAgents);
  }

  void parseBrowserUserAgents(String userAgents) {
    String[] agentsArray =  userAgents.split(",");
    browserUserAgents = new HashSet<Pattern>();
    for (String patternString : agentsArray) {
      browserUserAgents.add(Pattern.compile(patternString));
    }
  }

  void parseMethodsToIgnore(String mti) {
    String[] methods = mti.split(",");
    methodsToIgnore = new HashSet<String>();
    for (int i = 0; i < methods.length; i++) {
      methodsToIgnore.add(methods[i]);
    }
  }

  /**
   * This method interrogates the User-Agent String and returns whether it
   * refers to a browser.  If its not a browser, then the requirement for the
   * CSRF header will not be enforced; if it is a browser, the requirement will
   * be enforced.
   * <p>
   * A User-Agent String is considered to be a browser if it matches
   * any of the regex patterns from browser-useragent-regex; the default
   * behavior is to consider everything a browser that matches the following:
   * "^Mozilla.*,^Opera.*".  Subclasses can optionally override
   * this method to use different behavior.
   *
   * @param userAgent The User-Agent String, or null if there isn't one
   * @return true if the User-Agent String refers to a browser, false if not
   */
  protected boolean isBrowser(String userAgent) {
    if (userAgent == null) {
      return false;
    }
    for (Pattern pattern : browserUserAgents) {
      Matcher matcher = pattern.matcher(userAgent);
      if (matcher.matches()) {
        return true;
      }
    }
    return false;
  }

  /**
   * Defines the minimal API requirements for the filter to execute its
   * filtering logic.  This interface exists to facilitate integration in
   * components that do not run within a servlet container and therefore cannot
   * rely on a servlet container to dispatch to the {@link #doFilter} method.
   * Applications that do run inside a servlet container will not need to write
   * code that uses this interface.  Instead, they can use typical servlet
   * container configuration mechanisms to insert the filter.
   */
  public interface HttpInteraction {

    /**
     * Returns the value of a header.
     *
     * @param header name of header
     * @return value of header
     */
    String getHeader(String header);

    /**
     * Returns the method.
     *
     * @return method
     */
    String getMethod();

    /**
     * Called by the filter after it decides that the request may proceed.
     *
     * @throws IOException if there is an I/O error
     * @throws ServletException if the implementation relies on the servlet API
     *     and a servlet API call has failed
     */
    void proceed() throws IOException, ServletException;

    /**
     * Called by the filter after it decides that the request is a potential
     * CSRF attack and therefore must be rejected.
     *
     * @param code status code to send
     * @param message response message
     * @throws IOException if there is an I/O error
     */
    void sendError(int code, String message) throws IOException;
  }

  /**
   * Handles an {@link HttpInteraction} by applying the filtering logic.
   *
   * @param httpInteraction caller's HTTP interaction
   * @throws IOException if there is an I/O error
   * @throws ServletException if the implementation relies on the servlet API
   *     and a servlet API call has failed
   */
  public void handleHttpInteraction(HttpInteraction httpInteraction)
      throws IOException, ServletException {
    if (!isBrowser(httpInteraction.getHeader(HEADER_USER_AGENT)) ||
        methodsToIgnore.contains(httpInteraction.getMethod()) ||
        httpInteraction.getHeader(headerName) != null) {
      httpInteraction.proceed();
    } else {
      httpInteraction.sendError(HttpServletResponse.SC_BAD_REQUEST,
          "Missing Required Header for CSRF Vulnerability Protection");
    }
  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response,
      final FilterChain chain) throws IOException, ServletException {
    final HttpServletRequest httpRequest = (HttpServletRequest)request;
    final HttpServletResponse httpResponse = (HttpServletResponse)response;
    handleHttpInteraction(new ServletFilterHttpInteraction(httpRequest,
        httpResponse, chain));
  }

  @Override
  public void destroy() {
  }

  /**
   * Constructs a mapping of configuration properties to be used for filter
   * initialization.  The mapping includes all properties that start with the
   * specified configuration prefix.  Property names in the mapping are trimmed
   * to remove the configuration prefix.
   *
   * @param conf configuration to read
   * @param confPrefix configuration prefix
   * @return mapping of configuration properties to be used for filter
   *     initialization
   */
  public static Map<String, String> getFilterParams(Configuration conf,
      String confPrefix) {
    return conf.getPropsWithPrefix(confPrefix);
  }

  /**
   * {@link HttpInteraction} implementation for use in the servlet filter.
   */
  private static final class ServletFilterHttpInteraction
      implements HttpInteraction {

    private final FilterChain chain;
    private final HttpServletRequest httpRequest;
    private final HttpServletResponse httpResponse;

    /**
     * Creates a new ServletFilterHttpInteraction.
     *
     * @param httpRequest request to process
     * @param httpResponse response to process
     * @param chain filter chain to forward to if HTTP interaction is allowed
     */
    public ServletFilterHttpInteraction(HttpServletRequest httpRequest,
        HttpServletResponse httpResponse, FilterChain chain) {
      this.httpRequest = httpRequest;
      this.httpResponse = httpResponse;
      this.chain = chain;
    }

    @Override
    public String getHeader(String header) {
      return httpRequest.getHeader(header);
    }

    @Override
    public String getMethod() {
      return httpRequest.getMethod();
    }

    @Override
    public void proceed() throws IOException, ServletException {
      chain.doFilter(httpRequest, httpResponse);
    }

    @Override
    public void sendError(int code, String message) throws IOException {
      httpResponse.sendError(code, message);
    }
  }
}
