// 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 static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Strings.emptyToNull;
import static com.google.common.net.HttpHeaders.AUTHORIZATION;
import static com.google.gerrit.reviewdb.client.AccountExternalId.SCHEME_GERRIT;
import static java.nio.charset.StandardCharsets.ISO_8859_1;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.httpd.HtmlDomUtil;
import com.google.gerrit.httpd.RemoteUserUtil;
import com.google.gerrit.httpd.WebSession;
import com.google.gerrit.httpd.raw.HostPageServlet;
import com.google.gerrit.reviewdb.client.AccountExternalId;
import com.google.gerrit.server.config.AuthConfig;
import com.google.gwtexpui.server.CacheHeaders;
import com.google.gwtjsonrpc.server.RPCServletUtils;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Locale;

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;

/**
 * Watches request for the host page and requires login if not yet signed in.
 * <p>
 * If HTTP authentication has been enabled on this server this filter is bound
 * in front of the {@link HostPageServlet} and redirects users who are not yet
 * signed in to visit {@code /login/}, so the web container can force login.
 * This redirect is performed with JavaScript, such that any existing anchor
 * token in the URL can be rewritten and preserved through the authentication
 * process of any enterprise single sign-on solutions.
 */
@Singleton
class HttpAuthFilter implements Filter {
  private final DynamicItem<WebSession> sessionProvider;
  private final byte[] signInRaw;
  private final byte[] signInGzip;
  private final String loginHeader;
  private final String displaynameHeader;
  private final String emailHeader;
  private final String externalIdHeader;
  private final boolean userNameToLowerCase;

  @Inject
  HttpAuthFilter(final DynamicItem<WebSession> webSession,
      final AuthConfig authConfig) throws IOException {
    this.sessionProvider = webSession;

    final String pageName = "LoginRedirect.html";
    final String doc = HtmlDomUtil.readFile(getClass(), pageName);
    if (doc == null) {
      throw new FileNotFoundException("No " + pageName + " in webapp");
    }

    signInRaw = doc.getBytes(HtmlDomUtil.ENC);
    signInGzip = HtmlDomUtil.compress(signInRaw);
    loginHeader = firstNonNull(
        emptyToNull(authConfig.getLoginHttpHeader()),
        AUTHORIZATION);
    displaynameHeader = emptyToNull(authConfig.getHttpDisplaynameHeader());
    emailHeader = emptyToNull(authConfig.getHttpEmailHeader());
    externalIdHeader = emptyToNull(authConfig.getHttpExternalIdHeader());
    userNameToLowerCase = authConfig.isUserNameToLowerCase();
  }

  @Override
  public void doFilter(final ServletRequest request,
      final ServletResponse response, final FilterChain chain)
      throws IOException, ServletException {
    if (isSessionValid((HttpServletRequest) request)) {
      chain.doFilter(request, response);
    } else {
      // Not signed in yet. Since the browser state might have an anchor
      // token which we want to capture and carry through the auth process
      // we send back JavaScript now to capture that, and do the real work
      // of redirecting to the authentication area.
      //
      final HttpServletRequest req = (HttpServletRequest) request;
      final HttpServletResponse rsp = (HttpServletResponse) response;
      final byte[] tosend;
      if (RPCServletUtils.acceptsGzipEncoding(req)) {
        rsp.setHeader("Content-Encoding", "gzip");
        tosend = signInGzip;
      } else {
        tosend = signInRaw;
      }

      CacheHeaders.setNotCacheable(rsp);
      rsp.setContentType("text/html");
      rsp.setCharacterEncoding(HtmlDomUtil.ENC.name());
      rsp.setContentLength(tosend.length);
      try (OutputStream out = rsp.getOutputStream()) {
        out.write(tosend);
      }
    }
  }

  private boolean isSessionValid(HttpServletRequest req) {
    WebSession session = sessionProvider.get();
    if (session.isSignedIn()) {
      String user = getRemoteUser(req);
      return user == null || correctUser(user, session);
    }
    return false;
  }

  private static boolean correctUser(String user, WebSession session) {
    AccountExternalId.Key id = session.getLastLoginExternalId();
    return id != null
        && id.equals(new AccountExternalId.Key(SCHEME_GERRIT, user));
  }

  String getRemoteUser(HttpServletRequest req) {
    String remoteUser = RemoteUserUtil.getRemoteUser(req, loginHeader);
    return (userNameToLowerCase && remoteUser != null) ?
        remoteUser.toLowerCase(Locale.US) : remoteUser;
  }

  String getRemoteDisplayname(HttpServletRequest req) {
    if (displaynameHeader != null) {
      String raw = req.getHeader(displaynameHeader);
      return emptyToNull(new String(raw.getBytes(ISO_8859_1), UTF_8));
    }
    return null;
  }

  String getRemoteEmail(HttpServletRequest req) {
    if (emailHeader != null) {
      return emptyToNull(req.getHeader(emailHeader));
    }
    return null;
  }

  String getRemoteExternalIdToken(HttpServletRequest req) {
    if (externalIdHeader != null) {
      return emptyToNull(req.getHeader(externalIdHeader));
    }
    return null;
  }

  String getLoginHeader() {
    return loginHeader;
  }

  @Override
  public void init(final FilterConfig filterConfig) {
  }

  @Override
  public void destroy() {
  }
}
