// Copyright (C) 2009 The Android Open Source Project
//
// 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.gerrit.httpd.auth.container;

import com.google.gerrit.common.PageLinks;
import com.google.gerrit.httpd.HtmlDomUtil;
import com.google.gerrit.httpd.WebSession;
import com.google.gerrit.server.account.AccountException;
import com.google.gerrit.server.account.AccountManager;
import com.google.gerrit.server.account.AuthRequest;
import com.google.gerrit.server.account.AuthResult;
import com.google.gerrit.server.config.AuthConfig;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gwtorm.client.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;

import org.eclipse.jgit.util.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.io.IOException;
import java.io.Writer;

import javax.annotation.Nullable;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Initializes the user session if HTTP authentication is enabled.
 * <p>
 * If HTTP authentication has been enabled this servlet binds to {@code /login/}
 * and initializes the user session based on user information contained in the
 * HTTP request.
 */
@Singleton
class HttpLoginServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;
  private static final Logger log =
      LoggerFactory.getLogger(HttpLoginServlet.class);

  private static final String AUTHORIZATION = "Authorization";
  private final Provider<WebSession> webSession;
  private final Provider<String> urlProvider;
  private final AccountManager accountManager;
  private final String loginHeader;

  @Inject
  HttpLoginServlet(final AuthConfig authConfig,
      final Provider<WebSession> webSession,
      @CanonicalWebUrl @Nullable final Provider<String> urlProvider,
      final AccountManager accountManager) {
    this.webSession = webSession;
    this.urlProvider = urlProvider;
    this.accountManager = accountManager;

    final String hdr = authConfig.getLoginHttpHeader();
    this.loginHeader = hdr != null && !hdr.equals("") ? hdr : AUTHORIZATION;
  }

  @Override
  protected void doGet(final HttpServletRequest req,
      final HttpServletResponse rsp) throws ServletException, IOException {
    final String token = getToken(req);
    if ("logout".equals(token) || "signout".equals(token)) {
      req.getRequestDispatcher("/logout").forward(req, rsp);
      return;
    }

    rsp.setHeader("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
    rsp.setHeader("Pragma", "no-cache");
    rsp.setHeader("Cache-Control", "no-cache, must-revalidate");

    final String user = getRemoteUser(req);
    if (user == null || "".equals(user)) {
      log.error("Unable to authenticate user by " + loginHeader
          + " request header.  Check container or server configuration.");

      final Document doc = HtmlDomUtil.parseFile( //
          HttpLoginServlet.class, "ConfigurationError.html");

      replace(doc, "loginHeader", loginHeader);
      replace(doc, "ServerName", req.getServerName());
      replace(doc, "ServerPort", ":" + req.getServerPort());
      replace(doc, "ContextPath", req.getContextPath());

      final byte[] bin = HtmlDomUtil.toUTF8(doc);
      rsp.setStatus(HttpServletResponse.SC_FORBIDDEN);
      rsp.setContentType("text/html");
      rsp.setCharacterEncoding("UTF-8");
      rsp.setContentLength(bin.length);
      final ServletOutputStream out = rsp.getOutputStream();
      try {
        out.write(bin);
      } finally {
        out.flush();
        out.close();
      }
      return;
    }

    final AuthRequest areq = AuthRequest.forUser(user);
    final AuthResult arsp;
    try {
      arsp = accountManager.authenticate(areq);
    } catch (AccountException e) {
      log.error("Unable to authenticate user \"" + user + "\"", e);
      rsp.sendError(HttpServletResponse.SC_FORBIDDEN);
      return;
    }

    final StringBuilder rdr = new StringBuilder();
    rdr.append(urlProvider.get());
    rdr.append('#');
    if (arsp.isNew() && !token.startsWith(PageLinks.REGISTER + ",")) {
      rdr.append(PageLinks.REGISTER);
      rdr.append(',');
    }
    rdr.append(token);

    try {
      webSession.get().login(arsp, true /* persistent cookie */);
    } catch (OrmException e) {
      log.error("Unable to log in user \"" + user + "\"", e);
      rsp.setContentType("text/html");
      rsp.setCharacterEncoding(HtmlDomUtil.ENC);
      final Writer out = rsp.getWriter();
      out.write("<html>");
      out.write("<body>");
      out.write("<h1>An error occurred while attempting to log in</h1>");
      out.write("</body>");
      out.write("</html>");
      out.close();
      return;
    }
    rsp.sendRedirect(rdr.toString());
  }

  private void replace(Document doc, String name, String value) {
    Element e = HtmlDomUtil.find(doc, name);
    if (e != null) {
      e.setTextContent(value);
    } else {
      replaceByClass(doc, name, value);
    }
  }

  private void replaceByClass(Node parent, String name, String value) {
    final NodeList list = parent.getChildNodes();
    for (int i = 0; i < list.getLength(); i++) {
      final Node n = list.item(i);
      if (n instanceof Element) {
        final Element e = (Element) n;
        if (name.equals(e.getAttribute("class"))) {
          e.setTextContent(value);
        }
      }
      replaceByClass(n, name, value);
    }
  }

  private String getToken(final HttpServletRequest req) {
    String token = req.getPathInfo();
    if (token != null && token.startsWith("/")) {
      token = token.substring(1);
    }
    if (token == null || token.isEmpty()) {
      token = PageLinks.MINE;
    }
    return token;
  }

  private String getRemoteUser(final HttpServletRequest req) {
    if (AUTHORIZATION.equals(loginHeader)) {
      final String user = req.getRemoteUser();
      if (user != null && !"".equals(user)) {
        // The container performed the authentication, and has the user
        // identity already decoded for us. Honor that as we have been
        // configured to honor HTTP authentication.
        //
        return user;
      }

      // If the container didn't do the authentication we might
      // have done it in the front-end web server. Try to split
      // the identity out of the Authorization header and honor it.
      //
      String auth = req.getHeader(AUTHORIZATION);
      if (auth == null || "".equals(auth)) {
        return null;

      } else if (auth.startsWith("Basic ")) {
        auth = auth.substring("Basic ".length());
        auth = new String(Base64.decode(auth));
        final int c = auth.indexOf(':');
        return c > 0 ? auth.substring(0, c) : null;

      } else if (auth.startsWith("Digest ")) {
        final int u = auth.indexOf("username=\"");
        if (u <= 0) {
          return null;
        }
        auth = auth.substring(u + 10);
        final int e = auth.indexOf('"');
        return e > 0 ? auth.substring(0, auth.indexOf('"')) : null;

      } else {
        return null;
      }
    } else {
      // Nonstandard HTTP header. We have been told to trust this
      // header blindly as-is.
      //
      final String user = req.getHeader(loginHeader);
      return user != null && !"".equals(user) ? user : null;
    }
  }
}
