// Copyright (C) 2012 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;

import static java.nio.charset.StandardCharsets.UTF_8;
import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE;
import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;

import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.extensions.client.GitBasicAuthPolicy;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountException;
import com.google.gerrit.server.account.AccountManager;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.account.AuthRequest;
import com.google.gerrit.server.account.AuthResult;
import com.google.gerrit.server.account.AuthenticationFailedException;
import com.google.gerrit.server.account.externalids.PasswordVerifier;
import com.google.gerrit.server.auth.AuthenticationUnavailableException;
import com.google.gerrit.server.auth.NoSuchUserException;
import com.google.gerrit.server.config.AuthConfig;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.IOException;
import java.util.Locale;
import java.util.Optional;
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;
import javax.servlet.http.HttpServletResponseWrapper;
import org.apache.commons.codec.binary.Base64;
import org.eclipse.jgit.http.server.GitSmartHttpTools;

/**
 * Authenticates the current user by HTTP basic authentication.
 *
 * <p>The current HTTP request is authenticated by looking up the username and password from the
 * Base64 encoded Authorization header and validating them against any username/password configured
 * authentication system in Gerrit. This filter is intended only to protect the {@link
 * GitOverHttpServlet} and its handled URLs, which provide remote repository access over HTTP.
 *
 * @see <a href="http://www.ietf.org/rfc/rfc2617.txt">RFC 2617</a>
 */
@Singleton
class ProjectBasicAuthFilter implements Filter {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  public static final String REALM_NAME = "Gerrit Code Review";
  private static final String AUTHORIZATION = "Authorization";
  private static final String LIT_BASIC = "Basic ";

  private final DynamicItem<WebSession> session;
  private final AccountCache accountCache;
  private final AccountManager accountManager;
  private final AuthConfig authConfig;

  @Inject
  ProjectBasicAuthFilter(
      DynamicItem<WebSession> session,
      AccountCache accountCache,
      AccountManager accountManager,
      AuthConfig authConfig) {
    this.session = session;
    this.accountCache = accountCache;
    this.accountManager = accountManager;
    this.authConfig = authConfig;
  }

  @Override
  public void init(FilterConfig config) {}

  @Override
  public void destroy() {}

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    Response rsp = new Response((HttpServletResponse) response);

