// 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.auth.ldap;

import com.google.common.base.Throwables;
import com.google.common.cache.Cache;
import com.google.common.collect.ImmutableSet;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.data.ParameterizedString;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.account.AccountException;
import com.google.gerrit.server.account.AuthenticationFailedException;
import com.google.gerrit.server.auth.NoSuchUserException;
import com.google.gerrit.server.config.ConfigUtil;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.util.ssl.BlindHostnameVerifier;
import com.google.gerrit.util.ssl.BlindSSLSocketFactory;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import java.io.IOException;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.naming.CompositeName;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.PartialResultException;
import javax.naming.directory.Attribute;
import javax.naming.directory.DirContext;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.StartTlsRequest;
import javax.naming.ldap.StartTlsResponse;
import javax.net.ssl.SSLSocketFactory;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import org.eclipse.jgit.lib.Config;

@Singleton
class Helper {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  static final String LDAP_UUID = "ldap:";
  static final String STARTTLS_PROPERTY = Helper.class.getName() + ".startTls";

  private final Cache<String, ImmutableSet<String>> parentGroups;
  private final Config config;
  private final String server;
  private final String username;
  private final String password;
  private final String referral;
  private final boolean startTls;
  private final boolean sslVerify;
  private final String authentication;
  private volatile LdapSchema ldapSchema;
  private final String readTimeoutMillis;
  private final String connectTimeoutMillis;
  private final boolean useConnectionPooling;
  private final boolean groupsVisibleToAll;

  @Inject
  Helper(
      @GerritServerConfig Config config,
      @Named(LdapModule.PARENT_GROUPS_CACHE) Cache<String, ImmutableSet<String>> parentGroups) {
    this.config = config;
    this.server = LdapRealm.optional(config, "server");
    this.username = LdapRealm.optional(config, "username");
    this.password = LdapRealm.optional(config, "password", "");
    this.referral = LdapRealm.optional(config, "referral", "ignore");
    this.startTls = config.getBoolean("ldap", "startTls", false);
    this.sslVerify = config.getBoolean("ldap", "sslverify", true);
    this.groupsVisibleToAll = config.getBoolean("ldap", "groupsVisibleToAll", false);
    this.authentication = LdapRealm.optional(config, "authentication", "simple");
    String readTimeout = LdapRealm.optional(config, "readTimeout");
    if (readTimeout != null) {
      readTimeoutMillis =
          Long.toString(ConfigUtil.getTimeUnit(readTimeout, 0, TimeUnit.MILLISECONDS));
    } else {
      readTimeoutMillis = null;
    }
    String connectTimeout = LdapRealm.optional(config, "connectTimeout");
    if (connectTimeout != null) {
      connectTimeoutMillis =
          Long.toString(ConfigUtil.getTimeUnit(connectTimeout, 0, TimeUnit.MILLISECONDS));
    } else {
      connectTimeoutMillis = null;
    }
    this.parentGroups = parentGroups;
    this.useConnectionPooling = LdapRealm.optional(config, "useConnectionPooling", false);
  }

  private Properties createContextProperties() {
    final Properties env = new Properties();
    env.put(Context.INITIAL_CONTEXT_FACTORY, LdapRealm.LDAP);
    env.put(Context.PROVIDER_URL, server);
    if (server.startsWith("ldaps:") && !sslVerify) {
      Class<? extends SSLSocketFactory> factory = BlindSSLSocketFactory.class;
      env.put("java.naming.ldap.factory.socket", factory.getName());
    }
    if (readTimeoutMillis != null) {
      env.put("com.sun.jndi.ldap.read.timeout", readTimeoutMillis);
    }
    if (connectTimeoutMillis != null) {
      env.put("com.sun.jndi.ldap.connect.timeout", connectTimeoutMillis);
    }
    if (useConnectionPooling) {
      env.put("com.sun.jndi.ldap.connect.pool", "true");
    }
    return env;
  }

