ssh = new SSHService(); } public function validate(array $serverConfig, array $permissions): array { try { if (!$this->ssh->connect($serverConfig, true)) { return [ 'passed' => false, 'results' => [], 'error' => 'Could not connect to the remote server. Please check the connection details.', ]; } } catch (\Throwable $e) { return [ 'passed' => false, 'results' => [], 'error' => 'SSH connection failed: ' . $e->getMessage(), ]; } $results = []; foreach ($permissions as $index => $perm) { if (empty($perm['type']) || !isset($perm['value'])) { continue; } $type = $perm['type']; $value = $perm['value']; $description = $perm['description'] ?? ''; $command = $this->buildCheckCommand($type, $value); try { $output = $this->ssh->exec($command); $passed = $this->evaluateResult($type, $output); $results[] = [ 'type' => $type, 'value' => $value, 'description' => $description, 'passed' => $passed, 'message' => $passed ? 'Permission verified' : ($type === 'sudo' ? 'Passwordless sudo is not available' : 'Permission not granted: ' . trim($output['output'] ?? '')), ]; } catch (\Throwable $e) { $results[] = [ 'type' => $type, 'value' => $value, 'description' => $description, 'passed' => false, 'message' => 'Check failed: ' . $e->getMessage(), ]; } } $this->ssh->disconnect(); $allPassed = !empty($results) && empty(array_filter($results, fn($r) => !$r['passed'])); return [ 'passed' => $allPassed, 'results' => $results, 'error' => null, ]; } private function buildCheckCommand(string $type, string $value): string { return match ($type) { 'sudo' => 'sudo -n true 2>&1 && echo "OK" || echo "FAIL"', 'command' => sprintf('command -v %s 2>/dev/null && echo "OK" || echo "FAIL"', escapeshellarg($value)), 'file_read' => sprintf('test -r %s 2>/dev/null && echo "OK" || echo "FAIL"', escapeshellarg($value)), 'file_write' => sprintf('test -w %s 2>/dev/null && echo "OK" || echo "FAIL"', escapeshellarg($value)), 'custom' => sprintf('%s 2>&1; echo "EXIT:$?"', $value), default => 'echo "FAIL"', }; } private function evaluateResult(string $type, array $output): bool { $exitCode = $output['exit_status'] ?? 1; $stdout = trim($output['output'] ?? ''); if ($type === 'custom') { return $exitCode === 0; } return $exitCode === 0 && str_contains($stdout, 'OK'); } }