/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.drill.exec.rpc.user.security;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.drill.common.config.DrillConfig;
import org.apache.drill.exec.ExecConstants;
import org.apache.drill.exec.exception.DrillbitStartupException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Implementation of UserAuthenticator that reads passwords from an htpasswd
 * formatted file.
 * <p>
 * Currently supports MD5, SHA-1, and plaintext passwords.
 * <p>
 * Use the htpasswd command line tool to create and modify htpasswd files.
 * <p>
 * By default this loads the passwords from <code>/opt/drill/conf/htpasswd</code>.  Users can change the path by
 * putting the absolute file path as <code>drill.exec.security.user.auth.htpasswd.path</code> in
 * <code>drill-override.conf</code>.
 * <p>
 * This is intended for situations where the list of users is relatively static, and you are running
 * drill in a container so using pam is not convenient.
 */
@UserAuthenticatorTemplate(type = "htpasswd")
public class HtpasswdFileUserAuthenticator implements UserAuthenticator {
  private static final Logger logger = LoggerFactory.getLogger(HtpasswdFileUserAuthenticator.class);
  private static final Pattern HTPASSWD_LINE_PATTERN = Pattern.compile("^([^:]+):([^:]+)");
  public static final String DEFAULT_HTPASSWD_AUTHENTICATOR_PATH = "/opt/drill/conf/htpasswd";

  private String path = DEFAULT_HTPASSWD_AUTHENTICATOR_PATH;
  private long lastModified;
  private long lastFileSize;
  private Map<String, String> userToPassword;

  @Override
  public void setup(DrillConfig drillConfig) throws DrillbitStartupException {
    if (drillConfig.hasPath(ExecConstants.HTPASSWD_AUTHENTICATOR_PATH)) {
      path = drillConfig.getString(ExecConstants.HTPASSWD_AUTHENTICATOR_PATH);
    }
  }

  /**
   * Check password against hash read from the file
   *
   * @param password User provided password
   * @param hash     Hash stored in the htpasswd file
   * @return true if the password matched the hash
   */
  public static boolean isPasswordValid(String password, String hash) {
    if (hash.startsWith("$apr1$")) {
      return hash.equals(Md5Crypt.apr1Crypt(password, hash));
    } else if (hash.startsWith("$1$")) {
      return hash.equals(Md5Crypt.md5Crypt(password.getBytes(StandardCharsets.UTF_8), hash));
    } else if (hash.startsWith("{SHA}")) {
      return hash.substring(5).equals(Base64.getEncoder().encodeToString(DigestUtils.sha1(password)));
    } else if (hash.startsWith("$2y$")) {
      // bcrypt not supported currently
      return false;
    } else {
      return hash.equals(password);
    }
  }

  /**
   * Validate the given username and password against the password file
   *
   * @param username Username provided
   * @param password Password provided
   * @throws UserAuthenticationException If the username and password could not be validated
   */
  @Override
  public void authenticate(String username, String password) throws UserAuthenticationException {
    read();
    String hash = this.userToPassword.get(username);
    boolean credentialsAccepted = (hash != null && isPasswordValid(password, hash));
    if (!credentialsAccepted) {
      throw new UserAuthenticationException(String.format("htpasswd auth failed for user '%s'",
        username));
    }
  }

  /**
   * Read the password file into the map, if the file has changed since we last read it
   */
  protected synchronized void read() {
    File file = new File(path);
    long newLastModified = file.exists() ? file.lastModified() : 0;
    long newFileSize = file.exists() ? file.length() : 0;
    if (userToPassword == null || newLastModified != lastModified || newFileSize != lastFileSize) {
      HashMap<String, String> newMap = new HashMap<>();
      if(newFileSize != 0) {
        try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
          String line;
          while ((line = reader.readLine()) != null) {
            if (!line.isEmpty() && !line.startsWith("#")) {
              Matcher m = HTPASSWD_LINE_PATTERN.matcher(line);
              if (m.matches()) {
                newMap.put(m.group(1), m.group(2));
              }
            }
          }
        } catch (Exception e) {
          logger.error(MessageFormat.format("Failed to read htpasswd file at path {0}", file), e);
        }
      } else {
        logger.error(MessageFormat.format("Empty or missing htpasswd file at path {0}", file));
      }
      lastFileSize = newFileSize;
      lastModified = newLastModified;
      userToPassword = newMap;
    }
  }

  /**
   * Free resources associated with this authenticator
   */
  @Override
  public void close() {
    lastModified = 0;
    userToPassword = null;
  }
}
