255 lines
7.4 KiB
Bash
Executable file
255 lines
7.4 KiB
Bash
Executable file
#!/bin/bash
|
|
#Script : ai_token.sh
|
|
#Apps : MRDEVS TOOLS
|
|
#Description : Gestiona tokens de proveedores de IA usando SOPS
|
|
#Author : Sora Rosero One <sora@rosero.one>
|
|
#Generated by : Claude Code (claude-3-7-sonnet-20250219)
|
|
#Created : 2025/03/21 16:06:20
|
|
#Modified : 2025/03/21 17:14:59
|
|
#Version : 1.0.0
|
|
#Use Notes :
|
|
# Gestiona múltiples tokens de IA definidos en ai.tokens
|
|
#==============================================================================
|
|
# Derechos de Autor [2025] [Mauro Rosero P. <mauro@rosero.one>]
|
|
#==============================================================================
|
|
# Este programa es software libre: usted puede redistribuirlo y/o modificarlo
|
|
# bajo los términos de la Licencia Pública Affero General de GNU tal como
|
|
# lo publica la Free Software Foundation, ya sea la versión 3 de la licencia,
|
|
# o (a su elección) cualquier versión posterior.
|
|
#
|
|
# Este programa se distribuye con la esperanza de que sea útil,
|
|
# pero SIN NINGUNA GARANTÍA; sin siquiera la garantía implícita de
|
|
# COMERCIABILIDAD o IDONEIDAD PARA UN PROPÓSITO PARTICULAR. Consulte la
|
|
# Licencia Pública Affero General de GNU para obtener más detalles.
|
|
#
|
|
# Debería haber recibido una copia de la Licencia Pública Affero General
|
|
# junto con este programa. Si no la recibió, consulte <https://www.gnu.org/licenses/>.
|
|
|
|
# Configuración inicial
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
BIN_BASE="bin"
|
|
BIN_LIBS="lib"
|
|
BIN_MESG="msg"
|
|
BIN_CFGS="config"
|
|
BIN_SOPS="sops"
|
|
|
|
# Leer DEVSPATH desde el archivo de configuración o usar "devs" por defecto
|
|
if [ -f "$SCRIPT_DIR/$BIN_CFGS/devspath.dat" ]; then
|
|
DEVSPATH=$(cat "$SCRIPT_DIR/$BIN_CFGS/devspath.dat")
|
|
else
|
|
DEVSPATH="devs"
|
|
fi
|
|
|
|
BIN_HOME="$HOME/$DEVSPATH"
|
|
BIN_PATH=$BIN_HOME/$BIN_BASE
|
|
VERSION=$(cat "$BIN_HOME/$BIN_BASE/$BIN_CFGS/version")
|
|
|
|
# CHECK SHELL LANGUAGE
|
|
BIN_LANG=${LANG:0:2}
|
|
|
|
# Importar bibliotecas necesarias
|
|
source "${BIN_HOME}/${BIN_BASE}/${BIN_LIBS}/base.lib"
|
|
source "${BIN_HOME}/${BIN_BASE}/${BIN_LIBS}/developers.lib"
|
|
source "${BIN_HOME}/${BIN_BASE}/${BIN_LIBS}/console.lib"
|
|
|
|
# Cargar mensajes en el idioma del sistema o español por defecto
|
|
load_messages "${BIN_HOME}/${BIN_BASE}" "${BIN_MESG}" "${BIN_LANG}" "head"
|
|
load_messages "${BIN_HOME}/${BIN_BASE}" "${BIN_MESG}" "${BIN_LANG}" "developers"
|
|
apps_title="${aimsg_100}"
|
|
title="${head_000} ${head_002}"
|
|
|
|
# Comprobar dependencias necesarias
|
|
check_dependencies() {
|
|
# Verificar que 'dialog' esté instalado
|
|
if ! command -v dialog &>/dev/null; then
|
|
echo "${qrmsg_013}"
|
|
exit 1
|
|
fi
|
|
|
|
# Verificar que 'sops' esté instalado
|
|
if ! command -v sops &>/dev/null; then
|
|
dialog_error_box "${head_error}" "${aimsg_115}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
|
|
# Función para cargar la lista de proveedores desde el archivo de configuración
|
|
load_providers() {
|
|
local config_file="$BIN_HOME/$BIN_BASE/$BIN_CFGS/ai.tokens"
|
|
|
|
if [ ! -f "$config_file" ]; then
|
|
echo "${aimsg_111} $config_file"
|
|
exit 1
|
|
fi
|
|
|
|
# Inicializar arrays globales para los proveedores
|
|
provider_codes=()
|
|
provider_descs=()
|
|
|
|
# Leer el archivo de configuración y llenar los arrays
|
|
while IFS=',' read -r provider_code provider_desc enabled active extra; do
|
|
# Eliminar comillas
|
|
provider_code=$(echo "$provider_code" | tr -d '"')
|
|
provider_desc=$(echo "$provider_desc" | tr -d '"')
|
|
|
|
# Agregar a los arrays
|
|
provider_codes+=("$provider_code")
|
|
provider_descs+=("$provider_desc")
|
|
done < <(grep -v "^#" "$config_file")
|
|
}
|
|
|
|
# Función para encriptar token con SOPS
|
|
encrypt_token() {
|
|
local provider_code="$1"
|
|
local token="$2"
|
|
local output_file="$BIN_HOME/$BIN_SOPS/${provider_code}.sops.yaml"
|
|
local temp_file="/tmp/ai_token_$$"
|
|
|
|
# Crear directorio si no existe
|
|
mkdir -p "$BIN_HOME/$BIN_SOPS"
|
|
|
|
# Codificar el token en base64
|
|
local token_base64=$(echo -n "$token" | base64)
|
|
|
|
# Crear archivo temporal con token codificado
|
|
echo "$token_base64" > "$temp_file"
|
|
|
|
# Encriptar usando SOPS
|
|
if sops --encrypt "$temp_file" > "$output_file"; then
|
|
# Asegurar permisos adecuados
|
|
chmod 600 "$output_file"
|
|
rm -f "$temp_file"
|
|
return 0
|
|
else
|
|
rm -f "$temp_file"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Función para mostrar menú de proveedores usando console.lib
|
|
show_provider_menu() {
|
|
local options=""
|
|
local menu_text=""
|
|
|
|
# Construir el menú usando console.lib
|
|
for i in "${!provider_codes[@]}"; do
|
|
# Asegurarnos de que la clave sea única
|
|
if [ -n "$options" ]; then
|
|
options+="\n"
|
|
fi
|
|
options+="${i}:${provider_descs[i]}"
|
|
|
|
# Añadir descripción para el menú
|
|
if [ -n "$menu_text" ]; then
|
|
menu_text+="\n"
|
|
fi
|
|
menu_text+="${i} ${provider_codes[i]}"
|
|
done
|
|
|
|
# Mostrar menú usando console.lib
|
|
choice=$(menu_actions "${aimsg_101}" "$options" 12)
|
|
|
|
# Verificar salida
|
|
if [ "$choice" == "${head_key_end}" ]; then
|
|
clear
|
|
echo "${aimsg_108}"
|
|
exit 0
|
|
fi
|
|
|
|
# Obtener el código y descripción del proveedor seleccionado
|
|
selected_provider_code="${provider_codes[$choice]}"
|
|
selected_provider_desc="${provider_descs[$choice]}"
|
|
|
|
return 0
|
|
}
|
|
|
|
# Función para solicitar el token al usuario usando console.lib
|
|
get_token() {
|
|
local provider_name="$1"
|
|
local provider_code="$2"
|
|
|
|
while true; do
|
|
# Usar dialog_input_pass de console.lib
|
|
dialog_input_pass "${aimsg_102} $provider_name" "${aimsg_103} $provider_code:" ""
|
|
|
|
# Comprobar si el usuario canceló
|
|
if [ $codex -ne 0 ]; then
|
|
return 1
|
|
fi
|
|
|
|
# Validar token
|
|
if [ -z "$value" ]; then
|
|
dialog_error_box "${head_error}" "${aimsg_104}"
|
|
continue
|
|
fi
|
|
|
|
# Comprobar longitud del token (debe tener al menos 20 caracteres)
|
|
if [ ${#value} -lt 20 ]; then
|
|
dialog_error_box "${head_warning}" "${aimsg_105}"
|
|
|
|
# Preguntar si continuar
|
|
dialog_yesno "${aimsg_106}"
|
|
if [ $result -ne 0 ]; then
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
# Token válido
|
|
break
|
|
done
|
|
|
|
# Devolver el token
|
|
echo "$value"
|
|
return 0
|
|
}
|
|
|
|
# Función principal
|
|
main() {
|
|
check_dependencies
|
|
|
|
# Cargar proveedores
|
|
load_providers
|
|
|
|
# Mostrar menú de proveedores
|
|
show_provider_menu
|
|
|
|
# Ahora tenemos selected_provider_code y selected_provider_desc
|
|
provider_code="$selected_provider_code"
|
|
provider_desc="$selected_provider_desc"
|
|
|
|
# Verificar archivo de token si ya existe
|
|
sops_file="$BIN_HOME/$BIN_SOPS/${provider_code}.sops.yaml"
|
|
if [ -f "$sops_file" ]; then
|
|
# Preguntar con dialog_yesno de console.lib
|
|
dialog_yesno "${aimsg_107}"
|
|
|
|
if [ $result -ne 0 ]; then
|
|
dialog_error_box "${head_canceled}" "${aimsg_108}"
|
|
clear
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
# Obtener token
|
|
get_token "$provider_desc" "$provider_code"
|
|
if [ $? -ne 0 ]; then
|
|
dialog_error_box "${head_canceled}" "${aimsg_108}"
|
|
clear
|
|
exit 0
|
|
fi
|
|
|
|
# Encriptar token
|
|
if encrypt_token "$provider_code" "$value"; then
|
|
dialog_error_box "${head_success}" "${aimsg_109} $sops_file"
|
|
else
|
|
dialog_error_box "${head_error}" "${aimsg_110}"
|
|
clear
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Ejecutar función principal
|
|
main
|
|
clear
|
|
exit 0
|