diff options
author | Julius Härtl <jus@bitgrid.net> | 2019-10-16 11:33:39 +0300 |
---|---|---|
committer | Julius Härtl <jus@bitgrid.net> | 2019-12-02 14:28:30 +0300 |
commit | baa11f406390cca2a890c16bf1cf0b404b2fc700 (patch) | |
tree | 4e3d7eb0b39fb23650f89c56e93432041527e272 /lib | |
parent | 2dee8b69ce453e7bc0ebcec28cf375f7742d75d8 (diff) |
Start with direct editing
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AppInfo/Application.php | 12 | ||||
-rw-r--r-- | lib/Controller/DirectSessionController.php | 141 | ||||
-rw-r--r-- | lib/Controller/SessionController.php | 4 | ||||
-rw-r--r-- | lib/Db/Session.php | 5 | ||||
-rw-r--r-- | lib/DirectEditing/TextDirectEditor.php | 151 | ||||
-rw-r--r-- | lib/DirectEditing/TextDocumentCreator.php | 59 | ||||
-rw-r--r-- | lib/DirectEditing/TextDocumentTemplateCreator.php | 78 | ||||
-rw-r--r-- | lib/Service/ApiService.php | 22 | ||||
-rw-r--r-- | lib/Service/DocumentService.php | 63 | ||||
-rw-r--r-- | lib/Service/SessionService.php | 40 |
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; } |