Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013SfRSvDd335NPYEbBrDFGE
115 lines
7.3 KiB
Bash
Executable File
115 lines
7.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Página de entrada del sitio (27-oct-2026): instala el nginx nuevo de drogheda.helgen.online con respaldo, prueba y
|
|
# regreso automático. Se corre EN EL SERVIDOR con sudo (lo llama scripts/despliegue-1027.sh desde la Mac):
|
|
# sudo bash /srv/projects/drogheda/hbox-docs/backend/nginx/cambiar-entrada.sh servicio # 1. servicio nuevo (hilos, admins)
|
|
# sudo bash …/cambiar-entrada.sh aplicar # 2. nginx con página de entrada (si una prueba falla, regresa solo)
|
|
# sudo bash …/cambiar-entrada.sh deshacer # regresar al nginx anterior (ventana gris) si algo no te gusta
|
|
# sudo bash …/cambiar-entrada.sh probar # solo las pruebas, sin cambiar nada
|
|
set -uo pipefail
|
|
AQUI="$(cd "$(dirname "$0")" && pwd)"
|
|
BACK="$(dirname "$AQUI")"
|
|
# El archivo real de nginx de este sitio (el que está habilitado), no una ruta supuesta
|
|
CONF="$(readlink -f "$(grep -l 'server_name drogheda.helgen.online' /etc/nginx/sites-enabled/* 2>/dev/null | head -1)" 2>/dev/null)"
|
|
NUEVO="$AQUI/drogheda.helgen.online.conf"
|
|
HTP=/etc/nginx/hbox-docs.htpasswd
|
|
DATOS=/srv/projects/drogheda
|
|
UNIDAD=/etc/systemd/system/actas-hbox.service
|
|
HOST=drogheda.helgen.online
|
|
[ "$(id -u)" = 0 ] || { echo "Córrelo con sudo."; exit 1; }
|
|
|
|
ok=0; mal=0
|
|
prueba() { # nombre, esperado (subcadena), comando
|
|
local r; r="$(eval "$3" 2>&1)"
|
|
if [[ "$r" == *"$2"* ]]; then ok=$((ok+1)); echo " ✓ $1"; else mal=$((mal+1)); echo " ✕ $1 — esperaba «$2», obtuve: ${r:0:160}"; fi
|
|
}
|
|
C="curl -s --max-time 10 --resolve $HOST:443:127.0.0.1"
|
|
|
|
probar_backend() {
|
|
echo "## backend (127.0.0.1:8081)"
|
|
prueba "salud" '"ok":true' "curl -s --max-time 5 http://127.0.0.1:8081/api/salud"
|
|
prueba "/api/_auth sin sesión → 401" "401" "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8081/api/_auth"
|
|
prueba "/api/sesion responde" '"sesion":false' "curl -s http://127.0.0.1:8081/api/sesion"
|
|
prueba "incidencias cargadas" '"ok":true' "curl -s -H 'X-Remote-User: vigia' http://127.0.0.1:8081/api/incidencias/resumen"
|
|
prueba "standup cargado" '"ok":true' "curl -s -H 'X-Remote-User: vigia' http://127.0.0.1:8081/api/standup/estado"
|
|
}
|
|
cookie_de_prueba() { # sesión de 5 minutos para leo, firmada con el secreto del servicio (sin contraseña)
|
|
python3 - "$DATOS/.sesion-secreto" "$HTP" <<'PY'
|
|
import sys, time, hmac, hashlib
|
|
sec = open(sys.argv[1]).read().strip().encode()
|
|
h = [l.split(":", 1)[1].strip() for l in open(sys.argv[2]) if l.split(":", 1)[0].strip() == "leo"][0]
|
|
ver = hashlib.sha256(h.encode()).hexdigest()[:12]; v = int(time.time()) + 300
|
|
print("leo~%d~%s~%s" % (v, ver, hmac.new(sec, ("leo|%d|%s" % (v, ver)).encode(), hashlib.sha256).hexdigest()[:40]))
|
|
PY
|
|
}
|
|
probar_nginx() {
|
|
echo "## nginx ($HOST)"
|
|
prueba "/ sin sesión → 302 a /entrar.html" "entrar.html" "$C -o /dev/null -w '%{http_code} %{redirect_url}' https://$HOST/tableros/pendientes/"
|
|
prueba "/entrar.html → 200" "200" "$C -o /dev/null -w '%{http_code}' https://$HOST/entrar.html"
|
|
prueba "estilos públicos → 200" "200" "$C -o /dev/null -w '%{http_code}' https://$HOST/stylesheets/helgen.css"
|
|
prueba "/publico/entrar.js → 200" "200" "$C -o /dev/null -w '%{http_code}' https://$HOST/publico/entrar.js"
|
|
prueba "/api/sesion sin sesión → 200" '"sesion":false' "$C https://$HOST/api/sesion"
|
|
prueba "/api/tareas sin sesión → 401 JSON" '"sesion":false' "$C https://$HOST/api/tareas"
|
|
prueba "/api/_auth desde fuera → 404" "404" "$C -o /dev/null -w '%{http_code}' https://$HOST/api/_auth"
|
|
prueba "X-Remote-User falso no entra" '"sesion":false' "$C -H 'X-Remote-User: leo' https://$HOST/api/tareas"
|
|
prueba "entrar con contraseña mala → 401" '"codigo":"' "$C -H 'Content-Type: application/json' -d '{\"usuario\":\"vigia-prueba\",\"password\":\"x\"}' https://$HOST/api/entrar"
|
|
prueba "curl -u (Basic) ya no entra" '"sesion":false' "$C -A curl -u leo:x https://$HOST/api/whoami"
|
|
local CK; CK="$(cookie_de_prueba 2>/dev/null)"
|
|
prueba "con sesión: /api/whoami = leo" '"user":"leo"' "$C -b hbox_sesion=$CK https://$HOST/api/whoami"
|
|
prueba "con sesión: la página abre (200)" "200" "$C -b hbox_sesion=$CK -o /dev/null -w '%{http_code}' https://$HOST/tableros/pendientes/"
|
|
prueba "POST desde otro sitio → 403" "otro sitio" "$C -b hbox_sesion=$CK -H 'Origin: https://malo.example' -H 'Content-Type: application/json' -d '{}' https://$HOST/api/incidencias"
|
|
}
|
|
revisar_htpasswd() { # la entrada nueva lee $apr1$ y {SHA}; si alguien quedó con otro formato, no podría entrar
|
|
local otros; otros="$(cut -d: -f2 "$HTP" | grep -vcE '^(\$apr1\$|\{SHA\})' || true)"
|
|
if [ "${otros:-0}" != "0" ]; then
|
|
echo " ✕ $otros cuenta(s) del htpasswd con un formato que la entrada nueva no lee:"; cut -d: -f1,2 "$HTP" | grep -vE ':(\$apr1\$|\{SHA\})' | cut -d: -f1 | sed 's/^/ /'
|
|
echo " Restablécelas en Mi cuenta antes de cambiar nginx."; return 1
|
|
fi
|
|
echo " ✓ todas las contraseñas en \$apr1\$"
|
|
}
|
|
|
|
case "${1:-}" in
|
|
servicio)
|
|
UANT="$UNIDAD.antes-$(date +%Y%m%d-%H%M%S)"
|
|
cp -p "$UNIDAD" "$UANT" || { echo "No pude respaldar $UNIDAD: no cambio nada."; exit 1; }
|
|
install -m 644 "$BACK/actas-hbox.service" "$UNIDAD"
|
|
systemctl daemon-reload && systemctl restart actas-hbox
|
|
for i in 1 2 3 4 5 6 7 8 9 10; do curl -s --max-time 2 http://127.0.0.1:8081/api/salud >/dev/null && break; sleep 1; done
|
|
probar_backend
|
|
if [ "$mal" != 0 ]; then
|
|
echo "El servicio nuevo no pasó ($mal mal): regreso al anterior ($UANT). Revisa 'journalctl -u actas-hbox -n 50'."
|
|
cp -p "$UANT" "$UNIDAD" && systemctl daemon-reload && systemctl restart actas-hbox; exit 1
|
|
fi
|
|
echo "Servicio listo ($ok pruebas). Respaldo del anterior: $UANT"
|
|
;;
|
|
aplicar)
|
|
[ -n "$CONF" ] && [ -f "$CONF" ] || { echo "No encuentro el nginx de $HOST en sites-enabled. No cambio nada."; exit 1; }
|
|
echo "Archivo de nginx: $CONF"
|
|
probar_backend
|
|
[ "$mal" = 0 ] || { echo "El backend todavía no tiene la entrada nueva: corre primero «servicio». No cambié nginx."; exit 1; }
|
|
revisar_htpasswd || exit 1
|
|
# respaldo FUERA de sites-enabled/ (lo que esté ahí lo carga nginx: un respaldo ahí duplicaría el sitio)
|
|
mkdir -p /etc/nginx/respaldos-drogheda
|
|
RESP="/etc/nginx/respaldos-drogheda/$(basename "$CONF").antes-entrada-$(date +%Y%m%d-%H%M%S)"
|
|
cp -p "$CONF" "$RESP" || { echo "No pude respaldar $CONF: no cambio nada."; exit 1; }
|
|
echo "Respaldo: $RESP"
|
|
install -m 644 "$NUEVO" "$CONF"
|
|
if ! nginx -t 2>&1; then echo "nginx -t falló: regreso al anterior."; cp -p "$RESP" "$CONF"; nginx -t && systemctl reload nginx; exit 1; fi
|
|
systemctl reload nginx; sleep 1
|
|
ok=0; mal=0; probar_nginx
|
|
if [ "$mal" != 0 ]; then
|
|
echo "Algo falló ($mal): regreso al nginx anterior."; cp -p "$RESP" "$CONF"; nginx -t && systemctl reload nginx; exit 1
|
|
fi
|
|
echo; echo "Listo ($ok pruebas). Abre https://$HOST : debe salir la página de entrada. Para regresar: sudo bash $0 deshacer"
|
|
;;
|
|
deshacer)
|
|
[ -n "$CONF" ] || CONF=/etc/nginx/sites-available/drogheda.helgen.online.conf
|
|
RESP="$(ls -1t /etc/nginx/respaldos-drogheda/"$(basename "$CONF")".antes-entrada-* 2>/dev/null | head -1)"
|
|
[ -n "$RESP" ] || { echo "No hay respaldo de antes de la entrada."; exit 1; }
|
|
cp -p "$RESP" "$CONF" && nginx -t && systemctl reload nginx && echo "Regresé a $RESP (ventana gris de antes)."
|
|
;;
|
|
probar)
|
|
probar_backend; probar_nginx; echo "$ok bien · $mal mal"
|
|
;;
|
|
*) sed -n '2,9p' "$0"; exit 1 ;;
|
|
esac
|