#!/bin/bash

# Admin SSH access to THIS host. Manages the install user's authorized_keys —
# paste a public key to grant access — and, behind a lockout guard, sshd
# password authentication. Everything here is on-demand only: nothing runs
# during install or deploy. LibrePortal is the *server* here, so the admin
# brings their own public key; we never handle their private key.
#
# All the privileged work (editing ~/.ssh and /etc/ssh/sshd_config) lives in the
# root-owned helper /usr/local/sbin/libreportal-ssh-access (runSshAccess), which
# also enforces the lockout guards in the trust boundary. These functions are the
# manager-side CLI/WebUI front for it: they shape arguments and print the UX.

# The user admins actually log in as (has sudo). Falls back to libreportal.
hostSshUser()
{
    echo "${sudo_user_name:-libreportal}"
}

hostSshHome()
{
    local u; u=$(hostSshUser)
    [[ "$u" == "root" ]] && { echo "/root"; return; }
    echo "/home/$u"
}

hostSshAuthKeysFile()
{
    echo "$(hostSshHome)/.ssh/authorized_keys"
}

# Refresh the WebUI access snapshot after a change. No-op if generator absent.
hostSshRefreshUi()
{
    declare -f webuiGenerateSshAccess >/dev/null 2>&1 && webuiGenerateSshAccess >/dev/null 2>&1
    return 0
}

hostSshEnsureDir()
{
    runSshAccess ensure-dir
}

# Count valid authorized public keys.
hostSshKeyCount()
{
    runSshAccess key-count 2>/dev/null || echo 0
}

# True when sshd currently allows password authentication.
hostSshPasswordAuthEnabled()
{
    [[ "$(runSshAccess pw-status 2>/dev/null)" != "off" ]]
}

# Add a base64-encoded PUBLIC key to the install user's authorized_keys.
hostSshKeyAdd()
{
    local key_b64="$1"
    [[ -z "$key_b64" ]] && { isError "hostSshKeyAdd requires <base64-public-key>"; return 1; }

    local out rc
    out=$(runSshAccess key-add "$key_b64")
    rc=$?
    case "$out" in
        added)              isSuccessful "SSH key authorized for $(hostSshUser)" ;;
        already-authorized) isNotice "That key is already authorized." ;;
        *)
            [[ $rc -ne 0 ]] && { isError "Could not add key (not a valid SSH public key?)"; return 1; }
            ;;
    esac
    hostSshRefreshUi
}

# Remove the authorized key whose fingerprint matches $1. The helper guards
# against removing the last key while password auth is off (lockout).
hostSshKeyRemove()
{
    local fp="$1"
    [[ -z "$fp" ]] && { isError "hostSshKeyRemove requires <fingerprint>"; return 1; }

    local out rc
    out=$(runSshAccess key-remove "$fp" 2>&1)
    rc=$?
    if [[ $rc -eq 2 ]]; then
        isError "Refusing to remove the last key while password login is disabled — you'd be locked out. Re-enable password login first."
        return 1
    fi
    case "$out" in
        removed)  isSuccessful "Removed SSH key $fp" ;;
        no-match) isNotice "No key matched fingerprint $fp" ;;
        *)        [[ $rc -ne 0 ]] && { isError "Could not remove key."; return 1; } ;;
    esac
    hostSshRefreshUi
}

# Enable/disable sshd password authentication. Disabling is guarded (helper-side):
# there must be at least one authorized key, or you'd lock yourself out.
hostSshSetPasswordAuth()
{
    local want="$1"   # on|off
    case "$want" in
        on|off) ;;
        *) isError "hostSshSetPasswordAuth requires on|off"; return 1 ;;
    esac

    local out rc
    out=$(runSshAccess pw-set "$want" 2>&1)
    rc=$?
    if [[ $rc -eq 2 ]]; then
        isError "Refusing to disable password login with no authorized keys — add a key first or you'll be locked out."
        return 1
    fi
    if [[ $rc -ne 0 ]]; then
        isError "sshd config test failed — restored backup, no change made."
        return 1
    fi
    isSuccessful "Password login ${want} (sshd reloaded)."
    hostSshRefreshUi
}
