#!/bin/bash
set -e
set -u
set -f

TMPDIR="$(mktemp -d)"
export TMPDIR
trap 'rm -fr "$TMPDIR"' EXIT

if [ "$UID" -ne 0 ] && command -v sudo >/dev/null 2>&1
    then SUDO="sudo "
    else SUDO=""
fi

_help(){
    cat << EOF
Команда mos-auth-config включает и отключает вход в систему через учетную запись на mos.ru.
Требуется ее запуск от root.

Для включения входа через mos.ru выполните:
  ${SUDO}mos-auth-config enable
Для отключения входа через mos.ru выполните:
  ${SUDO}mos-auth-config disable
После чего перезагрузите компьютер (или перезапустите DM).

При включении (enable) выполняются следующие действия:
* устанавливается тема mos-auth в SDDM,
* устанавливается PAM-механизм автоочистки профиля гостя,
* включается поддержка сетевых папок (если установлен пакет 'mos-auth-folders').

При выключении (disable) выполняются следующие действия:
* возвращается тема SDDM, которая была настроена до включения,
* выключается PAM-механизм автоочистки профиля гостя,
* выключается поддержка сетевых папок.

Вы можете настраивать поведение авторизации через mos.ru путем изменения конфигурационного файла.
Для редактирования файла с конфигурацией (настройками) выполните:
  ${SUDO}mos-auth-config edit

Список команд:
  enable		Включение авторизации через mos.ru
  disable		Выключение авторизации через mos.ru
  status		Вывод текущего статуса авторизации через mos.ru в системе
  edit			Редактирование конфигурационного файла
  help			Вызов текущей справки
EOF
}

_check_root(){
    if [ "$UID" -ne 0 ]; then
        echo "Ошибка: необходимы root-права!"
        echo ""
        _help
        return 1
    fi
}

# $1: путь к конфигу SDDM для редактирования
_sddm_config(){
    local file
    file="$1"
    local tmp
    tmp="$(mktemp)"
    cat "$file" > "$tmp"
    py-ini-config set "$tmp" Theme Current mos-auth
    py-ini-config set "$tmp" Users MaximumUid 2000000000
    py-ini-config set "$tmp" Users MinimumUid 10000000
    grep -q 'Current=mos-auth' "$tmp"
    grep -q 'MaximumUid=2000000000' "$tmp"
    grep -q 'MinimumUid=10000000' "$tmp"
    cat "$tmp" > "$file"
    rm -f "$tmp"
}

_enable(){
    local fsddm
    local fold
    fsddm="/etc/sddm.conf"
    fold="/var/lib/mos-auth/mos-auth-old-settings"
    if test -f /var/lib/mos-auth/enabled
    then
        echo "Уже настроено. Выполните disable и снова enable"
        return 1
    fi
    mkdir -p /var/lib/mos-auth
    if test -f "$fsddm"
    then
        cp -f "$fsddm" /var/lib/mos-auth/sddm.conf.mos-auth-bak
        touch "$fold"
        if grep -q 'Current=' "$fsddm"
        then
            py-ini-config set "$fold" Theme Current "$(py-ini-config get $fsddm Theme Current)"
        fi
        if grep -q 'MinimumUid=' "$fsddm"
        then
            py-ini-config set "$fold" Users MinimumUid "$(py-ini-config get $fsddm Users MinimumUid)"
        fi
        if grep -q 'MaximumUid=' "$fsddm"
        then
            py-ini-config set "$fold" Users MaximumUid "$(py-ini-config get $fsddm Users MaximumUid)"
        fi
        if ! _sddm_config "$fsddm"; then
            echo "Ошибка правки конфига SDDM"
            return 1
        fi
    else
        echo "Нет файла /etc/sddm.conf, пропускаем настройку SDDM"
    fi

    # Проверим, корректная ли конфигурация authselect.
    if ! authselect check &> /dev/null;
    then
        # Если мигрируем с профиля sssd, который не прошел проверку
        # (то есть был отредактирован вручную не через authselect)
        if authselect current --raw | grep -q 'sssd'
        then
            # Устанавливаем "sssd" профиль заново через скрипт-хелпер
            # (который сам включит необходимые модули).
            /usr/libexec/realmd-rosa-setup sssd
        else
            # Иначе установим "local" профиль, если PAM настроен сейчас не через `authselect`.
            authselect select local --force
        fi
    fi

    local authselect_preserved_options="/var/lib/authselect/preserved-options"
    local authselect_preserved_options_nodomain="/var/lib/authselect/preserved-options-nodomain"

    # Активируем опцию для профиля гостя.
    local with_mos_auth_guest="with-mos-auth-guest"

    if authselect current --raw | grep -q "$with_mos_auth_guest"
    then
        echo "Опция для гостя в PAM-конфигурации уже активирована."
    else
        echo "Активируем опцию для гостя в PAM-конфигурации..."
        authselect enable-feature "$with_mos_auth_guest"
        if ! grep -q "$with_mos_auth_guest" "$authselect_preserved_options"
        then
            echo "$with_mos_auth_guest" >> "$authselect_preserved_options"
        fi
    fi

    # Активируем 'faillock' для профиля 'local'.
    local with_faillock="with-faillock"

    if authselect current --raw | grep -q 'local'
    then
        if authselect current --raw | grep -q "$with_faillock"
        then
            echo "Опция 'faillock' в PAM-конфигурации уже активирована."
        else
            echo "Активируем опцию 'faillock' в PAM-конфигурации..."
            authselect enable-feature "$with_faillock"
            if ! grep -q "$with_faillock" "$authselect_preserved_options_nodomain"
            then
                echo "$with_faillock" >> "$authselect_preserved_options_nodomain"
            fi
        fi
    else
        echo "Текущий профиль не является 'local'. Пропускаем настройку faillock."
    fi

    # Активируем опцию для сетевых папок.
    local with_mos_auth_folders="with-mos-auth-folders"
    local folders_binary="/usr/bin/mos-auth-folders-functions"

    if authselect current --raw | grep -q "$with_mos_auth_folders"
    then
        echo "Опция для сетевых папок в PAM-конфигурации уже активирована."
    else
        if test -f "$folders_binary"
        then
            echo "Активируем опцию для сетевых папок в PAM-конфигурации..."
            authselect enable-feature "$with_mos_auth_folders"
            if ! grep -q "$with_mos_auth_folders" "$authselect_preserved_options"
            then
                echo "$with_mos_auth_folders" >> "$authselect_preserved_options"
            fi
        fi
    fi

    # Если отсутствуют проводные подключения, удаляем специальный файл NetworkManager,
    # который отключает автоматическое создание стандартного подключения.
    if ! nmcli connection show | grep -iq ethernet
    then
        rm -f /var/lib/NetworkManager/no-auto-default.state
    fi

    touch /var/lib/mos-auth/enabled
}

