#!/usr/bin/env bash

# Author: Zhang Huangbin <zhb _at_ iredmail.org>

# -----------------------
# Roundcube.
# -----------------------
rcm_install()
{
    ECHO_INFO "Configure Roundcube webmail."

    if [ X"${RCM_USE_SOURCE}" == X'YES' ]; then
        cd ${PKG_MISC_DIR}

        # Extract source tarball.
        extract_pkg ${RCM_TARBALL} ${HTTPD_SERVERROOT}

        # Create symbol link, so that we don't need to modify web server config
        # file to set new version number after upgrading this software.
        ln -s ${RCM_HTTPD_ROOT} ${RCM_HTTPD_ROOT_SYMBOL_LINK} >> ${INSTALL_LOG} 2>&1

        ECHO_DEBUG "Set correct permission for Roundcubemail: ${RCM_HTTPD_ROOT}."
        chown -R ${SYS_USER_ROOT}:${SYS_GROUP_ROOT} ${RCM_HTTPD_ROOT}
        chown -R ${HTTPD_USER}:${HTTPD_GROUP} ${RCM_HTTPD_ROOT}/{temp,logs}
        chmod 0000 ${RCM_HTTPD_ROOT}/{CHANGELOG.md,INSTALL,LICENSE,README*,UPGRADING,installer,SQL}
    fi

    # Copy sample config files.
    cp -f ${SAMPLE_DIR}/roundcubemail/config.inc.php ${RCM_CONF}
    chown ${HTTPD_USER}:${HTTPD_GROUP} ${RCM_CONF}
    chmod 0600 ${RCM_CONF}

    if [ X"${DISTRO_CODENAME}" == X'rhel' ]; then
        # RHEL doesn't offer php-pspell package, use enchant spell engine instead.
        perl -pi -e 's#pspell#enchant#g' ${RCM_CONF}
    fi

    echo 'export status_rcm_install="DONE"' >> ${STATUS_FILE}
}

