#!/usr/bin/env bash
# web/folder-password -- HTTP Basic auth for one directory of a site
#
# Declarative: the registry stores the protected path and the vhost is
# regenerated from it, so the setting survives repair and cannot drift.
set -o pipefail
SELF=$(readlink -f "${BASH_SOURCE[0]}")
NV_BASE=$(cd "$(dirname "$SELF")/../../.." && pwd)
export NV_BASE
# shellcheck source=/dev/null
. "$NV_BASE/lib/core/bootstrap.sh"

nv_require_root || exit 1
ui_header "$(t web_m_folderpw)"

if [ "$(nv_site_count)" -eq 0 ]; then ui_info "$(t site_none)"; exit 0; fi

if [ $# -ge 1 ]; then domain=$1; else
    ui_info "$(nv_site_list | paste -sd' ' -)"
    printf '  %s: ' "$(t site_prompt_domain)"
    read -r domain || exit 130
fi
domain=$(nv_lower "$(nv_trim "$domain")")
nv_site_exists "$domain" || { ui_err "$(t site_not_registered)"; exit 2; }

cur=$(nv_site_get "$domain" protect_path "")
ui_kv "$(t col_domain)" "$domain"
ui_kv "$(t web_protected_path)" "${cur:-$(t web_none)}"
ui_blank

printf '  %s [0 = %s]: ' "$(t web_prompt_path)" "$(t web_remove_protection)"
read -r path || exit 130
path=$(nv_trim "$path")

if [ "$path" = "0" ] || [ -z "$path" ]; then
    if [ -z "$cur" ]; then ui_info "$(t web_no_protection)"; exit 0; fi
    nv_site_set "$domain" protect_path ""
    rm -f "$NV_STATE_DIR/sites/$domain.htpasswd"
    site_apply_vhost "$domain" || exit 1
    svc_reload "$(nv_site_get "$domain" php_version "$NV_SITE_PHP_VERSION")"
    ui_ok "$(t web_protection_removed)"
    exit 0
fi

case $path in /*) ;; *) path="/$path" ;; esac
path=${path%/}
nv_valid_path "$path" || { ui_err "$(t web_bad_path)"; exit 2; }

printf '  %s [admin]: ' "$(t web_prompt_user)"
read -r user || exit 130
user=$(nv_trim "$user"); [ -z "$user" ] && user='admin'
nv_valid_ident "$user" || { ui_err "$(t db_bad_user)"; exit 2; }

printf '  %s: ' "$(t web_prompt_pass)"
read -r -s pass || exit 130
printf '\n'
if [ ${#pass} -lt 8 ]; then ui_err "$(t web_weak_pass)"; exit 2; fi

f="$NV_STATE_DIR/sites/$domain.htpasswd"
install -d -m 0700 "$(dirname "$f")"
if nv_have htpasswd; then
    htpasswd -bcB "$f" "$user" "$pass" >/dev/null 2>&1 || { nv_fail 3401 "$(t web_htpasswd_failed)"; exit 1; }
else
    hash=$(openssl passwd -apr1 "$pass" 2>/dev/null) || { nv_fail 3401 "$(t web_htpasswd_failed)"; exit 1; }
    printf '%s:%s\n' "$user" "$hash" >"$f"
fi
chmod 0640 "$f"
chown root:www-data "$f" 2>/dev/null || true

nv_site_set "$domain" protect_path "$path"
if ! site_apply_vhost "$domain"; then
    nv_site_set "$domain" protect_path "$cur"
    site_apply_vhost "$domain" >/dev/null 2>&1 || true
    exit 1
fi
svc_reload "$(nv_site_get "$domain" php_version "$NV_SITE_PHP_VERSION")"
nv_trace folder-password "$domain $path user=$user"

ui_ok "$(t web_protection_on "$domain" "$path")"
ui_info "$(t web_user_is "$user")"
exit 0
