75 lines
2.8 KiB
PowerShell
75 lines
2.8 KiB
PowerShell
[CmdletBinding()]
|
|
param(
|
|
[string]$TailnetHost = '100.116.83.60',
|
|
[ValidateRange(1, 65535)]
|
|
[int]$SshPort = 22
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$root = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path
|
|
$configuration = @{}
|
|
Get-Content (Join-Path $root '.env') | ForEach-Object {
|
|
if ($_ -match '^([A-Z0-9_]+)=(.*)$') {
|
|
$configuration[$matches[1]] = $matches[2].Trim('"')
|
|
}
|
|
}
|
|
$sshUser = [string]$configuration.DSM_SSH_USER
|
|
if ([string]::IsNullOrWhiteSpace($sshUser)) { throw 'DSM_SSH_USER is unavailable.' }
|
|
|
|
$databaseTemp = [IO.Path]::GetTempFileName()
|
|
try {
|
|
$encoded = & ssh `
|
|
-o BatchMode=yes `
|
|
-o ConnectTimeout=8 `
|
|
-p $SshPort `
|
|
"$sshUser@$TailnetHost" `
|
|
'docker exec d3ro_voice_api base64 -w 0 /app/data/d3ro_api.db'
|
|
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($encoded)) {
|
|
throw 'Unable to read the API database for aggregate audit.'
|
|
}
|
|
[IO.File]::WriteAllBytes($databaseTemp, [Convert]::FromBase64String($encoded))
|
|
|
|
$python = @'
|
|
import json
|
|
import sqlite3
|
|
import sys
|
|
|
|
path = sys.argv[1]
|
|
connection = sqlite3.connect(f"file:{path}?mode=ro", uri=True)
|
|
tables = [row[0] for row in connection.execute(
|
|
"select name from sqlite_master where type='table' order by name"
|
|
)]
|
|
result = {"tables": tables}
|
|
for table in tables:
|
|
if "stt" not in table.lower() and "endpoint" not in table.lower():
|
|
continue
|
|
columns = [row[1] for row in connection.execute(f'pragma table_info("{table}")')]
|
|
row = {
|
|
"columns": columns,
|
|
"total": connection.execute(f'select count(*) from "{table}"').fetchone()[0],
|
|
}
|
|
key_column = next((name for name in columns if name.lower() in ("apikey", "api_key")), None)
|
|
enabled_column = next((name for name in columns if name.lower() in ("isenabled", "is_enabled", "enabled")), None)
|
|
if key_column:
|
|
row["configured_keys"] = connection.execute(
|
|
f'select count(*) from "{table}" where length(trim(coalesce("{key_column}", \'\'))) > 0'
|
|
).fetchone()[0]
|
|
if enabled_column:
|
|
row["enabled_rows"] = connection.execute(
|
|
f'select count(*) from "{table}" where "{enabled_column}" = 1'
|
|
).fetchone()[0]
|
|
result[table] = row
|
|
print(json.dumps(result, sort_keys=True))
|
|
connection.close()
|
|
'@
|
|
& python -c $python $databaseTemp
|
|
if ($LASTEXITCODE -ne 0) { throw 'SQLite aggregate audit failed.' }
|
|
} finally {
|
|
$encoded = $null
|
|
$resolvedTemp = [IO.Path]::GetFullPath($databaseTemp)
|
|
$tempRoot = [IO.Path]::GetFullPath([IO.Path]::GetTempPath())
|
|
if (-not $resolvedTemp.StartsWith($tempRoot, [StringComparison]::OrdinalIgnoreCase)) {
|
|
throw 'Refusing to delete a temporary database outside the system temp directory.'
|
|
}
|
|
if ([IO.File]::Exists($resolvedTemp)) { [IO.File]::Delete($resolvedTemp) }
|
|
}
|