/**
 * 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 java.io.IOException;
import java.io.Writer;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.MediaType;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authentication.client.AuthenticationException;
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.authorize.AuthorizationException;
import org.apache.hadoop.security.authorize.ProxyUsers;
import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenIdentifier;
import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenSecretManager;
import org.apache.hadoop.util.HttpExceptionUtils;
import org.apache.hadoop.util.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.annotations.VisibleForTesting;

/**
 * An {@link AuthenticationHandler} that implements Kerberos SPNEGO mechanism
 * for HTTP and supports Delegation Token functionality.
 * <p/>
 * In addition to the wrapped {@link AuthenticationHandler} configuration
 * properties, this handler supports the following properties prefixed
 * with the type of the wrapped <code>AuthenticationHandler</code>:
 * <ul>
 * <li>delegation-token.token-kind: the token kind for generated tokens
 * (no default, required property).</li>
 * <li>delegation-token.update-interval.sec: secret manager master key
 * update interval in seconds (default 1 day).</li>
 * <li>delegation-token.max-lifetime.sec: maximum life of a delegation
 * token in seconds (default 7 days).</li>
 * <li>delegation-token.renewal-interval.sec: renewal interval for
 * delegation tokens in seconds (default 1 day).</li>
 * <li>delegation-token.removal-scan-interval.sec: delegation tokens
 * removal scan interval in seconds (default 1 hour).</li>
 * </ul>
 *
 */
