Files
SGF/scripts/sgf-remaining-access.php
T
2026-11-11 09:00:17 +02:00

8 lines
3.7 KiB
PHP

<?php
$book=$argv[1]??'regression';require __DIR__.'/sgf-single-bootstrap.php';$p=json_decode(file_get_contents($repo.'/docs/integration/sgf-remaining-functions-access-proposal.json'),true);if(($p['approved']??false)!==true||($p['scope']??null)!==$f['scope'])throw new LogicException('Explicit scope approval required');$profiles=json_decode(file_get_contents($s['root'].'/single-profiles.json'),true)['profiles'];$resolve=fn($key)=>$key==='purchasing:validator'?$f['validator']:($profiles[$key]['user_id']??throw new LogicException('Unknown approved profile'));
$rights=array_column($p['new_host_rights'],'permission');$before=$host->table('a_clients')->orderBy('id')->get()->toJson();
$host->transaction(function()use($host,$p,$rights,$resolve){$old=$host->selectOne("SELECT pg_get_constraintdef(oid) value FROM pg_constraint WHERE conrelid='permission_grants'::regclass AND conname='permission_grants_scope_check'")->value;if(!str_contains($old,'commercial_quotes.view')){if(!preg_match('/^CHECK \((.*)\)$/s',$old,$m))throw new LogicException('Unknown grant constraint');$quoted=implode(',',array_map(fn($r)=>"'".$r."'",$rights));$host->statement('ALTER TABLE permission_grants DROP CONSTRAINT permission_grants_scope_check');$host->statement('ALTER TABLE permission_grants ADD CONSTRAINT permission_grants_scope_check CHECK (('.$m[1].') OR (unit_id IS NOT NULL AND permission IN ('.$quoted.')))');}
foreach([...$p['new_host_rights'],...$p['additional_existing_host_rights']] as $grant)foreach($grant['profiles'] as $profile){$id=$resolve($profile);if(!$host->table('company_memberships')->where(['user_id'=>$id,'tenant_id'=>1,'company_id'=>2])->exists())throw new LogicException('Preserve unknown membership');$value=$p['scope']+['user_id'=>$id,'permission'=>$grant['permission']];if($host->table('permission_grants')->where($value)->exists())continue;$host->table('permission_grants')->insert($value);App\Modules\Identity\Services\Audit::record('access.granted_on_creation',null,1,2,2,$id,['permission'=>$grant['permission'],'reason'=>$p['authorization']]);}});
$native->transaction(function()use($native,$p,$tag){if(!$native->table('organization_access')->where(['tenant_id'=>1,'active'=>true])->exists())throw new LogicException('Existing approved native profile mode required');foreach($p['existing_native_functions_to_grant_only_in_qa'] as $grant){$profile=$native->table('organization_profiles')->where(['tenant_id'=>1,'name'=>'SGF-STOCK-FINAL-QA-'.$tag.'-'.$grant['native_user_id']])->lockForUpdate()->first();if(!$profile)throw new LogicException('Only existing QA profile may be extended');$old=json_decode($profile->permissions,true);$new=array_values(array_unique([...$old,...$grant['functions']]));if($new===$old)continue;$native->table('organization_profiles')->where('id',$profile->id)->update(['permissions'=>json_encode($new),'version'=>$profile->version+1,'updated_at'=>now()]);$native->table('audit_logs')->insert(['tenant_id'=>1,'user_id'=>$grant['native_user_id'],'action'=>'sgf.remaining.qa_access','before'=>json_encode(['profile_id'=>$profile->id,'functions'=>$old]),'after'=>json_encode(['functions'=>$new,'approval'=>$p['authorization']]),'created_at'=>now()]);}});
if($before!==$host->table('a_clients')->orderBy('id')->get()->toJson())throw new LogicException('Client preservation failed');file_put_contents($work.'/remaining-access-result.json',json_encode(['passed'=>true,'book'=>$book,'new_right_names'=>15,'approved_existing_issue_right'=>true,'native_function_grants'=>8,'new_users'=>0,'new_profiles'=>0,'new_pg_roles'=>0,'public_grants'=>0,'business_commands'=>0,'client_records_unchanged'=>true],JSON_PRETTY_PRINT));echo json_encode(['passed'=>true,'book'=>$book,'proof'=>$work.'/remaining-access-result.json']).PHP_EOL;