51 lines
2.6 KiB
PHP
51 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Illuminate\Support\Facades\DB;
|
|
use Tempo\Finance\Composition\Bundle;
|
|
|
|
/** Trust anchor in the host. No executable artifact is loaded before its pinned hashes. */
|
|
final class FinanceBundle
|
|
{
|
|
public static function configure(): void
|
|
{
|
|
$root = config('common-finance-bundle.root');
|
|
if ($root === null) {
|
|
return;
|
|
}
|
|
$pin = config('common-finance-bundle.manifest_sha256');
|
|
if (! app()->environment(['testing', 'payable-testing']) || ! is_string($root) || ! is_string($pin) || ! preg_match('/^[a-f0-9]{64}$/D', $pin)) {
|
|
throw new \LogicException('FINANCE_BUNDLE_QA_ONLY');
|
|
}
|
|
$db = DB::connection();
|
|
$r = $db->selectOne("SELECT current_database() d,current_user u,inet_server_port() p,current_setting('cluster_name') c");
|
|
if ($db->getConfig('host') !== '127.0.0.1' || (int) $r->p !== 55439 || ! preg_match('/^compras_receipts_test_([a-f0-9]{12})$/D', $r->d, $m) || $r->u !== 'payable_history_native_'.$m[1] || ! preg_match('/^sgf_modular_regression_[a-f0-9]{12}$/D', $r->c)) {
|
|
throw new \LogicException('FINANCE_BUNDLE_DATABASE_REFUSED');
|
|
}
|
|
if ($db->selectOne('SELECT rolsuper OR rolcreatedb OR rolcreaterole OR rolreplication OR rolbypassrls elevated FROM pg_roles WHERE rolname=current_user')->elevated) {
|
|
throw new \LogicException('FINANCE_BUNDLE_ELEVATED_ROLE');
|
|
}
|
|
$root = realpath($root) ?: throw new \LogicException('FINANCE_BUNDLE_MISSING');
|
|
$manifest = $root.'/manifest.json';
|
|
$bytes = is_file($manifest) && ! is_link($manifest) ? file_get_contents($manifest) : false;
|
|
if (! is_string($bytes) || ! hash_equals($pin, hash('sha256', $bytes))) {
|
|
throw new \LogicException('FINANCE_BUNDLE_MANIFEST_MISMATCH');
|
|
}
|
|
$m = json_decode($bytes, true, 64, JSON_THROW_ON_ERROR);
|
|
$loader = null;
|
|
foreach ($m['files'] ?? [] as $f) {
|
|
if (($f['file'] ?? null) === 'Bundle.php') {
|
|
$loader = $f['sha256'] ?? null;
|
|
}
|
|
}
|
|
$loaderHash = is_file($root.'/Bundle.php') && ! is_link($root.'/Bundle.php') ? hash_file('sha256', $root.'/Bundle.php') : false;
|
|
if (! is_string($loader) || ! is_string($loaderHash) || ! hash_equals($loader, $loaderHash)) {
|
|
throw new \LogicException('FINANCE_BUNDLE_LOADER_MISMATCH');
|
|
}
|
|
require_once $root.'/Bundle.php';
|
|
$paths = Bundle::verify($root, $pin);
|
|
config(['common-payables.path' => $paths['payables'], 'general-ledger.path' => $paths['ledger']]);
|
|
}
|
|
}
|