Files
compras/app/Services/SgfInvoiceGateway.php
nala 976271f948
tests / ci (push) Canceled after 0s
commit melhorias1
2026-11-10 12:58:19 +02:00

41 lines
2.9 KiB
PHP

<?php
namespace App\Services;
use App\Models\User;
use Illuminate\Support\Facades\Http;
use LogicException;
/** Prepared gateway only; no event listener, route, scheduled job or automatic transmission. */
final class SgfInvoiceGateway
{
public function clientFor(User $actor,string $connection): \Tempo\SgcInvoiceClient\InvoiceClient
{
if(config('sgf_invoice.enabled')!==true)throw new LogicException('SGF invoice gateway disabled.');
$all=config('sgf_invoice.connections',[]);$c=$all[$connection]??null;
abort_unless(is_array($c)&&($c['enabled']??false)===true&&auth()->id()===$actor->id,403);
$current=User::where('tenant_id',$actor->tenant_id)->findOrFail($actor->id);
abort_unless(($c['source_scope']['tenant_id']??null)===$current->tenant_id&&$current->hasFunctions(['finance'])
&&!app(OrganizationAccess::class)->maintenanceOnly($current),403);
$path=config('sgf_invoice.client_package');$pin=config('sgf_invoice.client_package_sha256');
if(!is_string($path)||is_link($path)||!is_file($path)||!is_string($pin)||!preg_match('/^[a-f0-9]{64}$/D',$pin)
||!hash_equals($pin,hash_file('sha256',$path)))throw new LogicException('Verified client package required.');
if(class_exists(\Tempo\SgcInvoiceClient\InvoiceClient::class,false)){
if(!hash_equals($pin,hash_file('sha256',(new \ReflectionClass(\Tempo\SgcInvoiceClient\InvoiceClient::class))->getFileName())))throw new LogicException('Client version changed; restart separately.');
}else require_once $path;
$configurationHash=hash('sha256',json_encode($c,JSON_THROW_ON_ERROR));
return new \Tempo\SgcInvoiceClient\InvoiceClient($c['client_id'],$c['token'],$c['context_version'],$c['source_scope'],$c['target_scope'],
function(string $method,string $url,array $headers,?array $body)use($actor,$connection,$configurationHash):array{
// Recheck the originating person's authority immediately before every network operation.
$now=config('sgf_invoice.connections',[])[$connection]??null;
if(config('sgf_invoice.enabled')!==true||!is_array($now)||!hash_equals($configurationHash,hash('sha256',json_encode($now,JSON_THROW_ON_ERROR)))
||auth()->id()!==$actor->id)return ['status'=>403,'json'=>null];
$current=User::where('tenant_id',$actor->tenant_id)->find($actor->id);
if(!$current||!$current->hasFunctions(['finance'])||app(OrganizationAccess::class)->maintenanceOnly($current))return ['status'=>403,'json'=>null];
$http=Http::withHeaders($headers)->acceptJson()->asJson()->withoutRedirecting()->connectTimeout(3)->timeout(15);
$response=$method==='GET'?$http->get($url):$http->post($url,$body);
return ['status'=>$response->status(),'json'=>$response->json()];
},$c['origin']);
}
}