// 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.server.config;

import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_MAILTO;
import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_USERNAME;
import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_UUID;

import com.google.gerrit.extensions.client.AuthType;
import com.google.gerrit.extensions.client.GitBasicAuthPolicy;
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.auth.openid.OpenIdProviderPattern;
import com.google.gerrit.server.mail.SignedToken;
import com.google.gerrit.server.mail.XsrfException;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.lib.Config;

/** Authentication related settings from {@code gerrit.config}. */
@Singleton
public class AuthConfig {
  private final AuthType authType;
  private final String httpHeader;
  private final String httpDisplaynameHeader;
  private final String httpEmailHeader;
  private final String httpExternalIdHeader;
  private final String registerPageUrl;
  private final String registerUrl;
  private final String registerText;
  private final boolean trustContainerAuth;
  private final boolean enableRunAs;
  private final boolean userNameToLowerCase;
  private final boolean useContributorAgreements;
  private final String loginUrl;
  private final String loginText;
  private final String logoutUrl;
  private final String switchAccountUrl;
  private final String editFullNameUrl;
  private final String httpPasswordUrl;
  private final String openIdSsoUrl;
  private final List<String> openIdDomains;
  private final List<OpenIdProviderPattern> trustedOpenIDs;
  private final List<OpenIdProviderPattern> allowedOpenIDs;
  private final String cookiePath;
  private final String cookieDomain;
  private final boolean cookieHttpOnly;
  private final SignedToken emailReg;
  private final boolean allowRegisterNewEmail;
  private final boolean userNameCaseInsensitive;
  private final boolean userNameCaseInsensitiveMigrationMode;
  private final int externalIdsRefExpirySecs;
  private GitBasicAuthPolicy gitBasicAuthPolicy;
  private final Duration maxAuthTokenLifetime;
  private final int maxAuthTokensPerAccount;
  private final boolean httpPasswordFallbackEnabled;

  @Inject
  AuthConfig(@GerritServerConfig Config cfg) throws XsrfException {
    authType = toType(cfg);
    httpHeader = cfg.getString("auth", null, "httpheader");
    httpDisplaynameHeader = cfg.getString("auth", null, "httpdisplaynameheader");
    httpEmailHeader = cfg.getString("auth", null, "httpemailheader");
    httpExternalIdHeader = cfg.getString("auth", null, "httpexternalidheader");
    loginUrl = cfg.getString("auth", null, "loginurl");
    loginText = cfg.getString("auth", null, "logintext");
    logoutUrl = cfg.getString("auth", null, "logouturl");
    switchAccountUrl = cfg.getString("auth", null, "switchAccountUrl");
    editFullNameUrl = cfg.getString("auth", null, "editFullNameUrl");
    httpPasswordUrl = cfg.getString("auth", null, "httpPasswordUrl");
    registerPageUrl = cfg.getString("auth", null, "registerPageUrl");
    registerUrl = cfg.getString("auth", null, "registerUrl");
    registerText = cfg.getString("auth", null, "registerText");
    openIdSsoUrl = cfg.getString("auth", null, "openidssourl");
    openIdDomains = Arrays.asList(cfg.getStringList("auth", null, "openIdDomain"));
    trustedOpenIDs = toPatterns(cfg, "trustedOpenID");
    allowedOpenIDs = toPatterns(cfg, "allowedOpenID");
    cookiePath = cfg.getString("auth", null, "cookiepath");
    cookieDomain = cfg.getString("auth", null, "cookiedomain");
    cookieHttpOnly = cfg.getBoolean("auth", "cookiehttponly", true);
    trustContainerAuth = cfg.getBoolean("auth", "trustContainerAuth", false);
    enableRunAs = cfg.getBoolean("auth", null, "enableRunAs", true);
    gitBasicAuthPolicy = getBasicAuthPolicy(cfg);
    useContributorAgreements = cfg.getBoolean("auth", "contributoragreements", false);
    userNameToLowerCase = cfg.getBoolean("auth", "userNameToLowerCase", false);
    allowRegisterNewEmail = cfg.getBoolean("auth", "allowRegisterNewEmail", true);
    userNameCaseInsensitive = cfg.getBoolean("auth", "userNameCaseInsensitive", false);
    userNameCaseInsensitiveMigrationMode =
        cfg.getBoolean("auth", "userNameCaseInsensitiveMigrationMode", false);
    externalIdsRefExpirySecs =
        (int)
            ConfigUtil.getTimeUnit(cfg, "auth", null, "externalIdsRefExpiry", 0, TimeUnit.SECONDS);
    httpPasswordFallbackEnabled = cfg.getBoolean("auth", "httpPasswordFallbackEnabled", true);

    if (gitBasicAuthPolicy == GitBasicAuthPolicy.HTTP_LDAP
        && authType != AuthType.LDAP
        && authType != AuthType.LDAP_BIND) {
      throw new IllegalStateException(
          "use auth.gitBasicAuthPolicy HTTP_LDAP only with auth.type LDAP or LDAP_BIND");
    } else if (gitBasicAuthPolicy == GitBasicAuthPolicy.OAUTH && authType != AuthType.OAUTH) {
      throw new IllegalStateException(
          "use auth.gitBasicAuthPolicy OAUTH only with auth.type OAUTH");
    }

    String key = cfg.getString("auth", null, "registerEmailPrivateKey");
    if (key != null && !key.isEmpty()) {
      int age =
          (int)
              ConfigUtil.getTimeUnit(
                  cfg,
                  "auth",
                  null,
                  "maxRegisterEmailTokenAge",
                  TimeUnit.SECONDS.convert(12, TimeUnit.HOURS),
                  TimeUnit.SECONDS);
      emailReg = new SignedToken(age, key);
    } else {
      emailReg = null;
    }

    maxAuthTokenLifetime =
        Duration.ofMinutes(
            ConfigUtil.getTimeUnit(cfg, "auth", null, "maxAuthTokenLifetime", 0, TimeUnit.MINUTES));
    maxAuthTokensPerAccount = cfg.getInt("auth", "maxAuthTokensPerAccount", 10);
  }

