Files
compras/tests/Support/sgf-corrected-export.php
2026-11-02 20:27:11 +02:00

50 lines
3.0 KiB
PHP

<?php
// Source inspection and schema-only export. Never exports rows or changes source privileges.
use Illuminate\Contracts\Console\Kernel;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\DB;
use Symfony\Component\Process\Process;
$host = getenv('FIX_SOURCE_HOST');
$output = getenv('FIX_SCHEMA_FILE');
require $host.'/vendor/autoload.php';
$app = require $host.'/bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
try {
$db = DB::connection();
$db->beginTransaction();
$db->statement('SET TRANSACTION READ ONLY');
$tables = array_column($db->select("select tablename from pg_tables where schemaname='public' order by tablename"), 'tablename');
$acl = [];
foreach ($tables as $table) {
$rights = [];
foreach (['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'REFERENCES', 'TRIGGER', 'TRUNCATE'] as $right) {
if ($db->selectOne('select has_table_privilege(current_user,?,?) as allowed', ['public.'.$table, $right])->allowed) {
$rights[] = $right;
}
}$acl[$table] = $rights;
}
$fingerprints = [];
foreach (['permission_grants', 'company_memberships', 'identity_audit'] as $table) {
$rows = $db->select('select to_jsonb(t)::text as value from "'.$table.'" t order by to_jsonb(t)::text');
$fingerprints[$table] = hash('sha256', json_encode(array_column($rows, 'value'), JSON_THROW_ON_ERROR));
}
$functions = $db->select("select p.oid::regprocedure::text as identity from pg_proc p join pg_namespace n on n.oid=p.pronamespace where n.nspname='public' and has_function_privilege(current_user,p.oid,'EXECUTE') order by 1");
$config = $db->getConfig();
$db->rollBack();
if (getenv('FIX_CHECK_ONLY') === '1') {
echo json_encode(['source_security_fingerprints' => $fingerprints, 'tables' => $tables, 'database' => $config['database'], 'read_only' => true], JSON_THROW_ON_ERROR);
exit(0);
}
$dump = new Process(['C:/Program Files/PostgreSQL/17/bin/pg_dump.exe', '--schema-only', '--format=custom', '--no-owner', '--no-privileges', '--no-comments', '--file='.$output, '--dbname='.$config['database']], null,
['PGHOST' => $config['host'], 'PGPORT' => (string) $config['port'], 'PGUSER' => $config['username'], 'PGPASSWORD' => $config['password'], 'PGOPTIONS' => '-c default_transaction_read_only=on'], null, 60);
$dump->mustRun();
echo json_encode(['database' => $config['database'], 'tables' => $tables, 'runtime_table_acl' => $acl, 'runtime_functions' => array_column($functions, 'identity'), 'source_security_fingerprints' => $fingerprints, 'schema_sha256' => hash_file('sha256', $output), 'rows_exported' => 0, 'read_only' => true], JSON_THROW_ON_ERROR);
} catch (Throwable $error) {
if (isset($db) && $db->transactionLevel() > 0) {
$db->rollBack();
}fwrite(STDERR, 'Schema-only export failed: '.get_class($error).($error instanceof QueryException ? ' SQLSTATE '.($error->errorInfo[0] ?? '').'; '.$error->getSql() : '')."\n");
exit(1);
}