2cddf06b6c
Co-authored-by: 旅行呀~ <travelxiao@qq.com>
113 lines
3.1 KiB
PowerShell
113 lines
3.1 KiB
PowerShell
# Agent-safe: decrypt the local token and feed it to Git Credential Manager.
|
|
# Never prints the token. Never writes it to a file.
|
|
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$RemoteUrl
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
. (Join-Path $PSScriptRoot 'common.ps1')
|
|
|
|
$gitProfile = Get-GitSkillsProfile
|
|
if ($null -eq $gitProfile) {
|
|
Write-StatusLine -Key 'status' -Value 'failed'
|
|
Write-StatusLine -Key 'reason' -Value 'profile_missing'
|
|
exit 1
|
|
}
|
|
|
|
$username = ([string]$gitProfile.gitUsername).Trim()
|
|
if ([string]::IsNullOrWhiteSpace($username)) {
|
|
Write-StatusLine -Key 'status' -Value 'failed'
|
|
Write-StatusLine -Key 'reason' -Value 'git_username_missing'
|
|
exit 1
|
|
}
|
|
if ($username -match "[\r\n]") {
|
|
Write-StatusLine -Key 'status' -Value 'failed'
|
|
Write-StatusLine -Key 'reason' -Value 'git_username_invalid'
|
|
exit 1
|
|
}
|
|
|
|
if (-not (Test-Path -LiteralPath $script:TokenPath)) {
|
|
Write-StatusLine -Key 'status' -Value 'failed'
|
|
Write-StatusLine -Key 'reason' -Value 'token_missing'
|
|
exit 1
|
|
}
|
|
|
|
$parsed = Parse-GitRemoteUrl -RemoteUrl $RemoteUrl
|
|
$hostName = [string]$parsed.CredentialHost
|
|
if ([string]::IsNullOrWhiteSpace($hostName)) {
|
|
$hostName = [string]$parsed.Host
|
|
}
|
|
if ([string]::IsNullOrWhiteSpace($hostName)) {
|
|
Write-StatusLine -Key 'status' -Value 'failed'
|
|
Write-StatusLine -Key 'reason' -Value 'host_parse_failed'
|
|
exit 1
|
|
}
|
|
|
|
$credProtocol = 'https'
|
|
if ([string]$parsed.Protocol -eq 'http') {
|
|
$credProtocol = 'http'
|
|
}
|
|
|
|
$token = $null
|
|
$payload = $null
|
|
try {
|
|
$data = [System.IO.File]::ReadAllBytes($script:TokenPath)
|
|
$token = Unprotect-SecretBytes -Data $data
|
|
if ([string]::IsNullOrWhiteSpace($token)) {
|
|
Write-StatusLine -Key 'status' -Value 'failed'
|
|
Write-StatusLine -Key 'reason' -Value 'token_invalid'
|
|
exit 1
|
|
}
|
|
|
|
$payload = @"
|
|
protocol=$credProtocol
|
|
host=$hostName
|
|
username=$username
|
|
password=$token
|
|
|
|
"@
|
|
|
|
$psi = New-Object System.Diagnostics.ProcessStartInfo
|
|
$psi.FileName = 'git'
|
|
$psi.Arguments = 'credential approve'
|
|
$psi.UseShellExecute = $false
|
|
$psi.RedirectStandardInput = $true
|
|
$psi.RedirectStandardOutput = $true
|
|
$psi.RedirectStandardError = $true
|
|
$psi.CreateNoWindow = $true
|
|
|
|
$proc = New-Object System.Diagnostics.Process
|
|
$proc.StartInfo = $psi
|
|
[void]$proc.Start()
|
|
foreach ($line in ($payload -split "`r?`n")) {
|
|
$proc.StandardInput.WriteLine($line)
|
|
}
|
|
$proc.StandardInput.Close()
|
|
$null = $proc.StandardOutput.ReadToEnd()
|
|
$null = $proc.StandardError.ReadToEnd()
|
|
$proc.WaitForExit()
|
|
if ($proc.ExitCode -ne 0) {
|
|
Write-StatusLine -Key 'status' -Value 'failed'
|
|
Write-StatusLine -Key 'reason' -Value 'git_credential_approve_failed'
|
|
exit 1
|
|
}
|
|
}
|
|
catch {
|
|
Write-StatusLine -Key 'status' -Value 'failed'
|
|
Write-StatusLine -Key 'reason' -Value 'inject_error'
|
|
exit 1
|
|
}
|
|
finally {
|
|
$token = $null
|
|
$payload = $null
|
|
$data = $null
|
|
}
|
|
|
|
Write-StatusLine -Key 'status' -Value 'injected'
|
|
Write-StatusLine -Key 'host' -Value $hostName
|
|
Write-StatusLine -Key 'protocol' -Value $credProtocol
|
|
Write-StatusLine -Key 'username' -Value $username
|
|
Write-Output 'token=hidden'
|