Merge pull request #130 from pranavk/readonliness

Add UserCanWrite WOPI property
pull/1/head
Andras Timar 8 years ago committed by GitHub
commit a7f8fb75b3

@ -7,7 +7,7 @@
<table>
<name>*dbprefix*richdocuments_session</name>
<declaration>
<field>
<name>es_id</name>
<type>text</type>
@ -41,7 +41,7 @@
<length>64</length>
<comments>oC user who created the session</comments>
</field>
<index>
<name>richdocuments_session_ei_idx</name>
<primary>true</primary>
@ -51,14 +51,14 @@
<sorting>ascending</sorting>
</field>
</index>
</declaration>
</table>
<table>
<name>*dbprefix*richdocuments_member</name>
<declaration>
<field>
<name>member_id</name>
<type>integer</type>
@ -114,14 +114,14 @@
<unsigned>true</unsigned>
<length>1</length>
</field>
</declaration>
</table>
<table>
<name>*dbprefix*richdocuments_op</name>
<declaration>
<field>
<name>seq</name>
<type>integer</type>
@ -160,7 +160,7 @@
<notnull>false</notnull>
<comments>json-string</comments>
</field>
<index>
<name>richdocs_seq_pKey</name>
<primary>true</primary>
@ -181,13 +181,13 @@
<sorting>ascending</sorting>
</field>
</index>
</declaration>
</table>
<table>
<name>*dbprefix*richdocuments_invite</name>
<declaration>
<field>
<name>es_id</name>
<type>text</type>
@ -214,13 +214,13 @@
<unsigned>true</unsigned>
<length>4</length>
</field>
</declaration>
</table>
<table>
<name>*dbprefix*richdocuments_revisions</name>
<declaration>
<field>
<name>es_id</name>
<type>text</type>
@ -257,7 +257,7 @@
<notnull>true</notnull>
<comments>used to lookup revision in documents folder of member, eg hash.odt</comments>
</field>
<index>
<name>richdocuments_rev_eis_idx</name>
<unique>true</unique>
@ -270,10 +270,10 @@
<sorting>ascending</sorting>
</field>
</index>
</declaration>
</table>
<table>
<name>*dbprefix*richdocuments_wopi</name>
<declaration>
@ -320,6 +320,13 @@
<length>512</length>
<comments>Relative to storage e.g. /welcome.odt</comments>
</field>
<field>
<name>canwrite</name>
<type>boolean</type>
<default>false</default>
<notnull>true</notnull>
<comments>Can make changes to this file</comments>
</field>
<field>
<name>token</name>
<type>text</type>
@ -335,6 +342,15 @@
<length>4</length>
<comments>Expiration time of the token</comments>
</field>
<index>
<name>richdocuments_wopi_token_idx</name>
<unique>true</unique>
<field>
<name>token</name>
<sorting>ascending</sorting>
</field>
</index>
</declaration>
</table>
</database>

@ -5,7 +5,7 @@
<description>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.</description>
<summary>Edit office documents directly in your browser.</summary>
<licence>AGPL</licence>
<version>1.1.6</version>
<version>1.1.8</version>
<author>Collabora Productivity based on work of Frank Karlitschek, Victor Dubiniuk</author>
<bugs>https://github.com/owncloud/richdocuments/issues</bugs>
<repository type="git">https://github.com/owncloud/richdocuments.git</repository>

