From 7e64777f4a36cd7feefd164be86ab1353334601f Mon Sep 17 00:00:00 2001 From: Pranav Kant Date: Wed, 19 Oct 2016 20:58:10 +0530 Subject: [PATCH] Store canwrite property in DB Move whether the file is editable or not logic when generating a token and store it in the DB with the access token instead of checking it dynamically in WOPI calls. --- appinfo/database.xml | 7 +++ appinfo/info.xml | 2 +- controller/documentcontroller.php | 85 +++++++++++++++---------------- lib/db/wopi.php | 14 +++-- 4 files changed, 59 insertions(+), 49 deletions(-) diff --git a/appinfo/database.xml b/appinfo/database.xml index c441ed37..fe6c0760 100644 --- a/appinfo/database.xml +++ b/appinfo/database.xml @@ -320,6 +320,13 @@ 512 Relative to storage e.g. /welcome.odt + + canwrite + boolean + false + true + Can make changes to this file + token text diff --git a/appinfo/info.xml b/appinfo/info.xml index 18f56e7b..eeb3a996 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -5,7 +5,7 @@ Collabora Online allows you to to work with all kinds of office documents directly in your browser. This application requires Collabora Cloudsuite to be installed on one of your servers, please read the documentation to learn more about that. Edit office documents directly in your browser. AGPL - 1.1.7 + 1.1.8 Collabora Productivity based on work of Frank Karlitschek, Victor Dubiniuk https://github.com/owncloud/richdocuments/issues https://github.com/owncloud/richdocuments.git diff --git a/controller/documentcontroller.php b/controller/documentcontroller.php index 155b1615..35c3aef1 100644 --- a/controller/documentcontroller.php +++ b/controller/documentcontroller.php @@ -450,8 +450,41 @@ class DocumentController extends Controller { \OC::$server->getLogger()->debug('Generating WOPI Token for file {fileId}, version {version}.', [ 'app' => $this->appName, 'fileId' => $fileId, 'version' => $version ]); + $view = \OC\Files\Filesystem::getView(); + $path = $view->getPath($fileId); + $updatable = (bool)$view->isUpdatable($path); + + // Check if the editor (user who is accessing) is in editable group + // UserCanWrite only if + // 1. No edit groups are set or + // 2. if they are set, it is in one of the edit groups + $editorUid = \OC::$server->getUserSession()->getUser()->getUID(); + $editGroups = array_filter(explode('|', $this->appConfig->getAppValue('edit_groups'))); + if ($updatable && count($editGroups) > 0) { + $updatable = false; + foreach($editGroups as $editGroup) { + $editorGroup = \OC::$server->getGroupManager()->get($editGroup); + if (sizeof($editorGroup->searchUsers($editorUid)) > 0) { + \OC::$server->getLogger()->debug("Editor {editor} is in edit group {group}", [ + 'app' => $this->appName, + 'editor' => $editorUid, + 'group' => $editGroup + ]); + $updatable = true; + } + } + } + + // If token is for some versioned file + if ($version !== '0') { + \OC::$server->getLogger()->debug('setting updatable to false'); + $updatable = false; + } + + \OC::$server->getLogger()->debug('File with {fileid} has updatable set to {updatable}', [ 'app' => $this->appName, 'fileid' => $fileId, 'updatable' => $updatable ]); + $row = new Db\Wopi(); - $token = $row->generateFileToken($fileId, $version); + $token = $row->generateFileToken($fileId, $version, $updatable); // Return the token. return array( @@ -491,34 +524,9 @@ class DocumentController extends Controller { $this->loginUser($res['editor']); $view = \OC\Files\Filesystem::getView(); $info = $view->getFileInfo($res['path']); - $updatable = (bool)$view->isUpdatable($res['path']); - - \OC::$server->getLogger()->debug('File with {fileid} has updatable set to {updatable}', [ 'app' => $this->appName, 'fileid' => $fileId, 'updatable' => $updatable ]); $this->logoutUser(); - // Check if the editor (user who is accessing) is in editable group - $editorUid = \OC::$server->getUserManager()->get($res['editor'])->getUID(); - $editGroups = array_filter(explode('|', $this->appConfig->getAppValue('edit_groups'))); - - // UserCanWrite only if - // 1. No edit groups are set or - // 2. if they are set, it is in one of the edit groups - if ($updatable && count($editGroups) > 0) { - $updatable = false; - foreach($editGroups as $editGroup) { - $editorGroup = \OC::$server->getGroupManager()->get($editGroup); - if (sizeof($editorGroup->searchUsers($editorUid)) > 0) { - \OC::$server->getLogger()->debug("Editor {editor} is in edit group {group}", [ - 'app' => $this->appName, - 'editor' => $editorUid, - 'group' => $editGroup - ]); - $updatable = true; - } - } - } - if (!$info) { http_response_code(404); return false; @@ -531,7 +539,7 @@ class DocumentController extends Controller { 'Version' => $version, 'UserId' => $res['editor'], 'UserFriendlyName' => $editorName, - 'UserCanWrite' => $updatable + 'UserCanWrite' => $res['canwrite'] ? 'true' : 'false' ); } @@ -599,20 +607,18 @@ class DocumentController extends Controller { $version = $arr[1]; } - // Changing a previous version of the file is not possible - // Ignore WOPI put if such a request is encountered - if ($version !== '0') { - return array( - 'status' => 'success' - ); - } - \OC::$server->getLogger()->debug('Putting contents of file {fileId}, version {version} by token {token}.', [ 'app' => $this->appName, 'fileId' => $fileId, 'version' => $version, 'token' => $token ]); $row = new Db\Wopi(); $row->loadBy('token', $token); $res = $row->getPathForToken($fileId, $version, $token); + if (!$res['canwrite']) { + return array( + 'status' => 'error', + 'message' => 'Permission denied' + ); + } // Log-in as the user to regiser the change under her name. $editorid = $res['editor']; @@ -621,15 +627,6 @@ class DocumentController extends Controller { // login. This is necessary to make activity app register the // change made to this file under this user's (editorid) name. $this->loginUser($editorid); - $view = \OC\Files\Filesystem::getView(); - if (!$view->isUpdatable($res['path'])) { - \OC::$server->getLogger()->debug('User {editor} has no permission to change the file {fileId}.', [ - 'app' => $this->appName, - 'fileId' => $fileId, - 'editor' => $editorid - ]); - return; - } // Set up the filesystem view for the owner (where the file actually is). $userid = $res['owner']; diff --git a/lib/db/wopi.php b/lib/db/wopi.php index c826a1a5..c4ea3830 100644 --- a/lib/db/wopi.php +++ b/lib/db/wopi.php @@ -29,8 +29,8 @@ class Wopi extends \OCA\Richdocuments\Db{ protected $tableName = '`*PREFIX*richdocuments_wopi`'; - protected $insertStatement = 'INSERT INTO `*PREFIX*richdocuments_wopi` (`owner_uid`, `editor_uid`, `fileid`, `version`, `path`, `token`, `expiry`) - VALUES (?, ?, ?, ?, ?, ?, ?)'; + protected $insertStatement = 'INSERT INTO `*PREFIX*richdocuments_wopi` (`owner_uid`, `editor_uid`, `fileid`, `version`, `path`, `canwrite`, `token`, `expiry`) + VALUES (?, ?, ?, ?, ?, ?, ?, ?)'; protected $loadStatement = 'SELECT * FROM `*PREFIX*richdocuments_wopi` WHERE `token`= ?'; @@ -41,7 +41,7 @@ class Wopi extends \OCA\Richdocuments\Db{ * its the version number as stored by files_version app * Returns the token. */ - public function generateFileToken($fileId, $version){ + public function generateFileToken($fileId, $version, $updatable){ // Get the FS view of the current user. $view = \OC\Files\Filesystem::getView(); @@ -79,6 +79,7 @@ class Wopi extends \OCA\Richdocuments\Db{ $fileId, $version, $path, + $updatable, $token, time() + self::TOKEN_LIFETIME_SECONDS ]); @@ -120,6 +121,11 @@ class Wopi extends \OCA\Richdocuments\Db{ return false; } - return array('owner' => $row['owner_uid'], 'editor' => $row['editor_uid'], 'path' => $row['path']); + return array( + 'owner' => $row['owner_uid'], + 'editor' => $row['editor_uid'], + 'path' => $row['path'], + 'canwrite' => $row['canwrite'] + ); } }