@InterfaceAudience.Private
@InterfaceStability.Evolving
public abstract class DelegationTokenAuthenticationHandler
    implements AuthenticationHandler {
  private static final Logger LOG =
      LoggerFactory.getLogger(DelegationTokenAuthenticationHandler.class);

  protected static final String TYPE_POSTFIX = "-dt";

  public static final String PREFIX = "delegation-token.";

  public static final String TOKEN_KIND = PREFIX + "token-kind";

  private static final Set<String> DELEGATION_TOKEN_OPS = new HashSet<String>();

  public static final String DELEGATION_TOKEN_UGI_ATTRIBUTE =
      "hadoop.security.delegation-token.ugi";

  static {
    DELEGATION_TOKEN_OPS.add(KerberosDelegationTokenAuthenticator.
        DelegationTokenOperation.GETDELEGATIONTOKEN.toString());
    DELEGATION_TOKEN_OPS.add(KerberosDelegationTokenAuthenticator.
        DelegationTokenOperation.RENEWDELEGATIONTOKEN.toString());
    DELEGATION_TOKEN_OPS.add(KerberosDelegationTokenAuthenticator.
        DelegationTokenOperation.CANCELDELEGATIONTOKEN.toString());
  }

  private AuthenticationHandler authHandler;
  private DelegationTokenManager tokenManager;
  private String authType;

  public DelegationTokenAuthenticationHandler(AuthenticationHandler handler) {
    authHandler = handler;
    authType = handler.getType();
  }

  @VisibleForTesting
  DelegationTokenManager getTokenManager() {
    return tokenManager;
  }

  AuthenticationHandler getAuthHandler() {
    return authHandler;
  }

  @Override
  public void init(Properties config) throws ServletException {
    authHandler.init(config);
    initTokenManager(config);
  }

  /**
   * 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.
   *
   * @param secretManager a <code>DelegationTokenSecretManager</code> instance
   */
  public void setExternalDelegationTokenSecretManager(
      AbstractDelegationTokenSecretManager secretManager) {
    tokenManager.setExternalDelegationTokenSecretManager(secretManager);
  }

  @VisibleForTesting
  @SuppressWarnings("unchecked")
  public void initTokenManager(Properties config) {
    Configuration conf = new Configuration(false);
    for (Map.Entry entry : config.entrySet()) {
      conf.set((String) entry.getKey(), (String) entry.getValue());
    }
    String tokenKind = conf.get(TOKEN_KIND);
    if (tokenKind == null) {
      throw new IllegalArgumentException(
          "The configuration does not define the token kind");
    }
    tokenKind = tokenKind.trim();
    tokenManager = new DelegationTokenManager(conf, new Text(tokenKind));
    tokenManager.init();
  }

  @Override
  public void destroy() {
    tokenManager.destroy();
    authHandler.destroy();
  }

  @Override
  public String getType() {
    return authType;
  }

  private static final String ENTER = System.getProperty("line.separator");

  /**
   * This method checks if the given HTTP request corresponds to a management
   * operation.
   *
   * @param request The HTTP request
   * @return true if the given HTTP request corresponds to a management
   *         operation false otherwise
   * @throws IOException In case of I/O error.
   */
  protected final boolean isManagementOperation(HttpServletRequest request)
      throws IOException {
    String op = ServletUtils.getParameter(request,
        KerberosDelegationTokenAuthenticator.OP_PARAM);
    op = (op != null) ? StringUtils.toUpperCase(op) : null;
    return DELEGATION_TOKEN_OPS.contains(op) &&
        !request.getMethod().equals("OPTIONS");
  }

  @Override
  @SuppressWarnings("unchecked")
  public boolean managementOperation(AuthenticationToken token,
      HttpServletRequest request, HttpServletResponse response)
      throws IOException, AuthenticationException {
    boolean requestContinues = true;
    LOG.trace("Processing operation for req=({}), token: {}", request, token);
    String op = ServletUtils.getParameter(request,
        KerberosDelegationTokenAuthenticator.OP_PARAM);
    op = (op != null) ? StringUtils.toUpperCase(op) : null;
    if (isManagementOperation(request)) {
      KerberosDelegationTokenAuthenticator.DelegationTokenOperation dtOp =
          KerberosDelegationTokenAuthenticator.
              DelegationTokenOperation.valueOf(op);
      if (dtOp.getHttpMethod().equals(request.getMethod())) {
        boolean doManagement;
        if (dtOp.requiresKerberosCredentials() && token == null) {
          // Don't authenticate via DT for DT ops.
          token = authHandler.authenticate(request, response);
          LOG.trace("Got token: {}.", token);
          if (token == null) {
            requestContinues = false;
            doManagement = false;
          } else {
            doManagement = true;
          }
        } else {
          doManagement = true;
        }
        if (doManagement) {
          UserGroupInformation requestUgi = (token != null)
              ? UserGroupInformation.createRemoteUser(token.getUserName())
              : null;
          // Create the proxy user if doAsUser exists
          String doAsUser = DelegationTokenAuthenticationFilter.getDoAs(request);
          if (requestUgi != null && doAsUser != null) {
            requestUgi = UserGroupInformation.createProxyUser(
                doAsUser, requestUgi);
            try {
              ProxyUsers.authorize(requestUgi, request.getRemoteAddr());
            } catch (AuthorizationException ex) {
              HttpExceptionUtils.createServletExceptionResponse(response,
                  HttpServletResponse.SC_FORBIDDEN, ex);
              return false;
            }
          }
          Map map = null;
          switch (dtOp) {
            case GETDELEGATIONTOKEN:
              if (requestUgi == null) {
                throw new IllegalStateException("request UGI cannot be NULL");
              }
              String renewer = ServletUtils.getParameter(request,
                  KerberosDelegationTokenAuthenticator.RENEWER_PARAM);
              String service = ServletUtils.getParameter(request,
                  KerberosDelegationTokenAuthenticator.SERVICE_PARAM);
              try {
                Token<?> dToken = tokenManager.createToken(requestUgi, renewer,
                    service);
                map = delegationTokenToJSON(dToken);
              } catch (IOException ex) {
                throw new AuthenticationException(ex.toString(), ex);
              }
              break;
            case RENEWDELEGATIONTOKEN:
              if (requestUgi == null) {
                throw new IllegalStateException("request UGI cannot be NULL");
              }
              String tokenToRenew = ServletUtils.getParameter(request,
                  KerberosDelegationTokenAuthenticator.TOKEN_PARAM);
              if (tokenToRenew == null) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST,
                    MessageFormat.format(
                        "Operation [{0}] requires the parameter [{1}]", dtOp,
                        KerberosDelegationTokenAuthenticator.TOKEN_PARAM)
                );
                requestContinues = false;
              } else {
                Token<AbstractDelegationTokenIdentifier> dt = new Token();
                try {
                  dt.decodeFromUrlString(tokenToRenew);
                  long expirationTime = tokenManager.renewToken(dt,
                      requestUgi.getShortUserName());
                  map = new HashMap();
                  map.put("long", expirationTime);
                } catch (IOException ex) {
                  throw new AuthenticationException(ex.toString(), ex);
                }
              }
              break;
            case CANCELDELEGATIONTOKEN:
              String tokenToCancel = ServletUtils.getParameter(request,
                  KerberosDelegationTokenAuthenticator.TOKEN_PARAM);
              if (tokenToCancel == null) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST,
                    MessageFormat.format(
                        "Operation [{0}] requires the parameter [{1}]", dtOp,
                        KerberosDelegationTokenAuthenticator.TOKEN_PARAM)
                );
                requestContinues = false;
              } else {
                Token<AbstractDelegationTokenIdentifier> dt = new Token();
                try {
                  dt.decodeFromUrlString(tokenToCancel);
                  tokenManager.cancelToken(dt, (requestUgi != null)
                      ? requestUgi.getShortUserName() : null);
                } catch (IOException ex) {
                  response.sendError(HttpServletResponse.SC_NOT_FOUND,
                      "Invalid delegation token, cannot cancel");
                  requestContinues = false;
                }
              }
              break;
          }
          if (requestContinues) {
            response.setStatus(HttpServletResponse.SC_OK);
            if (map != null) {
              response.setContentType(MediaType.APPLICATION_JSON);
              Writer writer = response.getWriter();
              ObjectMapper jsonMapper = new ObjectMapper();
              jsonMapper.writeValue(writer, map);
              writer.write(ENTER);
              writer.flush();
            }
            requestContinues = false;
          }
        }
      } else {
        response.sendError(HttpServletResponse.SC_BAD_REQUEST,
            MessageFormat.format(
                "Wrong HTTP method [{0}] for operation [{1}], it should be " +
                    "[{2}]", request.getMethod(), dtOp, dtOp.getHttpMethod()));
        requestContinues = false;
      }
    }
    return requestContinues;
  }

  @SuppressWarnings("unchecked")
  private static Map delegationTokenToJSON(Token token) throws IOException {
    Map json = new LinkedHashMap();
    json.put(
        KerberosDelegationTokenAuthenticator.DELEGATION_TOKEN_URL_STRING_JSON,
        token.encodeToUrlString());
    Map response = new LinkedHashMap();
    response.put(KerberosDelegationTokenAuthenticator.DELEGATION_TOKEN_JSON,
        json);
    return response;
  }

  /**
   * Authenticates a request looking for the <code>delegation</code>
   * query-string parameter and verifying it is a valid token. If there is not
   * <code>delegation</code> query-string parameter, it delegates the
   * authentication to the {@link KerberosAuthenticationHandler} unless it is
   * disabled.
   *
   * @param request the HTTP client request.
   * @param response the HTTP client response.
   * @return the authentication token for the authenticated request.
   * @throws IOException thrown if an IO error occurred.
   * @throws AuthenticationException thrown if the authentication failed.
   */
  @SuppressWarnings("unchecked")
  @Override
  public AuthenticationToken authenticate(HttpServletRequest request,
      HttpServletResponse response)
      throws IOException, AuthenticationException {
    AuthenticationToken token;
    String delegationParam = getDelegationToken(request);
    if (delegationParam != null) {
      LOG.debug("Authenticating with dt param: {}", delegationParam);
      try {
        Token<AbstractDelegationTokenIdentifier> dt = new Token();
        dt.decodeFromUrlString(delegationParam);
        UserGroupInformation ugi = tokenManager.verifyToken(dt);
        final String shortName = ugi.getShortUserName();

        // creating a ephemeral token
        token = new AuthenticationToken(shortName, ugi.getUserName(),
            getType());
        token.setExpires(0);
        request.setAttribute(DELEGATION_TOKEN_UGI_ATTRIBUTE, ugi);
      } catch (Throwable ex) {
        token = null;
        HttpExceptionUtils.createServletExceptionResponse(response,
            HttpServletResponse.SC_FORBIDDEN, new AuthenticationException(ex));
      }
    } else {
      LOG.debug("Falling back to {} (req={})", authHandler.getClass(), request);
      token = authHandler.authenticate(request, response);
    }
    return token;
  }

  private String getDelegationToken(HttpServletRequest request)
      throws IOException {
    String dToken = request.getHeader(
        DelegationTokenAuthenticator.DELEGATION_TOKEN_HEADER);
    if (dToken == null) {
      dToken = ServletUtils.getParameter(request,
          KerberosDelegationTokenAuthenticator.DELEGATION_PARAM);
    }
    return dToken;
  }

}
