62 lines
2.7 KiB
PHP
62 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
final class EditorialRequest extends Command
|
|
{
|
|
protected $signature = 'editorial:request {method} {path} {--payload=} {--image=}';
|
|
|
|
protected $description = 'Call this environment\'s editorial API without exposing the credential';
|
|
|
|
public function handle(): int
|
|
{
|
|
$path = $this->argument('path');
|
|
$method = strtoupper($this->argument('method'));
|
|
if (! preg_match('~\A[a-zA-Z0-9_/-]+\z~', $path) || str_contains($path, '..') || ! in_array($method, ['GET', 'POST'])) {
|
|
$this->error('Invalid API operation.');
|
|
|
|
return 1;
|
|
}
|
|
$file = config('editorial.credential_file');
|
|
$credential = is_file($file) ? json_decode(file_get_contents($file), true) : null;
|
|
if (! $credential || ($credential['environment'] ?? '') !== app()->environment() || ($credential['project'] ?? '') !== 'fna-v3'
|
|
|| ($credential['base_url'] ?? '') !== config('editorial.base_url')) {
|
|
$this->error('Credential binding mismatch.');
|
|
|
|
return 1;
|
|
}
|
|
$base = rtrim(config('editorial.base_url'), '/');
|
|
if (app()->environment('local') && ! in_array(parse_url($base, PHP_URL_HOST), ['fna-v3.loc', 'localhost', '127.0.0.1'])) {
|
|
$this->error('Local client refuses a nonlocal target.');
|
|
|
|
return 1;
|
|
}
|
|
try {
|
|
$request = Http::withOptions(['proxy' => '', 'allow_redirects' => false])->withToken($credential['fields']['api_key'])->acceptJson()->connectTimeout(3)->timeout(30);
|
|
if ($this->option('image')) {
|
|
$image = $this->option('image');
|
|
if (! is_file($image)) {
|
|
$this->error('Image not found.');
|
|
|
|
return 1;
|
|
}
|
|
$response = $request->attach('image', fopen($image, 'r'), basename($image))->post($base.'/api/editorial/v1/'.$path);
|
|
} else {
|
|
$payload = $this->option('payload') ? json_decode(file_get_contents($this->option('payload')), true, 512, JSON_THROW_ON_ERROR) : [];
|
|
$response = $request->send($method, $base.'/api/editorial/v1/'.$path, $method === 'GET' ? [] : ['json' => $payload]);
|
|
}
|
|
$data = $response->json();
|
|
$this->line(json_encode(['http_status' => $response->status(), 'data' => $data], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return $response->successful() ? 0 : 1;
|
|
} catch (\Throwable) {
|
|
$this->error('Editorial request failed; credential and request headers were not displayed.');
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
}
|