From d1501ab1d329f0693ebe615efaf87e65277d3fc6 Mon Sep 17 00:00:00 2001 From: Julius Knorr Date: Fri, 27 Dec 2024 15:48:46 +0100 Subject: [PATCH] feat: Check remove server connectivity Signed-off-by: Julius Knorr --- lib/Command/ActivateConfig.php | 9 +++++++ lib/Controller/SettingsController.php | 2 ++ lib/Service/ConnectivityService.php | 36 +++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/lib/Command/ActivateConfig.php b/lib/Command/ActivateConfig.php index de25ecd19a..35e4bd0a93 100644 --- a/lib/Command/ActivateConfig.php +++ b/lib/Command/ActivateConfig.php @@ -81,6 +81,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int return 1; } + try { + $this->connectivityService->testCallback($output); + } catch (\Throwable $e) { + // FIXME: Optional when allowing generic WOPI servers + $output->writeln('Failed to fetch wopi'); + $output->writeln($e->getMessage()); + return 1; + } + // Summarize URLs for easier debugging $output->writeln(''); diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index 6dee13062f..6087d43375 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -65,6 +65,7 @@ public function checkSettings(): DataResponse { $output = new NullOutput(); $this->connectivityService->testDiscovery($output); $this->connectivityService->testCapabilities($output); + $this->connectivityService->testCallback($output); } catch (\Exception $e) { $this->logger->error($e->getMessage(), ['exception' => $e]); return new DataResponse([ @@ -181,6 +182,7 @@ public function setSettings( $this->connectivityService->testDiscovery($output); $this->connectivityService->testCapabilities($output); $this->connectivityService->autoConfigurePublicUrl(); + $this->connectivityService->testCallback($output); } catch (\Throwable $e) { return new JSONResponse([ 'status' => 'error', diff --git a/lib/Service/ConnectivityService.php b/lib/Service/ConnectivityService.php index fd19fb16f1..cb2c4c0ad3 100644 --- a/lib/Service/ConnectivityService.php +++ b/lib/Service/ConnectivityService.php @@ -9,6 +9,8 @@ use Exception; use OCA\Richdocuments\AppConfig; use OCA\Richdocuments\WOPI\Parser; +use OCP\Http\Client\IClientService; +use OCP\IURLGenerator; use Symfony\Component\Console\Output\OutputInterface; class ConnectivityService { @@ -17,6 +19,8 @@ public function __construct( private DiscoveryService $discoveryService, private CapabilitiesService $capabilitiesService, private Parser $parser, + private IClientService $clientService, + private IURLGenerator $urlGenerator, ) { } @@ -47,6 +51,38 @@ public function testCapabilities(OutputInterface $output): void { $output->writeln('✓ Detected WOPI server: ' . $this->capabilitiesService->getServerProductName() . ' ' . $this->capabilitiesService->getProductVersion() . ''); } + public function testCallback(OutputInterface $output): void { + $url = $this->parser->getUrlSrcValue('Capabilities'); + if ($url === '') { + // Fixme can we skip early if the collabora version does not have the wopiAccessCheck endpoint, maybe it can be exposed in discovery + return; + } + + $url = str_replace('/hosting/capabilities', '/hosting/wopiAccessCheck', $url); + + $callbackUrl = $this->urlGenerator->getAbsoluteURL('/status.php'); + + $client = $this->clientService->newClient(); + try { + $response = $client->post($url, [ + ...RemoteOptionsService::getDefaultOptions(), + 'body' => json_encode([ + 'callbackUrl' => $callbackUrl, + ]), + 'headers' => [ + 'Content-Type' => 'application/json', + ], + ]); + $result = json_decode($response->getBody(), true, 512, JSON_THROW_ON_ERROR); + if ($result['status'] === 'CheckStatus::WopiHostNotAllowed') { + throw new \Exception('WOPI host not allowed by Collabora'); + } + } catch (Exception $e) { + throw $e; + } + $output->writeln('✓ URL Callback ok'); + } + /** * Detect public URL of the WOPI server for setting CSP on Nextcloud *