  private static List<OpenIdProviderPattern> toPatterns(Config cfg, String name) {
    String[] s = cfg.getStringList("auth", null, name);
    if (s.length == 0) {
      s = new String[] {"http://", "https://"};
    }

    List<OpenIdProviderPattern> r = new ArrayList<>();
    for (String pattern : s) {
      r.add(OpenIdProviderPattern.create(pattern));
    }
    return Collections.unmodifiableList(r);
  }

  private static AuthType toType(Config cfg) {
    return cfg.getEnum("auth", null, "type", AuthType.OPENID);
  }

  private GitBasicAuthPolicy getBasicAuthPolicy(Config cfg) {
    GitBasicAuthPolicy defaultAuthPolicy =
        isLdapAuthType()
            ? GitBasicAuthPolicy.LDAP
            : isOAuthType() ? GitBasicAuthPolicy.OAUTH : GitBasicAuthPolicy.HTTP;
    return cfg.getEnum("auth", null, "gitBasicAuthPolicy", defaultAuthPolicy);
  }

  /** Type of user authentication used by this Gerrit server. */
  public AuthType getAuthType() {
    return authType;
  }

  public String getLoginHttpHeader() {
    return httpHeader;
  }

  public String getHttpDisplaynameHeader() {
    return httpDisplaynameHeader;
  }

  public String getHttpEmailHeader() {
    return httpEmailHeader;
  }

  public String getHttpExternalIdHeader() {
    return httpExternalIdHeader;
  }

  public String getLoginUrl() {
    return loginUrl;
  }

  public String getLoginText() {
    return loginText;
  }

  public String getLogoutURL() {
    return logoutUrl;
  }

  public String getSwitchAccountUrl() {
    return switchAccountUrl;
  }

  public String getEditFullNameUrl() {
    return editFullNameUrl;
  }

  public String getHttpPasswordUrl() {
    return httpPasswordUrl;
  }

  public String getOpenIdSsoUrl() {
    return openIdSsoUrl;
  }

  public List<String> getOpenIdDomains() {
    return openIdDomains;
  }

  public String getCookiePath() {
    return cookiePath;
  }

