#!/usr/bin/env bash
#
# setup-piste-proxy.sh
# ---------------------
# Installe et configure un proxy HTTP (Squid) sur un VPS Debian/Ubuntu afin de
# relayer les appels du module « Tropratik e-Facture » vers les API PISTE /
# Chorus Pro lorsque l'hébergement du site WordPress est bloqué par le WAF
# de PISTE (erreur HTTP 403).
#
# Le proxy est volontairement RESTREINT aux seuls domaines *.piste.gouv.fr et
# protégé par authentification (utilisateur + mot de passe) : il ne s'agit donc
# PAS d'un proxy ouvert.
#
# Usage :
#   sudo bash setup-piste-proxy.sh
#
# Auteur : Tropratik.fr — distribué sous licence GPLv2 or later.

set -euo pipefail

# ── Valeurs par défaut (modifiables via les invites) ────────────────────────
DEFAULT_PORT="3128"
SQUID_CONF="/etc/squid/squid.conf"
PASSWD_FILE="/etc/squid/passwd"
ALLOWED_DOMAIN=".piste.gouv.fr"   # autorise piste.gouv.fr et ses sous-domaines

# ── Couleurs ────────────────────────────────────────────────────────────────
RED=$'\e[31m'; GREEN=$'\e[32m'; YELLOW=$'\e[33m'; BOLD=$'\e[1m'; RESET=$'\e[0m'

info()  { echo "${GREEN}[INFO]${RESET} $*"; }
warn()  { echo "${YELLOW}[ATTENTION]${RESET} $*"; }
error() { echo "${RED}[ERREUR]${RESET} $*" >&2; }

# ── 1. Vérifications préalables ─────────────────────────────────────────────
if [[ "${EUID}" -ne 0 ]]; then
    error "Ce script doit être exécuté en root (utilisez : sudo bash setup-piste-proxy.sh)."
    exit 1
fi

if ! command -v apt-get >/dev/null 2>&1; then
    error "Distribution non prise en charge : ce script requiert apt (Debian / Ubuntu)."
    exit 1
fi

# ── 2. Saisie des paramètres ────────────────────────────────────────────────
echo "${BOLD}Configuration du proxy PISTE pour Tropratik e-Facture${RESET}"
echo

read -r -p "Port d'écoute du proxy [${DEFAULT_PORT}] : " PROXY_PORT
PROXY_PORT="${PROXY_PORT:-$DEFAULT_PORT}"
if ! [[ "${PROXY_PORT}" =~ ^[0-9]+$ ]] || (( PROXY_PORT < 1 || PROXY_PORT > 65535 )); then
    error "Port invalide : ${PROXY_PORT}"
    exit 1
fi

read -r -p "Nom d'utilisateur du proxy : " PROXY_USER
if [[ -z "${PROXY_USER}" ]]; then
    error "Le nom d'utilisateur ne peut pas être vide."
    exit 1
fi

read -r -s -p "Mot de passe du proxy : " PROXY_PASS; echo
read -r -s -p "Confirmez le mot de passe : " PROXY_PASS2; echo
if [[ -z "${PROXY_PASS}" ]]; then
    error "Le mot de passe ne peut pas être vide."
    exit 1
fi
if [[ "${PROXY_PASS}" != "${PROXY_PASS2}" ]]; then
    error "Les mots de passe ne correspondent pas."
    exit 1
fi

# ── 3. Installation des paquets ─────────────────────────────────────────────
info "Installation de Squid et des utilitaires nécessaires…"
export DEBIAN_FRONTEND=noninteractive
apt-get update -y
apt-get install -y squid apache2-utils

# Localisation du module d'authentification basic_ncsa_auth selon la distribution.
NCSA_AUTH=""
for candidate in \
    /usr/lib/squid/basic_ncsa_auth \
    /usr/lib/squid3/basic_ncsa_auth \
    /usr/libexec/squid/basic_ncsa_auth; do
    if [[ -x "${candidate}" ]]; then
        NCSA_AUTH="${candidate}"
        break
    fi
done
if [[ -z "${NCSA_AUTH}" ]]; then
    error "Module d'authentification basic_ncsa_auth introuvable. Squid est-il bien installé ?"
    exit 1
fi

