Refine ACP system health/update checks and CLI PHP validation

This commit is contained in:
2026-02-27 19:59:29 +01:00
parent 41387be802
commit 1f26aa7fb5
7 changed files with 497 additions and 232 deletions

View File

@@ -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;
}
}