/*
 * Copyright 2013 Florian Zschocke
 * Copyright 2013 gitblit.com
 *
 * 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.gitblit.auth;

import java.io.File;
import java.io.FileInputStream;
import java.text.MessageFormat;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.Crypt;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.Md5Crypt;

import com.gitblit.Constants;
import com.gitblit.Constants.AccountType;
import com.gitblit.Keys;
import com.gitblit.auth.AuthenticationProvider.UsernamePasswordAuthenticationProvider;
import com.gitblit.models.UserModel;


/**
 * Implementation of a user service using an Apache htpasswd file for authentication.
 *
 * This user service implement custom authentication using entries in a file created
 * by the 'htpasswd' program of an Apache web server. All possible output
 * options of the 'htpasswd' program version 2.2 are supported:
 * plain text (only on Windows and Netware),
 * glibc crypt() (not on Windows and NetWare),
 * Apache MD5 (apr1),
 * unsalted SHA-1.
 *
 * Configuration options:
 * realm.htpasswd.backingUserService - Specify the backing user service that is used
 *                                     to keep the user data other than the password.
 *                                     The default is '${baseFolder}/users.conf'.
 * realm.htpasswd.userfile - The text file with the htpasswd entries to be used for
 *                           authentication.
 *                           The default is '${baseFolder}/htpasswd'.
 * realm.htpasswd.overrideLocalAuthentication - Specify if local accounts are overwritten
 *                                              when authentication matches for an
 *                                              external account.
 *
 * @author Florian Zschocke
 *
 */
public class HtpasswdAuthProvider extends UsernamePasswordAuthenticationProvider {

    private static final String KEY_HTPASSWD_FILE = Keys.realm.htpasswd.userfile;
    private static final String DEFAULT_HTPASSWD_FILE = "${baseFolder}/htpasswd";

    private static final String KEY_SUPPORT_PLAINTEXT_PWD = "realm.htpasswd.supportPlaintextPasswords";

    private boolean supportPlainTextPwd;

    private File htpasswdFile;

    private final Map<String, String> htUsers = new ConcurrentHashMap<String, String>();

    private volatile long lastModified;

    public HtpasswdAuthProvider() {
        super("htpasswd");
    }

    /**
     * Setup the user service.
     *
     * The HtpasswdUserService extends the GitblitUserService and is thus
     * backed by the available user services provided by the GitblitUserService.
     * In addition the setup tries to read and parse the htpasswd file to be used
     * for authentication.
     *
     * @param settings
     * @since 0.7.0
     */
    @Override
    public void setup() {
        String os = System.getProperty("os.name").toLowerCase();
        if (os.startsWith("windows") || os.startsWith("netware")) {
            supportPlainTextPwd = true;
        } else {
            supportPlainTextPwd = false;
        }
        read();
        logger.debug("Read " + htUsers.size() + " users from htpasswd file: " + this.htpasswdFile);
    }

    @Override
    public boolean supportsCredentialChanges() {
        return false;
    }

    @Override
    public boolean supportsDisplayNameChanges() {
        return true;
    }

    @Override
    public boolean supportsEmailAddressChanges() {
        return true;
    }

    @Override
    public boolean supportsTeamMembershipChanges() {
        return true;
    }

    /**
     * Authenticate a user based on a username and password.
     *
     * If the account is determined to be a local account, authentication
     * will be done against the locally stored password.
     * Otherwise, the configured htpasswd file is read. All current output options
     * of htpasswd are supported: clear text, crypt(), Apache MD5 and unsalted SHA-1.
     *
     * @param username
     * @param password
     * @return a user object or null
     */
    @Override
    public UserModel authenticate(String username, char[] password) {
        read();
        String storedPwd = htUsers.get(username);
        if (storedPwd != null) {
            boolean authenticated = false;
            final String passwd = new String(password);

            // test Apache MD5 variant encrypted password
            if (storedPwd.startsWith("$apr1$")) {
                if (storedPwd.equals(Md5Crypt.apr1Crypt(passwd, storedPwd))) {
                    logger.debug("Apache MD5 encoded password matched for user '" + username + "'");
                    authenticated = true;
                }
            }
            // test unsalted SHA password
            else if (storedPwd.startsWith("{SHA}")) {
                String passwd64 = Base64.encodeBase64String(DigestUtils.sha1(passwd));
                if (storedPwd.substring("{SHA}".length()).equals(passwd64)) {
                    logger.debug("Unsalted SHA-1 encoded password matched for user '" + username + "'");
                    authenticated = true;
                }
            }
            // test libc crypt() encoded password
            else if (supportCryptPwd() && storedPwd.equals(Crypt.crypt(passwd, storedPwd))) {
                logger.debug("Libc crypt encoded password matched for user '" + username + "'");
                authenticated = true;
            }
            // test clear text
            else if (supportPlaintextPwd() && storedPwd.equals(passwd)){
                logger.debug("Clear text password matched for user '" + username + "'");
                authenticated = true;
            }


            if (authenticated) {
                logger.debug("Htpasswd authenticated: " + username);

                UserModel curr = userManager.getUserModel(username);
                UserModel user;
                if (curr == null) {
                    // create user object for new authenticated user
                    user = new UserModel(username);
                } else {
                	user = curr;
                }

                // create a user cookie
                setCookie(user, password);

                // Set user attributes, hide password from backing user service.
                user.password = Constants.EXTERNAL_ACCOUNT;
                user.accountType = getAccountType();

                // Push the looked up values to backing file
               	updateUser(user);

                return user;
            }
        }

        return null;
    }

    /**
     * Get the account type used for this user service.
     *
     * @return AccountType.HTPASSWD
     */
    @Override
	public AccountType getAccountType() {
        return AccountType.HTPASSWD;
    }

    /**
     * Reads the realm file and rebuilds the in-memory lookup tables.
     */
    protected synchronized void read() {
    	boolean forceReload = false;
    	File file = getFileOrFolder(KEY_HTPASSWD_FILE, DEFAULT_HTPASSWD_FILE);
        if (!file.equals(htpasswdFile)) {
            this.htpasswdFile = file;
            this.htUsers.clear();
            forceReload = true;
        }

        if (htpasswdFile.exists() && (forceReload || (htpasswdFile.lastModified() != lastModified))) {
            lastModified = htpasswdFile.lastModified();
            htUsers.clear();

            Pattern entry = Pattern.compile("^([^:]+):(.+)");

            Scanner scanner = null;
            try {
                scanner = new Scanner(new FileInputStream(htpasswdFile));
                while (scanner.hasNextLine()) {
                    String line = scanner.nextLine().trim();
                    if (!line.isEmpty() &&  !line.startsWith("#")) {
                        Matcher m = entry.matcher(line);
                        if (m.matches()) {
                            htUsers.put(m.group(1), m.group(2));
                        }
                    }
                }
            } catch (Exception e) {
                logger.error(MessageFormat.format("Failed to read {0}", htpasswdFile), e);
            } finally {
                if (scanner != null) {
                	scanner.close();
                }
            }
        }
    }

    private boolean supportPlaintextPwd() {
        return this.settings.getBoolean(KEY_SUPPORT_PLAINTEXT_PWD, supportPlainTextPwd);
    }

    private boolean supportCryptPwd() {
        return !supportPlaintextPwd();
    }

    /*
     * Method only used for unit tests. Return number of users read from htpasswd file.
     */
    public int getNumberHtpasswdUsers() {
        return this.htUsers.size();
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + "(" + ((htpasswdFile != null) ? htpasswdFile.getAbsolutePath() : "null") + ")";
    }
}
