diff options
author | Julius Härtl <jus@bitgrid.net> | 2019-04-13 21:28:28 +0300 |
---|---|---|
committer | Julius Härtl <jus@bitgrid.net> | 2019-04-13 21:28:28 +0300 |
commit | 1bdb0ff3eaa0f8a874bbf306ca5fe8a45f8e6ff4 (patch) | |
tree | 69363d95e38dc7b02a55c4e2cf3a9149f75cbb46 /lib/Controller | |
parent | 66adbbbe655ef62f1545a39c2bf31630455af8da (diff) |
Add first working version of collaborative editing
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Diffstat (limited to 'lib/Controller')
-rw-r--r-- | lib/Controller/PublicSessionController.php | 51 | ||||
-rw-r--r-- | lib/Controller/SessionController.php | 79 |
2 files changed, 113 insertions, 17 deletions
diff --git a/lib/Controller/PublicSessionController.php b/lib/Controller/PublicSessionController.php new file mode 100644 index 000000000..446b02fde --- /dev/null +++ b/lib/Controller/PublicSessionController.php @@ -0,0 +1,51 @@ +<?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); + + +namespace OCA\Text\Controller; + +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\Http\FileDisplayResponse; +use OCP\Files\IRootFolder; +use OCP\ICacheFactory; +use OCP\IRequest; +use OCP\ITempManager; +use OCP\Security\ISecureRandom; + +class PublicSessionController extends SessionController { + + /** + * TODO: maybe set guestUserId in middleware + */ + + /** + * @PublicPage + */ + public function push($transaction): DataResponse { + parent::push($transaction); + } + +} diff --git a/lib/Controller/SessionController.php b/lib/Controller/SessionController.php index 0ce4c1e03..7416bd5c3 100644 --- a/lib/Controller/SessionController.php +++ b/lib/Controller/SessionController.php @@ -4,10 +4,14 @@ declare(strict_types=1); namespace OCA\Text\Controller; +use OCA\Text\Service\DocumentService; +use OCA\Text\Service\SessionService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\FileDisplayResponse; +use OCP\AppFramework\Http\NotFoundResponse; use OCP\Files\IRootFolder; +use OCP\Files\NotFoundException; use OCP\ICacheFactory; use OCP\IRequest; use OCP\ITempManager; @@ -15,51 +19,92 @@ use OCP\Security\ISecureRandom; class SessionController extends Controller { + private $cache; + private $sessionService; + private $documentService; - private $userId; - private $secureRandom; - - public function __construct(string $appName, IRequest $request, ICacheFactory $cacheFactory, ITempManager $tempManager, $userId, IRootFolder $rootFolder, ISecureRandom $secureRandom) { + public function __construct(string $appName, IRequest $request, ICacheFactory $cacheFactory, SessionService $sessionService, DocumentService $documentService) { parent::__construct($appName, $request); - $this->userId = $userId; - $this->file = $rootFolder->get('example.md'); - $this->secureRandom = $secureRandom; + $this->cache = $cacheFactory->createDistributed('textSession'); + $this->sessionService = $sessionService; + $this->documentService = $documentService; + } + + /** + * Initialize the session as a client so it can use the other methods + * + * @NoCSRFRequired + * @NoAdminRequired + */ + public function create($file) { + $document = $this->documentService->createDocumentByPath($file); + $session = $this->sessionService->initSession($document->getId()); + return new DataResponse([ + 'document' => $document, + 'session' => $session + ]); } /** + * + * * @NoCSRFRequired * @NoAdminRequired */ - public function init() { - $sessionId = $this->secureRandom->generate(32, ISecureRandom::CHAR_DIGITS); - $token = $this->secureRandom->generate(32); - // save session to database - // return session details + public function fetch($documentId, $sessionId, $token) { + if ($this->sessionService->isValidSession($documentId, $sessionId, $token)) { + $this->sessionService->removeInactiveSessions($documentId); + $file = $this->documentService->getBaseFile($documentId); + return new FileDisplayResponse($file); + } + return new NotFoundResponse(); } /** + * Close existing session when quiting the client gracefully + * This reduces some cleanup work if used by the client + * * @NoCSRFRequired * @NoAdminRequired */ - public function push($transaction): DataResponse { + public function close($documentId, $sessionId, $token): DataResponse { + // TODO: To implement return new DataResponse([]); } /** + * Client tries to commit a set of transactions to the document + * * @NoCSRFRequired * @NoAdminRequired */ - public function get() { - return new FileDisplayResponse($this->file); + public function push($documentId, $sessionId, $token, $version, $steps): DataResponse { + if ($this->sessionService->isValidSession($documentId, $sessionId, $token)) { + try { + $steps = $this->documentService->addStep($documentId, $sessionId, $steps, $version); + } catch (\Exception $e) { + return new DataResponse($e->getMessage(), 500); + } + return new DataResponse($steps); + } + return new DataResponse([], 500); } /** + * Eventsource based handler + * * @NoCSRFRequired * @NoAdminRequired */ - public function sync($transaction): DataResponse { - return new DataResponse([]); + public function sync($documentId, $version = 0): DataResponse { + if ($version === $this->cache->get('document-version-'.$documentId)) { + return new DataResponse(['steps' => []]); + } + return new DataResponse([ + 'steps' => $this->documentService->getSteps($documentId, $version), + 'sessions' => $this->sessionService->getActiveSessions($documentId) + ]); } } |