diff options
author | Julius Härtl <jus@bitgrid.net> | 2019-06-12 15:32:20 +0300 |
---|---|---|
committer | Julius Härtl <jus@bitgrid.net> | 2019-06-12 15:32:42 +0300 |
commit | 6824232ab2269a7b815c66f2b7cc57612f15f201 (patch) | |
tree | 61ab9e1f0a4221502187895c7c770bc97e132531 /lib | |
parent | a0e5b0ddab7ebbaa4f09b379a7c98ad298b9b90d (diff) |
Cleanup sessions/steps when no session are active anymore
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Controller/PublicSessionController.php | 4 | ||||
-rw-r--r-- | lib/Controller/SessionController.php | 4 | ||||
-rw-r--r-- | lib/Db/DocumentMapper.php | 8 | ||||
-rw-r--r-- | lib/Db/SessionMapper.php | 11 | ||||
-rw-r--r-- | lib/Db/StepMapper.php | 9 | ||||
-rw-r--r-- | lib/DocumentHasUnsavedChangesException.php | 29 | ||||
-rw-r--r-- | lib/Service/ApiService.php | 27 | ||||
-rw-r--r-- | lib/Service/DocumentService.php | 85 | ||||
-rw-r--r-- | lib/Service/SessionService.php | 1 |
9 files changed, 109 insertions, 69 deletions
diff --git a/lib/Controller/PublicSessionController.php b/lib/Controller/PublicSessionController.php index 68eb2c937..9abb5170d 100644 --- a/lib/Controller/PublicSessionController.php +++ b/lib/Controller/PublicSessionController.php @@ -74,8 +74,8 @@ class PublicSessionController extends PublicShareController { * @NoAdminRequired * @PublicPage */ - public function create(string $token, string $file = null, $guestName = null): DataResponse { - return $this->apiService->create(null, $file, $token, $guestName); + public function create(string $token, string $file = null, $guestName = null, $forceRecreate = false): DataResponse { + return $this->apiService->create(null, $file, $token, $guestName, $forceRecreate); } /** diff --git a/lib/Controller/SessionController.php b/lib/Controller/SessionController.php index aff55f0bc..380353a6f 100644 --- a/lib/Controller/SessionController.php +++ b/lib/Controller/SessionController.php @@ -25,8 +25,8 @@ class SessionController extends Controller { /** * @NoAdminRequired */ - public function create(int $fileId = null, string $file = null): DataResponse { - return $this->apiService->create($fileId, $file); + public function create(int $fileId = null, string $file = null, $forceRecreate = false): DataResponse { + return $this->apiService->create($fileId, $file, null, null, $forceRecreate); } /** diff --git a/lib/Db/DocumentMapper.php b/lib/Db/DocumentMapper.php index 9f4113a9d..a4f097b1b 100644 --- a/lib/Db/DocumentMapper.php +++ b/lib/Db/DocumentMapper.php @@ -35,7 +35,12 @@ class DocumentMapper extends QBMapper { parent::__construct($db, 'text_documents', Document::class); } - public function find($documentId) { + /** + * @param $documentId + * @return Document + * @throws DoesNotExistException + */ + public function find($documentId): Document { /* @var $qb IQueryBuilder */ $qb = $this->db->getQueryBuilder(); $result = $qb->select('*') @@ -50,4 +55,5 @@ class DocumentMapper extends QBMapper { } return Document::fromRow($data); } + } diff --git a/lib/Db/SessionMapper.php b/lib/Db/SessionMapper.php index 36e355d00..87e305cff 100644 --- a/lib/Db/SessionMapper.php +++ b/lib/Db/SessionMapper.php @@ -73,6 +73,17 @@ class SessionMapper extends QBMapper { return $this->findEntities($qb); } + public function findAllInactive() { + /* @var $qb IQueryBuilder */ + $qb = $this->db->getQueryBuilder(); + $qb->select('id','color','document_id', 'last_contact','user_id','guest_name') + ->from($this->getTableName()) + ->where($qb->expr()->gt('last_contact', $qb->createNamedParameter(time()-SessionService::SESSION_VALID_TIME))) + ->execute(); + + return $this->findEntities($qb); + } + public function deleteInactive($documentId) { /* @var $qb IQueryBuilder */ $qb = $this->db->getQueryBuilder(); diff --git a/lib/Db/StepMapper.php b/lib/Db/StepMapper.php index b39c1d79b..1f0ec698e 100644 --- a/lib/Db/StepMapper.php +++ b/lib/Db/StepMapper.php @@ -59,4 +59,13 @@ class StepMapper extends QBMapper { ->where($qb->expr()->eq('document_id', $qb->createNamedParameter($documentId))) ->execute(); } + + public function deleteBeforeVersion($documentId, $version) { + /* @var $qb IQueryBuilder */ + $qb = $this->db->getQueryBuilder(); + $qb->delete($this->getTableName()) + ->where($qb->expr()->eq('document_id', $qb->createNamedParameter($documentId))) + ->andWhere($qb->expr()->lte('version', $qb->createNamedParameter($version))) + ->execute(); + } } diff --git a/lib/DocumentHasUnsavedChangesException.php b/lib/DocumentHasUnsavedChangesException.php new file mode 100644 index 000000000..1fe827817 --- /dev/null +++ b/lib/DocumentHasUnsavedChangesException.php @@ -0,0 +1,29 @@ +<?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; + + +class DocumentHasUnsavedChangesException extends \Exception { + +} diff --git a/lib/Service/ApiService.php b/lib/Service/ApiService.php index 3fd934a34..1d0c517ba 100644 --- a/lib/Service/ApiService.php +++ b/lib/Service/ApiService.php @@ -28,6 +28,7 @@ namespace OCA\Text\Service; use Exception; use OC\Files\Node\File; +use OCA\Text\DocumentHasUnsavedChangesException; use OCA\Text\DocumentSaveConflictException; use OCA\Text\VersionMismatchException; use OCP\AppFramework\Http\DataResponse; @@ -50,26 +51,36 @@ class ApiService { $this->documentService = $documentService; } - public function create($fileId = null, $filePath = null, $token = null, $guestName = null): DataResponse { + public function create($fileId = null, $filePath = null, $token = null, $guestName = null, $forceRecreate = false): DataResponse { try { $readOnly = true; /** @var File $file */ $file = null; if ($token) { - list($document, $file) = $this->documentService->createDocumentByShareToken($token, $filePath); + $file = $this->documentService->getFileByShareToken($token, $filePath); try { $this->documentService->checkSharePermissions($token, Constants::PERMISSION_UPDATE); $readOnly = false; } catch (NotFoundException $e) {} } else if ($fileId) { - list($document, $file) = $this->documentService->createDocumentByFileId($fileId); + $file = $this->documentService->getFileById($fileId); $readOnly = !$file->isUpdateable(); } else if ($filePath) { - list($document, $file) = $this->documentService->createDocumentByPath($filePath); + $file = $this->documentService->getFileByPath($filePath); $readOnly = !$file->isUpdateable(); } else { return new DataResponse('No valid file argument provided', 500); } + + $this->sessionService->removeInactiveSessions($file->getId()); + $activeSessions = $this->sessionService->getActiveSessions($file->getId()); + if (count($activeSessions) === 0) { + try { + $this->documentService->resetDocument($file->getId(), $forceRecreate); + } catch (DocumentHasUnsavedChangesException $e) {} + } + + $document = $this->documentService->createDocument($file); } catch (Exception $e) { return new DataResponse($e->getMessage(), 500); } @@ -97,9 +108,13 @@ class ApiService { public function close($documentId, $sessionId, $sessionToken): DataResponse { $this->sessionService->closeSession($documentId, $sessionId, $sessionToken); - //if ($this->documentService->) - //$this->sessionService->cleanupSessions(); $this->sessionService->removeInactiveSessions($documentId); + $activeSessions = $this->sessionService->getActiveSessions($documentId); + if (count($activeSessions) === 0) { + try { + $this->documentService->resetDocument($documentId); + } catch (DocumentHasUnsavedChangesException $e) {} + } return new DataResponse([]); } diff --git a/lib/Service/DocumentService.php b/lib/Service/DocumentService.php index a5b1f7e28..33062c327 100644 --- a/lib/Service/DocumentService.php +++ b/lib/Service/DocumentService.php @@ -32,6 +32,7 @@ use OCA\Text\Db\Document; use OCA\Text\Db\DocumentMapper; use OCA\Text\Db\Step; use OCA\Text\Db\StepMapper; +use OCA\Text\DocumentHasUnsavedChangesException; use OCA\Text\DocumentSaveConflictException; use OCA\Text\VersionMismatchException; use OCP\AppFramework\Db\DoesNotExistException; @@ -109,53 +110,13 @@ class DocumentService { } /** - * @param $path - * @return array - * @throws NotFoundException - * @throws InvalidPathException - * @throws NotPermittedException - */ - public function createDocumentByPath($path) { - /** @var File $file */ - $file = $this->rootFolder->getUserFolder($this->userId)->get($path); - return [$this->createDocument($file), $file]; - } - - /** - * @param $fileId - * @return array - * @throws NotFoundException - * @throws InvalidPathException - * @throws NotPermittedException - */ - public function createDocumentByFileId($fileId) { - $file = $this->getFileById($fileId); - return [$this->createDocument($file), $file]; - } - - /** - * @param $shareToken - * @param null $filePath - * @return array - * @throws InvalidPathException - * @throws NotFoundException - * @throws NotPermittedException - */ - public function createDocumentByShareToken($shareToken, $filePath = null) { - $file = $this->getFileByShareToken($shareToken, $filePath); - return [$this->createDocument($file), $file]; - } - - - - /** * @param File $file * @return Entity * @throws NotFoundException * @throws InvalidPathException * @throws NotPermittedException */ - protected function createDocument(File $file): Document { + public function createDocument(File $file): Document { try { $document = $this->documentMapper->find($file->getFileInfo()->getId()); @@ -166,14 +127,6 @@ class DocumentService { return $document; } - // TODO: Only do this when no sessions active, otherise we need to resolve the conflict differently - // TODO: Add parameter so that we can force this, else just opening the document will cause a rebuild - $lastMTime = $document->getLastSavedVersionTime(); - if ($file->getMTime() > $lastMTime && $lastMTime > 0) { - $this->resetDocument($document->getId()); - throw new NotFoundException(); - } - return $document; } catch (DoesNotExistException $e) { } catch (InvalidPathException $e) { @@ -304,18 +257,30 @@ class DocumentService { return $document; } - public function resetDocument($documentId): void { - $this->stepMapper->deleteAll($documentId); + /** + * @param $documentId + * @param bool $force + * @throws DocumentHasUnsavedChangesException + */ + public function resetDocument($documentId, $force = false): void { try { $document = $this->documentMapper->find($documentId); - $this->documentMapper->delete($document); - } catch (DoesNotExistException $e) { - } - try { - $this->appData->getFolder('documents')->getFile($documentId)->delete(); - } catch (NotFoundException $e) { - } catch (NotPermittedException $e) { + if ($force || !$this->hasUnsavedChanges($document)) { + $this->stepMapper->deleteAll($documentId); + $this->documentMapper->delete($document); + + try { + $this->appData->getFolder('documents')->getFile($documentId)->delete(); + } catch (NotFoundException $e) { + } catch (NotPermittedException $e) { + } + } + + if ($this->hasUnsavedChanges($document)) { + throw new DocumentHasUnsavedChangesException('Did not reset document, as it has unsaved changes'); + } + } catch (DoesNotExistException $e) { } } @@ -323,6 +288,10 @@ class DocumentService { return $this->rootFolder->getUserFolder($this->userId)->getById($fileId)[0]; } + public function getFileByPath($path): Node { + return $this->rootFolder->getUserFolder($this->userId)->get($path); + } + /** * @param $shareToken * @param null|string $path diff --git a/lib/Service/SessionService.php b/lib/Service/SessionService.php index 9de0ea0a9..fe796955c 100644 --- a/lib/Service/SessionService.php +++ b/lib/Service/SessionService.php @@ -89,6 +89,7 @@ class SessionService { public function removeInactiveSessions($documentId) { return $this->sessionMapper->deleteInactive($documentId); } + public function isValidSession($documentId, $sessionId, $token) { try { $session = $this->sessionMapper->find($documentId, $sessionId, $token); |