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

github.com/nextcloud/text.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-10-16 11:33:39 +0300
committerJulius Härtl <jus@bitgrid.net>2019-12-02 14:28:30 +0300
commitbaa11f406390cca2a890c16bf1cf0b404b2fc700 (patch)
tree4e3d7eb0b39fb23650f89c56e93432041527e272 /lib
parent2dee8b69ce453e7bc0ebcec28cf375f7742d75d8 (diff)
Start with direct editing
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Diffstat (limited to 'lib')
-rw-r--r--lib/AppInfo/Application.php12
-rw-r--r--lib/Controller/DirectSessionController.php141
-rw-r--r--lib/Controller/SessionController.php4
-rw-r--r--lib/Db/Session.php5
-rw-r--r--lib/DirectEditing/TextDirectEditor.php151
-rw-r--r--lib/DirectEditing/TextDocumentCreator.php59
-rw-r--r--lib/DirectEditing/TextDocumentTemplateCreator.php78
-rw-r--r--lib/Service/ApiService.php22
-rw-r--r--lib/Service/DocumentService.php63
-rw-r--r--lib/Service/SessionService.php40
10 files changed, 537 insertions, 38 deletions
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index 93ba04806..954a32e1a 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -24,7 +24,10 @@ declare(strict_types=1);
namespace OCA\Text\AppInfo;
+use OCA\Text\DirectEditing\TextDirectEditor;
use OCP\AppFramework\App;
+use OCP\DirectEditing\RegisterDirectEditorEvent;
+use OCP\EventDispatcher\IEventDispatcher;
class Application extends App {
@@ -36,9 +39,18 @@ class Application extends App {
* Application constructor.
*
* @param array $params
+ * @throws \OCP\AppFramework\QueryException
*/
public function __construct(array $params = []) {
parent::__construct(self::APP_NAME, $params);
+
+ $container = $this->getContainer();
+ /** @var IEventDispatcher $eventDispatcher */
+ $eventDispatcher = $this->getContainer()->getServer()->query(IEventDispatcher::class);
+ $eventDispatcher->addListener(RegisterDirectEditorEvent::class, function (RegisterDirectEditorEvent $event) use ($container) {
+ $editor = $container->query(TextDirectEditor::class);
+ $event->register($editor);
+ });
}
}
diff --git a/lib/Controller/DirectSessionController.php b/lib/Controller/DirectSessionController.php
new file mode 100644
index 000000000..aef43873e
--- /dev/null
+++ b/lib/Controller/DirectSessionController.php
@@ -0,0 +1,141 @@
+<?php
+/**
+ * @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
+ *
+ * @author Julius Härtl <jus@bitgrid.net>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
+ *
+ * @author Julius Härtl <jus@bitgrid.net>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Text\Controller;
+
+use OC\Authentication\Exceptions\InvalidTokenException;
+use OCA\Text\Service\ApiService;
+use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http\Response;
+use OCP\AppFramework\PublicShareController;
+use OCP\DirectEditing\IManager;
+use OCP\ISession;
+use OCP\Share\Exceptions\ShareNotFound;
+use OCP\Share\IManager as ShareManager;
+use OCP\AppFramework\Http\DataResponse;
+use OCP\IRequest;
+use OCP\Share\IShare;
+
+class DirectSessionController extends Controller {
+
+ /** @var ShareManager */
+ private $shareManager;
+
+ /** @var IShare */
+ private $share;
+
+ /** @var ApiService */
+ private $apiService;
+ /** @var IManager */
+ private $directManager;
+
+ public function __construct(string $appName, IRequest $request, ShareManager $shareManager, ApiService $apiService, IManager $directManager) {
+ parent::__construct($appName, $request);
+ $this->shareManager = $shareManager;
+ $this->apiService = $apiService;
+ $this->directManager = $directManager;
+ }
+
+ /**
+ * @PublicPage
+ */
+ public function create(string $token, string $file = null, $guestName = null, bool $forceRecreate = false): DataResponse {
+ try {
+ $tokenObject = $this->directManager->getToken($token);
+ $tokenObject->extend();
+ $tokenObject->useTokenScope();
+ $node = $tokenObject->getFile();
+ $node->touch();
+ return new DataResponse([
+ 'mtime' => $node->getMTime()
+ ]);
+ } catch (InvalidTokenException $e) {
+ return new DataResponse('error');
+ }
+ //return $this->apiService->create(null, $file, $token, $guestName, $forceRecreate);
+ }
+
+ /**
+ * @NoAdminRequired
+ * @PublicPage
+ */
+ public function fetch(int $documentId, string $sessionId, string $sessionToken): Response {
+ return $this->apiService->fetch($documentId, $sessionId, $sessionToken);
+ }
+
+ /**
+ * @NoAdminRequired
+ * @PublicPage
+ */
+ public function close(int $documentId, int $sessionId, string $sessionToken): DataResponse {
+ return $this->apiService->close($documentId, $sessionId, $sessionToken);
+ }
+
+ /**
+ * @NoAdminRequired
+ * @PublicPage
+ */
+ public function push(int $documentId, int $sessionId, string $sessionToken, int $version, array $steps, string $token): DataResponse {
+ return $this->apiService->push($documentId, $sessionId, $sessionToken, $version, $steps, $token);
+ }
+
+ /**
+ * @NoAdminRequired
+ * @PublicPage
+ */
+ public function sync(string $token, int $documentId, int $sessionId, string $sessionToken, int $version = 0, string $autosaveContent = null, bool $force = false, bool $manualSave = false): DataResponse {
+ return $this->apiService->sync($documentId, $sessionId, $sessionToken, $version, $autosaveContent, $force, $manualSave, $token);
+ }
+
+ /**
+ * @NoAdminRequired
+ * @PublicPage
+ */
+ public function updateSession(int $documentId, int $sessionId, string $sessionToken, string $guestName) {
+ return $this->apiService->updateSession($documentId, $sessionId, $sessionToken, $guestName);
+ }
+
+}
diff --git a/lib/Controller/SessionController.php b/lib/Controller/SessionController.php
index 28660cb77..ff95a6cd9 100644
--- a/lib/Controller/SessionController.php
+++ b/lib/Controller/SessionController.php
@@ -51,6 +51,7 @@ class SessionController extends Controller {
/**
* @NoAdminRequired
+ * @PublicPage
*/
public function fetch(int $documentId, int $sessionId, string $sessionToken): Response {
return $this->apiService->fetch($documentId, $sessionId, $sessionToken);
@@ -58,6 +59,7 @@ class SessionController extends Controller {
/**
* @NoAdminRequired
+ * @PublicPage
*/
public function close(int $documentId, int $sessionId, string $sessionToken): DataResponse {
return $this->apiService->close($documentId, $sessionId, $sessionToken);
@@ -65,6 +67,7 @@ class SessionController extends Controller {
/**
* @NoAdminRequired
+ * @PublicPage
*/
public function push(int $documentId, int $sessionId, string $sessionToken, int $version, array $steps): DataResponse {
return $this->apiService->push($documentId, $sessionId, $sessionToken, $version, $steps);
@@ -72,6 +75,7 @@ class SessionController extends Controller {
/**
* @NoAdminRequired
+ * @PublicPage
*/
public function sync(int $documentId, int $sessionId, string $sessionToken, int $version = 0, string $autosaveContent = null, bool $force = false, bool $manualSave = false): DataResponse {
return $this->apiService->sync($documentId, $sessionId, $sessionToken, $version, $autosaveContent, $force, $manualSave);
diff --git a/lib/Db/Session.php b/lib/Db/Session.php
index dc3bc9b7d..9f5e17161 100644
--- a/lib/Db/Session.php
+++ b/lib/Db/Session.php
@@ -26,6 +26,11 @@ namespace OCA\Text\Db;
use OCP\AppFramework\Db\Entity;
+/**
+ * @method setLastContact(int $getTime)
+ * @method getDocumentId()
+ * @method getUserId()
+ */
class Session extends Entity implements \JsonSerializable {
public $id;
diff --git a/lib/DirectEditing/TextDirectEditor.php b/lib/DirectEditing/TextDirectEditor.php
new file mode 100644
index 000000000..cb6e06879
--- /dev/null
+++ b/lib/DirectEditing/TextDirectEditor.php
@@ -0,0 +1,151 @@
+<?php
+/**
+ * @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
+ *
+ * @author Julius Härtl <jus@bitgrid.net>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Text\DirectEditing;
+
+use OCA\Files\Controller\ApiController;
+use OCA\Text\AppInfo\Application;
+use OCA\Text\Service\ApiService;
+use OCP\AppFramework\Http\NotFoundResponse;
+use OCP\AppFramework\Http\Response;
+use OCP\AppFramework\Http\TemplateResponse;
+use OCP\DirectEditing\IEditor;
+use OCP\DirectEditing\IToken;
+use OCP\Files\InvalidPathException;
+use OCP\Files\NotFoundException;
+use OCP\Files\NotPermittedException;
+use OCP\IInitialStateService;
+use OCP\IL10N;
+
+class TextDirectEditor implements IEditor {
+
+ /** @var IL10N */
+ private $l10n;
+
+ /** @var IInitialStateService */
+ private $initialStateService;
+
+ /** @var ApiService */
+ private $apiService;
+
+ public function __construct(IL10N $l10n, IInitialStateService $initialStateService, ApiService $apiService) {
+ $this->l10n = $l10n;
+ $this->initialStateService = $initialStateService;
+ $this->apiService = $apiService;
+ }
+
+ /**
+ * Return a unique identifier for the editor
+ *
+ * e.g. richdocuments
+ *
+ * @return string
+ */
+ public function getId(): string {
+ return Application::APP_NAME;
+ }
+
+ /**
+ * Return a readable name for the editor
+ *
+ * e.g. Collabora Online
+ *
+ * @return string
+ */
+ public function getName(): string {
+ return $this->l10n->t('Nextcloud Text');
+ }
+
+ /**
+ * A list of mimetypes that should open the editor by default
+ *
+ * @return array
+ */
+ public function getMimetypes(): array {
+ return [
+ 'text/markdown'
+ ];
+ }
+
+ /**
+ * A list of mimetypes that can be opened in the editor optionally
+ *
+ * @return array
+ */
+ public function getMimetypesOptional(): array {
+ return [
+ 'text/plain'
+ ];
+ }
+
+ /**
+ * Return a list of file creation options to be presented to the user
+ *
+ * @return array of ACreateFromTemplate|ACreateEmpty
+ */
+ public function getCreators(): array {
+ return [
+ new TextDocumentCreator($this->l10n),
+ new TextDocumentTemplateCreator($this->l10n)
+ ];
+ }
+
+ /**
+ * Return if the view is able to securely view a file without downloading it to the browser
+ *
+ * @return bool
+ */
+ public function isSecure(): bool {
+ return false;
+ }
+
+ /**
+ * Return a template response for displaying the editor
+ *
+ * open can only be called once when the client requests the editor with a one-time-use token
+ * For handling editing and later requests, editors need to impelement their own token handling and take care of invalidation
+ *
+ * This behavior is similar to the current direct editing implementation in collabora where we generate a one-time token and switch over to the regular wopi token for the actual editing/saving process
+ *
+ * @param IToken $token
+ * @return Response
+ */
+ public function open(IToken $token): Response {
+ $token->useTokenScope();
+ try {
+ $session = $this->apiService->create($token->getFile()->getId());
+ $this->initialStateService->provideInitialState('text', 'file', [
+ 'fileId' => $token->getFile()->getId(),
+ 'content' => $token->getFile()->getContent(),
+ 'session' => \json_encode($session->getData())
+ ]);
+ $this->initialStateService->provideInitialState('text', 'directEditingToken', $token->getToken());
+ return new TemplateResponse('text', 'main', [], 'base');
+ } catch (InvalidPathException $e) {
+ } catch (NotFoundException $e) {
+ } catch (NotPermittedException $e) {
+ }
+ return new NotFoundResponse();
+ }
+
+}
diff --git a/lib/DirectEditing/TextDocumentCreator.php b/lib/DirectEditing/TextDocumentCreator.php
new file mode 100644
index 000000000..6b78cefb4
--- /dev/null
+++ b/lib/DirectEditing/TextDocumentCreator.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
+ *
+ * @author Julius Härtl <jus@bitgrid.net>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Text\DirectEditing;
+
+
+use OCP\DirectEditing\ACreateEmpty;
+use OCP\Files\File;
+use OCP\IL10N;
+
+class TextDocumentCreator extends ACreateEmpty {
+
+ /**
+ * @var IL10N
+ */
+ private $l10n;
+
+ public function __construct(IL10N $l10n) {
+ $this->l10n = $l10n;
+ }
+
+ public function getId(): string {
+ return 'textdocument';
+ }
+
+ public function getName(): string {
+ return $this->l10n->t('New text document');
+ }
+
+ public function getExtension(): string {
+ return '.md';
+ }
+
+ public function create(File $file, string $creatorId = null, string $templateId = null): void {
+ parent::create($file, $creatorId, $templateId); // TODO: Change the autogenerated stub
+
+ $file->putContent('## Empty document with Nextcloud Text');
+ }
+}
diff --git a/lib/DirectEditing/TextDocumentTemplateCreator.php b/lib/DirectEditing/TextDocumentTemplateCreator.php
new file mode 100644
index 000000000..d7732573c
--- /dev/null
+++ b/lib/DirectEditing/TextDocumentTemplateCreator.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
+ *
+ * @author Julius Härtl <jus@bitgrid.net>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Text\DirectEditing;
+
+
+use OCP\DirectEditing\ACreateFromTemplate;
+use OCP\Files\File;
+use OCP\IL10N;
+
+class TextDocumentTemplateCreator extends ACreateFromTemplate {
+
+ const TEMPLATES = [
+ '1' => [
+ 'id' => '1',
+ 'extension' => 'md',
+ 'name' => 'Weekly ToDo',
+ 'preview' => 'https://cloud.bitgrid.net/apps/richdocuments/template/preview/832537'
+ ],
+ '2' => [
+ 'id' => '2',
+ 'extension' => 'md',
+ 'name' => 'Meeting notes',
+ 'preview' => 'https://cloud.bitgrid.net/apps/richdocuments/template/preview/832537'
+ ]
+ ];
+
+ /**
+ * @var IL10N
+ */
+ private $l10n;
+
+ public function __construct(IL10N $l10n) {
+ $this->l10n = $l10n;
+ }
+
+ public function getId(): string {
+ return 'textdocumenttemplate';
+ }
+
+ public function getName(): string {
+ return $this->l10n->t('New text document from template');
+ }
+
+ public function getExtension(): string {
+ return '.md';
+ }
+
+ public function getTemplates(): array {
+ return self::TEMPLATES;
+ }
+
+ public function create(File $file, string $creatorId = null, string $templateId = null): void {
+ $template = self::TEMPLATES[$templateId];
+ $file->putContent('## ' . $template['name'] . '\n\n' . 'Created from a template with Nextcloud text');
+ }
+
+}
diff --git a/lib/Service/ApiService.php b/lib/Service/ApiService.php
index c6a35c610..a43498ceb 100644
--- a/lib/Service/ApiService.php
+++ b/lib/Service/ApiService.php
@@ -61,7 +61,6 @@ class ApiService {
try {
$readOnly = true;
/** @var File $file */
- $file = null;
if ($token) {
$file = $this->documentService->getFileByShareToken($token, $this->request->getParam('filePath'));
try {
@@ -72,9 +71,6 @@ class ApiService {
} else if ($fileId) {
$file = $this->documentService->getFileById($fileId);
$readOnly = !$file->isUpdateable();
- } else if ($filePath) {
- $file = $this->documentService->getFileByPath($filePath);
- $readOnly = !$file->isUpdateable();
} else {
return new DataResponse('No valid file argument provided', 500);
}
@@ -132,11 +128,8 @@ class ApiService {
* @throws \OCP\AppFramework\Db\DoesNotExistException
*/
public function push($documentId, $sessionId, $sessionToken, $version, $steps, $token = null): DataResponse {
- if ($token) {
- $file = $this->documentService->getFileByShareToken($token, $this->request->getParam('filePath'));
- } else {
- $file = $this->documentService->getFileById($documentId);
- }
+ $session = $this->sessionService->getSession($documentId, $sessionId, $sessionToken);
+ $file = $this->documentService->getFileForSession($session, $token);
if ($this->sessionService->isValidSession($documentId, $sessionId, $sessionToken) && !$this->documentService->isReadOnly($file, $token)) {
try {
$steps = $this->documentService->addStep($documentId, $sessionId, $steps, $version);
@@ -162,16 +155,13 @@ class ApiService {
'document' => $this->documentService->get($documentId)
];
+ $session = $this->sessionService->getSession($documentId, $sessionId, $sessionToken);
+ $file = $this->documentService->getFileForSession($session, $token);
+
try {
- $result['document'] = $this->documentService->autosave($documentId, $version, $autosaveContent, $force, $manualSave, $token, $this->request->getParam('filePath'));
+ $result['document'] = $this->documentService->autosave($file, $documentId, $version, $autosaveContent, $force, $manualSave, $token, $this->request->getParam('filePath'), $userId);
} catch (DocumentSaveConflictException $e) {
try {
- if ($token) {
- /** @var File $file */
- $file = $this->documentService->getFileByShareToken($token, $this->request->getParam('filePath'));
- } else {
- $file = $this->documentService->getFileById($documentId);
- }
$result['outsideChange'] = $file->getContent();
} catch (LockedException $e) {
// Ignore locked exception since it might happen due to an autosave action happening at the same time
diff --git a/lib/Service/DocumentService.php b/lib/Service/DocumentService.php
index 605a404fc..be682251d 100644
--- a/lib/Service/DocumentService.php
+++ b/lib/Service/DocumentService.php
@@ -26,6 +26,8 @@ declare(strict_types=1);
namespace OCA\Text\Service;
use \InvalidArgumentException;
+use OCA\Text\Db\Session;
+use OCP\DirectEditing\IManager;
use function json_encode;
use OC\Files\Node\File;
use OCA\Text\Db\Document;
@@ -108,6 +110,18 @@ class DocumentService {
} catch (NotFoundException $e) {
$this->appData->newFolder('documents');
}
+
+ // FIXME
+ $token = \OC::$server->getRequest()->getParam('token');
+ if ($this->userId === null && $token !== null) {
+ $this->directManager = \OC::$server->query(IManager::class);
+ try {
+ $tokenObject = $this->directManager->getToken($token);
+ $tokenObject->extend();
+ $tokenObject->useTokenScope();
+ $this->userId = $tokenObject->getUser();
+ } catch (\Exception $e) {}
+ }
}
/**
@@ -216,7 +230,7 @@ class DocumentService {
* @param $autoaveDocument
* @param bool $force
* @param bool $manualSave
- * @param null $token
+ * @param null $shareToken
* @return Document
* @throws DocumentSaveConflictException
* @throws DoesNotExistException
@@ -226,22 +240,15 @@ class DocumentService {
* @throws NotPermittedException
* @throws ShareNotFound
*/
- public function autosave($documentId, $version, $autoaveDocument, $force = false, $manualSave = false, $token = null, $filePath = null): Document {
+ public function autosave($file, $documentId, $version, $autoaveDocument, $force = false, $manualSave = false, $shareToken = null, $filePath = null, $userId = null): Document {
/** @var Document $document */
$document = $this->documentMapper->find($documentId);
- /** @var File $file */
- if (!$token) {
- $file = $this->getFileById($documentId);
- } else {
- $file = $this->getFileByShareToken($token, $filePath);
- }
-
if ($file === null) {
throw new NotFoundException();
}
- if ($this->isReadOnly($file, $token)) {
+ if ($this->isReadOnly($file, $shareToken)) {
return $document;
}
@@ -308,19 +315,42 @@ class DocumentService {
}
/**
+ * @param Session $session
+ * @param $shareToken
+ * @return \OCP\Files\File|Folder|Node
* @throws NotFoundException
*/
- public function getFileById($fileId): Node {
- $files = $this->rootFolder->getUserFolder($this->userId)->getById($fileId);
- if (count($files) === 0) {
+ public function getFileForSession(Session $session, $shareToken) {
+ if ($session->getUserId() !== null) {
+ return $this->getFileById($session->getDocumentId(), $session->getUserId());
+ }
+ try {
+ $share = $this->shareManager->getShareByToken($shareToken);
+
+ } catch (ShareNotFound $e) {
throw new NotFoundException();
}
- return $files[0];
+ $node = $share->getNode();
+ if ($node instanceof \OCP\Files\File) {
+ return $node;
+ }
+ if ($node instanceof Folder) {
+ return $node->getById($session->getDocumentId())[0];
+ }
+ throw new \InvalidArgumentException('No proper share data');
}
- public function getFileByPath($path): Node {
- return $this->rootFolder->getUserFolder($this->userId)->get($path);
+ /**
+ * @throws NotFoundException
+ */
+ public function getFileById($fileId, $userId = null): Node {
+ $files = $this->rootFolder->getUserFolder($this->userId ?? $userId)->getById($fileId);
+ if (count($files) === 0) {
+ throw new NotFoundException();
+ }
+
+ return $files[0];
}
/**
@@ -332,7 +362,6 @@ class DocumentService {
public function getFileByShareToken($shareToken, $path = null) {
try {
$share = $this->shareManager->getShareByToken($shareToken);
-
} catch (ShareNotFound $e) {
throw new NotFoundException();
}
diff --git a/lib/Service/SessionService.php b/lib/Service/SessionService.php
index b7be301ef..457fea497 100644
--- a/lib/Service/SessionService.php
+++ b/lib/Service/SessionService.php
@@ -29,6 +29,7 @@ use OCA\Text\Db\Session;
use OCA\Text\Db\SessionMapper;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\DirectEditing\IManager;
use OCP\IAvatar;
use OCP\IAvatarManager;
use OCP\Security\ISecureRandom;
@@ -40,13 +41,29 @@ class SessionService {
private $sessionMapper;
private $secureRandom;
private $timeFactory;
+ private $avatarManager;
private $userId;
- public function __construct(SessionMapper $sessionMapper, ISecureRandom $secureRandom, ITimeFactory $timeFactory, $userId) {
+ /** @var Session cache current session in the request */
+ private $session = null;
+
+ public function __construct(SessionMapper $sessionMapper, ISecureRandom $secureRandom, ITimeFactory $timeFactory, IAvatarManager $avatarManager, $userId) {
$this->sessionMapper = $sessionMapper;
$this->secureRandom = $secureRandom;
$this->timeFactory = $timeFactory;
$this->userId = $userId;
+ // FIXME
+ $token = \OC::$server->getRequest()->getParam('token');
+ if ($this->userId === null && $token !== null) {
+ $this->directManager = \OC::$server->query(IManager::class);
+ try {
+ $tokenObject = $this->directManager->getToken($token);
+ $tokenObject->extend();
+ $tokenObject->useTokenScope();
+ $this->userId = $tokenObject->getUser();
+ } catch (\Exception $e) {}
+ }
+ $this->avatarManager = $avatarManager;
}
public function initSession($documentId, $guestName = null): Session {
@@ -55,9 +72,7 @@ class SessionService {
$userName = $this->userId ? $this->userId : $guestName;
$session->setUserId($userName);
$session->setToken($this->secureRandom->generate(64));
- /** @var IAvatarManager $avatarGenerator */
- $avatarGenerator = \OC::$server->query(IAvatarManager::class);
- $color = $avatarGenerator->getGuestAvatar($userName)->avatarBackgroundColor($userName);
+ $color = $this->avatarManager->getGuestAvatar($userName)->avatarBackgroundColor($userName);
$color = sprintf("#%02x%02x%02x", $color->r, $color->g, $color->b);
$session->setColor($color);
if ($this->userId === null) {
@@ -96,9 +111,24 @@ class SessionService {
return $this->sessionMapper->deleteInactive($documentId);
}
+ public function getSession($documentId, $sessionId, $token) {
+ if ($this->session !== null) {
+ return $this->session;
+ }
+ try {
+ return $this->sessionMapper->find($documentId, $sessionId, $token);
+ } catch (DoesNotExistException $e) {
+ $this->session = false;
+ return false;
+ }
+ }
+
public function isValidSession($documentId, $sessionId, $token) {
+ if ($this->userId) {
+ return true;
+ }
try {
- $session = $this->sessionMapper->find($documentId, $sessionId, $token);
+ $session = $this->getSession($documentId, $sessionId, $token);
} catch (DoesNotExistException $e) {
return false;
}