#!/usr/bin/env bash # Регистрирует публичные SSH-ключи в Gitea через API. set -euo pipefail CONFIG_DIR="${CONFIG_DIR:-$HOME/CursorRules/local}" HOSTS_CONFIG="${HOSTS_CONFIG:-$CONFIG_DIR/git-ssh-hosts.conf}" WHAT_IF="${WHAT_IF:-0}" log_step() { printf '[*] %s\n' "$1"; } log_ok() { printf '[+] %s\n' "$1"; } log_warn() { printf '[!] %s\n' "$1"; } if [[ ! -f "$HOSTS_CONFIG" ]]; then echo "Config not found: $HOSTS_CONFIG" >&2 exit 1 fi read_kv_file() { local file="$1" local line key value while IFS= read -r line || [[ -n "$line" ]]; do [[ "$line" =~ ^[[:space:]]*# ]] && continue [[ "$line" != *=* ]] && continue key="${line%%=*}" value="${line#*=}" key="${key%"${key##*[![:space:]]}"}" value="${value#"${value%%[![:space:]]*}"}" printf '%s=%s\n' "$key" "$value" done < "$file" } declare -A PROFILE_KEYNAME PROFILE_GITEA current_section='' current_name='' while IFS= read -r line || [[ -n "$line" ]]; do line="${line%%#*}" line="${line%"${line##*[![:space:]]}"}" [[ -z "$line" ]] && continue if [[ "$line" =~ ^\[profile:(.+)\]$ ]]; then current_section='profile' current_name="${BASH_REMATCH[1]}" continue fi if [[ "$line" =~ ^\[host: ]]; then current_section='' continue fi [[ "$line" != *=* || "$current_section" != 'profile' ]] && continue key="${line%%=*}" value="${line#*=}" key="${key%"${key##*[![:space:]]}"}" value="${value#"${value%%[![:space:]]*}"}" case "$key" in KeyName) PROFILE_KEYNAME["$current_name"]="$value" ;; GiteaConfig) PROFILE_GITEA["$current_name"]="$value" ;; esac done < "$HOSTS_CONFIG" SSH_DIR="$HOME/.ssh" MACHINE="$(hostname -s 2>/dev/null || hostname)" declare -A REGISTERED register_gitea_key() { local cfg_file="$1" local pub_path="$2" local title="$3" declare -A CFG=() local kv key value while IFS= read -r kv; do key="${kv%%=*}" value="${kv#*=}" CFG["$key"]="$value" done < <(read_kv_file "$cfg_file") if [[ -z "${CFG[GiteaApiPassword]:-}" ]]; then log_warn "$title : GiteaApiPassword empty — add key manually in Gitea UI" cat "$pub_path" return 0 fi local base="${CFG[GiteaApiUrl]%/}" local auth user pass pub body response user="${CFG[GiteaApiUser]}" pass="${CFG[GiteaApiPassword]}" auth="$(printf '%s:%s' "$user" "$pass" | base64 -w0 2>/dev/null || printf '%s:%s' "$user" "$pass" | base64)" pub="$(tr -d '\r\n' < "$pub_path")" response="$(curl -fsS -H "Authorization: Basic $auth" "$base/api/v1/user/keys" 2>/dev/null || true)" if [[ -n "$response" ]] && printf '%s' "$response" | grep -Fq "$pub"; then log_ok "$title : key already registered" return 0 fi body="$(printf '{"title":"%s","key":"%s"}' "$title" "$pub")" if [[ "$WHAT_IF" == '1' ]]; then log_step "WhatIf: POST $base/api/v1/user/keys ($title)" return 0 fi curl -fsS -X POST -H "Authorization: Basic $auth" -H 'Content-Type: application/json' \ -d "$body" "$base/api/v1/user/keys" >/dev/null log_ok "$title : registered" } for profile in "${!PROFILE_GITEA[@]}"; do gitea_config="${PROFILE_GITEA[$profile]}" [[ -z "$gitea_config" ]] && continue key_name="${PROFILE_KEYNAME[$profile]}" [[ -z "$key_name" || -n "${REGISTERED[$key_name]:-}" ]] && continue REGISTERED["$key_name"]=1 gitea_path="$CONFIG_DIR/$gitea_config" pub_path="$SSH_DIR/$key_name.pub" if [[ ! -f "$gitea_path" ]]; then log_warn "Gitea config not found: $gitea_path" continue fi if [[ ! -f "$pub_path" ]]; then log_warn "Public key not found: $pub_path (run setup-git-ssh.sh first)" continue fi title="$MACHINE-$key_name" log_step "Registering $key_name" register_gitea_key "$gitea_path" "$pub_path" "$title" done log_ok 'Gitea SSH key registration done'