  private LdapContext createContext(Properties env) throws IOException, NamingException {
    LdapContext ctx = new InitialLdapContext(env, null);
    if (startTls) {
      StartTlsResponse tls = (StartTlsResponse) ctx.extendedOperation(new StartTlsRequest());
      SSLSocketFactory sslfactory = null;
      if (!sslVerify) {
        sslfactory = (SSLSocketFactory) BlindSSLSocketFactory.getDefault();
        tls.setHostnameVerifier(BlindHostnameVerifier.getInstance());
      }
      tls.negotiate(sslfactory);
      ctx.addToEnvironment(STARTTLS_PROPERTY, tls);
    }
    return ctx;
  }

  void close(DirContext ctx) {
    try {
      StartTlsResponse tls = (StartTlsResponse) ctx.removeFromEnvironment(STARTTLS_PROPERTY);
      if (tls != null) {
        tls.close();
      }
    } catch (IOException | NamingException e) {
      logger.atWarning().withCause(e).log("Cannot close LDAP startTls handle");
    }
    try {
      ctx.close();
    } catch (NamingException e) {
      logger.atWarning().withCause(e).log("Cannot close LDAP handle");
    }
  }

  DirContext open() throws IOException, NamingException, LoginException {
    final Properties env = createContextProperties();
    env.put(Context.SECURITY_AUTHENTICATION, authentication);
    env.put(Context.REFERRAL, referral);
    if ("GSSAPI".equals(authentication)) {
      return kerberosOpen(env);
    }
    LdapContext ctx = createContext(env);
    if (username != null) {
      ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, username);
      ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
      ctx.reconnect(null);
    }
    return ctx;
  }

  private DirContext kerberosOpen(Properties env)
      throws IOException, LoginException, NamingException {
    LoginContext ctx = new LoginContext("KerberosLogin");
    ctx.login();
    Subject subject = ctx.getSubject();
    try {
      return Subject.doAs(
          subject,
          new PrivilegedExceptionAction<DirContext>() {
            @Override
            public DirContext run() throws IOException, NamingException {
              return createContext(env);
            }
          });
    } catch (PrivilegedActionException e) {
      Throwables.throwIfInstanceOf(e.getException(), IOException.class);
      Throwables.throwIfInstanceOf(e.getException(), NamingException.class);
      Throwables.throwIfInstanceOf(e.getException(), RuntimeException.class);
      logger.atWarning().withCause(e.getException()).log("Internal error");
      return null;
    } finally {
      ctx.logout();
    }
  }

  DirContext authenticate(String dn, String password) throws AccountException {
    final Properties env = createContextProperties();
    try {
      LdapContext ctx = createContext(env);
      ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION, "simple");
      ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, dn);
      ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
      ctx.addToEnvironment(Context.REFERRAL, referral);
      ctx.reconnect(null);
      return ctx;
    } catch (IOException | NamingException e) {
      throw new AuthenticationFailedException("Incorrect username or password", e);
    }
  }

  LdapSchema getSchema(DirContext ctx) {
    if (ldapSchema == null) {
      synchronized (this) {
        if (ldapSchema == null) {
          ldapSchema = new LdapSchema(ctx);
        }
      }
    }
    return ldapSchema;
  }

  LdapQuery.Result findAccount(
      Helper.LdapSchema schema, DirContext ctx, String username, boolean fetchMemberOf)
      throws NamingException, AccountException {
    final HashMap<String, String> params = new HashMap<>();
    params.put(LdapRealm.USERNAME, username);

    List<LdapQuery> accountQueryList;
    if (fetchMemberOf && schema.type.accountMemberField() != null) {
      accountQueryList = schema.accountWithMemberOfQueryList;
    } else {
      accountQueryList = schema.accountQueryList;
    }

    for (LdapQuery accountQuery : accountQueryList) {
      List<LdapQuery.Result> res = accountQuery.query(ctx, params);
      if (res.size() == 1) {
        return res.get(0);
      } else if (res.size() > 1) {
        throw new AccountException("Duplicate users: " + username);
      }
    }
    throw new NoSuchUserException(username);
  }

  Set<AccountGroup.UUID> queryForGroups(
      final DirContext ctx, String username, LdapQuery.Result account) throws NamingException {
    final LdapSchema schema = getSchema(ctx);
    final Set<String> groupDNs = new HashSet<>();

    if (!schema.groupMemberQueryList.isEmpty()) {
      final HashMap<String, String> params = new HashMap<>();

      if (account == null) {
        try {
          account = findAccount(schema, ctx, username, false);
        } catch (AccountException e) {
          return Collections.emptySet();
        }
      }
      for (String name : schema.groupMemberQueryList.get(0).getParameters()) {
        params.put(name, account.get(name));
      }

      params.put(LdapRealm.USERNAME, username);

      for (LdapQuery groupMemberQuery : schema.groupMemberQueryList) {
        for (LdapQuery.Result r : groupMemberQuery.query(ctx, params)) {
          recursivelyExpandGroups(groupDNs, schema, ctx, r.getDN());
        }
      }
    }

    if (schema.accountMemberField != null) {
      if (account == null || account.getAll(schema.accountMemberField) == null) {
        try {
          account = findAccount(schema, ctx, username, true);
        } catch (AccountException e) {
          return Collections.emptySet();
        }
      }

      final Attribute groupAtt = account.getAll(schema.accountMemberField);
      if (groupAtt != null) {
        final NamingEnumeration<?> groups = groupAtt.getAll();
        try {
          while (groups.hasMore()) {
            final String nextDN = (String) groups.next();
            recursivelyExpandGroups(groupDNs, schema, ctx, nextDN);
          }
        } catch (PartialResultException e) {
          // Ignored
        }
      }
    }

    final Set<AccountGroup.UUID> actual = new HashSet<>();
    for (String dn : groupDNs) {
      actual.add(new AccountGroup.UUID(LDAP_UUID + dn));
    }

    if (actual.isEmpty()) {
      return Collections.emptySet();
    }
    return ImmutableSet.copyOf(actual);
  }

  private void recursivelyExpandGroups(
      final Set<String> groupDNs,
      final LdapSchema schema,
      final DirContext ctx,
      final String groupDN) {
    if (groupDNs.add(groupDN)
        && schema.accountMemberField != null
        && schema.accountMemberExpandGroups) {
      ImmutableSet<String> cachedParentsDNs = parentGroups.getIfPresent(groupDN);
      if (cachedParentsDNs == null) {
        // Recursively identify the groups it is a member of.
        ImmutableSet.Builder<String> dns = ImmutableSet.builder();
        try {
          final Name compositeGroupName = new CompositeName().add(groupDN);
          final Attribute in =
              ctx.getAttributes(compositeGroupName, schema.accountMemberFieldArray)
                  .get(schema.accountMemberField);
          if (in != null) {
            final NamingEnumeration<?> groups = in.getAll();
            try {
              while (groups.hasMore()) {
                dns.add((String) groups.next());
              }
            } catch (PartialResultException e) {
              // Ignored
            }
          }
        } catch (NamingException e) {
          logger.atWarning().withCause(e).log("Could not find group %s", groupDN);
        }
        cachedParentsDNs = dns.build();
        parentGroups.put(groupDN, cachedParentsDNs);
      }
      for (String dn : cachedParentsDNs) {
        recursivelyExpandGroups(groupDNs, schema, ctx, dn);
      }
    }
  }

  public boolean groupsVisibleToAll() {
    return this.groupsVisibleToAll;
  }

  class LdapSchema {
    final LdapType type;

    final ParameterizedString accountFullName;
    final ParameterizedString accountEmailAddress;
    final ParameterizedString accountSshUserName;
    final String accountMemberField;
    final boolean accountMemberExpandGroups;
    final String[] accountMemberFieldArray;
    final List<LdapQuery> accountQueryList;
    final List<LdapQuery> accountWithMemberOfQueryList;

    final List<String> groupBases;
    final SearchScope groupScope;
    final ParameterizedString groupPattern;
    final ParameterizedString groupName;
    final List<LdapQuery> groupMemberQueryList;

    LdapSchema(DirContext ctx) {
      type = discoverLdapType(ctx);
      groupMemberQueryList = new ArrayList<>();
      accountQueryList = new ArrayList<>();
      accountWithMemberOfQueryList = new ArrayList<>();

      final Set<String> accountAtts = new HashSet<>();

      // Group query
      //

      groupBases = LdapRealm.optionalList(config, "groupBase");
      groupScope = LdapRealm.scope(config, "groupScope");
      groupPattern = LdapRealm.paramString(config, "groupPattern", type.groupPattern());
      groupName = LdapRealm.paramString(config, "groupName", type.groupName());
      final String groupMemberPattern =
          LdapRealm.optdef(config, "groupMemberPattern", type.groupMemberPattern());

      for (String groupBase : groupBases) {
        if (groupMemberPattern != null) {
          final LdapQuery groupMemberQuery =
              new LdapQuery(
                  groupBase,
                  groupScope,
                  new ParameterizedString(groupMemberPattern),
                  Collections.<String>emptySet());
          if (groupMemberQuery.getParameters().isEmpty()) {
            throw new IllegalArgumentException("No variables in ldap.groupMemberPattern");
          }

          accountAtts.addAll(groupMemberQuery.getParameters());

          groupMemberQueryList.add(groupMemberQuery);
        }
      }

      // Account query
      //
      accountFullName = LdapRealm.paramString(config, "accountFullName", type.accountFullName());
      if (accountFullName != null) {
        accountAtts.addAll(accountFullName.getParameterNames());
      }
      accountEmailAddress =
          LdapRealm.paramString(config, "accountEmailAddress", type.accountEmailAddress());
      if (accountEmailAddress != null) {
        accountAtts.addAll(accountEmailAddress.getParameterNames());
      }
      accountSshUserName =
          LdapRealm.paramString(config, "accountSshUserName", type.accountSshUserName());
      if (accountSshUserName != null) {
        accountAtts.addAll(accountSshUserName.getParameterNames());
      }
      accountMemberField =
          LdapRealm.optdef(config, "accountMemberField", type.accountMemberField());
      if (accountMemberField != null) {
        accountMemberFieldArray = new String[] {accountMemberField};
      } else {
        accountMemberFieldArray = null;
      }
      accountMemberExpandGroups =
          LdapRealm.optional(config, "accountMemberExpandGroups", type.accountMemberExpandGroups());

      final SearchScope accountScope = LdapRealm.scope(config, "accountScope");
      final String accountPattern =
          LdapRealm.reqdef(config, "accountPattern", type.accountPattern());

      Set<String> accountWithMemberOfAtts;
      if (accountMemberField != null) {
        accountWithMemberOfAtts = new HashSet<>(accountAtts);
        accountWithMemberOfAtts.add(accountMemberField);
      } else {
        accountWithMemberOfAtts = null;
      }
      for (String accountBase : LdapRealm.requiredList(config, "accountBase")) {
        LdapQuery accountQuery =
            new LdapQuery(
                accountBase, accountScope, new ParameterizedString(accountPattern), accountAtts);
        if (accountQuery.getParameters().isEmpty()) {
          throw new IllegalArgumentException("No variables in ldap.accountPattern");
        }
        accountQueryList.add(accountQuery);

        if (accountWithMemberOfAtts != null) {
          LdapQuery accountWithMemberOfQuery =
              new LdapQuery(
                  accountBase,
                  accountScope,
                  new ParameterizedString(accountPattern),
                  accountWithMemberOfAtts);
          accountWithMemberOfQueryList.add(accountWithMemberOfQuery);
        }
      }
    }

    LdapType discoverLdapType(DirContext ctx) {
      try {
        return LdapType.guessType(ctx);
      } catch (NamingException e) {
        logger.atWarning().withCause(e).log(
            "Cannot discover type of LDAP server at %s,"
                + " assuming the server is RFC 2307 compliant.",
            server);
        return LdapType.RFC_2307;
      }
    }
  }
}
