#!/usr/bin/env bash # gitea skill — helper REST autenticado contra gitea.nucleoriofrio.com. # # Uso: # query.sh /version # GET /api/v1/version # query.sh /repos/NucleOS/nucleo-infra/pulls # GET # query.sh "/repos/NucleOS/nucleo-infra/pulls?state=open" # query.sh -X POST -H 'Content-Type: application/json' \ # --data-binary @body.json /repos/NucleOS/X/pulls # # Auth: # - GITEA_USER_PAT en el entorno → se usa esa (override one-shot para admin). # - Sino GITEA_PAT del .env → el PAT de claudecode0. # # Admin guard: # Bloquea endpoints que requieren admin del org NucleOS (Actions # secrets/variables, /admin/*) salvo que GITEA_USER_PAT esté seteada. set -euo pipefail SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" ENV_FILE="$SKILL_DIR/.env" if [[ ! -f "$ENV_FILE" ]]; then echo "ERROR: $ENV_FILE no existe. Corré setup.sh primero:" >&2 echo " bash $SKILL_DIR/scripts/setup.sh" >&2 exit 1 fi set -a # shellcheck disable=SC1090 source "$ENV_FILE" set +a : "${GITEA_BASE_URL:?GITEA_BASE_URL no definido en .env}" # ─── Resolver PAT: USER_PAT (override) > GITEA_PAT (default) ──────────── if [[ -n "${GITEA_USER_PAT:-}" ]]; then PAT="$GITEA_USER_PAT" USING_USER_PAT=1 else : "${GITEA_PAT:?GITEA_PAT vacío en .env. Re-correr setup.sh.}" PAT="$GITEA_PAT" USING_USER_PAT=0 fi # ─── Parsear args: separar flags de curl del path ─────────────────────── args=() path="" while [[ $# -gt 0 ]]; do case "$1" in -X|--request|-d|--data|--data-raw|--data-binary|--data-urlencode|-H|--header|-o|--output|-T|--upload-file|-F|--form) args+=("$1" "$2"); shift 2 ;; -X*|--request=*|--data=*|--data-raw=*|--data-binary=*|--header=*) args+=("$1"); shift ;; --) shift; break ;; -*) args+=("$1"); shift ;; *) path="$1"; shift ;; esac done [[ $# -gt 0 && -z "$path" ]] && path="$1" if [[ -z "$path" ]]; then cat >&2 < Ejemplos: query.sh /version query.sh /repos/NucleOS/nucleo-infra/pulls query.sh "/repos/NucleOS/nucleo-infra/pulls?state=open" query.sh -X POST -H 'Content-Type: application/json' \\ --data-binary @body.json /repos/NucleOS/X/pulls Ver endpoints.md para la cheat sheet completa. EOF exit 2 fi # Asegurar leading / case "$path" in /*) ;; http*) echo "ERROR: pasá solo el path (sin host)." >&2; exit 1 ;; *) path="/$path" ;; esac # Prefijar /api/v1 si el path no empieza con /api/ if [[ "$path" != /api/* ]]; then full_path="/api/v1${path}" else full_path="$path" fi # ─── Admin guard ──────────────────────────────────────────────────────── # Bloquear endpoints que necesitan admin del org NucleOS, salvo que # GITEA_USER_PAT esté seteada (override deliberado). if [[ "$USING_USER_PAT" -eq 0 ]]; then guard_path="${full_path%%\?*}" if [[ "$guard_path" =~ ^/api/v1/admin/ ]] \ || [[ "$guard_path" =~ ^/api/v1/orgs/[^/]+/actions/(secrets|variables)(/|$) ]] \ || [[ "$guard_path" =~ ^/api/v1/repos/[^/]+/[^/]+/actions/(secrets|variables)(/|$) ]]; then cat >&2 < y re-corré el comando. Apenas termine, **recordale BORRAR el PAT** desde https://gitea.nucleoriofrio.com/user/settings/applications (Gitea no tiene PATs efímeros nativos — el cleanup es manual y obligatorio). Path bloqueado: $guard_path EOF exit 3 fi fi # ─── Llamar ───────────────────────────────────────────────────────────── exec curl -sS \ -H "Authorization: token ${PAT}" \ -H "Accept: application/json" \ "${args[@]}" \ "${GITEA_BASE_URL}${full_path}"