#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
source "$(dirname "$0")/lib/ulib/ulib" || exit 1
urequire DEFAULTS

function display_help() {
    uecho "$scriptname: créer un utilisateur sudoer et lui installer une clé publique ssh

USAGE
    $scriptname user [-p pubkey]

OPTIONS
    -p, --pkfile PKFILE
        Installer la clé publique ssh contenue dans le fichier spécifié. Par
        défaut, prendre le fichier ~/.ssh/id_rsa.pub de l'utilisateur courant.
    -s, --pkstring PUBKEY
        Installer la clé publique ssh spécifiée. Cette option avancée n'est pas
        utilisée en temps normal. Elle a la priorité sur l'option --pkfile
    -l, --luser
        Ne pas donner à l'utilisateur le droit de sudoer.
    -h, --host [USER@]HOST
        Créer l'utilisateur sur l'hôte distant spécifié. Si l'utilisateur
        distant n'est pas root, il doit être sudoer.
    -T, --tmproot TMPROOT
        Spécifier le répertoire temporaire sur l'hôte distant, comme par exemple
        /var/tmp. Cette option est utile pour certains serveurs, qui ont un /tmp
        minuscule.
    -S, --ssh SSH
        Spécifier le programme à utiliser pour la connection par ssh."
}

function create_user() {
    # Créer le user, si nécessaire
    # retourner vrai si le user a été créé, faux si ce n'était pas nécessaire
    local user="$1" password="$2"
    [ -z "$(getent passwd "$user")" ] || return 1
    estep "Creation de l'utilisateur $user..."
    useradd -s /bin/bash -m "$user"
    [ -n "$password" ] || return 0
    if ! (echo "$password" | passwd --stdin "$user" 2>/dev/null); then
        echo "$user:$password" | chpasswd
    fi
    return 0
}

function init_sudoer() {
    local user="$1"
    local TAB=$'\t'
    if [ -d /etc/sudoers.d ]; then
        if [ ! -f "/etc/sudoers.d/$user" ]; then
            estep "Ajout de $user comme sudoer dans /etc/sudoers.d/$user"
            echo "$user${TAB}ALL=(ALL) NOPASSWD: ALL" >"/etc/sudoers.d/$user"
            chmod 440 "/etc/sudoers.d/$user"
        fi
    elif [ -f /etc/sudoers ]; then
        if ! grep -q "^$user" /etc/sudoers; then
            estep "Ajout de user comme sudoer dans /etc/sudoers..."
            echo "$user${TAB}ALL=(ALL) NOPASSWD: ALL" >>/etc/sudoers
        fi
    fi
}

function install_pubkeys() {
    # Installer la clé $1 pour l'utilisateur $2
    # $1 peut contenir autant de clés que nécessaire, une par ligne
    local user="$1" pubkeys="$2"
    local homedir="$(eval "echo ~$user")"
    [ -d "$homedir" ] || return

    local sshdir="$homedir/.ssh"
    if [ ! -d "$sshdir" ]; then
        mkdir -p "$sshdir"
        chmod 700 "$sshdir"
        chown -R "$user:" "$sshdir"
    fi
    local ak="$sshdir/authorized_keys"
    if [ ! -f "$ak" ]; then
        touch "$ak"
        chown "$user:" "$ak"
    fi

    local -a pks
    local pk
    array_from_lines pks "$pubkeys"
    for pk in "${pks[@]}"; do
        if ! grep -q "$pk" "$ak"; then
            estep "Installation de la clé ${pk:0:20}... pour $user"
            echo "$pk" >>"$ak"
        fi
    done
}

pkfile=
pkstring=
luser=
host=
tmproot=
SSH=
args=(
    --help '$exit_with display_help'
    -p:,--pkfile: pkfile=
    -s:,--pkstring: pkstring=
    -l,--luser luser=1
    -h:,-H:,--host: host=
    -T:,--tmproot: tmproot=
    -S:,--ssh: SSH=
)
parse_args "$@"; set -- "${args[@]}"

user="$1"
[ -n "$user" ] || die "Vous devez spécifier l'utilisateur à créer"

if [ -z "$pkstring" ]; then
    if [ -z "$pkfile" ]; then
        if [ -f ~/.ssh/id_rsa.pub ]; then pkfile=~/.ssh/id_rsa.pub
        elif [ -f ~/.ssh/id_dsa.pub ]; then pkfile=~/.ssh/id_dsa.pub
        fi
    fi
    if [ -f "$pkfile" ]; then pkstring="$(<"$pkfile")"
    elif [ -n "$pkfile" ]; then die "$pkfile: fichier introuvable"
    fi
fi

if [ -z "$host" ]; then
    # déploiement local
    run_as_root ${pkstring:+-s "$pkstring"} ${luser:+-l} "$user"
    create_user "$user"
    [ -z "$luser" ] && init_sudoer "$user"
    [ -n "$pkstring" ] && install_pubkeys "$user" "$pkstring"
    exit 0

else
    # déploiement distant
    if [ -n "$host" ]; then
        splituserhost "$host" remoteuser host
        [ -n "$remoteuser" ] || remoteuser=root
    fi
    if [ -n "$SSH" ]; then
        ssh=("$SSH" -o StrictHostKeyChecking=no -o ConnectTimeout=2 -qt)
        scp=(scp -S "$SSH" -o StrictHostKeyChecking=no -o ConnectTimeout=2 -q)
    else
        ssh=(ssh -o StrictHostKeyChecking=no -o ConnectTimeout=2 -qt)
        scp=(scp -o StrictHostKeyChecking=no -o ConnectTimeout=2 -q)
    fi

    ac_set_tmpdir workdir
    mkdir "$workdir/lib"
    ulibsync "$workdir/lib"
    cp "$script" "$workdir"
    echo "#!/bin/bash
$(qvals "./$scriptname" ${pkstring:+-s "$pkstring"} ${luser:+-l} "$user")" >"$workdir/do_remote"
    chmod +x "$workdir/do_remote"

    ac_set_tmpfile archive
    archivename="$(basename "$archive")"

    "$scriptdir/mkusfx" --tmp-archive --bare -o "$archive" "$workdir" ./do_remote || die

    estep "Copie du script sur $remoteuser@$host"
    "${scp[@]}" "$archive" "$remoteuser@$host:" || die

    estep "Exécution du script"
    "${ssh[@]}" "$remoteuser@$host" "\
__estack=$(qval "$__estack")
__tlevel=$(qval "$__tlevel")
export __estack __tlevel
${UTOOLS_LANG:+UTOOLS_LANG='$UTOOLS_LANG'; export UTOOLS_LANG
}$(qvals "./$archivename" ${tmproot:+--tmproot "$tmproot"})"
    r=$?
    ac_clean "$workdir"

    exit $r
fi