/**
 * 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.token.delegation.web;

import com.google.common.annotations.VisibleForTesting;

import org.apache.curator.framework.CuratorFramework;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.SaslRpcServer;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
import org.apache.hadoop.security.authentication.server.AuthenticationHandler;
import org.apache.hadoop.security.authentication.server.AuthenticationToken;
import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
import org.apache.hadoop.security.authentication.server.MultiSchemeAuthenticationHandler;
import org.apache.hadoop.security.authentication.server.PseudoAuthenticationHandler;
import org.apache.hadoop.security.authentication.util.ZKSignerSecretProvider;
import org.apache.hadoop.security.authorize.AuthorizationException;
import org.apache.hadoop.security.authorize.ProxyUsers;
import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenSecretManager;
import org.apache.hadoop.security.token.delegation.ZKDelegationTokenSecretManager;
import org.apache.hadoop.util.HttpExceptionUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.nio.charset.Charset;
import java.security.Principal;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;

/**
 *  The <code>DelegationTokenAuthenticationFilter</code> filter is a
 *  {@link AuthenticationFilter} with Hadoop Delegation Token support.
 *  <p/>
 *  By default it uses it own instance of the {@link
 *  AbstractDelegationTokenSecretManager}. For situations where an external
 *  <code>AbstractDelegationTokenSecretManager</code> is required (i.e. one that
 *  shares the secret with <code>AbstractDelegationTokenSecretManager</code>
 *  instance running in other services), the external
 *  <code>AbstractDelegationTokenSecretManager</code> must be set as an
 *  attribute in the {@link ServletContext} of the web application using the
 *  {@link #DELEGATION_TOKEN_SECRET_MANAGER_ATTR} attribute name (
 *  'hadoop.http.delegation-token-secret-manager').
 */
