'wordpress_org_core_checksums', 'components.integrity' => 'wordpress_org_plugin_checksums', 'external.vulnerability_intelligence' => 'wordfence_vulnerability_feed', ); private RunRepository $runs; private FindingRepository $findings; private ExternalOperationRepository $operations; private AuditRegistry $registry; private ExternalFindingBuilder $builder; private TransactionManager $transaction; public function __construct( RunRepository $runs, FindingRepository $findings, ExternalOperationRepository $operations, AuditRegistry $registry, ExternalFindingBuilder $builder, TransactionManager $transaction ) { $this->runs = $runs; $this->findings = $findings; $this->operations = $operations; $this->registry = $registry; $this->builder = $builder; $this->transaction = $transaction; } /** * @param list $data_classes Exact disclosed classes. * @param callable(string):array $operation Receives one UTC timestamp. * @return array{run_uuid:string,status:string,finding:array} */ public function execute( string $check_id, string $language, int $actor_id, string $disclosure_version, array $data_classes, string $payload_fingerprint, callable $operation ): array { if ( ! isset( self::SERVICES[ $check_id ] ) || ! in_array( $language, array( 'en', 'ru' ), true ) || $actor_id < 1 ) { throw new \InvalidArgumentException( 'external_audit_invalid' ); } $service = self::SERVICES[ $check_id ]; $run = null; $operation_uuid = null; try { $run = $this->runs->create( 'external', $language, $this->registry->registry_version(), $this->registry->external_budget_for( $check_id ), $actor_id ); $run = $this->runs->transition( $run->uuid(), RunStatus::PREFLIGHT, $actor_id ); $this->runs->update_coverage( $run->id(), 0, 1 ); $run = $this->runs->transition( $run->uuid(), RunStatus::QUEUED, $actor_id ); $operation_uuid = $this->operations->begin( $run->id(), $service, $disclosure_version, $data_classes, $actor_id, $payload_fingerprint ); $run = $this->runs->transition( $run->uuid(), RunStatus::RUNNING, $actor_id ); $outcome = 'succeeded'; $timestamp = gmdate( DATE_RFC3339 ); try { $finding = $operation( $timestamp ); } catch ( \Throwable $exception ) { $finding = $this->builder->error( $check_id, $service, $timestamp ); $outcome = 'failed'; } if ( 'warning' === $finding['status'] || 'not_tested' === $finding['status'] ) { $outcome = 'partial'; } elseif ( 'error' === $finding['status'] ) { $outcome = 'failed'; } $this->transaction->begin(); $this->findings->save( $run->id(), $finding ); $this->runs->update_coverage( $run->id(), (int) $finding['coverage']['observed'], (int) $finding['coverage']['total'] ); $run = $this->runs->transition( $run->uuid(), RunStatus::COMPLETED, $actor_id ); $this->operations->complete( $operation_uuid, $outcome ); $this->transaction->commit(); } catch ( \Throwable $exception ) { $this->transaction->rollback(); $this->settle_failed_operation( null === $run ? null : $run->uuid(), $operation_uuid, $actor_id ); throw $exception; } return array( 'run_uuid' => $run->uuid(), 'status' => $run->status(), 'finding' => $finding, ); } private function settle_failed_operation( ?string $run_uuid, ?string $operation_uuid, int $actor_id ): void { if ( null !== $operation_uuid ) { try { $this->operations->complete( $operation_uuid, 'failed' ); } catch ( \Throwable $ignored ) { unset( $ignored ); // Best effort after a storage failure; never replace the root cause. } } if ( null === $run_uuid ) { return; } try { $run = $this->runs->get_by_uuid( $run_uuid ); if ( null === $run || in_array( $run->status(), array( RunStatus::FAILED, RunStatus::CANCELLED, RunStatus::COMPLETED ), true ) ) { return; } $target = RunStatus::DRAFT === $run->status() ? RunStatus::CANCELLED : RunStatus::FAILED; $this->runs->transition( $run_uuid, $target, $actor_id ); } catch ( \Throwable $ignored ) { unset( $ignored ); // Best effort after a storage failure; never replace the root cause. } } }