#!/bin/bash # # Library: developers.lib # Description: Developers Tools Library # Modified: 2024/12/09 08:20:00 # Derechos de Autor (C) [2024] [Mauro Rosero P. ] # # 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 . GPG_DEFAULT_PATH=$HOME/.gnupg GPG_CONFIG_PATH=bin/config GPG_TEMPLATE=gpg.config GPG_CONFIG=gpg.conf GPG_BACKUP_CFG=gpg.backup GPGP_BACKUP_SECRET=gpg.secret GPG_SUBKEY_ID="" GPG_REVOKE_FILES="*.rev" DB_GPG_PATH=$HOME/.gnupg DB_GPG_FILE=$USER.db DB_GPG_SUBKEYS_KEY="subkey_id" DB_GPG_SUBKEYS="GPG_SUBKEYS" SQL_GPG_SUBKEYS="${DB_GPG_SUBKEYS}.sql" # Test library function devslib_test() { echo "Developers Library loaded!" exit 1 } # Configuración global para servicios Git FORGEJO_API_URL="https://forgejo.rosero.one/api/v1" FORGEJO_CONFIG_FILE="$HOME/.developer/forgejo.cfg" # Set gpg environment function gpg_setting() { local BIN_CONFIG=$1 local GPG_PATH=$2 local LOCAL_BACKUP=$3 local TIMESTAMP=$4 # Check if gpg directory path exists if [ ! -d "${GPG_PATH}" ] then # Create gpg directory path mkdir -p ${GPG_PATH} if [ $? -ne 0 ]; then return 2 fi fi # Check if gpg template file exists if [ ! -f "${BIN_CONFIG}/${GPG_CFG_PATH}/${GPG_TEMPLATE}" ] then return 1 fi if [ -d "${LOCAL_BACKUP}" ] then if [ -f "${GPG_PATH}/${GPG_CONFIG}" ] then # Destination file backup local BACKUP_FILE="${LOCAL_BACKUP}/gpg_${TIMESTAMP}.bak" cp -f "${GPG_PATH}/${GPG_CONFIG}" "${BACKUP_FILE}" if [ $? -ne 0 ]; then return 3 fi fi fi # Copia el archivo de plantilla al destino cp -f "${BIN_CONFIG}/${GPG_CFG_PATH}/${GPG_TEMPLATE}" "${GPG_PATH}/${GPG_CONFIG}" return $? } # Generate token for backup file function gpg_backup_token() { local SECRET_FILE=$1 if [[ ! -e $archivo_token ]] then local BACKUP_TOKEN=$(uuidgen | base64 ) echo "$BACKUP_TOKEN" > "$SECRET_FILE" chmod 600 "$SECRET_FILE" fi return 0 } # FULL EXTENDED GNUGP BACKUP function developer_backup() { local DB_BACKUP=$1 local BIN_CONFIG=$2 local TIMESTAMP=$3 local GNUGP_PATH=$4 local rc=0 # Check if backup configuration file exists if [ ! -f $BIN_CONFIG/$GPG_BACKUP_CFG ] then return 10 fi local LOCAL_BACKUP=$HOME/$(cat < $BIN_CONFIG/$GPG_BACKUP_CFG) # Check if backup path exist if [ -z "$LOCAL_BACKUP" ]; then return 11 fi if [ ! -d "${LOCAL_BACKUP}" ] then mkdir -p "${LOCAL_BACKUP}" rc=$? if [ $rc -ne 0 ]; then return $rc fi fi gpg_backup_token "${LOCAL_BACKUP}/$GPGP_BACKUP_SECRET" # Get secret backup ZPASSWORD=$(echo "$(cat < "${LOCAL_BACKUP}/$GPGP_BACKUP_SECRET")" | base64 -d) if [ -z "${ZPASSWORD}" ]; then return 13 fi # Export full backup keys to backup work path local TMP_PATH=$(mktemp -d) local TMP_FILE="gpg.bak" gpg --export-options backup -o "${TMP_PATH}/${TMP_FILE}" --export rc=$? if [ $rc -ne 0 ]; then rm -rf "${tmp_path}" return $rc fi # Dump GPG_SUBKEYS table to SQL local TMP_DB_DUMP="${SQL_GPG_SUBKEYS}" local DB_DUMP="${TMP_PATH}/${TMP_DB_DUMP}" sqlite_dump "${DB_BACKUP}" "${DB_DUMP}" "${DB_GPG_SUBKEYS}" rc=$? if [ ${rc} -ne 0 ] then rm -rf "${TMP_PATH}" return $rc fi # Copy full .gnupg for backup mkdir ${TMP_PATH}/.gnupg if [ $? -eq 0 ]; then cp -rf $GNUGP_PATH/* ${TMP_PATH}/.gnupg/ rc=$? if [ $rc -ne 0 ] then rm -rf "${TMP_PATH}" return $rc fi fi # Copy full .ssh for backup mkdir ${TMP_PATH}/.ssh if [ $? -eq 0 ]; then cp -rf $HOME/.ssh/* ${TMP_PATH}/.ssh/ rc=$? if [ $rc -ne 0 ] then rm -rf "${TMP_PATH}" return $rc fi fi # Copy .giconfig for user to backup if [ -f $HOME/.gitconfig ]; then cp -f $HOME/.gitconfig ${TMP_PATH}/ rc=$? if [ $rc -ne 0 ] then rm -rf "${TMP_PATH}" return $rc fi fi # Copy .developer folder for user to backup mkdir ${TMP_PATH}/.developer if [ $? -eq 0 ] && [ -d $HOME/.developer ]; then cp -rf $HOME/.developer/* ${TMP_PATH}/.developer/ rc=$? if [ $rc -ne 0 ] then rm -rf "${TMP_PATH}" return $rc fi fi # Change backup work path to make zip archive cd "${TMP_PATH}" # Comprimir el archivo de respaldo en un archivo ZIP protegido con contraseña BACKUP_FILE="${LOCAL_BACKUP}/gpg_${USER}_${TIMESTAMP}" zip -qqr -P "${ZPASSWORD}" $BACKUP_FILE * .gnupg .ssh .gitconfig .developer rc=$? if [ $rc -ne 0 ] then rm -rf "${TMP_PATH}" return $rc fi rm -rf "${TMP_PATH}" return 0 } # RESTORE PROFILE DEVELOPER LOCAL BACKUP function developer_restore() { local BIN_CONFIG=$1 local BACKUP_ZIP=$2 local rc=0 # Check provided backup zip filename if [ -z "$BACKUP_ZIP" ]; then return 10 fi # Check if backup zip file exists if [ ! -f "$BACKUP_ZIP" ] then return 11 fi # Check if backup configuration file exists local LOCAL_BACKUP=$(dirname $BACKUP_ZIP) if [ ! -f $LOCAL_BACKUP/$GPGP_BACKUP_SECRET ] then return 12 fi # Get secret backup ZPASSWORD=$(echo "$(cat < "${LOCAL_BACKUP}/$GPGP_BACKUP_SECRET")" | base64 -d) if [ -z "${ZPASSWORD}" ]; then return 14 fi clear # Restore zip full .gnupg path unzip -qqo -P "$ZPASSWORD" "$BACKUP_ZIP" ".gnupg"/* -d $HOME rc=$? if [ $rc -ne 0 ]; then return $rc fi # Restore zip full .ssh path unzip -qqo -P "$ZPASSWORD" "$BACKUP_ZIP" ".ssh"/* -d $HOME rc=$? if [ $rc -ne 0 ]; then return $rc fi # Restore zip full .gitconfig file unzip -qqo -P "$ZPASSWORD" "$BACKUP_ZIP" ".gitconfig" -d $HOME rc=$? if [ $rc -ne 0 ]; then return $rc fi # Restore zip full .developer directory unzip -qqo -P "$ZPASSWORD" "$BACKUP_ZIP" ".developer"/* -d $HOME rc=$? if [ $rc -ne 0 ]; then return $rc fi return 0 } # Función para crear un proyecto Git en Forgejo # $1: nombre del proyecto # $2: descripción del proyecto # $3: tipo de visibilidad (private/public) [por defecto: private] # $4: ruta local del proyecto (opcional) # Return: 0 si se crea correctamente, otro valor en caso de error function forgejo_create_project() { local PROJECT_NAME=$1 local PROJECT_DESC=$2 local VISIBILITY=${3:-private} # Por defecto private si no se especifica local PROJECT_PATH=$4 # Verificar parámetros obligatorios if [ -z "$PROJECT_NAME" ] || [ -z "$PROJECT_DESC" ]; then return 10 # Error: faltan parámetros obligatorios fi # Verificar que el archivo de configuración de Forgejo existe if [ ! -f "$FORGEJO_CONFIG_FILE" ]; then mkdir -p "$(dirname "$FORGEJO_CONFIG_FILE")" # Si el archivo no existe, preguntar por token if [ -t 0 ]; then # Solo si es terminal interactiva echo "Archivo de configuración de Forgejo no encontrado." echo "" echo "Para generar un token en Forgejo:" echo "1. Inicie sesión en $FORGEJO_API_URL (sin '/api/v1')" echo "2. Vaya a Configuración → Aplicaciones" echo "3. Genere un nuevo token de acceso personal con permisos de 'repo'" echo "" read -p "Ingrese su token de acceso de Forgejo: " FORGEJO_TOKEN echo "FORGEJO_TOKEN=$FORGEJO_TOKEN" > "$FORGEJO_CONFIG_FILE" chmod 600 "$FORGEJO_CONFIG_FILE" # Restricción de permisos por seguridad else return 11 # Error: no existe configuración y no es interactivo fi fi # Cargar token de Forgejo source "$FORGEJO_CONFIG_FILE" if [ -z "$FORGEJO_TOKEN" ]; then return 12 # Error: token no disponible fi # Verificar visibilidad válida if [ "$VISIBILITY" != "private" ] && [ "$VISIBILITY" != "public" ]; then VISIBILITY="private" # Establecer valor por defecto si es inválido fi # Preparar datos para la API local API_DATA="{\"name\":\"$PROJECT_NAME\",\"description\":\"$PROJECT_DESC\",\"private\":$([ "$VISIBILITY" == "private" ] && echo "true" || echo "false")}" # Comprobar si podemos acceder a la API local API_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$FORGEJO_API_URL/version") if [ "$API_STATUS" != "200" ]; then echo "ERROR: No se puede acceder a la API de Forgejo. Código de estado: $API_STATUS" >&2 echo "{\"error\":\"No se puede acceder a la API. Código: $API_STATUS\"}" > "$HOME/.developer/${PROJECT_NAME}.error" return 13 fi # Verificar token local TOKEN_CHECK=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: token $FORGEJO_TOKEN" "$FORGEJO_API_URL/user") if [ "$TOKEN_CHECK" != "200" ]; then echo "ERROR: Token inválido o sin acceso. Código de estado: $TOKEN_CHECK" >&2 echo "{\"error\":\"Token inválido o sin acceso. Código: $TOKEN_CHECK\"}" > "$HOME/.developer/${PROJECT_NAME}.error" return 12 fi # Llamar a la API de Forgejo para crear el repositorio local API_RESPONSE=$(curl -s -X POST "$FORGEJO_API_URL/user/repos" \ -H "Authorization: token $FORGEJO_TOKEN" \ -H "Content-Type: application/json" \ -d "$API_DATA" 2>/tmp/curl_error.log) echo "DEBUG: Respuesta API: $API_RESPONSE" >&2 # Verificar respuesta if echo "$API_RESPONSE" | grep -q "\"id\":[0-9]*"; then local REPO_URL=$(echo "$API_RESPONSE" | grep -o '"clone_url":"[^"]*"' | cut -d'"' -f4) if [ -n "$REPO_URL" ]; then echo "$REPO_URL" > "$HOME/.developer/${PROJECT_NAME}.repo" else # Extraer HTML URL como fallback REPO_URL=$(echo "$API_RESPONSE" | grep -o '"html_url":"[^"]*"' | head -1 | cut -d'"' -f4) if [ -n "$REPO_URL" ]; then echo "$REPO_URL" > "$HOME/.developer/${PROJECT_NAME}.repo" else echo "ERROR: No se pudo extraer la URL del repositorio." >&2 echo "$API_RESPONSE" > "$HOME/.developer/${PROJECT_NAME}.error" return 14 fi fi # Si se proporcionó una ruta local, configurar el repositorio if [ -n "$PROJECT_PATH" ] && [ -d "$PROJECT_PATH" ]; then cd "$PROJECT_PATH" # Verificar si ya es un repositorio git if [ -d ".git" ]; then # Añadir el remoto git remote add origin "$REPO_URL" git push -u origin main || git push -u origin master else # Inicializar el repositorio y hacer primer commit si no existe git init git add . git commit -m "[INIT] Proyecto $PROJECT_NAME" git remote add origin "$REPO_URL" git push -u origin main fi fi return 0 # Éxito else # Guardar mensaje de error echo "$API_RESPONSE" > "$HOME/.developer/${PROJECT_NAME}.error" return 13 # Error: falló la creación del repositorio fi }