Files
fn_registry/bash/functions/browser/apply_chromium_extension_policy.sh
T
Egutierrez 830f2d34de feat(browser): funciones idempotentes para config de sistema de chromium
Cierra el gap de reproducibilidad entre PCs del proyecto web_scraping:
la organizacion de extensiones y el CDP global dejaban de ser pasos
manuales con sudo documentados en prosa.

- apply_chromium_extension_policy: escribe ExtensionInstallForcelist
  (whitelist via --keep) en /etc/chromium/policies/managed/extensions.json
  de forma idempotente, con backup automatico y validacion JSON. --dry-run
  previsualiza sin tocar el sistema.
- apply_chromium_cdp_flag: gestiona /etc/chromium.d/cdp (CDP global).
  Loopback por defecto, --network para bind 0.0.0.0 (con aviso), --remove
  para desactivar, --dry-run para previsualizar. Idempotente con backup.

Ambas: dominio browser, grupo navegator, impuras (escriben en /etc via
sudo), guard de auto-ejecucion (ejecutables con fn run y sourceables).

Docs del proyecto (CONVENTIONS.md reglas 8/9, CHROMIUM_SYSTEM.md
inventario + tabla accionable) ahora apuntan a 'fn run apply_chromium_*'
como metodo canonico en vez de editar los archivos de /etc a mano.
2026-06-05 16:33:35 +02:00

206 lines
7.5 KiB
Bash

