Refine ACP system health/update checks and CLI PHP validation
This commit is contained in:
@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
class SettingController extends Controller
|
||||
{
|
||||
@@ -38,6 +39,12 @@ class SettingController extends Controller
|
||||
]);
|
||||
|
||||
$value = $data['value'] ?? '';
|
||||
if ($data['key'] === 'system.php_binary') {
|
||||
$validationError = $this->validatePhpBinarySetting($value);
|
||||
if ($validationError !== null) {
|
||||
return response()->json(['message' => $validationError], 422);
|
||||
}
|
||||
}
|
||||
|
||||
$setting = Setting::updateOrCreate(
|
||||
['key' => $data['key']],
|
||||
@@ -67,6 +74,12 @@ class SettingController extends Controller
|
||||
$updated = [];
|
||||
|
||||
foreach ($data['settings'] as $entry) {
|
||||
if (($entry['key'] ?? '') === 'system.php_binary') {
|
||||
$validationError = $this->validatePhpBinarySetting($entry['value'] ?? '');
|
||||
if ($validationError !== null) {
|
||||
return response()->json(['message' => $validationError], 422);
|
||||
}
|
||||
}
|
||||
$setting = Setting::updateOrCreate(
|
||||
['key' => $entry['key']],
|
||||
['value' => $entry['value'] ?? '']
|
||||
@@ -80,4 +93,66 @@ class SettingController extends Controller
|
||||
|
||||
return response()->json($updated);
|
||||
}
|
||||
|
||||
public function validateSystemPhpBinary(Request $request): JsonResponse
|
||||
{
|
||||
$user = $request->user();
|
||||
if (!$user || !$user->roles()->where('name', 'ROLE_ADMIN')->exists()) {
|
||||
return response()->json(['message' => 'Forbidden'], 403);
|
||||
}
|
||||
|
||||
$data = $request->validate([
|
||||
'value' => ['required', 'string'],
|
||||
]);
|
||||
|
||||
$validationError = $this->validatePhpBinarySetting($data['value']);
|
||||
if ($validationError !== null) {
|
||||
return response()->json(['message' => $validationError], 422);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'message' => 'PHP interpreter is valid.',
|
||||
]);
|
||||
}
|
||||
|
||||
private function validatePhpBinarySetting(string $value): ?string
|
||||
{
|
||||
$binary = trim($value);
|
||||
if ($binary === '' || $binary === 'php') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($binary === 'keyhelp-php-domain') {
|
||||
return '`keyhelp-php-domain` is disabled. Use a concrete binary (e.g. keyhelp-php84).';
|
||||
}
|
||||
|
||||
$resolved = null;
|
||||
if (str_contains($binary, '/')) {
|
||||
if (!is_executable($binary)) {
|
||||
return "Configured PHP binary '{$binary}' is not executable.";
|
||||
}
|
||||
$resolved = $binary;
|
||||
} else {
|
||||
$escapedBinary = escapeshellarg($binary);
|
||||
$process = new Process(['sh', '-lc', "command -v {$escapedBinary}"]);
|
||||
$process->setTimeout(5);
|
||||
$process->run();
|
||||
if (!$process->isSuccessful()) {
|
||||
return "Configured PHP binary '{$binary}' was not found in PATH.";
|
||||
}
|
||||
$resolved = trim($process->getOutput());
|
||||
if ($resolved === '') {
|
||||
return "Configured PHP binary '{$binary}' was not found in PATH.";
|
||||
}
|
||||
}
|
||||
|
||||
$phpCheck = new Process([$resolved, '-r', 'echo PHP_VERSION;']);
|
||||
$phpCheck->setTimeout(5);
|
||||
$phpCheck->run();
|
||||
if (!$phpCheck->isSuccessful() || trim($phpCheck->getOutput()) === '') {
|
||||
return "Configured binary '{$binary}' is not a working PHP CLI executable.";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user