'app/','Laravel\\Fortify\\'=>'fortify/']as$prefix=>$directory){ if(!str_starts_with($class,$prefix))continue; $tail=substr($class,strlen($prefix));abort_unless(preg_match('/^[A-Za-z0-9_\\\\]+$/D',$tail),503); $relative=$directory.str_replace('\\','/',$tail).'.php';$pin=$files[$relative]??null;$file=realpath($bundle.'/'.$relative);$base=realpath($bundle); abort_unless(is_string($pin)&&preg_match('/^[a-f0-9]{64}$/D',$pin)&&$base&&$file&&str_starts_with(strtolower($file),strtolower($base.DIRECTORY_SEPARATOR))&&!is_link($bundle.'/'.$relative)&&hash_equals($pin,hash_file('sha256',$file)),503,'Dependência do pacote incompatível.'); require_once $file;return; } } public function run(string $right,\Closure $work):mixed { abort_unless(config('receipt_qa.enabled')===true,404); if(str_starts_with($right,'general_ledger.'))abort_unless(config('sgf_single_installation.enabled')===true&&config('sgf_single_installation.ledger_enabled')===true,404); if(str_starts_with($right,'supplier_payables.'))abort_unless(config('sgf_single_installation.enabled')===true&&config('sgf_single_installation.finance_enabled')===true,404); if(str_starts_with($right,'stock.')){ abort_unless(config('stock_operations.enabled')===true,404); $allowed=['stock.view','stock.operations.prepare','stock.operations.confirm']; if(config('stock_operations.final_enabled')===true)$allowed=[...$allowed,'stock.transfers.receive','stock.lots.review']; if(config('stock_catalogue.enabled')===true)$allowed=[...$allowed,'stock.items.prepare','stock.items.review']; if(config('stock_completion.enabled')===true)$allowed=[...$allowed,'stock.planning.view','stock.planning.prepare','stock.planning.review','stock.disposition.view','stock.disposition.prepare','stock.disposition.review']; abort_unless(in_array($right,$allowed,true),403); } if(str_starts_with($right,'purchasing_obligations.'))abort_unless(config('receipt_qa.obligations_enabled')===true,404); if(str_starts_with($right,'purchasing_invoices.'))abort_unless(config('receipt_qa.invoices_enabled')===true,404); if(str_starts_with($right,'purchasing_requests.'))abort_unless(config('receipt_qa.requests_enabled')===true,404); if(str_starts_with($right,'purchasing_orders.'))abort_unless(config('receipt_qa.orders_enabled')===true,404); if(str_starts_with($right,'purchasing_suppliers.'))abort_unless(config('receipt_qa.suppliers_enabled')===true,404); if(str_starts_with($right,'purchasing_sourcing.'))abort_unless(config('receipt_qa.sourcing_enabled')===true,404); abort_unless(app()->environment('budget-testing'),403); BudgetAdapter::guard(); $host=DB::connection();$db=$host->getDatabaseName();$role=$host->getConfig('username'); abort_unless(preg_match('/^budget_core_sgf_([a-f0-9]{12})$/D',$db,$m)&&$role==='ir_composition_'.$m[1],403); $run=(string)getenv('SGF_ISOLATED_REGRESSION_RUN'); $hostConfig=$host->getConfig();abort_unless(preg_match('/^[a-f0-9]{12}$/D',$run)&&($hostConfig['host']??null)==='127.0.0.1'&&(int)($hostConfig['port']??0)===55439&&empty($hostConfig['read'])&&empty($hostConfig['write'])&&($hostConfig['search_path']??'public')==='public',403); $identity=$host->selectOne("SELECT current_user role,current_setting('cluster_name') cluster,rolsuper OR rolcreatedb OR rolcreaterole OR rolreplication OR rolbypassrls elevated FROM pg_roles WHERE rolname=current_user"); abort_unless(!$identity->elevated&&$identity->role===$role&&$identity->cluster==='sgf_modular_regression_'.$run,403); $expected='C:/laragon/data/sgf-tempo/run/modular-regression-'.$run.'/private/receipt-composition-'.$m[1]; $profile=realpath((string)config('receipt_qa.profile')); abort_unless($profile&&strtolower(str_replace('\\','/',$profile))===strtolower($expected.'/binding.json'),403); $p=json_decode(file_get_contents($profile),true,64,JSON_THROW_ON_ERROR); $ctx=app(CompanyContext::class);$scope=$ctx->identifiers()+['unit_id'=>$ctx->unitId()];$user=$ctx->userId(); abort_unless($scope['unit_id']&&request()->user()->id===$user,403); $key=implode(':',array_values($scope)).':'.$user;$binding=$p['bindings'][$key]??null; if(config('sgf_single_installation.enabled')===true&&config('sgf_single_installation.bindings_sha256')!==null){ $file=$expected.'/single-bindings.json';$pin=config('sgf_single_installation.bindings_sha256'); abort_unless(is_string($pin)&&preg_match('/^[a-f0-9]{64}$/D',$pin)&&is_file($file)&&!is_link($file)&&hash_equals($pin,hash_file('sha256',$file)),503); $additional=json_decode(file_get_contents($file),true,32,JSON_THROW_ON_ERROR); abort_unless(($additional['composition']??null)===$m[1],403); if(isset($additional['bindings'][$key]))$binding=$additional['bindings'][$key]; } abort_unless($binding,403,'Origem de recepção não autorizada neste contexto.'); // A Stock-specific map is explicit and pinned; it cannot change purchasing bindings. if(str_starts_with($right,'stock.')&&config('stock_operations.profile_sha256')!==null){ $mapFile=$expected.'/stock-operations-binding.json';$pin=config('stock_operations.profile_sha256'); abort_unless(is_string($pin)&&preg_match('/^[a-f0-9]{64}$/D',$pin)&&is_file($mapFile)&&!is_link($mapFile)&&hash_equals($pin,hash_file('sha256',$mapFile)),503); $map=json_decode(file_get_contents($mapFile),true,32,JSON_THROW_ON_ERROR);$warehouses=$map['warehouse_bindings'][$key]??null; abort_unless(($map['composition']??null)===$m[1]&&is_array($warehouses)&&count($warehouses)>0&&count($warehouses)<=1000&&!array_filter($warehouses,fn($id)=>!is_int($id)||$id<1),403); $binding['warehouse_ids']=$warehouses;$binding['stock_profile_sha256']=$pin; } if(config('receipt_qa.obligations_enabled')===true)abort_unless(($binding['payable_instance']??null)==='qa-stock-ledger-'.$m[1]&&config('common-payables.source_instance')===$binding['payable_instance']&&config('common-payables.history_enabled')===false&&config('common-payables.history_decisions_enabled')===false,403); $p['context_key']=$key; $bundle=realpath($expected.'/bundle');$manifest=$bundle.'/manifest.json'; abort_unless($bundle&&hash_equals($p['manifest_sha256'],hash_file('sha256',$manifest)),503); $files=json_decode(file_get_contents($manifest),true,64,JSON_THROW_ON_ERROR)['files']; foreach($files as$file=>$pin)abort_unless(preg_match('~^(app|fortify)/[A-Za-z0-9_/]+\.php$~D',$file)&&!str_contains($file,'..')&&is_string($pin)&&preg_match('/^[a-f0-9]{64}$/D',$pin),503); if(config('receipt_qa.orders_enabled')===true||config('receipt_qa.sourcing_enabled')===true){ $economic=$expected.'/economic';abort_unless(isset($p['economic_manifest_sha256'])&&is_file($economic.'/manifest.json')&&hash_equals($p['economic_manifest_sha256'],hash_file('sha256',$economic.'/manifest.json')),503); $economicFiles=json_decode(file_get_contents($economic.'/manifest.json'),true,32,JSON_THROW_ON_ERROR)['files'];$names=array_keys($economicFiles);sort($names);abort_unless($names===['ProposalScoring.php','QuotationPricing.php'],503); foreach($economicFiles as$file=>$pin){abort_unless(is_file($economic.'/'.$file)&&!is_link($economic.'/'.$file)&&hash_equals($pin,hash_file('sha256',$economic.'/'.$file)),503);$class='Tempo\\Purchasing\\Economic\\'.basename($file,'.php');if(class_exists($class,false)){abort_unless(hash_equals($pin,hash_file('sha256',(new \ReflectionClass($class))->getFileName())),503);}else require_once $economic.'/'.$file;} } if(config('receipt_qa.requests_enabled')===true){ $internal=$expected.'/internal';abort_unless(isset($p['internal_manifest_sha256'])&&hash_equals($p['internal_manifest_sha256'],hash_file('sha256',$internal.'/manifest.json')),503);$pins=json_decode(file_get_contents($internal.'/manifest.json'),true,32,JSON_THROW_ON_ERROR)['files'];$names=array_keys($pins);sort($names);abort_unless($names===['InternalRequisitions.php','RequisitionFailure.php','RequisitionPort.php'],503);foreach(['RequisitionPort.php','RequisitionFailure.php','InternalRequisitions.php']as$file){$pin=$pins[$file];abort_unless(preg_match('/^[a-f0-9]{64}$/D',$pin)&&!is_link($internal.'/'.$file)&&hash_equals($pin,hash_file('sha256',$internal.'/'.$file)),503);$class='Tempo\\Purchasing\\Internal\\'.basename($file,'.php');if(class_exists($class,false)||interface_exists($class,false)){abort_unless(hash_equals($pin,hash_file('sha256',(new \ReflectionClass($class))->getFileName())),503);}else require_once $internal.'/'.$file;} } if(!isset(self::$loaded[$bundle])){ abort_unless(self::$loaded===[],503,'Uma só versão do workflow por processo.'); spl_autoload_register(fn($class)=>self::loadClass($class,$bundle,$files)); Gate::policy(\Tempo\Purchasing\Embedded\Models\GoodsReceipt::class,\Tempo\Purchasing\Embedded\Policies\GoodsReceiptPolicy::class);Gate::policy(\Tempo\Purchasing\Embedded\Models\Supplier::class,\Tempo\Purchasing\Embedded\Policies\SupplierPolicy::class);self::$loaded[$bundle]=true; app()->singleton(\Tempo\Purchasing\Embedded\Services\ReplenishmentRun::class); } $connection=$p['connection'];abort_unless(($connection['driver']??null)==='pgsql'&&($connection['host']??null)==='127.0.0.1'&&(int)($connection['port']??0)===55439 &&($connection['database']??null)==='compras_receipts_test_'.$m[1]&&($connection['username']??null)==='payable_history_native_'.$m[1] &&empty($connection['url'])&&empty($connection['read'])&&empty($connection['write'])&&($connection['search_path']??null)==='public',403); config(['database.connections.receipt_native'=>$connection]);$native=DB::connection('receipt_native'); $i=$native->selectOne("SELECT current_user role,current_database() db,current_setting('cluster_name') cluster,rolsuper OR rolcreatedb OR rolcreaterole OR rolreplication OR rolbypassrls elevated FROM pg_roles WHERE rolname=current_user"); abort_unless(!$i->elevated&&$i->role===$connection['username']&&$i->db===$connection['database']&&$i->cluster==='sgf_modular_regression_'.$run,403); return $host->transaction(function()use($host,$scope,$user,$right,$binding,$work,$p,$native){ if(str_starts_with($right,'stock.')){$host->statement("SET LOCAL lock_timeout='5s'");$host->statement("SET LOCAL statement_timeout='15s'");} // Hold existing authority until the native transaction ends; no host business writes. abort_unless($host->table('users')->where('id',$user)->lockForUpdate()->first(),403); abort_unless($host->table('company_memberships')->where(['user_id'=>$user,'tenant_id'=>$scope['tenant_id'],'company_id'=>$scope['company_id']])->lockForUpdate()->first(),403); $view=str_starts_with($right,'purchasing_invoices.')?'purchasing_invoices.view':(str_starts_with($right,'purchasing_requests.')?'purchasing_requests.view':(str_starts_with($right,'purchasing_suppliers.')?'purchasing_suppliers.view':(str_starts_with($right,'purchasing_sourcing.')?'purchasing_sourcing.view':(str_starts_with($right,'purchasing_orders.')?'purchasing_orders.view':'purchasing_receipts.view')))); if(str_starts_with($right,'purchasing_obligations.'))$view='purchasing_obligations.view'; if(str_starts_with($right,'stock.'))$view='stock.view'; if(str_starts_with($right,'general_ledger.'))$view='general_ledger.view'; if(str_starts_with($right,'supplier_payables.'))$view='supplier_payables.view'; foreach(['company.view'=>null,'unit.view'=>$scope['unit_id'],$view=>$scope['unit_id'],$right=>$scope['unit_id']]as$permission=>$unit) abort_unless($host->table('permission_grants')->where(['user_id'=>$user,'tenant_id'=>$scope['tenant_id'],'company_id'=>$scope['company_id'],'unit_id'=>$unit,'permission'=>$permission])->lockForUpdate()->first(),403); $default=DB::getDefaultConnection();$guard=Auth::getDefaultDriver();$environment=app()->environment(); config(['auth.guards.receipt_native'=>['driver'=>'session','provider'=>'receipt_native'],'auth.providers.receipt_native'=>['driver'=>'eloquent','model'=>\Tempo\Purchasing\Embedded\Models\User::class]]); DB::setDefaultConnection('receipt_native');Schema::clearResolvedInstance('db.schema');Auth::shouldUse('receipt_native');app()->instance('env','testing'); try{ $actor=\Tempo\Purchasing\Embedded\Models\User::where('tenant_id',$binding['tenant_id'])->findOrFail($binding['actor_id']);Auth::guard('receipt_native')->setUser($actor); return $native->transaction(function()use($native,$actor,$binding,$work,$p,$right){ if(str_starts_with($right,'stock.')){$native->statement("SET LOCAL lock_timeout='5s'");$native->statement("SET LOCAL statement_timeout='15s'");} $native->table('tenants')->where('id',$actor->tenant_id)->lockForUpdate()->firstOrFail(); $version=[$p['context_key'],$binding,$p['manifest_sha256']];$origin=['sgf_context_key'=>$p['context_key'],'workflow_manifest'=>$p['manifest_sha256']]; if(isset($p['internal_manifest_sha256'])){$version[]=$p['internal_manifest_sha256'];$origin['internal_manifest']=$p['internal_manifest_sha256'];} if(isset($p['economic_manifest_sha256'])){$version[]=$p['economic_manifest_sha256'];$origin['economic_manifest']=$p['economic_manifest_sha256'];} return $work($actor,$binding,hash('sha256',json_encode($version,JSON_THROW_ON_ERROR)),$origin); }); }finally{Auth::forgetGuards();Auth::shouldUse($guard);DB::setDefaultConnection($default);Schema::clearResolvedInstance('db.schema');app()->instance('env',$environment);} }); } }