rcm_initialize_db()
{
    ECHO_DEBUG "Import SQL database and privileges for Roundcubemail."

    # Initial roundcube db.
    if [ X"${BACKEND}" == X'OPENLDAP' -o X"${BACKEND}" == X'MYSQL' ]; then
        ${MYSQL_CLIENT_ROOT} <<EOF
-- Create database and grant privileges
CREATE DATABASE ${RCM_DB_NAME} DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER "${RCM_DB_USER}"@"${MYSQL_GRANT_HOST}" IDENTIFIED BY '${RCM_DB_PASSWD}';
GRANT ALL ON ${RCM_DB_NAME}.* TO "${RCM_DB_USER}"@"${MYSQL_GRANT_HOST}";

-- Import Roundcubemail SQL template
USE ${RCM_DB_NAME};
SOURCE ${RCM_HTTPD_ROOT}/SQL/mysql.initial.sql;

FLUSH PRIVILEGES;
EOF

        # Generate .my.cnf file
        cat > /root/.my.cnf-${RCM_DB_USER} <<EOF
[client]
host=${MYSQL_SERVER_ADDRESS}
port=${MYSQL_SERVER_PORT}
user=${RCM_DB_USER}
password="${RCM_DB_PASSWD}"
EOF

    elif [ X"${BACKEND}" == X'PGSQL' ]; then
        cp -f ${RCM_HTTPD_ROOT}/SQL/postgres.initial.sql ${PGSQL_USER_HOMEDIR}/rcm.sql >> ${INSTALL_LOG} 2>&1
        chmod 0777 ${PGSQL_USER_HOMEDIR}/rcm.sql

        su - ${SYS_USER_PGSQL} -c "psql -d template1 >/dev/null" >> ${INSTALL_LOG} 2>&1 <<EOF
-- Create database and role
CREATE DATABASE ${RCM_DB_NAME} WITH TEMPLATE template0 ENCODING 'UTF8';
CREATE ROLE ${RCM_DB_USER} WITH LOGIN ENCRYPTED PASSWORD '${RCM_DB_PASSWD}' NOSUPERUSER NOCREATEDB NOCREATEROLE;

-- Grant privilege
ALTER DATABASE ${RCM_DB_NAME} OWNER TO ${RCM_DB_USER};
EOF

        # Import sql templte as roundcube user.
        su - ${SYS_USER_PGSQL} -c "psql -U ${RCM_DB_USER} -d ${RCM_DB_NAME}" >> ${INSTALL_LOG} 2>&1 <<EOF
-- Import Roundcubemail SQL template
\i ${PGSQL_USER_HOMEDIR}/rcm.sql;

-- Grant privileges
-- GRANT SELECT,INSERT,UPDATE,DELETE ON cache,cache_index,cache_messages,cache_shared,cache_thread,contactgroupmembers,contactgroups,contacts,dictionary,identities,searches,session,system,users TO ${RCM_DB_USER};
-- GRANT SELECT,UPDATE,USAGE ON contacts_seq,contactgroups_seq,identities_seq,searches_seq,users_seq TO ${RCM_DB_USER};
EOF

        # Grant privilege to update password (vmail.mailbox) through roundcube webmail
        su - ${SYS_USER_PGSQL} -c "psql -d ${VMAIL_DB_NAME} >/dev/null" >> ${INSTALL_LOG} 2>&1 <<EOF
\c ${VMAIL_DB_NAME};
GRANT UPDATE,SELECT ON mailbox TO ${RCM_DB_USER};
EOF
        rm -f ${PGSQL_USER_HOMEDIR}/rcm.sql >> ${INSTALL_LOG} 2>&1
    fi

    # Grant privileges
    if [ X"${BACKEND}" == X'MYSQL' ]; then
        ${MYSQL_CLIENT_ROOT} <<EOF
-- Grant privileges for Roundcubemail, so that user can change
-- their own password and setting mail forwarding.
GRANT UPDATE,SELECT ON ${VMAIL_DB_NAME}.mailbox TO "${RCM_DB_USER}"@"${MYSQL_GRANT_HOST}";
-- GRANT UPDATE,SELECT ON ${VMAIL_DB_NAME}.mailbox TO "${RCM_DB_USER}"@"${HOSTNAME}";

FLUSH PRIVILEGES;
EOF
    fi

    echo 'export status_rcm_initialize_db="DONE"' >> ${STATUS_FILE}
}