#!/usr/bin/env bash
# apply_chromium_extension_policy — Escribe de forma idempotente la política managed de Chromium
# que fuerza la instalación de un conjunto de extensiones en CUALQUIER perfil del navegador.
apply_chromium_extension_policy() {
local policy_path="/etc/chromium/policies/managed/extensions.json"
local update_url="https://clients2.google.com/service/update2/crx"
local dry_run=0
local -a ext_ids=()
# --- Parseo de argumentos ---
while [[ $# -gt 0 ]]; do
case "$1" in
--keep)
if [[ -z "${2:-}" ]]; then
echo "apply_chromium_extension_policy: --keep requiere un ID de extensión" >&2
return 1
fi
ext_ids+=("$2")
shift 2
;;
--policy-path)
if [[ -z "${2:-}" ]]; then
echo "apply_chromium_extension_policy: --policy-path requiere un valor" >&2
return 1
fi
policy_path="$2"
shift 2
;;
--update-url)
if [[ -z "${2:-}" ]]; then
echo "apply_chromium_extension_policy: --update-url requiere un valor" >&2
return 1
fi
update_url="$2"
shift 2
;;
--dry-run)
dry_run=1
shift
;;
*)
echo "apply_chromium_extension_policy: argumento desconocido: $1" >&2
echo "Uso: apply_chromium_extension_policy --keep <ext_id> [--keep <ext_id>]... [--policy-path <path>] [--update-url <url>] [--dry-run]" >&2
return 1
;;
esac
done
# --- Validar que hay al menos una extensión ---
if [[ ${#ext_ids[@]} -eq 0 ]]; then
echo "apply_chromium_extension_policy: se requiere al menos un --keep <ext_id>" >&2
return 1
fi
# --- Construir el JSON ---
local forcelist_entries=""
local first=1
for id in "${ext_ids[@]}"; do
if [[ $first -eq 0 ]]; then
forcelist_entries+=","$'\n'
fi
forcelist_entries+=" \"${id};${update_url}\""
first=0
done
local new_json
new_json=$(printf '{\n "ExtensionInstallForcelist": [\n%s\n ]\n}\n' "$forcelist_entries")
# --- Modo dry-run ---
if [[ $dry_run -eq 1 ]]; then
echo "[dry-run] JSON que se escribiría en: ${policy_path}"
echo "---"
echo "$new_json"
echo "---"
echo "[dry-run] No se ha modificado el sistema."
return 0
fi
# --- Idempotencia: comparar con contenido actual ---
if [[ -f "$policy_path" ]]; then
local current_content
current_content=$(cat "$policy_path" 2>/dev/null || true)
if [[ "$current_content" == "$new_json" ]]; then
echo "apply_chromium_extension_policy: política ya aplicada (sin cambios). Nada que hacer."
return 0
fi
fi
# --- Backup del archivo existente ---
local backup_path=""
if [[ -f "$policy_path" ]]; then
local date_suffix
date_suffix=$(date +%Y%m%d)
backup_path="${policy_path}.bak.${date_suffix}"
if [[ ! -f "$backup_path" ]]; then
echo "apply_chromium_extension_policy: creando backup → ${backup_path}"
if [[ $EUID -ne 0 ]]; then
sudo cp "$policy_path" "$backup_path" || {
echo "apply_chromium_extension_policy: no se pudo crear el backup en ${backup_path}" >&2
return 1
}
else
cp "$policy_path" "$backup_path" || {
echo "apply_chromium_extension_policy: no se pudo crear el backup en ${backup_path}" >&2
return 1
}
fi
else
echo "apply_chromium_extension_policy: backup del día ya existe (${backup_path}), se omite."
fi
fi
# --- Crear directorio padre si no existe ---
local policy_dir
policy_dir=$(dirname "$policy_path")
if [[ ! -d "$policy_dir" ]]; then
echo "apply_chromium_extension_policy: creando directorio ${policy_dir}"
if [[ $EUID -ne 0 ]]; then
sudo mkdir -p "$policy_dir" || {
echo "apply_chromium_extension_policy: no se pudo crear el directorio ${policy_dir}" >&2
return 1
}
else
mkdir -p "$policy_dir" || {
echo "apply_chromium_extension_policy: no se pudo crear el directorio ${policy_dir}" >&2
return 1
}
fi
fi
# --- Escribir el JSON vía tmpfile + sudo cp / tee ---
local tmpfile
tmpfile=$(mktemp /tmp/chromium_policy_XXXXXX.json)
echo "$new_json" > "$tmpfile"
if [[ $EUID -ne 0 ]]; then
sudo cp "$tmpfile" "$policy_path" || {
echo "apply_chromium_extension_policy: no se pudo escribir ${policy_path}" >&2
rm -f "$tmpfile"
# Restaurar backup si hubo
if [[ -n "$backup_path" && -f "$backup_path" ]]; then
echo "apply_chromium_extension_policy: restaurando backup tras error..."
sudo cp "$backup_path" "$policy_path" 2>/dev/null || true
fi
return 1
}
else
cp "$tmpfile" "$policy_path" || {
echo "apply_chromium_extension_policy: no se pudo escribir ${policy_path}" >&2
rm -f "$tmpfile"
if [[ -n "$backup_path" && -f "$backup_path" ]]; then
echo "apply_chromium_extension_policy: restaurando backup tras error..."
cp "$backup_path" "$policy_path" 2>/dev/null || true
fi
return 1
}
fi
rm -f "$tmpfile"
# --- Validar el JSON escrito ---
local validation_ok=0
if command -v python3 &>/dev/null; then
python3 -c "import json,sys; json.load(open(sys.argv[1]))" "$policy_path" 2>/dev/null && validation_ok=1
elif command -v jq &>/dev/null; then
jq . "$policy_path" &>/dev/null && validation_ok=1
else
# Sin parser disponible, asumir OK (el JSON lo generamos nosotros)
validation_ok=1
fi
if [[ $validation_ok -eq 0 ]]; then
echo "apply_chromium_extension_policy: el JSON escrito no es válido — restaurando backup" >&2
if [[ -n "$backup_path" && -f "$backup_path" ]]; then
if [[ $EUID -ne 0 ]]; then
sudo cp "$backup_path" "$policy_path" 2>/dev/null || true
else
cp "$backup_path" "$policy_path" 2>/dev/null || true
fi
fi
return 1
fi
# --- Resumen final ---
echo "apply_chromium_extension_policy: política aplicada correctamente."
echo " Ruta : ${policy_path}"
echo " Extensiones forzadas (${#ext_ids[@]}):"
for id in "${ext_ids[@]}"; do
echo " - ${id}"
done
if [[ -n "$backup_path" && -f "$backup_path" ]]; then
echo " Backup : ${backup_path}"
fi
echo ""
echo " AVISO: Chromium cachea la politica en memoria. Para que surta efecto:"
echo " pkill -9 chromium (cierra TODOS los procesos)"
echo " # Luego relanza Chromium. O desde un Chromium abierto:"
echo " # chrome://policy → 'Reload policies'"
}
# Auto-ejecución al correr el archivo directo (bash file.sh / fn run). Si se hace `source`,
# solo se define la función y no se ejecuta nada.
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
apply_chromium_extension_policy "$@"
fi