Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/richdocuments.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AppInfo/Application.php37
-rw-r--r--lib/Controller/WopiController.php16
-rw-r--r--lib/Service/FederationService.php58
-rw-r--r--lib/TemplateManager.php10
4 files changed, 100 insertions, 21 deletions
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index 7b72e938..7e86f801 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -41,6 +41,7 @@ use OCA\Viewer\Event\LoadViewer;
use OCP\AppFramework\App;
use OCP\AppFramework\QueryException;
use OCP\EventDispatcher\IEventDispatcher;
+use OCP\GlobalScale\IConfig;
use OCP\IPreview;
class Application extends App {
@@ -139,22 +140,42 @@ class Application extends App {
$path = $container->getServer()->getRequest()->getPathInfo();
} catch (\Exception $e) {}
if (strpos($path, '/apps/files') === 0 && $container->getServer()->getAppManager()->isEnabledForUser('federation')) {
- /** @var TrustedServers $trustedServers */
- $trustedServers = $container->query(TrustedServers::class);
/** @var FederationService $federationService */
- $federationService = $container->query(FederationService::class);
+ $federationService = \OC::$server->query(FederationService::class);
+
+ // Always add trusted servers on global scale
+ /** @var IConfig $globalScale */
+ $globalScale = $container->query(IConfig::class);
+ if ($globalScale->isGlobalScaleEnabled()) {
+ $trustedList = \OC::$server->getConfig()->getSystemValue('gs.trustedHosts', []);
+ foreach ($trustedList as $server) {
+ $this->addTrustedRemote($policy, $server);
+ }
+ }
$remoteAccess = $container->getServer()->getRequest()->getParam('richdocuments_remote_access');
- if ($remoteAccess && $trustedServers->isTrustedServer($remoteAccess)) {
- $remoteCollabora = $federationService->getRemoteCollaboraURL($remoteAccess);
- $policy->addAllowedFrameDomain($remoteAccess);
- $policy->addAllowedFrameDomain($remoteCollabora);
+ if ($remoteAccess && $federationService->isTrustedRemote($remoteAccess)) {
+ $this->addTrustedRemote($policy, $remoteAccess);
}
}
$cspManager->addDefaultPolicy($policy);
}
+ private function addTrustedRemote($policy, $url) {
+ /** @var FederationService $federationService */
+ $federationService = \OC::$server->query(FederationService::class);
+ try {
+ $remoteCollabora = $federationService->getRemoteCollaboraURL($url);
+ $policy->addAllowedFrameDomain($url);
+ $policy->addAllowedFrameDomain($remoteCollabora);
+ } catch (\Exception $e) {
+ // We can ignore this exception for adding predefined domains to the CSP as it it would then just
+ // reload the page to set a proper allowed frame domain if we don't have a fixed list of trusted
+ // remotes in a global scale scenario
+ }
+ }
+
public function checkAndEnableCODEServer() {
// Supported only on Linux OS, and x86_64 & ARM64 platforms
$supportedArchs = array('x86_64', 'aarch64');
@@ -190,7 +211,7 @@ class Application extends App {
$discoveryManager = $this->getContainer()->query(DiscoveryManager::class);
$capabilitiesService = $this->getContainer()->query(CapabilitiesService::class);
- $discoveryManager->refretch();
+ $discoveryManager->refetch();
$capabilitiesService->clear();
$capabilitiesService->refetch();
}
diff --git a/lib/Controller/WopiController.php b/lib/Controller/WopiController.php
index a0a475bd..0fbc5ef3 100644
--- a/lib/Controller/WopiController.php
+++ b/lib/Controller/WopiController.php
@@ -353,15 +353,23 @@ class WopiController extends Controller {
$versionPath = '/files_versions/' . $relPath . '.v' . $version;
$view = new View('/' . $wopi->getOwnerUid());
if ($view->file_exists($versionPath)){
- $response = new StreamResponse($view->fopen($versionPath, 'rb'));
+ $info = $view->getFileInfo($versionPath);
+ if ($info->getSize() === 0) {
+ $response = new Http\Response();
+ } else {
+ $response = new StreamResponse($view->fopen($versionPath, 'rb'));
+ }
}
else {
return new JSONResponse([], Http::STATUS_NOT_FOUND);
}
}
- else
- {
- $response = new StreamResponse($file->fopen('rb'));
+ else {
+ if ($file->getSize() === 0) {
+ $response = new Http\Response();
+ } else {
+ $response = new StreamResponse($file->fopen('rb'));
+ }
}
$response->addHeader('Content-Disposition', 'attachment');
$response->addHeader('Content-Type', 'application/octet-stream');
diff --git a/lib/Service/FederationService.php b/lib/Service/FederationService.php
index fce2ea74..1d18fdef 100644
--- a/lib/Service/FederationService.php
+++ b/lib/Service/FederationService.php
@@ -35,6 +35,7 @@ use OCP\Files\NotFoundException;
use OCP\Http\Client\IClientService;
use OCP\ICache;
use OCP\ICacheFactory;
+use OCP\IConfig;
use OCP\ILogger;
class FederationService {
@@ -47,14 +48,17 @@ class FederationService {
private $logger;
/** @var TrustedServers */
private $trustedServers;
+ /** @var IConfig */
+ private $config;
/** @var TokenManager */
private $tokenManager;
- public function __construct(ICacheFactory $cacheFactory, IClientService $clientService, ILogger $logger, TokenManager $tokenManager) {
+ public function __construct(ICacheFactory $cacheFactory, IClientService $clientService, ILogger $logger, TokenManager $tokenManager, IConfig $config) {
$this->cache = $cacheFactory->createLocal('richdocuments_remote/');
$this->clientService = $clientService;
$this->logger = $logger;
$this->tokenManager = $tokenManager;
+ $this->config = $config;
try {
$this->trustedServers = \OC::$server->query( \OCA\Federation\TrustedServers::class);
} catch (QueryException $e) {}
@@ -66,7 +70,7 @@ class FederationService {
* @throws \Exception
*/
public function getRemoteCollaboraURL($remote) {
- if ($this->trustedServers === null || !$this->trustedServers->isTrustedServer($remote)) {
+ if (!$this->isTrustedRemote($remote)) {
throw new \Exception('Unable to determine collabora URL of remote server ' . $remote . ' - Remote is not a trusted server');
}
if ($remoteCollabora = $this->cache->get('richdocuments_remote/' . $remote)) {
@@ -86,6 +90,54 @@ class FederationService {
return '';
}
+ public function isTrustedRemote($domainWithPort) {
+ if (strpos($domainWithPort, 'http://') === 0 || strpos($domainWithPort, 'https://') === 0) {
+ $port = parse_url($domainWithPort, PHP_URL_PORT);
+ $domainWithPort = parse_url($domainWithPort, PHP_URL_HOST) . ($port ? ':' . $port : '');
+ }
+
+ if ($this->trustedServers !== null && $this->trustedServers->isTrustedServer($domainWithPort)) {
+ return true;
+ }
+
+ $domain = $this->getDomainWithoutPort($domainWithPort);
+
+ $trustedList = $this->config->getSystemValue('gs.trustedHosts', []);
+ if (!is_array($trustedList)) {
+ return false;
+ }
+
+ foreach ($trustedList as $trusted) {
+ if (!is_string($trusted)) {
+ break;
+ }
+ $regex = '/^' . implode('[-\.a-zA-Z0-9]*', array_map(function ($v) {
+ return preg_quote($v, '/');
+ }, explode('*', $trusted))) . '$/i';
+ if (preg_match($regex, $domain) || preg_match($regex, $domainWithPort)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Strips a potential port from a domain (in format domain:port)
+ * @param string $host
+ * @return string $host without appended port
+ */
+ private function getDomainWithoutPort($host) {
+ $pos = strrpos($host, ':');
+ if ($pos !== false) {
+ $port = substr($host, $pos + 1);
+ if (is_numeric($port)) {
+ $host = substr($host, 0, $pos);
+ }
+ }
+ return $host;
+ }
+
public function getRemoteDirectUrl($remote, $shareToken, $filePath) {
if ($this->getRemoteCollaboraURL() === '') {
return '';
@@ -108,7 +160,7 @@ class FederationService {
}
public function getRemoteFileDetails($remote, $remoteToken) {
- if ($this->trustedServers === null || !$this->trustedServers->isTrustedServer($remote)) {
+ if (!$this->isTrustedRemote($remote)) {
$this->logger->info('Unable to determine collabora URL of remote server ' . $remote . ' - Remote is not a trusted server');
return null;
}
diff --git a/lib/TemplateManager.php b/lib/TemplateManager.php
index 2c5e33bb..5edd0d16 100644
--- a/lib/TemplateManager.php
+++ b/lib/TemplateManager.php
@@ -424,18 +424,16 @@ class TemplateManager {
* @return Folder
*/
private function getSystemTemplateDir() {
- return $this->rootFolder->get('appdata_' . $this->config->getSystemValue('instanceid', null))
- ->get('richdocuments')
- ->get('templates');
+ $path = 'appdata_' . $this->config->getSystemValue('instanceid', null) . '/richdocuments/templates';
+ return $this->rootFolder->get($path);
}
/**
* @return Folder
*/
private function getEmptyTemplateDir() {
- return $this->rootFolder->get('appdata_' . $this->config->getSystemValue('instanceid', null))
- ->get('richdocuments')
- ->get('empty_templates');
+ $path = 'appdata_' . $this->config->getSystemValue('instanceid', null) . '/richdocuments/empty_templates';
+ return $this->rootFolder->get($path);
}
/**