rcm_config()
{
    ECHO_DEBUG "Configure database for Roundcubemail: ${RCM_CONF_DIR}/*."

    cd ${RCM_CONF_DIR}

    perl -pi -e 's#PH_IMAP_SERVER#$ENV{IMAP_SERVER}#g' ${RCM_CONF}

    perl -pi -e 's#PH_PHP_CONN_TYPE#$ENV{PHP_CONN_TYPE}#g' ${RCM_CONF}
    perl -pi -e 's#PH_RCM_DB_USER#$ENV{RCM_DB_USER}#g' ${RCM_CONF}
    perl -pi -e 's#PH_RCM_DB_PASSWD#$ENV{RCM_DB_PASSWD}#g' ${RCM_CONF}
    perl -pi -e 's#PH_RCM_DB_NAME#$ENV{RCM_DB_NAME}#g' ${RCM_CONF}
    perl -pi -e 's#PH_SQL_SERVER_ADDRESS#$ENV{SQL_SERVER_ADDRESS}#g' ${RCM_CONF}
    perl -pi -e 's#PH_SQL_SERVER_PORT#$ENV{SQL_SERVER_PORT}#g' ${RCM_CONF}

    perl -pi -e 's#PH_SMTP_SERVER#$ENV{SMTP_SERVER}#g' ${RCM_CONF}
    perl -pi -e 's#PH_RCM_DES_KEY#$ENV{RCM_DES_KEY}#g' ${RCM_CONF}
    perl -pi -e 's#PH_MESSAGE_SIZE_LIMIT_MB#$ENV{MESSAGE_SIZE_LIMIT_MB}#g' ${RCM_CONF}
    perl -pi -e 's#PH_FIRST_DOMAIN#$ENV{FIRST_DOMAIN}#g' ${RCM_CONF}

    # Enable mime.types on Linux
    if [ X"${KERNEL_NAME}" == X"LINUX" ]; then
        perl -pi -e 's#//(.*mime_types.*)#${1}#' ${RCM_CONF}
    fi

    if [ X"${BACKEND}" == X'OPENLDAP' ]; then
        export LDAP_SERVER_HOST LDAP_SERVER_PORT LDAP_BIND_VERSION LDAP_BASEDN LDAP_ATTR_DOMAIN_RDN LDAP_ATTR_USER_RDN
        cd ${RCM_CONF_DIR}
        ECHO_DEBUG "Setting global LDAP address book in Roundcube."

        cat ${SAMPLE_DIR}/roundcubemail/global_ldap_address_book.inc.php >> ${RCM_CONF}
        perl -pi -e 's#PH_LDAP_SERVER_HOST#$ENV{LDAP_SERVER_HOST}#g' ${RCM_CONF}
        perl -pi -e 's#PH_LDAP_SERVER_PORT#$ENV{LDAP_SERVER_PORT}#g' ${RCM_CONF}
        perl -pi -e 's#PH_LDAP_BASEDN#$ENV{LDAP_BASEDN}#g' ${RCM_CONF}
    fi

    cat >> ${TIP_FILE} <<EOF
Roundcube webmail: ${RCM_HTTPD_ROOT}
    * Config file: ${RCM_CONF_DIR}
    * Web access:
        - URL: http://${HOSTNAME}/mail/ (will be redirected to https:// site)
        - URL: https://${HOSTNAME}/mail/ (secure connection)
        - Username: ${DOMAIN_ADMIN_EMAIL}
        - Password: ${DOMAIN_ADMIN_PASSWD_PLAIN}
    * SQL database account:
        - Database name: ${RCM_DB_NAME}
        - Username: ${RCM_DB_USER}
        - Password: ${RCM_DB_PASSWD}
    * Cron job:
        - Command: "crontab -l -u ${SYS_USER_ROOT}"

EOF

    echo 'export status_rcm_config="DONE"' >> ${STATUS_FILE}
}

rcm_cron_setup()
{
    ECHO_DEBUG "Setup daily cron job to keep SQL database clean."
    cat >> ${CRON_FILE_ROOT} <<EOF
# ${PROG_NAME}: Cleanup Roundcube SQL database
2   2   *   *   *   ${PHP_BIN} ${RCM_HTTPD_ROOT_SYMBOL_LINK}/bin/cleandb.sh >/dev/null

# ${PROG_NAME}: Cleanup Roundcube temporary files under 'temp/' directory
2   2   *   *   *   ${PHP_BIN} ${RCM_HTTPD_ROOT_SYMBOL_LINK}/bin/gc.sh >/dev/null
EOF

    echo 'export status_rcm_cron_setup="DONE"' >> ${STATUS_FILE}
}

rcm_plugin_managesieve()
{
    ECHO_DEBUG "Config plugin: managesieve."
    cd ${RCM_CONF_DIR}

    export MANAGESIEVE_SERVER MANAGESIEVE_PORT
    cd ${RCM_HTTPD_ROOT}/plugins/managesieve/ && \
    cp config.inc.php.dist config.inc.php && \
    perl -pi -e 's#(.*managesieve_host.*=).*#${1} "$ENV{MANAGESIEVE_SERVER}";#' config.inc.php
    perl -pi -e 's#(.*managesieve_auth_type.*=).*#${1} "LOGIN";#' config.inc.php
    perl -pi -e 's#(.*managesieve_port.*=).*#${1} $ENV{MANAGESIEVE_PORT};#' config.inc.php
    perl -pi -e 's#(.*managesieve_usetls.*=).*#${1} true;#' config.inc.php
    perl -pi -e 's#(.*managesieve_default.. =).*#${1} "";#' config.inc.php
    perl -pi -e 's#(.*managesieve_vacation.*=).*#${1} 1;#' config.inc.php
    perl -pi -e 's#(.*managesieve_forward.*=).*#${1} 1;#' config.inc.php

    # Disable ssl peer verify
    perl -pi -e 's#(.*managesieve_conn_options.*=.*)(null.*)#${1}array("ssl" => array("verify_peer" => false, "verify_peer_name" => false));#' config.inc.php

    echo 'export status_rcm_plugin_managesieve="DONE"' >> ${STATUS_FILE}
}