  public String getCookieDomain() {
    return cookieDomain;
  }

  public boolean getCookieHttpOnly() {
    return cookieHttpOnly;
  }

  public int getExternalIdsRefExpirySecs() {
    return externalIdsRefExpirySecs;
  }

  public SignedToken getEmailRegistrationToken() {
    return emailReg;
  }

  /** OpenID identities which the server permits for authentication. */
  public List<OpenIdProviderPattern> getAllowedOpenIDs() {
    return allowedOpenIDs;
  }

  /** Whether git-over-http should trust authentication done by container. */
  public boolean isTrustContainerAuth() {
    return trustContainerAuth;
  }

  /** Returns true if users with Run As capability can impersonate others. */
  public boolean isRunAsEnabled() {
    return enableRunAs;
  }

  /** Whether user name should be converted to lower-case before validation */
  public boolean isUserNameToLowerCase() {
    return userNameToLowerCase;
  }

  /** Whether user name should be matched case insenitive */
  public boolean isUserNameCaseInsensitive() {
    return userNameCaseInsensitive;
  }

  /** Whether user name case insensitive migration is in progress */
  public boolean isUserNameCaseInsensitiveMigrationMode() {
    return userNameCaseInsensitiveMigrationMode;
  }

  public GitBasicAuthPolicy getGitBasicAuthPolicy() {
    return gitBasicAuthPolicy;
  }

  /** Whether contributor agreements are used. */
  public boolean isUseContributorAgreements() {
    return useContributorAgreements;
  }

  public boolean isIdentityTrustable(Collection<ExternalId> ids) {
    switch (getAuthType()) {
      case DEVELOPMENT_BECOME_ANY_ACCOUNT,
          HTTP,
          HTTP_LDAP,
          LDAP,
          LDAP_BIND,
          CLIENT_SSL_CERT_LDAP,
          CUSTOM_EXTENSION,
          OAUTH -> {
        // only way in is through some external system that the admin trusts
        //
        return true;
      }
      case OPENID_SSO -> {
        // There's only one provider in SSO mode, so it must be okay.
        return true;
      }
      case OPENID -> {
        // All identities must be trusted in order to trust the account.
        //
        for (ExternalId e : ids) {
          if (!isTrusted(e)) {
            return false;
          }
        }
        return true;
      }
      default -> {
        // Assume not, we don't understand the login format.
        //
        return false;
      }
    }
  }

  private boolean isTrusted(ExternalId id) {
    if (id.isScheme(SCHEME_MAILTO)) {
      // mailto identities are created by sending a unique validation
      // token to the address and asking them to come back to the site
      // with that token.
      //
      return true;
    }

    if (id.isScheme(SCHEME_UUID)) {
      // UUID identities are absolutely meaningless and cannot be
      // constructed through any normal login process we use.
      //
      return true;
    }

    if (id.isScheme(SCHEME_USERNAME)) {
      // We can trust their username, its local to our server only.
      //
      return true;
    }

    for (OpenIdProviderPattern p : trustedOpenIDs) {
      if (p.matches(id)) {
        return true;
      }
    }
    return false;
  }

  public String getRegisterPageUrl() {
    return registerPageUrl;
  }

  public String getRegisterUrl() {
    return registerUrl;
  }

  public String getRegisterText() {
    return registerText;
  }

  public boolean isLdapAuthType() {
    return authType == AuthType.LDAP || authType == AuthType.LDAP_BIND;
  }

  public boolean isOAuthType() {
    return authType == AuthType.OAUTH;
  }

  public boolean isAllowRegisterNewEmail() {
    return allowRegisterNewEmail;
  }

  public Optional<Duration> getMaxAuthTokenLifetime() {
    if (maxAuthTokenLifetime.isZero() || maxAuthTokenLifetime.isNegative()) {
      return Optional.empty();
    }
    return Optional.of(maxAuthTokenLifetime);
  }

  public int getMaxAuthTokensPerAccount() {
    return maxAuthTokensPerAccount;
  }

  public boolean isHttpPasswordFallbackEnabled() {
    return httpPasswordFallbackEnabled;
  }
}