    if (isSignedInGitRequest(req) || verify(req, rsp)) {
      chain.doFilter(req, rsp);
    }
  }

  private boolean isSignedInGitRequest(HttpServletRequest req) {
    boolean isGitRequest = req.getRequestURI() != null && GitSmartHttpTools.isGitClient(req);
    boolean isAlreadySignedIn = session.get().isSignedIn();
    boolean res = isAlreadySignedIn && isGitRequest;
    logger.atFine().log(
        "HTTP:%s %s signedIn=%s (isAlreadySignedIn=%s, isGitRequest=%s)",
        req.getMethod(), req.getRequestURI(), res, isAlreadySignedIn, isGitRequest);
    return res;
  }

  private boolean verify(HttpServletRequest req, Response rsp) throws IOException {
    final String hdr = req.getHeader(AUTHORIZATION);
    if (hdr == null || !hdr.startsWith(LIT_BASIC)) {
      // Allow an anonymous connection through, or it might be using a
      // session cookie instead of basic authentication.
      return true;
    }

    final byte[] decoded = Base64.decodeBase64(hdr.substring(LIT_BASIC.length()));
    String usernamePassword = new String(decoded, encoding(req));
    int splitPos = usernamePassword.indexOf(':');
    if (splitPos < 1) {
      rsp.sendError(SC_UNAUTHORIZED);
      return false;
    }

    String username = usernamePassword.substring(0, splitPos);
    String password = usernamePassword.substring(splitPos + 1);
    if (Strings.isNullOrEmpty(password)) {
      rsp.sendError(SC_UNAUTHORIZED);
      return false;
    }
    if (authConfig.isUserNameToLowerCase()) {
      username = username.toLowerCase(Locale.US);
    }

    Optional<AccountState> accountState =
        accountCache.getByUsername(username).filter(a -> a.account().isActive());
    if (!accountState.isPresent()) {
      logger.atWarning().log(
          "Authentication failed for %s: account inactive or not provisioned in Gerrit", username);
      rsp.sendError(SC_UNAUTHORIZED);
      return false;
    }

    AccountState who = accountState.get();
    GitBasicAuthPolicy gitBasicAuthPolicy = authConfig.getGitBasicAuthPolicy();
    if (gitBasicAuthPolicy == GitBasicAuthPolicy.HTTP
        || gitBasicAuthPolicy == GitBasicAuthPolicy.HTTP_LDAP) {
      if (PasswordVerifier.checkPassword(who.externalIds(), username, password)) {
        logger.atFine().log(
            "HTTP:%s %s username/password authentication succeeded",
            req.getMethod(), req.getRequestURI());
        return succeedAuthentication(who, null);
      }
    }

    if (gitBasicAuthPolicy == GitBasicAuthPolicy.HTTP) {
      return failAuthentication(rsp, username, req);
    }

    AuthRequest whoAuth = AuthRequest.forUser(username);
    whoAuth.setPassword(password);

    try {
      AuthResult whoAuthResult = accountManager.authenticate(whoAuth);
      setUserIdentified(whoAuthResult.getAccountId(), whoAuthResult);
      logger.atFine().log(
          "HTTP:%s %s Realm authentication succeeded", req.getMethod(), req.getRequestURI());
      return true;
    } catch (NoSuchUserException e) {
      if (PasswordVerifier.checkPassword(who.externalIds(), username, password)) {
        return succeedAuthentication(who, null);
      }
      logger.atWarning().withCause(e).log(authenticationFailedMsg(username, req));
      rsp.sendError(SC_UNAUTHORIZED);
      return false;
    } catch (AuthenticationFailedException e) {
      // This exception is thrown if the user provided wrong credentials, we don't need to log a
      // stacktrace for it.
      logger.atWarning().log(authenticationFailedMsg(username, req) + ": %s", e.getMessage());
      rsp.sendError(SC_UNAUTHORIZED);
      return false;
    } catch (AuthenticationUnavailableException e) {
      logger.atSevere().withCause(e).log("could not reach authentication backend");
      rsp.sendError(SC_SERVICE_UNAVAILABLE);
      return false;
    } catch (AccountException e) {
      logger.atWarning().withCause(e).log(authenticationFailedMsg(username, req));
      rsp.sendError(SC_UNAUTHORIZED);
      return false;
    }
  }

  private boolean succeedAuthentication(AccountState who, @Nullable AuthResult whoAuthResult) {
    setUserIdentified(who.account().id(), whoAuthResult);
    return true;
  }

  private boolean failAuthentication(Response rsp, String username, HttpServletRequest req)
      throws IOException {
    logger.atWarning().log(
        authenticationFailedMsg(username, req)
            + ": password does not match the one stored in Gerrit");
    rsp.sendError(SC_UNAUTHORIZED);
    return false;
  }

  static String authenticationFailedMsg(String username, HttpServletRequest req) {
    return String.format("Authentication from %s failed for %s", req.getRemoteAddr(), username);
  }

  private void setUserIdentified(Account.Id id, @Nullable AuthResult whoAuthResult) {
    WebSession ws = session.get();
    ws.setUserAccountId(id);
    ws.setAccessPathOk(AccessPath.GIT, true);
    ws.setAccessPathOk(AccessPath.REST_API, true);

    if (whoAuthResult != null) {
      ws.login(whoAuthResult, false);
    }
  }

  private String encoding(HttpServletRequest req) {
    return MoreObjects.firstNonNull(req.getCharacterEncoding(), UTF_8.name());
  }

  static class Response extends HttpServletResponseWrapper {
    private static final String WWW_AUTHENTICATE = "WWW-Authenticate";

    Response(HttpServletResponse rsp) {
      super(rsp);
    }

    private void status(int sc) {
      if (sc == SC_UNAUTHORIZED) {
        StringBuilder v = new StringBuilder();
        v.append(LIT_BASIC);
        v.append("realm=\"").append(REALM_NAME).append("\"");
        setHeader(WWW_AUTHENTICATE, v.toString());
      } else if (containsHeader(WWW_AUTHENTICATE)) {
        setHeader(WWW_AUTHENTICATE, null);
      }
    }

    @Override
    public void sendError(int sc, String msg) throws IOException {
      status(sc);
      super.sendError(sc, msg);
    }

    @Override
    public void sendError(int sc) throws IOException {
      status(sc);
      super.sendError(sc);
    }

    @Override
    @Deprecated
    public void setStatus(int sc, String sm) {
      status(sc);
      super.setStatus(sc, sm);
    }

    @Override
    public void setStatus(int sc) {
      status(sc);
      super.setStatus(sc);
    }
  }
}