rcm_plugin_password()
{
    ECHO_DEBUG "Config plugin: password."
    cd ${RCM_CONF_DIR}

    cd ${RCM_HTTPD_ROOT}/plugins/password/
    cp config.inc.php.dist config.inc.php
    chown ${HTTPD_USER}:${HTTPD_GROUP} config.inc.php
    chmod 0400 config.inc.php

    # Determine whether current password is required to change password
    perl -pi -e 's#(.*password_confirm_current.*=).*#${1} true;#' config.inc.php

    # Require the new password to be a certain length
    perl -pi -e 's#(.*password_minimum_length.*=).*#${1} 8;#' config.inc.php

    # Require the new password to contain a letter and punctuation character
    perl -pi -e 's#(.*password_require_nonalpha.*=).*#${1} true;#' config.inc.php
    perl -pi -e 's#(.*password_log.*=).*#${1} true;#' config.inc.php

    # Roundcube uses scheme name in lower cases
    export default_password_scheme="$(echo ${DEFAULT_PASSWORD_SCHEME} | tr '[A-Z]' '[a-z]')"

    # Dovecot uses scheme name in upper cases
    export dovecotpw_method="${DEFAULT_PASSWORD_SCHEME}"

    if [ X"${dovecotpw_method}" == X'BCRYPT' ]; then
        # Password scheme name used in Dovecot (doveadm pw).
        export default_password_scheme='blf-crypt'
        export dovecotpw_method='BLF-CRYPT'
    fi

    # Roundcube supports ssha, but not ssha512.
    if [ X"${BACKEND}" == X'OPENLDAP' ]; then
        export default_password_scheme='ssha'
    fi

    perl -pi -e 's#(.*password_algorithm.*=).*#${1} "$ENV{default_password_scheme}";#' config.inc.php
    perl -pi -e 's#(.*password_algorithm_prefix.*=).*#${1} "{$ENV{DEFAULT_PASSWORD_SCHEME}}";#' config.inc.php

    perl -pi -e 's#(.*password_dovecotpw.*=.*for dovecot-1.*)#//${1}#' config.inc.php
    perl -pi -e 's#// (.*password_dovecotpw.*=).*for dovecot-2.*#${1} "$ENV{DOVECOT_DOVEADM_BIN} pw";#' config.inc.php

    perl -pi -e 's#(.*password_dovecotpw_method.*=).*#${1} "$ENV{dovecotpw_method}";#' config.inc.php
    perl -pi -e 's#(.*password_dovecotpw_with_method.*=).*#${1} true;#' config.inc.php

    if [ X"${BACKEND}" == X'MYSQL' -o X"${BACKEND}" == X'PGSQL' ]; then
        perl -pi -e 's#(.*password_driver.*=).*#${1} "sql";#' config.inc.php
        perl -pi -e 's#(.*password_db_dsn.*= )(.*)#${1}"$ENV{PHP_CONN_TYPE}://$ENV{RCM_DB_USER}:$ENV{RCM_DB_PASSWD}\@$ENV{SQL_SERVER_ADDRESS}/$ENV{VMAIL_DB_NAME}";#' config.inc.php

        perl -pi -e 's#(.*password_query.*=).*#${1} "UPDATE mailbox SET password=%P,passwordlastchange=NOW() WHERE username=%u";#' config.inc.php

    elif [ X"${BACKEND}" == X'OPENLDAP' ]; then
        perl -pi -e 's#(.*password_confirm_current.*=).*#${1} true;#' config.inc.php

        perl -pi -e 's#(.*password_driver.*=).*#${1} "ldap_simple";#' config.inc.php
        perl -pi -e 's#(.*password_ldap_host.*=).*#${1} "$ENV{LDAP_SERVER_HOST}";#' config.inc.php
        perl -pi -e 's#(.*password_ldap_port.*=).*#${1} "$ENV{LDAP_SERVER_PORT}";#' config.inc.php
        perl -pi -e 's#(.*password_ldap_starttls.*=).*#${1} false;#' config.inc.php
        perl -pi -e 's#(.*password_ldap_version.*=).*#${1} "3";#' config.inc.php
        perl -pi -e 's#(.*password_ldap_basedn...=).*#${1} "$ENV{LDAP_BASEDN}";#' config.inc.php
        perl -pi -e 's#(.*password_ldap_userDN_mask...=).*#${1} "$ENV{LDAP_ATTR_USER_RDN}=%login,$ENV{LDAP_ATTR_GROUP_RDN}=$ENV{LDAP_ATTR_GROUP_USERS},$ENV{LDAP_ATTR_DOMAIN_RDN}=%domain,$ENV{LDAP_BASEDN}";#' config.inc.php

        perl -pi -e 's#(.*password_ldap_method.*=).*#${1} "user";#' config.inc.php
        perl -pi -e 's#(.*password_ldap_adminDN.*=).*#${1} "null";#' config.inc.php
        perl -pi -e 's#(.*password_ldap_adminPW.*=).*#${1} "null";#' config.inc.php

        perl -pi -e 's#(.*password_ldap_encodage.*=).*#${1} "$ENV{default_password_scheme}";#' config.inc.php
        perl -pi -e 's#(.*password_ldap_pwattr.*=).*#${1} "userPassword";#' config.inc.php
        perl -pi -e 's#(.*password_ldap_lchattr.*=).*#${1} "shadowLastChange";#' config.inc.php
        perl -pi -e 's#(.*password_ldap_force_replace.*=).*#${1} true;#' config.inc.php
    fi

    echo 'export status_rcm_plugin_password="DONE"' >> ${STATUS_FILE}
}