@ -95,6 +95,8 @@ class DocumentController extends Controller {
* @param string $userid
*/
private function loginUser($userid) {
\OC_Util::tearDownFS();
$users = \OC::$server->getUserManager()->search($userid, 1, 0);
if (count($users) > 0) {
$user = array_shift($users);
@ -113,6 +115,18 @@ class DocumentController extends Controller {
\OC::$server->getUserSession()->setUser($user);
}
}
\OC_Util::setupFS();
}
/**
* Log out the current user
* This is helpful when we are artifically logged in as someone
*/
private function logoutUser() {
\OC_Util::tearDownFS();
\OC::$server->getSession()->close();
}
private function responseError($message, $hint = ''){
@ -305,9 +319,7 @@ class DocumentController extends Controller {
'uploadMaxHumanFilesize' => \OCP\Util::humanFileSize($maxUploadFilesize),
'allowShareWithLink' => $this->settings->getAppValue('core', 'shareapi_allow_links', 'yes'),
'wopi_url' => $webSocket,
'edit_groups' => $this->appConfig->getAppValue('edit_groups'),
'doc_format' => $this->appConfig->getAppValue('doc_format'),
'usergroups' => $usergroups
'doc_format' => $this->appConfig->getAppValue('doc_format')
]);
$policy = new ContentSecurityPolicy();
@ -438,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(
@ -476,13 +521,11 @@ class DocumentController extends Controller {
}
// Login the user to see his mount locations
$this->loginUser($res['owner']);
$view = new \OC\Files\View('/' . $res['owner'] . '/files');
$this->loginUser($res['editor']);
$view = \OC\Files\Filesystem::getView();
$info = $view->getFileInfo($res['path']);
// Close the session created for user login
\OC::$server->getSession()->close();
$this->logoutUser();
if (!$info) {
http_response_code(404);
@ -490,13 +533,13 @@ class DocumentController extends Controller {
}
$editorName = \OC::$server->getUserManager()->get($res['editor'])->getDisplayName();
\OC::$server->getLogger()->debug('File info: {info}.', [ 'app' => $this->appName, 'info' => $info ]);
return array(
'BaseFileName' => $info['name'],
'Size' => $info['size'],
'Version' => $version,
'UserId' => $res['editor'],
'UserFriendlyName' => $editorName
'UserFriendlyName' => $editorName,
'UserCanWrite' => $res['canwrite'] ? 'true' : 'false'
);
}
@ -534,10 +577,6 @@ class DocumentController extends Controller {
if ($version !== '0') {
\OCP\JSON::checkAppEnabled('files_versions');
// Setup the FS
\OC_Util::tearDownFS();
\OC_Util::setupFS($ownerid, '/' . $ownerid . '/files');
list($ownerid, $filename) = \OCA\Files_Versions\Storage::getUidAndFilename($res['path']);
$filename = '/files_versions/' . $filename . '.v' . $version;
@ -546,8 +585,7 @@ class DocumentController extends Controller {
$filename = '/files' . $res['path'];
}
// Close the session created for user login
\OC::$server->getSession()->close();
$this->logoutUser();
return new DownloadResponse($this->request, $ownerid, $filename);
}
@ -569,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'];
@ -603,14 +639,11 @@ class DocumentController extends Controller {
// Setup the FS which is needed to emit hooks (versioning).
\OC_Util::tearDownFS();
\OC_Util::setupFS($userid, $root);
\OC_Util::setupFS($userid);
$view->file_put_contents($res['path'], $content);
\OC_Util::tearDownFS();
// clear any session created before
\OC::$server->getSession()->close();
$this->logoutUser();
return array(
'status' => 'success'

@ -99,16 +99,9 @@ class SessionController extends Controller{
$view = \OC\Files\Filesystem::getView();
$path = $view->getPath($fileId);
if ($view->isUpdatable($path)) {
$file = new File($fileId);
$response = Db\Session::start($this->uid, $file);
} else {
$info = $view->getFileInfo($path);
$response = [
'permissions' => $info['permissions'],
'id' => $fileId
];
}
$file = new File($fileId);
$response = Db\Session::start($this->uid, $file);
$response = array_merge(
$response,
[ 'status'=>'success' ]

@ -17,29 +17,6 @@ $.widget('oc.documentGrid', {
jQuery.when(this._load(fileId))
.then(function(){
that._render();
if (!documentsMain.isGuest) {
var editGroups = $('#edit_groups').val()
.split('|')
.filter(function(e) {
return e.length !== 0;
});
var usergroups = $('#usergroups').val()
.split('|')
.filter(function(e) {
return e.length !== 0;
});
documentsMain.canEdit = (editGroups.length === 0);
if (!documentsMain.canEdit && usergroups.length >= 1) {
for (var idx in usergroups) {
if (editGroups.indexOf(usergroups[idx]) !== -1) {
documentsMain.canEdit = true;
break;
}
}
}
}
documentsMain.renderComplete = true;
});
},
@ -658,6 +635,7 @@ var documentsMain = {
documentsMain.esId = response.es_id;
documentsMain.memberId = response.member_id;
documentsMain.canEdit = response.permissions & OC.PERMISSION_UPDATE;
documentsMain.loadDocument();

@ -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();
@ -49,7 +49,7 @@ class Wopi extends \OCA\Richdocuments\Db{
// Get the virtual path (if the file is shared).
$path = $view->getPath($fileId);
if (!$view->is_file($path) || !$view->isUpdatable($path)) {
if (!$view->is_file($path)) {
throw new \Exception('Invalid fileId.');
}
@ -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']
);
}
}

@ -51,6 +51,4 @@ script('files', 'jquery.fileupload');
<?php if ($_['enable_previews']): ?>
<input type="hidden" id="previews_enabled" value="<?php p($_['enable_previews']) ?>" />
<?php endif; ?>
<input type="hidden" name="allowShareWithLink" id="allowShareWithLink" value="<?php p($_['allowShareWithLink']) ?>" />
<input type="hidden" name="edit_groups" id="edit_groups" value="<?php p($_['edit_groups']) ?>" />
<input type="hidden" name="usergroups" id="usergroups" value="<?php p($_['usergroups']) ?>" />
<input type="hidden" name="allowShareWithLink" id="allowShareWithLink" value="<?php p($_['allowShareWithLink']) ?>" />
Loading…
Cancel
Save