Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
}
},
"require": {
"ext-json": "*"
"ext-json": "*",
"ext-simplexml": "*"
},
"require-dev": {
"roave/security-advisories": "dev-master",
Expand Down
3 changes: 2 additions & 1 deletion composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@
'OCA\\Richdocuments\\Preview\\Pdf' => $baseDir . '/../lib/Preview/Pdf.php',
'OCA\\Richdocuments\\Reference\\OfficeTargetReferenceProvider' => $baseDir . '/../lib/Reference/OfficeTargetReferenceProvider.php',
'OCA\\Richdocuments\\Service\\CapabilitiesService' => $baseDir . '/../lib/Service/CapabilitiesService.php',
'OCA\\Richdocuments\\Service\\ConnectivityService' => $baseDir . '/../lib/Service/ConnectivityService.php',
'OCA\\Richdocuments\\Service\\DemoService' => $baseDir . '/../lib/Service/DemoService.php',
'OCA\\Richdocuments\\Service\\DiscoveryService' => $baseDir . '/../lib/Service/DiscoveryService.php',
'OCA\\Richdocuments\\Service\\FederationService' => $baseDir . '/../lib/Service/FederationService.php',
'OCA\\Richdocuments\\Service\\FileTargetService' => $baseDir . '/../lib/Service/FileTargetService.php',
'OCA\\Richdocuments\\Service\\FontService' => $baseDir . '/../lib/Service/FontService.php',
Expand All @@ -75,6 +77,5 @@
'OCA\\Richdocuments\\Template\\CollaboraTemplateProvider' => $baseDir . '/../lib/Template/CollaboraTemplateProvider.php',
'OCA\\Richdocuments\\TokenManager' => $baseDir . '/../lib/TokenManager.php',
'OCA\\Richdocuments\\UploadException' => $baseDir . '/../lib/UploadException.php',
'OCA\\Richdocuments\\WOPI\\DiscoveryManager' => $baseDir . '/../lib/WOPI/DiscoveryManager.php',
'OCA\\Richdocuments\\WOPI\\Parser' => $baseDir . '/../lib/WOPI/Parser.php',
);
3 changes: 2 additions & 1 deletion composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ class ComposerStaticInitRichdocuments
'OCA\\Richdocuments\\Preview\\Pdf' => __DIR__ . '/..' . '/../lib/Preview/Pdf.php',
'OCA\\Richdocuments\\Reference\\OfficeTargetReferenceProvider' => __DIR__ . '/..' . '/../lib/Reference/OfficeTargetReferenceProvider.php',
'OCA\\Richdocuments\\Service\\CapabilitiesService' => __DIR__ . '/..' . '/../lib/Service/CapabilitiesService.php',
'OCA\\Richdocuments\\Service\\ConnectivityService' => __DIR__ . '/..' . '/../lib/Service/ConnectivityService.php',
'OCA\\Richdocuments\\Service\\DemoService' => __DIR__ . '/..' . '/../lib/Service/DemoService.php',
'OCA\\Richdocuments\\Service\\DiscoveryService' => __DIR__ . '/..' . '/../lib/Service/DiscoveryService.php',
'OCA\\Richdocuments\\Service\\FederationService' => __DIR__ . '/..' . '/../lib/Service/FederationService.php',
'OCA\\Richdocuments\\Service\\FileTargetService' => __DIR__ . '/..' . '/../lib/Service/FileTargetService.php',
'OCA\\Richdocuments\\Service\\FontService' => __DIR__ . '/..' . '/../lib/Service/FontService.php',
Expand All @@ -90,7 +92,6 @@ class ComposerStaticInitRichdocuments
'OCA\\Richdocuments\\Template\\CollaboraTemplateProvider' => __DIR__ . '/..' . '/../lib/Template/CollaboraTemplateProvider.php',
'OCA\\Richdocuments\\TokenManager' => __DIR__ . '/..' . '/../lib/TokenManager.php',
'OCA\\Richdocuments\\UploadException' => __DIR__ . '/..' . '/../lib/UploadException.php',
'OCA\\Richdocuments\\WOPI\\DiscoveryManager' => __DIR__ . '/..' . '/../lib/WOPI/DiscoveryManager.php',
'OCA\\Richdocuments\\WOPI\\Parser' => __DIR__ . '/..' . '/../lib/WOPI/Parser.php',
);