@InterfaceAudience.Private
@InterfaceStability.Evolving
public class DelegationTokenAuthenticationFilter
    extends AuthenticationFilter {

  private static final String APPLICATION_JSON_MIME = "application/json";
  private static final String ERROR_EXCEPTION_JSON = "exception";
  private static final String ERROR_MESSAGE_JSON = "message";

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

  /**
   * Sets an external <code>DelegationTokenSecretManager</code> instance to
   * manage creation and verification of Delegation Tokens.
   * <p/>
   * This is useful for use cases where secrets must be shared across multiple
   * services.
   */

  public static final String DELEGATION_TOKEN_SECRET_MANAGER_ATTR =
      "hadoop.http.delegation-token-secret-manager";

  private static final Charset UTF8_CHARSET = Charset.forName("UTF-8");

  private static final ThreadLocal<UserGroupInformation> UGI_TL =
      new ThreadLocal<UserGroupInformation>();
  public static final String PROXYUSER_PREFIX = "proxyuser";

  private SaslRpcServer.AuthMethod handlerAuthMethod;

  /**
   * It delegates to
   * {@link AuthenticationFilter#getConfiguration(String, FilterConfig)} and
   * then overrides the {@link AuthenticationHandler} to use if authentication
   * type is set to <code>simple</code> or <code>kerberos</code> in order to use
   * the corresponding implementation with delegation token support.
   *
   * @param configPrefix parameter not used.
   * @param filterConfig parameter not used.
   * @return hadoop-auth de-prefixed configuration for the filter and handler.
   */
  @Override
  protected Properties getConfiguration(String configPrefix,
      FilterConfig filterConfig) throws ServletException {
    Properties props = super.getConfiguration(configPrefix, filterConfig);
    setAuthHandlerClass(props);
    return props;
  }

  /**
   * Set AUTH_TYPE property to the name of the corresponding authentication
   * handler class based on the input properties.
   * @param props input properties.
   */
  protected void setAuthHandlerClass(Properties props)
      throws ServletException {
    String authType = props.getProperty(AUTH_TYPE);
    if (authType == null) {
      throw new ServletException("Config property "
          + AUTH_TYPE + " doesn't exist");
    }
    if (authType.equals(PseudoAuthenticationHandler.TYPE)) {
      props.setProperty(AUTH_TYPE,
          PseudoDelegationTokenAuthenticationHandler.class.getName());
    } else if (authType.equals(KerberosAuthenticationHandler.TYPE)) {
      props.setProperty(AUTH_TYPE,
          KerberosDelegationTokenAuthenticationHandler.class.getName());
    } else if (authType.equals(MultiSchemeAuthenticationHandler.TYPE)) {
      props.setProperty(AUTH_TYPE,
          MultiSchemeDelegationTokenAuthenticationHandler.class.getName());
    }
  }

  /**
   * Returns the proxyuser configuration. All returned properties must start
   * with <code>proxyuser.</code>'
   * <p/>
   * Subclasses may override this method if the proxyuser configuration is 
   * read from other place than the filter init parameters.
   *
   * @param filterConfig filter configuration object
   * @return the proxyuser configuration properties.
   * @throws ServletException thrown if the configuration could not be created.
   */
  protected Configuration getProxyuserConfiguration(FilterConfig filterConfig)
      throws ServletException {
    // this filter class gets the configuration from the filter configs, we are
    // creating an empty configuration and injecting the proxyuser settings in
    // it. In the initialization of the filter, the returned configuration is
    // passed to the ProxyUsers which only looks for 'proxyusers.' properties.
    Configuration conf = new Configuration(false);
    Enumeration<?> names = filterConfig.getInitParameterNames();
    while (names.hasMoreElements()) {
      String name = (String) names.nextElement();
      if (name.startsWith(PROXYUSER_PREFIX + ".")) {
        String value = filterConfig.getInitParameter(name);
        conf.set(name, value);
      }
    }
    return conf;
  }


  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    super.init(filterConfig);
    AuthenticationHandler handler = getAuthenticationHandler();
    AbstractDelegationTokenSecretManager dtSecretManager =
        (AbstractDelegationTokenSecretManager) filterConfig.getServletContext().
            getAttribute(DELEGATION_TOKEN_SECRET_MANAGER_ATTR);
    if (dtSecretManager != null && handler
        instanceof DelegationTokenAuthenticationHandler) {
      DelegationTokenAuthenticationHandler dtHandler =
          (DelegationTokenAuthenticationHandler) getAuthenticationHandler();
      dtHandler.setExternalDelegationTokenSecretManager(dtSecretManager);
    }
    if (handler instanceof PseudoAuthenticationHandler ||
        handler instanceof PseudoDelegationTokenAuthenticationHandler) {
      setHandlerAuthMethod(SaslRpcServer.AuthMethod.SIMPLE);
    }
    if (handler instanceof KerberosAuthenticationHandler ||
        handler instanceof KerberosDelegationTokenAuthenticationHandler) {
      setHandlerAuthMethod(SaslRpcServer.AuthMethod.KERBEROS);
    }

    // proxyuser configuration
    Configuration conf = getProxyuserConfiguration(filterConfig);
    ProxyUsers.refreshSuperUserGroupsConfiguration(conf, PROXYUSER_PREFIX);
  }

  @Override
  protected void initializeAuthHandler(String authHandlerClassName,
      FilterConfig filterConfig) throws ServletException {
    // A single CuratorFramework should be used for a ZK cluster.
    // If the ZKSignerSecretProvider has already created it, it has to
    // be set here... to be used by the ZKDelegationTokenSecretManager
    ZKDelegationTokenSecretManager.setCurator((CuratorFramework)
        filterConfig.getServletContext().getAttribute(ZKSignerSecretProvider.
            ZOOKEEPER_SIGNER_SECRET_PROVIDER_CURATOR_CLIENT_ATTRIBUTE));
    super.initializeAuthHandler(authHandlerClassName, filterConfig);
    ZKDelegationTokenSecretManager.setCurator(null);
  }

  protected void setHandlerAuthMethod(SaslRpcServer.AuthMethod authMethod) {
    this.handlerAuthMethod = authMethod;
  }

  @VisibleForTesting
  static String getDoAs(HttpServletRequest request) {
    String queryString = request.getQueryString();
    if (queryString == null) {
      return null;
    }
    List<NameValuePair> list = URLEncodedUtils.parse(queryString, UTF8_CHARSET);
    if (list != null) {
      for (NameValuePair nv : list) {
        if (DelegationTokenAuthenticatedURL.DO_AS.
            equalsIgnoreCase(nv.getName())) {
          return nv.getValue();
        }
      }
    }
    return null;
  }

  static UserGroupInformation getHttpUserGroupInformationInContext() {
    return UGI_TL.get();
  }

  @Override
  protected void doFilter(FilterChain filterChain, HttpServletRequest request,
      HttpServletResponse response) throws IOException, ServletException {
    boolean requestCompleted = false;
    UserGroupInformation ugi = null;
    AuthenticationToken authToken = (AuthenticationToken)
        request.getUserPrincipal();
    if (authToken != null && authToken != AuthenticationToken.ANONYMOUS) {
      // if the request was authenticated because of a delegation token,
      // then we ignore proxyuser (this is the same as the RPC behavior).
      ugi = (UserGroupInformation) request.getAttribute(
          DelegationTokenAuthenticationHandler.DELEGATION_TOKEN_UGI_ATTRIBUTE);
      if (ugi == null) {
        String realUser = request.getUserPrincipal().getName();
        ugi = UserGroupInformation.createRemoteUser(realUser,
            handlerAuthMethod);
        String doAsUser = getDoAs(request);
        if (doAsUser != null) {
          ugi = UserGroupInformation.createProxyUser(doAsUser, ugi);
          try {
            ProxyUsers.authorize(ugi, request.getRemoteAddr());
          } catch (AuthorizationException ex) {
            HttpExceptionUtils.createServletExceptionResponse(response,
                HttpServletResponse.SC_FORBIDDEN, ex);
            requestCompleted = true;
            if (LOG.isDebugEnabled()) {
              LOG.debug("Authentication exception: " + ex.getMessage(), ex);
            } else {
              LOG.warn("Authentication exception: " + ex.getMessage());
            }
          }
        }
      }
      UGI_TL.set(ugi);
    }
    if (!requestCompleted) {
      final UserGroupInformation ugiF = ugi;
      try {
        request = new HttpServletRequestWrapper(request) {

          @Override
          public String getAuthType() {
            return (ugiF != null) ? handlerAuthMethod.toString() : null;
          }

          @Override
          public String getRemoteUser() {
            return (ugiF != null) ? ugiF.getShortUserName() : null;
          }

          @Override
          public Principal getUserPrincipal() {
            return (ugiF != null) ? new Principal() {
              @Override
              public String getName() {
                return ugiF.getUserName();
              }
            } : null;
          }
        };
        super.doFilter(filterChain, request, response);
      } finally {
        UGI_TL.remove();
      }
    }
  }
}
