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:
authorJulius Härtl <jus@bitgrid.net>2019-08-16 14:49:25 +0300
committerJulius Härtl <jus@bitgrid.net>2019-08-27 19:43:24 +0300
commit0ef0b05bd2a4b232f18f4b64a3863b7f64376fa6 (patch)
treec45082ad57a9716cddfe830b91b858913605d9dc /lib
parentf65eddfaa11cc726ce4aed70c9b05ab32369a24b (diff)
Handle CSP properly
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Diffstat (limited to 'lib')
-rw-r--r--lib/AppInfo/Application.php4
-rw-r--r--lib/Controller/DirectViewController.php42
-rw-r--r--lib/Controller/DocumentController.php43
-rw-r--r--lib/Controller/OCSController.php22
-rw-r--r--lib/Service/FederationService.php5
-rw-r--r--lib/TokenManager.php15
6 files changed, 100 insertions, 31 deletions
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index 2ac62482..d69bc858 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -85,7 +85,7 @@ class Application extends App {
}
- public function updateCSP() {
+ public function updateCSP(): void {
$container = $this->getContainer();
$publicWopiUrl = $container->getServer()->getConfig()->getAppValue('richdocuments', 'public_wopi_url', '');
@@ -111,7 +111,7 @@ class Application extends App {
$trustedServers = $container->query(TrustedServers::class);
/** @var FederationService $federationService */
$federationService = $container->query(FederationService::class);
- $remoteAccess = \OC::$server->getRequest()->getParam('richdocuments_remote_access');
+ $remoteAccess = $container->getServer()->getRequest()->getParam('richdocuments_remote_access');
if ($remoteAccess && $trustedServers->isTrustedServer($remoteAccess)) {
$remoteCollabora = $federationService->getRemoteCollaboraURL($remoteAccess);
diff --git a/lib/Controller/DirectViewController.php b/lib/Controller/DirectViewController.php
index 0d5f8c71..8a52777b 100644
--- a/lib/Controller/DirectViewController.php
+++ b/lib/Controller/DirectViewController.php
@@ -24,6 +24,7 @@ namespace OCA\Richdocuments\Controller;
use OCA\Richdocuments\AppConfig;
use OCA\Richdocuments\Db\DirectMapper;
+use OCA\Richdocuments\Service\FederationService;
use OCA\Richdocuments\TemplateManager;
use OCA\Richdocuments\TokenManager;
use OCP\AppFramework\Controller;
@@ -31,6 +32,7 @@ use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\AppFramework\Http\JSONResponse;
+use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
@@ -72,6 +74,7 @@ class DirectViewController extends Controller {
$this->config = $config;
$this->appConfig = $appConfig;
$this->templateManager = $templateManager;
+ $this->federationService = \OC::$server->query(FederationService::class);
}
/**
@@ -85,12 +88,14 @@ class DirectViewController extends Controller {
try {
$direct = $this->directMapper->getByToken($token);
} catch (DoesNotExistException $e) {
- //TODO show 404
- return new JSONResponse([], Http::STATUS_NOT_FOUND);
+ $params = [
+ 'errors' => [['error' => $e->getMessage()]]
+ ];
+ return new TemplateResponse('core', 'error', $params, 'guest');
}
// Delete the token. They are for 1 time use only
- $this->directMapper->delete($direct);
+ //$this->directMapper->delete($direct);
$folder = $this->rootFolder->getUserFolder($direct->getUid());
if ($this->templateManager->isTemplate($direct->getFileid())) {
@@ -114,9 +119,33 @@ class DirectViewController extends Controller {
throw new \Exception();
}
+ /**
+ * Open file from remote collabora
+ */
+ if ($item->getFileInfo()->getStorage()->instanceOfStorage(\OCA\Files_Sharing\External\Storage::class)) {
+ $remote = $item->getStorage()->getRemote();
+ $remoteCollabora = $this->federationService->getRemoteCollaboraURL($remote);
+ if ($remoteCollabora !== '') {
+ $wopi = $this->tokenManager->getRemoteTokenFromDirect($item, $direct->getUid());
+ $url = $remote . 'index.php/apps/richdocuments/remote?shareToken=' . $item->getStorage()->getToken() .
+ '&remoteServer=' . $wopi->getServerHost() .
+ '&remoteServerToken=' . $wopi->getToken();
+ if ($item->getInternalPath() !== '') {
+ $url .= '&filePath=' . $item->getInternalPath();
+ }
+ $response = new RedirectResponse($url);
+ $response->addHeader('X-Frame-Options', 'ALLOW');
+ return $response;
+ } else {
+ $this->logger->warning('Failed to connect to remote collabora instance for ' . $item->getId());
+ }
+ }
list($urlSrc, $token) = $this->tokenManager->getToken($item->getId(), null, $direct->getUid(), true);
} catch (\Exception $e) {
- return new JSONResponse([], Http::STATUS_BAD_REQUEST);
+ $params = [
+ 'errors' => [['error' => $e->getMessage()]]
+ ];
+ return new TemplateResponse('core', 'error', $params, 'guest');
}
$relativePath = $folder->getRelativePath($item->getPath());
@@ -142,7 +171,10 @@ class DirectViewController extends Controller {
$response->setContentSecurityPolicy($policy);
return $response;
} catch (\Exception $e) {
- return new JSONResponse([], Http::STATUS_BAD_REQUEST);
+ $params = [
+ 'errors' => [['error' => $e->getMessage()]]
+ ];
+ return new TemplateResponse('core', 'error', $params, 'guest');
}
}
diff --git a/lib/Controller/DocumentController.php b/lib/Controller/DocumentController.php
index 6ddd97bf..ac27e799 100644
--- a/lib/Controller/DocumentController.php
+++ b/lib/Controller/DocumentController.php
@@ -170,6 +170,47 @@ class DocumentController extends Controller {
}
/**
+ * Redirect to the files app with proper CSP headers set for federated editing
+ *
+ * This is a workaround since we cannot set a nonce for allowing dynamic URLs in the richdocument iframe
+ *
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function open($fileId) {
+ try {
+ $folder = $this->rootFolder->getUserFolder($this->uid);
+ $item = $folder->getById($fileId)[0];
+ if (!($item instanceof Node)) {
+ throw new \Exception();
+ }
+
+ if ($item->getStorage()->instanceOfStorage(\OCA\Files_Sharing\External\Storage::class)) {
+ $remote = $item->getStorage()->getRemote();
+ $remoteCollabora = $this->federationService->getRemoteCollaboraURL($remote);
+ if ($remoteCollabora !== '') {
+ $dir = $item->getInternalPath() === '' ? '/' : $item->getInternalPath();
+ $url = '/index.php/apps/files?dir=' . $dir .
+ '&richdocuments_open=' . $item->getName() .
+ '&richdocuments_fileId=' . $fileId .
+ '&richdocuments_remote_access=' . $remote;
+ return new RedirectResponse($url);
+ }
+ $this->logger->warning('Failed to connect to remote collabora instance for ' . $fileId);
+ }
+ } catch (\Exception $e) {
+ $this->logger->logException($e, ['app'=>'richdocuments']);
+ $params = [
+ 'errors' => [['error' => $e->getMessage()]]
+ ];
+ return new TemplateResponse('core', 'error', $params, 'guest');
+ }
+
+ return new TemplateResponse('core', '403', [], 'guest');
+ }
+
+ /**
* @NoAdminRequired
*
* @param string $fileId
@@ -199,6 +240,8 @@ class DocumentController extends Controller {
$response = new RedirectResponse($url);
$response->addHeader('X-Frame-Options', 'ALLOW');
return $response;
+ } else {
+ $this->logger->warning('Failed to connect to remote collabora instance for ' . $fileId);
}
}
list($urlSrc, $token) = $this->tokenManager->getToken($item->getId());
diff --git a/lib/Controller/OCSController.php b/lib/Controller/OCSController.php
index fe1e9de5..8574ffb7 100644
--- a/lib/Controller/OCSController.php
+++ b/lib/Controller/OCSController.php
@@ -109,29 +109,7 @@ class OCSController extends \OCP\AppFramework\OCSController {
throw new OCSBadRequestException('Cannot view folder');
}
- /**
- * Open file from remote collabora
- */
- if ($node->getStorage()->instanceOfStorage(\OCA\Files_Sharing\External\Storage::class)) {
- $remote = $node->getStorage()->getRemote();
- $remoteCollabora = $this->federationService->getRemoteDirectToken($remote);
- if ($remoteCollabora !== '') {
- $wopi = $this->tokenManager->getRemoteToken($item);
- $url = $remote . 'index.php/apps/richdocuments/remote?shareToken=' . $item->getStorage()->getToken() .
- '&remoteServer=' . $wopi->getServerHost() .
- '&remoteServerToken=' . $wopi->getToken();
- if ($item->getInternalPath() !== '') {
- $url .= '&filePath=' . $item->getInternalPath();
- }
- $response = new RedirectResponse($url);
- $response->addHeader('X-Frame-Options', 'ALLOW');
- return $response;
- }
- }
-
- //TODO check if we can even edit this file with collabora
$direct = $this->directMapper->newDirect($this->userId, $fileId);
- // TODO: convert to remote token if needed
return new DataResponse([
'url' => $this->urlGenerator->linkToRouteAbsolute('richdocuments.directView.show', [
diff --git a/lib/Service/FederationService.php b/lib/Service/FederationService.php
index 8b2e775d..22b6387b 100644
--- a/lib/Service/FederationService.php
+++ b/lib/Service/FederationService.php
@@ -28,6 +28,7 @@ use OCA\Federation\TrustedServers;
use OCP\AppFramework\QueryException;
use OCP\Http\Client\IClientService;
use OCP\ICache;
+use OCP\ICacheFactory;
use OCP\ILogger;
class FederationService {
@@ -41,8 +42,8 @@ class FederationService {
/** @var TrustedServers */
private $trustedServers;
- public function __construct(ICache $cache, IClientService $clientService, ILogger $logger) {
- $this->cache = $cache;
+ public function __construct(ICacheFactory $cacheFactory, IClientService $clientService, ILogger $logger) {
+ $this->cache = $cacheFactory->createLocal('richdocuments_remote/');
$this->clientService = $clientService;
$this->logger = $logger;
try {
diff --git a/lib/TokenManager.php b/lib/TokenManager.php
index f73141f6..68278d54 100644
--- a/lib/TokenManager.php
+++ b/lib/TokenManager.php
@@ -232,4 +232,19 @@ class TokenManager {
$this->wopiMapper->update($wopi);
return $wopi;
}
+
+ /**
+ * @param Node $node
+ * @return Wopi
+ */
+ public function getRemoteTokenFromDirect(Node $node, $editorUid) {
+ list($urlSrc, $token, $wopi) = $this->getToken($node->getId(), null, $editorUid, true, true);
+ $wopi->setIsRemoteToken(true);
+ $wopi->setRemoteServer($node->getStorage()->getRemote());
+
+ $this->wopiMapper->update($wopi);
+ return $wopi;
+ }
+
+
}