# ── 4. Création de l'utilisateur du proxy ───────────────────────────────────
info "Création du compte proxy « ${PROXY_USER} »…"
# -c crée/écrase le fichier ; on protège l'accès au fichier de mots de passe.
htpasswd -b -c "${PASSWD_FILE}" "${PROXY_USER}" "${PROXY_PASS}"
chown proxy:proxy "${PASSWD_FILE}" 2>/dev/null || true
chmod 640 "${PASSWD_FILE}"

# ── 5. Écriture de la configuration Squid ───────────────────────────────────
info "Écriture de la configuration Squid (${SQUID_CONF})…"
if [[ -f "${SQUID_CONF}" && ! -f "${SQUID_CONF}.tropratik.bak" ]]; then
    cp "${SQUID_CONF}" "${SQUID_CONF}.tropratik.bak"
    info "Sauvegarde de l'ancienne configuration : ${SQUID_CONF}.tropratik.bak"
fi

cat > "${SQUID_CONF}" <<EOF
# Configuration générée par setup-piste-proxy.sh (Tropratik e-Facture).
# Proxy d'accès restreint aux API PISTE / Chorus Pro.

http_port ${PROXY_PORT}

# ── Authentification basique ────────────────────────────────────────────────
auth_param basic program ${NCSA_AUTH} ${PASSWD_FILE}
auth_param basic realm Proxy PISTE Tropratik
acl authenticated proxy_auth REQUIRED

# ── Restriction des destinations autorisées ────────────────────────────────
acl piste_domains dstdomain ${ALLOWED_DOMAIN}

# ── Sécurité CONNECT (HTTPS) limitée au port 443 ───────────────────────────
acl SSL_ports port 443
acl CONNECT method CONNECT
http_access deny CONNECT !SSL_ports

# ── Règles d'accès ──────────────────────────────────────────────────────────
# Seuls les utilisateurs authentifiés ET visant un domaine PISTE sont autorisés.
http_access allow authenticated piste_domains
http_access deny all

# ── Confidentialité : on masque l'adresse du client d'origine ──────────────
forwarded_for delete
via off

# Journalisation minimale.
access_log /var/log/squid/access.log
EOF

# ── 6. Validation et redémarrage ────────────────────────────────────────────
info "Vérification de la configuration Squid…"
if ! squid -k parse >/dev/null 2>&1; then
    error "La configuration Squid est invalide. Consultez : squid -k parse"
    exit 1
fi

info "Redémarrage de Squid…"
systemctl enable squid >/dev/null 2>&1 || true
systemctl restart squid

# ── 7. Ouverture du pare-feu (si UFW est présent) ───────────────────────────
if command -v ufw >/dev/null 2>&1; then
    info "Ouverture du port ${PROXY_PORT} dans UFW…"
    ufw allow "${PROXY_PORT}/tcp" >/dev/null 2>&1 || warn "Impossible d'ajouter la règle UFW automatiquement."
else
    warn "UFW n'est pas installé : pensez à ouvrir le port ${PROXY_PORT}/tcp dans votre pare-feu / groupe de sécurité."
fi

# ── 8. Récapitulatif ────────────────────────────────────────────────────────
PUBLIC_IP="$(curl -fsS https://api.ipify.org 2>/dev/null || hostname -I | awk '{print $1}')"

echo
echo "${BOLD}${GREEN}Installation terminée.${RESET}"
echo
echo "Renseignez ces valeurs dans l'onglet « Chorus Pro » du module :"
echo "  ${BOLD}Hôte proxy${RESET}   : ${PUBLIC_IP}"
echo "  ${BOLD}Port proxy${RESET}   : ${PROXY_PORT}"
echo "  ${BOLD}Utilisateur${RESET}  : ${PROXY_USER}"
echo "  ${BOLD}Mot de passe${RESET} : (celui que vous venez de saisir)"
echo
echo "Test rapide depuis votre poste (doit renvoyer une réponse de PISTE, pas un 403) :"
echo "  curl -x \"http://${PROXY_USER}:VOTRE_MDP@${PUBLIC_IP}:${PROXY_PORT}\" -I https://oauth.piste.gouv.fr/api/oauth/token"
echo
warn "Le proxy n'autorise QUE les domaines *.piste.gouv.fr : il ne peut pas servir de proxy générique."