Expand Down
6 changes: 4 additions & 2 deletions cypress/e2e/settings.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ describe('Office admin settings', function() {
.clear()
.type((usesHttps ? 'https' : 'http') + '://invalid.example.com{enter}')
cy.wait('@updateSettings').its('response.statusCode').should('equal', 500)
cy.get('#security-warning-state-failure .message')
cy.get('.notecard')
.first()
.scrollIntoView()
.should('be.visible')
.should('contain.text', 'Could not establish connection to the Collabora Online server.')
Expand All @@ -64,7 +65,8 @@ describe('Office admin settings', function() {
.clear()
.type(collaboraUrl + '{enter}')
cy.wait('@updateSettings').its('response.statusCode').should('equal', 200)
cy.get('#security-warning-state-ok .message')
cy.get('.notecard')
.first()
.scrollIntoView()
.should('be.visible')
.should('contain.text', 'Collabora Online server is reachable.')
Expand Down
13 changes: 11 additions & 2 deletions lib/AppConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@
use OCP\GlobalScale\IConfig as GlobalScaleConfig;

class AppConfig {
// URL that Nextcloud will use to connect to Collabora
public const WOPI_URL = 'wopi_url';
// URL that the browser will use to connect to Collabora (inherited from the discovery endpoint of Collabora,
// either wopi_url or what is configured as server_name)
public const PUBLIC_WOPI_URL = 'public_wopi_url';
// URL that should be used by Collabora to connect back to Nextcloud (defaults to the users browser host)
public const WOPI_CALLBACK_URL = 'wopi_callback_url';

public const FEDERATION_USE_TRUSTED_DOMAINS = 'federation_use_trusted_domains';

Expand Down Expand Up @@ -144,6 +149,10 @@ public function getCollaboraUrlInternal(): string {
return $this->config->getAppValue(Application::APPNAME, self::WOPI_URL, '');
}

public function getNextcloudUrl(): string {
return $this->config->getAppValue(Application::APPNAME, self::WOPI_CALLBACK_URL, '');
}

public function getDisableCertificateValidation(): bool {
return $this->config->getAppValue(Application::APPNAME, 'disable_certificate_verification', 'no') === 'yes';
}
Expand Down Expand Up @@ -197,7 +206,7 @@ public function getDomainList(): array {
$this->getGSDomains()
);

return array_filter($urls);
return array_map(fn ($url) => idn_to_ascii($url), array_filter($urls));
}

private function getFederationDomains(): array {
Expand Down Expand Up @@ -235,7 +244,7 @@ private function getGSDomains(): array {
/**
* Strips the path and query parameters from the URL.
*/
private function domainOnly(string $url): string {
public function domainOnly(string $url): string {
$parsedUrl = parse_url($url);
$scheme = isset($parsedUrl['scheme']) ? $parsedUrl['scheme'] . '://' : '';
$host = $parsedUrl['host'] ?? '';
Expand Down
6 changes: 3 additions & 3 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@
use OCA\Richdocuments\Preview\Pdf;
use OCA\Richdocuments\Reference\OfficeTargetReferenceProvider;
use OCA\Richdocuments\Service\CapabilitiesService;
use OCA\Richdocuments\Service\DiscoveryService;
use OCA\Richdocuments\Template\CollaboraTemplateProvider;
use OCA\Richdocuments\WOPI\DiscoveryManager;
use OCA\Viewer\Event\LoadViewer;
use OCP\App\IAppManager;
use OCP\AppFramework\App;
Expand Down Expand Up @@ -220,10 +220,10 @@ public function checkAndEnableCODEServer() {
$appConfig->setAppValue('wopi_url', $new_wopi_url);
$appConfig->setAppValue('disable_certificate_verification', 'yes');

$discoveryManager = $this->getContainer()->get(DiscoveryManager::class);
$discoveryService = $this->getContainer()->get(DiscoveryService::class);
$capabilitiesService = $this->getContainer()->get(CapabilitiesService::class);

$discoveryManager->refetch();
$discoveryService->refetch();
$capabilitiesService->clear();
$capabilitiesService->refetch();
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Backgroundjobs/ObtainCapabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ public function __construct(CapabilitiesService $capabilitiesService) {
}

protected function run($argument) {
$this->capabilitiesService->refetch();
$this->capabilitiesService->fetchFromRemote();
}
}
5 changes: 3 additions & 2 deletions lib/Capabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,9 @@ public function getCapabilities() {
'productName' => $this->capabilitiesService->getProductName(),
'editonline_endpoint' => $this->urlGenerator->linkToRouteAbsolute('richdocuments.document.editOnline'),
'config' => [
'wopi_url' => $this->config->getAppValue('wopi_url'),
'public_wopi_url' => $this->config->getAppValue('public_wopi_url'),
'wopi_url' => $this->config->getCollaboraUrlInternal(),
'public_wopi_url' => $this->config->getCollaboraUrlPublic(),
'wopi_callback_url' => $this->config->getNextcloudUrl(),
'disable_certificate_verification' => $this->config->getAppValue('disable_certificate_verification'),
'edit_groups' => $this->config->getAppValue('edit_groups'),
'use_groups' => $this->config->getAppValue('use_groups'),
Expand Down
103 changes: 72 additions & 31 deletions lib/Command/ActivateConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,54 +26,95 @@

use OCA\Richdocuments\AppConfig;
use OCA\Richdocuments\Service\CapabilitiesService;
use OCA\Richdocuments\WOPI\DiscoveryManager;
use OCA\Richdocuments\WOPI\Parser;
use OCA\Richdocuments\Service\ConnectivityService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class ActivateConfig extends Command {
/** @var AppConfig */
private $appConfig;

/** @var CapabilitiesService */
private $capabilitiesService;

/** @var DiscoveryManager */
private $discoveryManager;

/** @var Parser */
private $wopiParser;

public function __construct(AppConfig $appConfig, CapabilitiesService $capabilitiesService, DiscoveryManager $discoveryManager, Parser $wopiParser) {
public function __construct(
private AppConfig $appConfig,
private ConnectivityService $connectivityService,
private CapabilitiesService $capabilitiesService,
) {
parent::__construct();

$this->appConfig = $appConfig;
$this->capabilitiesService = $capabilitiesService;
$this->discoveryManager = $discoveryManager;
$this->wopiParser = $wopiParser;
}

protected function configure() {
$this
->setName('richdocuments:activate-config')
->setAliases(['richdocuments:setup'])
->addOption('wopi-url', 'w', InputOption::VALUE_REQUIRED, 'URL that the Nextcloud server will use to connect to Collabora', null)
->addOption('callback-url', 'c', InputOption::VALUE_REQUIRED, 'URL that is passed to Collabora to connect back to Nextcloud', null)
->setDescription('Activate config changes');
}

protected function execute(InputInterface $input, OutputInterface $output) {
try {
$this->discoveryManager->refetch();
$this->capabilitiesService->clear();
$capaUrlSrc = $this->wopiParser->getUrlSrc('Capabilities');
if (is_array($capaUrlSrc) && $capaUrlSrc['action'] === 'getinfo') {
$public_wopi_url = str_replace('/hosting/capabilities', '', $capaUrlSrc['urlsrc']);
if ($public_wopi_url !== null) {
$this->appConfig->setAppValue('public_wopi_url', $public_wopi_url);
}
if ($input->getOption('wopi-url') !== null) {
$wopiUrl = $input->getOption('wopi-url');
$this->appConfig->setAppValue(AppConfig::WOPI_URL, $wopiUrl);
$output->writeln('<info>✓ Set WOPI url to ' . $wopiUrl . '</info>');
}

if ($input->getOption('callback-url') !== null) {
$callbackUrl = $input->getOption('callback-url');
$this->appConfig->setAppValue(AppConfig::WOPI_CALLBACK_URL, $callbackUrl);
$output->writeln('<info>✓ Set callback url to ' . $callbackUrl . '</info>');
} else {
$this->appConfig->setAppValue(AppConfig::WOPI_CALLBACK_URL, '');
$output->writeln('<info>✓ Reset callback url autodetect</info>');
}

$output->writeln('Checking configuration');
$output->writeln('🛈 Configured WOPI URL: ' . $this->appConfig->getCollaboraUrlInternal());
$output->writeln('🛈 Configured public WOPI URL: ' . $this->appConfig->getCollaboraUrlPublic());
$output->writeln('🛈 Configured callback URL: ' . $this->appConfig->getNextcloudUrl());
$output->writeln('');

try {
$this->connectivityService->testDiscovery($output);
} catch (\Throwable $e) {
$output->writeln('<error>Failed to fetch discovery endpoint from ' . $this->appConfig->getCollaboraUrlInternal());
$output->writeln($e->getMessage());
return 1;
}
$this->capabilitiesService->clear();
$this->capabilitiesService->refetch();
$output->writeln('<info>Activated any config changes</info>');

try {
$this->connectivityService->testCapabilities($output);
} catch (\Throwable $e) {
// FIXME: Optional when allowing generic WOPI servers
$output->writeln('<error>Failed to fetch capabilities endpoint from ' . $this->capabilitiesService->getCapabilitiesEndpoint());
$output->writeln($e->getMessage());
return 1;
}

try {
$this->connectivityService->autoConfigurePublicUrl();
} catch (\Throwable $e) {
$output->writeln('<error>Failed to determine public URL from discovery response</error>');
$output->writeln($e->getMessage());
return 1;
}

// Summarize URLs for easier debugging

$output->writeln('');
$output->writeln('Collabora URL (used for Nextcloud to contact the Collabora server):');
$output->writeln(' ' . $this->appConfig->getCollaboraUrlInternal());

$output->writeln('Collabora public URL (used in the browser to open Collabora):');
$output->writeln(' ' . $this->appConfig->getCollaboraUrlPublic());

$output->writeln('Callback URL (used by Collabora to connect back to Nextcloud):');
$callbackUrl = $this->appConfig->getNextcloudUrl();
if ($callbackUrl === '') {
$output->writeln(' autodetected (will use the same URL as your user for browsing Nextcloud)');
} else {
$output->writeln(' ' . $this->appConfig->getNextcloudUrl());
}

return 0;
} catch (\Exception $e) {
$output->writeln('<error>Failed to activate any config changes</error>');
Expand Down
10 changes: 1 addition & 9 deletions lib/Command/ConvertToBigInt.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,13 @@
use OC\DB\Connection;
use OC\DB\SchemaWrapper;
use OCP\DB\Types;
use OCP\IDBConnection;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;

class ConvertToBigInt extends Command {
/** @var IDBConnection */
private $connection;

/**
* @param IDBConnection $connection
*/
public function __construct(Connection $connection) {
$this->connection = $connection;
public function __construct(private Connection $connection) {
parent::__construct();
}

Expand Down
Loading