Files
huntingclubroster/tests/runtime_privileges.php
T

18 lines
1.6 KiB
PHP
Raw Normal View History

<?php
if(PHP_SAPI!=='cli')exit;
require __DIR__.'/../classes/Base.php';
$settings=(new Base())->getSettings();$name=(string)$settings->DatabaseName;
if(!preg_match('/\Ahcr_http_test_[a-f0-9]{12}\z/',$name))throw new RuntimeException('Disposable database required.');
$db=(new Base())->connect();$account='hcr_check_'.bin2hex(random_bytes(6));$password=bin2hex(random_bytes(24));$identity=$db->quote($account)."@'%'";
$db->exec('CREATE USER '.$identity.' IDENTIFIED BY '.$db->quote($password));
try{
$sql=file_get_contents(__DIR__.'/../deploy/runtime-grants.sql.example');$sql=preg_replace('/^--.*$/m','',$sql);$sql=str_replace(['huntingclubroster',"'hcr_runtime'@'app-host.example'"],[$name,$identity],$sql);
foreach(explode(';',$sql) as $statement)if(trim($statement))$db->exec($statement);
$limited=new PDO('mysql:host='.$settings->DatabaseServer.';port='.(int)$settings->DatabasePort.';dbname='.$name,$account,$password,[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION]);
$limited->beginTransaction();Audit::required($limited,1,'runtime privilege verification');$limited->commit();$checks=1;
foreach(['DELETE FROM journal','UPDATE club_payments SET amount_cents=amount_cents','DELETE FROM club_dues','ALTER TABLE clubs ADD COLUMN forbidden INT'] as $statement){
try{$limited->exec($statement);throw new RuntimeException('A forbidden runtime operation was allowed.');}catch(PDOException $e){if(!in_array((int)($e->errorInfo[1]??0),[1142,1143],true))throw $e;$checks++;}
}
echo "$checks runtime privilege checks passed: audit inserts work; history deletion, payment edits, and schema changes are denied.\n";
}finally{$db->exec('DROP USER '.$identity);}