// Copyright 2011 Google Inc. All Rights Reserved.
//
// Licensed 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 com.google.enterprise.adaptor;

import com.google.enterprise.apis.client.GsaClient;
import com.google.gdata.util.AuthenticationException;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;

import java.io.*;
import java.net.*;
import java.nio.charset.Charset;
import java.util.logging.*;

/**
 * Require GSA-Administrator authentication before allowing requests.
 */
class AdministratorSecurityHandler implements HttpHandler {
  private static final Logger log
      = Logger.getLogger(AdministratorSecurityHandler.class.getName());
  /** Key used to store the fact the user has been authenticated. */
  private static final String SESSION_ATTR_NAME = "dashboard-authned";
  /** Page to display when prompting for user credentials. */
  private static final String LOGIN_PAGE = "resources/login.html";
  /** Page to display when the user credentials are invalid. */
  private static final String LOGIN_FAILED_PAGE = "resources/login-failed.html";
  /** Page to display when the user credentials were not able to be verified. */
  private static final String LOGIN_INDETERMINATE_PAGE
      = "resources/login-indeterminate.html";

  /** Wrapped handler, for when the user is authenticated. */
  private final HttpHandler handler;
  /** Manager that handles keeping track of authenticated users. */
  private final SessionManager<HttpExchange> sessionManager;
  /** Trusted entity for performing authentication of user credentials. */
  private final AuthnClient authnClient;

  AdministratorSecurityHandler(HttpHandler handler,
      SessionManager<HttpExchange> sessionManager, AuthnClient authnClient) {
    this.handler = handler;
    this.sessionManager = sessionManager;
    this.authnClient = authnClient;
  }

  public AdministratorSecurityHandler(HttpHandler handler,
      SessionManager<HttpExchange> sessionManager, String gsaHostname,
      boolean useHttps) {
    this(handler, sessionManager, new GsaAuthnClient(gsaHostname, useHttps));
  }

  private void meteredHandle(HttpExchange ex) throws IOException {
    String pageToDisplay = LOGIN_PAGE;

    if ("POST".equals(ex.getRequestMethod())) {
      AuthzStatus authn = validUsernameAndPassword(ex);
      if (authn == AuthzStatus.PERMIT) {
        // Need the client to access the page via GET since the only reason the
        // request method was POST was because of submitting our login form.
        HttpExchanges.sendRedirect(ex, HttpExchanges.getRequestUri(ex));
        return;
      } else if (authn == AuthzStatus.INDETERMINATE) {
        pageToDisplay = LOGIN_INDETERMINATE_PAGE;
      } else {
        pageToDisplay = LOGIN_FAILED_PAGE;
      }
    }

    // Send login page.
    InputStream is = this.getClass().getResourceAsStream(pageToDisplay);
    if (is == null) {
      throw new IOException("Could not load login page");
    }
    byte[] page;
    try {
      page = IOHelper.readInputStreamToByteArray(is);
    } finally {
      is.close();
    }
    HttpExchanges.respond(
        ex, HttpURLConnection.HTTP_FORBIDDEN, "text/html", page);
  }

  /**
   * Check POST data to see if the user can be authenticated by the GSA. This
   * abuses the {@code AuthzStatus} class, using it for Authn, but it was
   * convenient.
   *
   * @return {@code PERMIT} if user authenticated, {@code DENY} if invalid
   *   credentials, and {@code INDETERMINATE} otherwise
   */
  private AuthzStatus validUsernameAndPassword(HttpExchange ex)
      throws IOException {
    log.fine("Not already authenticated");
    // Check to see if they provided a username and password.
    String username = null;
    String password = null;
    try {
      String request = IOHelper.readInputStreamToString(
          ex.getRequestBody(), Charset.forName("US-ASCII"));
      for (String pair : request.split("&")) {
        String[] splitPair = pair.split("=", 2);
        if (splitPair.length != 2) {
          continue;
        }
        splitPair[0] = URLDecoder.decode(splitPair[0], "UTF-8");
        splitPair[1] = URLDecoder.decode(splitPair[1], "UTF-8");
        if ("username".equals(splitPair[0])) {
          username = splitPair[1];
        } else if ("password".equals(splitPair[0])) {
          password = splitPair[1];
        }
        if (username != null && password != null) {
          break;
        }
      }
    } catch (Exception e) {
      log.log(Level.FINE, "Processing POST caused exception", e);
      // Assume that they were POSTing to a different page, since they didn't
      // provide the expected input.
      username = null;
      password = null;
    }
    if (username == null || password == null) {
      log.fine("Username or password is null. Not authenticated");
      // Must not have been from our login page.
      return AuthzStatus.INDETERMINATE;
    }

    // Check to see if provided username and password are valid.
    AuthzStatus result = authnClient.authn(username, password);
    if (result == AuthzStatus.INDETERMINATE) {
      log.fine("Failed communicating with the GSA");
      return result;
    } else if (result != AuthzStatus.PERMIT) {
      log.fine("GSA login was not successful");
      return result;
    }

    // We have a winner. Store in the session that they are a valid user.
    log.fine("GSA login successful");
    Session session = sessionManager.getSession(ex);
    session.setAttribute(SESSION_ATTR_NAME, true);
    return AuthzStatus.PERMIT;
  }

  @Override
  public void handle(HttpExchange ex) throws IOException {
    // Clickjacking defence.
    ex.getResponseHeaders().set("X-Frame-Options", "deny");

    // This comment is no longer true and exists from before logging was done in
    // a filter. TODO(ejona): split into a separate filter and handler.
    // Perform fast-path checking here to prevent double-logging most requests.
    Session session = sessionManager.getSession(ex, false);
    if (session != null && session.getAttribute(SESSION_ATTR_NAME) != null) {
      handler.handle(ex);
      return;
    }
    meteredHandle(ex);
  }

  interface AuthnClient {
    public AuthzStatus authn(String username, String password);
  }

  static class GsaAuthnClient implements AuthnClient {
    private String gsaHostname;
    private boolean useHttps;

    public GsaAuthnClient(String gsaHostname, boolean useHttps) {
      this.gsaHostname = gsaHostname;
      this.useHttps = useHttps;
    }

    @Override
    public AuthzStatus authn(String username, String password) {
      String protocol = useHttps ? "https" : "http";
      int port = useHttps ? 8443 : 8000;
      try {
        new GsaClient(protocol, gsaHostname, port, username, password);
      } catch (AuthenticationException e) {
        log.log(Level.FINE, "AuthenticationException", e);
        if (e.getCause() instanceof ConnectException) {
          return AuthzStatus.INDETERMINATE;
        } else if (e.getCause() instanceof UnknownHostException) {
          return AuthzStatus.INDETERMINATE;
        }
        return AuthzStatus.DENY;
      }
      return AuthzStatus.PERMIT;
    }
  }
}
