Files
Rules/scripts/Register-GiteaSshKeys.ps1
T
PapaTramp bdf405e2c1 Добавить bootstrap для новых ПК и Linux-скрипты.
SSH-ключи и Gitea API до clone Rules; init-cursor копирует из локального $HOME/CursorRules.
2026-06-18 10:01:11 +10:00

137 lines
4.2 KiB
PowerShell

#Requires -Version 5.1
<#
.SYNOPSIS
Регистрирует публичные SSH-ключи в Gitea через API (kalinamall, papatramp).
#>
[CmdletBinding()]
param(
[string]$ConfigDir = "$HOME\CursorRules\local",
[string]$HostsConfig = '',
[switch]$WhatIf
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
function Write-Step([string]$Message) { Write-Host "[*] $Message" -ForegroundColor Cyan }
function Write-Ok([string]$Message) { Write-Host "[+] $Message" -ForegroundColor Green }
function Write-Warn([string]$Message) { Write-Host "[!] $Message" -ForegroundColor Yellow }
function Read-KeyValueFile {
param([string]$Path)
$data = @{}
Get-Content -LiteralPath $Path | ForEach-Object {
if ($_ -match '^([^#=]+)=(.*)$') {
$data[$Matches[1].Trim()] = $Matches[2].Trim()
}
}
return $data
}
function Read-GitSshHostsConfig {
param([string]$Path)
$profiles = @{}
$currentProfile = $null
Get-Content -LiteralPath $Path | ForEach-Object {
$line = $_.Trim()
if (-not $line -or $line.StartsWith('#')) { return }
if ($line -match '^\[profile:(.+)\]$') {
$currentProfile = $Matches[1]
$profiles[$currentProfile] = @{}
return
}
if ($line -match '^\[host:') { $currentProfile = $null; return }
if ($line -match '^([^=]+)=(.*)$' -and $currentProfile) {
$profiles[$currentProfile][$Matches[1].Trim()] = $Matches[2].Trim()
}
}
return $profiles
}
function Get-GiteaAuthHeader {
param([hashtable]$Cfg)
$pair = '{0}:{1}' -f $Cfg.GiteaApiUser, $Cfg.GiteaApiPassword
$auth = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($pair))
return @{ Authorization = $auth; 'Content-Type' = 'application/json' }
}
function Register-GiteaKey {
param(
[hashtable]$Cfg,
[string]$PublicKeyPath,
[string]$Title
)
if (-not $Cfg.GiteaApiPassword) {
Write-Warn "$Title : GiteaApiPassword empty - add key manually in Gitea UI"
Write-Host (Get-Content -LiteralPath $PublicKeyPath -Raw).Trim()
return
}
$base = $Cfg.GiteaApiUrl.TrimEnd('/')
$headers = Get-GiteaAuthHeader -Cfg $Cfg
$pub = (Get-Content -LiteralPath $PublicKeyPath -Raw).Trim()
$existing = Invoke-RestMethod -Method Get -Uri "$base/api/v1/user/keys" -Headers $headers -TimeoutSec 15
foreach ($item in @($existing)) {
if ($item.key.Trim() -eq $pub) {
Write-Ok "$Title : key already registered ($($item.title))"
return
}
}
$body = (@{ title = $Title; key = $pub } | ConvertTo-Json)
if ($WhatIf) {
Write-Step "WhatIf: POST $base/api/v1/user/keys ($Title)"
return
}
$created = Invoke-RestMethod -Method Post -Uri "$base/api/v1/user/keys" -Headers $headers -Body $body -TimeoutSec 30
Write-Ok "$Title : registered ($($created.title))"
}
if (-not $HostsConfig) {
$HostsConfig = Join-Path $ConfigDir 'git-ssh-hosts.conf'
}
if (-not (Test-Path -LiteralPath $HostsConfig)) {
throw "Config not found: $HostsConfig"
}
$profiles = Read-GitSshHostsConfig -Path $HostsConfig
$sshDir = Join-Path $HOME '.ssh'
$machine = $env:COMPUTERNAME
if (-not $machine) { $machine = [Environment]::MachineName }
$registered = @{}
foreach ($profileName in $profiles.Keys) {
$profile = $profiles[$profileName]
$giteaConfigName = $profile.GiteaConfig
if (-not $giteaConfigName) { continue }
$keyName = $profile.KeyName
if ($registered.ContainsKey($keyName)) { continue }
$registered[$keyName] = $true
$giteaPath = Join-Path $ConfigDir $giteaConfigName
if (-not (Test-Path -LiteralPath $giteaPath)) {
Write-Warn "Gitea config not found: $giteaPath"
continue
}
$cfg = Read-KeyValueFile -Path $giteaPath
$pubPath = Join-Path $sshDir "$keyName.pub"
if (-not (Test-Path -LiteralPath $pubPath)) {
Write-Warn "Public key not found: $pubPath (run Setup-GitSsh first)"
continue
}
$title = "$machine-$keyName"
Write-Step "Registering $keyName on $($cfg.GiteaHost)"
Register-GiteaKey -Cfg $cfg -PublicKeyPath $pubPath -Title $title
}
Write-Ok 'Gitea SSH key registration done'