rcm_plugin_enigma()
{
    ECHO_DEBUG "Config plugin: enigma."

    cd ${RCM_HTTPD_ROOT}/plugins/enigma/
    cp -f config.inc.php.dist config.inc.php
    perl -pi -e 's#(.*enigma_pgp_homedir.*=).*#${1} "$ENV{RCM_PLUGIN_ENIGMA_PGP_HOMEDIR}";#' config.inc.php

    # Directory used to store pgp keys generated by enigma plugin.
    mkdir -p ${RCM_PLUGIN_ENIGMA_PGP_HOMEDIR} >> ${INSTALL_LOG} 2>&1
    chown ${HTTPD_USER}:${HTTPD_GROUP} ${RCM_PLUGIN_ENIGMA_PGP_HOMEDIR}
    chmod 0700 ${RCM_PLUGIN_ENIGMA_PGP_HOMEDIR}

    echo 'export status_rcm_plugin_enigma="DONE"' >> ${STATUS_FILE}
}

rcm_setup() {
    check_status_before_run rcm_install

    if [ X"${INITIALIZE_SQL_DATA}" == X'YES' ]; then
        check_status_before_run rcm_initialize_db
    fi

    check_status_before_run rcm_config
    check_status_before_run rcm_cron_setup
    check_status_before_run rcm_plugin_managesieve
    check_status_before_run rcm_plugin_password
    check_status_before_run rcm_plugin_enigma

    write_iredmail_kv "sql_user_${RCM_DB_USER}" "${RCM_DB_PASSWD}"
    write_iredmail_kv roundcube_des_key "${RCM_DES_KEY}"
    echo 'export status_rcm_setup="DONE"' >> ${STATUS_FILE}
}