_disable(){
    local fsddm
    local fold
    fold="/var/lib/mos-auth/mos-auth-old-settings"
    for fsddm in "/etc/sddm.conf" "/etc/sddm.conf.d/kde_settings.conf"
    do
        echo "$fsddm"
        if test -f "$fsddm"
        then
            if test -f "$fold" && grep -q 'Current=' "$fold"
            then
                py-ini-config set "$fsddm" Theme Current "$(py-ini-config get $fold Theme Current)"
            else
                py-ini-config del "$fsddm" Theme Current --flush || echo "Восстановление не требуется"
            fi
            if test -f "$fold" && grep -q 'MinimumUid=' "$fold"
            then
                py-ini-config set "$fsddm" Users MinimumUid "$(py-ini-config get $fold Users MinimumUid)"
            else
                py-ini-config del "$fsddm" Users MinimumUid --flush || echo "Восстановление не требуется"
            fi
            if test -f "$fold" && grep -q 'MaximumUid=' "$fold"
            then
                py-ini-config set "$fsddm" Users MaximumUid "$(py-ini-config get $fold Users MaximumUid)"
            else
                py-ini-config del "$fsddm" Users MaximumUid --flush || echo "Восстановление не требуется"
            fi
        fi
    done
    rm -f "$fold"

    local authselect_preserved_options="/var/lib/authselect/preserved-options"
    local authselect_preserved_options_nodomain="/var/lib/authselect/preserved-options-nodomain"

    # Деактивируем опцию для профиля гостя.
    local with_mos_auth_guest="with-mos-auth-guest"
    if authselect current --raw | grep -q "$with_mos_auth_guest"
    then
        echo "Деактивируем опцию для гостя в PAM-конфигурации..."
        authselect disable-feature "$with_mos_auth_guest"
        if test -f "$authselect_preserved_options"
        then
            sed -i "/$with_mos_auth_guest/d" "$authselect_preserved_options"
        fi
    fi

    # Деактивируем 'faillock' для профиля 'local'.
    local with_faillock="with-faillock"
    if authselect current --raw | grep -q 'local'
    then
        if authselect current --raw | grep -q "$with_faillock"
        then
            echo "Деактивируем опцию 'faillock' в PAM-конфигурации..."
            authselect disable-feature "$with_faillock"
            if test -f "$authselect_preserved_options_nodomain"
            then
                sed -i "/$with_faillock/d" "$authselect_preserved_options_nodomain"
            fi
        fi
    fi

    # Деактивируем опцию для сетевых папок.
    local with_mos_auth_folders="with-mos-auth-folders"
    local folders_binary="/usr/bin/mos-auth-folders-functions"
    if authselect current --raw | grep -q "$with_mos_auth_folders"
    then
        echo "Деактивируем опцию для сетевых папок в PAM-конфигурации..."
        authselect disable-feature "$with_mos_auth_folders"
        if test -f "$authselect_preserved_options"
        then
            sed -i "/$with_mos_auth_folders/d" "$authselect_preserved_options"
        fi
    fi

    rm -f /var/lib/mos-auth/enabled

    echo "Конфигурация mos-auth успешно отключена."
}

_status(){
    if test -f /var/lib/mos-auth/enabled
    then
        echo "В данный момент авторизация через mos.ru включена."
    else
        echo "В данный момент авторизация через mos.ru выключена."
    fi
}

_edit(){
    command ${VISUAL:-${EDITOR:-$(command -v nano)}} /etc/mos-auth/mos-auth.conf
}

_main(){
    case "${1:-X}" in
        enable )
            _check_root
            _enable
        ;;
        disable )
            _check_root
            _disable
        ;;
        help )
            _help
        ;;
        status )
            _status
        ;;
        edit )
            _check_root
            _edit
        ;;
        * )
            _help
            exit 1
        ;;
    esac
}

if [ "${SOURCING:-0}" -ne 1 ]; then
    _main "$@"
fi
