Compare commits

...

22 Commits

Author SHA1 Message Date
Andras Timar
f74a7b7f4a Bump version to 1.11.29 2017-05-24 22:40:54 +02:00
Andras Timar
cc5fb99cb4 Fix issue#68: undefined variable instanceId
(cherry picked from commit 4ffef00aca19df831179d51a8cef5376df6fd6c1)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-05-24 15:12:23 +02:00
Andras Timar
d4e0ac2387 Bump version to 1.11.28
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-05-23 10:45:44 +02:00
Marius Blüm
586c925bb1 Update Collabora screenshots
Signed-off-by: Marius Blüm <marius@lineone.io>(cherry picked from commit b320276ee187b9127ae785df6ab2a208ed7f6cf7)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-05-23 10:44:15 +02:00
Pranav Kant
5e42ea1dab allowfullscreen
(cherry picked from commit 75a12f07e4474004cd3c7fd06a36fc07397eab95)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-05-23 10:43:03 +02:00
Andras Timar
6925e4f2f6 Bump version to 1.11.27 2017-05-18 10:14:03 +02:00
Andras Timar
bd68097a92 Update CHANGELOG.md
(cherry picked from commit f6b7e441d9f4dd4b7155e15bb43375c05b427c2c)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-05-18 10:13:25 +02:00
Pranav Kant
2385b70915 Fix file revisions
(cherry picked from commit 9bb400714cf8297ba1e40f4014730f0f40a4a43a)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-05-18 10:12:08 +02:00
Pranav Kant
b1e51782fc Bin superfluous returnToDir logic
This was initially introduced in OC so that we know which directory to
go after we close the editor but this seems unnecessary here in NC as
richdocuments is just an iframe which is removed from DOM when we close
the document.

(cherry picked from commit a5f6569591f11905c75b7cf978f76be12368ba42)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-05-18 10:10:31 +02:00
Andras Timar
ff1ee24c46 modify version to 1.1.26-nc11 2017-04-28 12:41:48 +02:00
Andras Timar
ff7aa2d5e8 Bump version to 1.1.25.1 for Nextcloud 11 2017-04-28 12:29:17 +02:00
Andras Timar
472a22ef21 Updated CHANGELOG.md 2017-04-28 12:28:15 +02:00
Pranav Kant
c21c029fa4 Send file path to the client also, fix revision history
(cherry picked from commit 66935d4bed3dc053b00fdb86921d127fbc11ada9)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-04-28 12:28:15 +02:00
Lukas Reschke
7e4c59e360 Append instance id to rev history
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
(cherry picked from commit 9cd9258dbbf1e4c740213c8ab4cc6dfcbbab2a29)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-04-28 12:28:15 +02:00
Lukas Reschke
ad61db1158 Add instance id to file id
For multitenancy

Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
(cherry picked from commit 1441bdc59423beac0ec72e92d4c3e2a78ad1da10)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-04-28 12:28:14 +02:00
michag86
6b629b2c67 Make files_versions work again
Added some lines which were lost after rewrite with version 1.1.22.
(cherry picked from commit c72f22e18018925f4be9e007bbac0ce2fba6cc9d)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-04-28 12:28:14 +02:00
Pranav Kant
f790f640b1 Fix incorrect language tags feeding to loleaflet
loleaflet expect a BCP47 language tag syntax while OC.getLocale returns
a lanugage tag where subtags are separated by '_' instead of '-'
(BCP47).

It seems safe to just replace '_' with '-' before feeding it to
loleaflet

(cherry picked from commit 5596ae17ce3610ebb23f7709112fdcaa314efc28)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-04-28 12:28:14 +02:00
Pranav Kant
674a6cb384 Try opening readonly documents too
Also simplify the logic during file action registration. Basically, we
should try to open all known mimetypes; file permissions are taken care
of later in the WOPI protocol.

Without this commit, it is not possible to open a document in a
directory for which user has no write access.

(cherry picked from commit f36c5106d6c52decac6caeb46c3ed65797e9a3d4)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-04-28 12:28:14 +02:00
Andras Timar
df0c7cce94 replace trailing slash of wopi url
(cherry picked from commit 6d49e2d003b1c724bbc1e9958b2eb5946b75e2eb)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-04-28 12:28:14 +02:00
Andras Timar
1cc5e43106 set the correct language tag expected by JS
(cherry picked from commit b565415e1c223afd690ce62aa9604aabe86b31a2)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-04-28 12:28:13 +02:00
Andras Timar
f74b0b3018 add rtf and txt as supported file formats
(cherry picked from commit 829b2b77b977102c4df0c1657b1bd7bc68c876ba)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-04-28 12:28:13 +02:00
Lukas Reschke
bf72f5b01d Uses proper top height
Fixes https://github.com/nextcloud/richdocuments/issues/5

Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
(cherry picked from commit 43ffbf2e97701cb62a71d0e81bc8efda1b1e9e5b)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-04-28 12:28:13 +02:00
12 changed files with 115 additions and 105 deletions

View File

@ -1,3 +1,22 @@
**1.11.29**
- Bug: fix undefined instanceId
**1.11.28**
- Bug: Allow full screen
- Updated screenshots
**1.11.27**
- Bug: Fix revision history
**1.1.25.1**
- Bug: Fix height for revision history viewer
- Bug: Set the correct language tag expected by JS
- Bug: Replace trailing slash of WOPI URL
- Bug: Try opening readonly documents too
- Bug: Fix revision history
- Feature: Add rtf and txt as supported file formats
- Feature: Support for multitenancy installations of LibreOffice Online
**1.1.24**
- Bug: Fix undefined PHP notices
- Security: Properly check for password on password protected shares

View File

@ -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.24</version>
<version>1.11.29</version>
<author>Collabora Productivity based on work of Frank Karlitschek, Victor Dubiniuk</author>
<bugs>https://github.com/nextcloud/richdocuments/issues</bugs>
<repository type="git">https://github.com/nextcloud/richdocuments.git</repository>
@ -22,7 +22,6 @@
<prevent_group_restriction/>
</types>
<screenshot>https://nextcloud.com/wp-content/themes/next/assets/img/features/collabora-document.png</screenshot>
<screenshot>https://nextcloud.com/wp-content/themes/next/assets/img/features/collabora-app.png</screenshot>
<screenshot>https://nextcloud.com/wp-content/themes/next/assets/img/features/collabora-presentation.png</screenshot>
<screenshot>https://nextcloud.com/wp-content/themes/next/assets/img/features/collabora-spreadsheet.png</screenshot>
<settings>

View File

@ -133,7 +133,7 @@
width: 100%;
z-index: 600;
background-color: #ddd !important;
top: 45px;
top: 0px;
bottom: 0;
}
@ -149,7 +149,7 @@
z-index: 600;
background-color: #efefef !important;
right: 0;
top: 45px;
top: 0px;
bottom: 0;
box-sizing: border-box;
overflow-x: hidden;

View File

@ -4,7 +4,7 @@ var documentsSettings = {
save : function() {
$('#wopi_apply').attr('disabled', true);
var data = {
wopi_url : $('#wopi_url').val()
wopi_url : $('#wopi_url').val().replace(/\/$/, '')
};
OC.msg.startAction('#documents-admin-msg', t('richdocuments', 'Saving...'));

View File

@ -72,7 +72,6 @@ var documentsMain = {
loadErrorHint : '',
renderComplete: false, // false till page is rendered with all required data about the document(s)
toolbar : '<div id="ocToolbar"><div id="ocToolbarInside"></div><span id="toolbar" class="claro"></span></div>',
returnToDir : null, // directory where we started from in the 'Files' app
UI : {
/* Editor wrapper HTML */
@ -129,7 +128,7 @@ var documentsMain = {
var urlsrc = documentsMain.urlsrc +
"WOPISrc=" + wopisrc +
"&title=" + encodeURIComponent(title) +
"&lang=" + OC.getLocale() +
"&lang=" + OC.getLocale().replace('_', '-') + // loleaflet expects a BCP47 language tag syntax
"&permission=readonly";
// access_token - must be passed via a form post
@ -163,7 +162,6 @@ var documentsMain = {
if (version === 0) {
formattedTimestamp = t('richdocuments', 'Latest revision');
downloadUrl = OC.generateUrl('apps/files/download'+ documentPath);
fileId = fileId.replace(/_.*/, '');
} else {
downloadUrl = OC.generateUrl('apps/files_versions/download.php?file={file}&revision={revision}',
{file: documentPath, revision: version});
@ -268,12 +266,8 @@ var documentsMain = {
documentsMain.UI.notify(t('richdocuments', 'Failed to revert the document to older version'));
}
// generate file id with returnToDir information in it, if any
var fileid = e.currentTarget.parentElement.dataset.fileid.replace(/_.*/, '') +
(documentsMain.returnToDir ? '_' + documentsMain.returnToDir : '');
// load the file again, it should get reverted now
window.location = OC.generateUrl('apps/richdocuments/index#{fileid}', {fileid: fileid});
window.location = OC.generateUrl('apps/richdocuments/index#{fileid}', {fileid: e.currentTarget.parentElement.dataset.fileid});
window.location.reload();
documentsMain.overlay.documentOverlay('hide');
}
@ -320,7 +314,7 @@ var documentsMain = {
var urlsrc = documentsMain.urlsrc +
"WOPISrc=" + wopisrc +
"&title=" + encodeURIComponent(title) +
"&lang=" + OC.getLocale() +
"&lang=" + OC.getLocale().replace('_', '-') + // loleaflet expects a BCP47 language tag syntax
"&closebutton=1" +
"&revisionhistory=1";
if (!documentsMain.canEdit || action === "view") {
@ -426,11 +420,6 @@ var documentsMain = {
// Does anything indicate that we need to autostart a session?
fileId = getURLParameter('fileid').replace(/^\W*/, '');
if (fileId.indexOf('_') >= 0) {
documentsMain.returnToDir = unescape(fileId.replace(/^[^_]*_/, ''));
fileId = fileId.replace(/_.*/, '');
}
documentsMain.show(fileId);
if (fileId) {

View File

@ -1,7 +1,7 @@
/* globals FileList, OCA.Files.fileActions, oc_debug */
var odfViewer = {
isDocuments : false,
supportedMimesReadWrite: [
supportedMimes: [
'application/vnd.oasis.opendocument.text',
'application/vnd.oasis.opendocument.spreadsheet',
'application/vnd.oasis.opendocument.graphics',
@ -12,6 +12,9 @@ var odfViewer = {
'application/vnd.wordperfect',
'application/msonenote',
'application/msword',
'application/rtf',
'text/rtf',
'text/plain',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
'application/vnd.ms-word.document.macroEnabled.12',
@ -35,34 +38,19 @@ var odfViewer = {
register : function() {
var i,
mimeReadOnly,
mimeReadWrite;
mime;
for (i = 0; i < odfViewer.supportedMimesReadWrite.length; ++i) {
mimeReadOnly = odfViewer.supportedMimesReadWrite[i];
OCA.Files.fileActions.register(mimeReadOnly, 'View', OC.PERMISSION_READ, '', odfViewer.onEdit);
OCA.Files.fileActions.setDefault(mimeReadOnly, 'View');
}
for (i = 0; i < odfViewer.supportedMimesReadWrite.length; ++i) {
mimeReadWrite = odfViewer.supportedMimesReadWrite[i];
for (i = 0; i < odfViewer.supportedMimes.length; ++i) {
mime = odfViewer.supportedMimes[i];
OCA.Files.fileActions.register(
mimeReadWrite,
mime,
'Edit',
OC.PERMISSION_UPDATE,
OC.PERMISSION_UPDATE | OC.PERMISSION_READ,
OC.imagePath('core', 'actions/rename'),
odfViewer.onEdit,
t('richdocuments', 'Edit')
);
OCA.Files.fileActions.register(
mimeReadWrite,
'View',
OC.PERMISSION_READ,
OC.imagePath('core', 'actions/rename'),
odfViewer.onEdit,
t('richdocuments', 'View')
);
OCA.Files.fileActions.setDefault(mimeReadWrite, 'View');
OCA.Files.fileActions.setDefault(mimeReadWrite, 'Edit');
OCA.Files.fileActions.setDefault(mime, 'Edit');
}
},
@ -89,7 +77,7 @@ var odfViewer = {
);
} else {
viewer = OC.generateUrl(
'apps/richdocuments/index?fileId={fileId}_{dir}&requesttoken={requesttoken}',
'apps/richdocuments/index?fileId={fileId}&requesttoken={requesttoken}',
{
fileId: fileId,
dir: fileDir,
@ -102,7 +90,7 @@ var odfViewer = {
FileList.setViewerMode(true);
}
var $iframe = $('<iframe id="richdocumentsframe" style="width:100%;height:100%;display:block;position:absolute;top:0;" src="'+viewer+'" />');
var $iframe = $('<iframe id="richdocumentsframe" allowfullscreen style="width:100%;height:100%;display:block;position:absolute;top:0;z-index:5;" src="'+viewer+'" />');
if ($('#isPublic').val()) {
// force the preview to adjust its height
$('#preview').append($iframe).css({height: '100%'});
@ -227,7 +215,7 @@ $(document).ready(function() {
// FIXME: Hack for single public file view since it is not attached to the fileslist
$(document).ready(function(){
// FIXME: FIlter compatible mime types
if ($('#isPublic').val() && odfViewer.supportedMimesReadWrite.indexOf($('#mimetype').val()) !== -1) {
if ($('#isPublic').val() && odfViewer.supportedMimes.indexOf($('#mimetype').val()) !== -1) {
odfViewer.onEdit($('#filename').val());
}
});

View File

@ -104,10 +104,11 @@ class DocumentController extends Controller {
$params = [
'permissions' => $item->getPermissions(),
'title' => $item->getName(),
'fileId' => $item->getId(),
'fileId' => $item->getId() . '_' . $this->settings->getSystemValue('instanceid'),
'token' => $token,
'urlsrc' => $urlSrc,
'path' => '/',
'path' => $folder->getRelativePath($item->getPath()),
'instanceId' => $this->settings->getSystemValue('instanceid'),
];
$response = new TemplateResponse('richdocuments', 'documents', $params, 'empty');
@ -153,10 +154,11 @@ class DocumentController extends Controller {
$params = [
'permissions' => $share->getPermissions(),
'title' => $item->getName(),
'fileId' => $item->getId(),
'fileId' => $item->getId() . '_' . $this->settings->getSystemValue('instanceid'),
'token' => $token,
'urlsrc' => $urlSrc,
'path' => '/',
'instanceId' => $this->settings->getSystemValue('instanceid'),
];
$response = new TemplateResponse('richdocuments', 'documents', $params, 'empty');
@ -231,12 +233,13 @@ class DocumentController extends Controller {
if ($content && $view->file_put_contents($path, $content)) {
$info = $view->getFileInfo($path);
$ret = $this->wopiParser->getUrlSrc($mimetype);
$lolang = strtolower(str_replace('_', '-', $this->settings->getUserValue($this->uid, 'core', 'lang', 'en')));
$response = array(
'status' => 'success',
'fileid' => $info['fileid'],
'fileid' => $info['fileid'] . '_' . $this->settings->getSystemValue('instanceid'),
'urlsrc' => $ret['urlsrc'],
'action' => $ret['action'],
'lolang' => $this->settings->getUserValue($this->uid, 'core', 'lang', 'en'),
'lolang' => $lolang,
'data' => \OCA\Files\Helper::formatFileInfo($info)
);
} else {

View File

@ -21,7 +21,9 @@
namespace OCA\Richdocuments\Controller;
use OC\Files\View;
use OCA\Richdocuments\Db\Wopi;
use OCA\Richdocuments\Helper;
use OCA\Richdocuments\WOPI\Parser;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
@ -35,32 +37,19 @@ use OCP\AppFramework\Http\StreamResponse;
class WopiController extends Controller {
/** @var IRootFolder */
private $rootFolder;
/** @var string */
private $userId;
/** @var IUserManager */
private $userManager;
/** @var Parser */
private $wopiParser;
/**
* @param string $appName
* @param IRequest $request
* @param IRootFolder $rootFolder
* @param string $UserId
* @param IUserManager $userManager
* @param Parser $wopiParser
*/
public function __construct($appName,
$UserId,
IRequest $request,
IRootFolder $rootFolder,
IUserManager $userManager,
Parser $wopiParser) {
IRootFolder $rootFolder) {
parent::__construct($appName, $request);
$this->rootFolder = $rootFolder;
$this->userId = $UserId;
$this->userManager = $userManager;
$this->wopiParser = $wopiParser;
}
/**
@ -76,16 +65,9 @@ class WopiController extends Controller {
public function checkFileInfo($fileId) {
$token = $this->request->getParam('access_token');
$arr = explode('_', $fileId, 2);
$version = '0';
if (count($arr) === 2) {
list($fileId, $version) = $arr;
}
$row = new Wopi();
$row->loadBy('token', $token);
$res = $row->getPathForToken($fileId, $version, $token);
list($fileId, , $version) = Helper::parseFileId($fileId);
$db = new Wopi();
$res = $db->getPathForToken($fileId, $token);
if ($res === false) {
return new JSONResponse([], Http::STATUS_FORBIDDEN);
}
@ -130,22 +112,32 @@ class WopiController extends Controller {
*/
public function getFile($fileId,
$access_token) {
$arr = explode('_', $fileId, 2);
$version = '0';
if (count($arr) === 2) {
list($fileId, $version) = $arr;
}
list($fileId, , $version) = Helper::parseFileId($fileId);
$row = new Wopi();
$row->loadBy('token', $access_token);
$res = $row->getPathForToken($fileId, $version, $access_token);
$res = $row->getPathForToken($fileId, $access_token);
try {
/** @var File $file */
$userFolder = $this->rootFolder->getUserFolder($res['owner']);
$file = $userFolder->getById($fileId)[0];
$response = new StreamResponse($file->fopen('rb'));
if ($version !== '0')
{
$view = new View('/' . $res['owner'] . '/files');
$relPath = $view->getRelativePath($file->getPath());
$versionPath = '/files_versions/' . $relPath . '.v' . $version;
$view = new View('/' . $res['owner']);
if ($view->file_exists($versionPath)){
$response = new StreamResponse($view->fopen($versionPath, 'rb'));
}
else {
$response->setStatus(Http::STATUS_NOT_FOUND);
}
}
else
{
$response = new StreamResponse($file->fopen('rb'));
}
$response->addHeader('Content-Disposition', 'attachment');
$response->addHeader('Content-Type', 'application/octet-stream');
return $response;
@ -165,17 +157,14 @@ class WopiController extends Controller {
* @param string $access_token
* @return JSONResponse
*/
public function putFile($fileId, $access_token) {
$arr = explode('_', $fileId, 2);
$version = '0';
if (count($arr) === 2) {
list($fileId, $version) = $arr;
}
public function putFile($fileId,
$access_token) {
list($fileId, , $version) = Helper::parseFileId($fileId);
$row = new Wopi();
$row->loadBy('token', $access_token);
$res = $row->getPathForToken($fileId, $version, $access_token);
$res = $row->getPathForToken($fileId, $access_token);
if (!$res['canwrite']) {
return new JSONResponse([], Http::STATUS_FORBIDDEN);
}
@ -185,6 +174,9 @@ class WopiController extends Controller {
$userFolder = $this->rootFolder->getUserFolder($res['owner']);
$file = $userFolder->getById($fileId)[0];
$content = fopen('php://input', 'rb');
// Setup the FS which is needed to emit hooks (versioning).
\OC_Util::tearDownFS();
\OC_Util::setupFS($res['owner']);
$file->putContent($content);
return new JSONResponse();
} catch (\Exception $e) {

View File

@ -22,6 +22,7 @@
namespace OCA\Richdocuments;
use OC\Share\Constants;
use OCA\Richdocuments\Helper;
use OCA\Richdocuments\Db\Wopi;
use OCA\Richdocuments\WOPI\Parser;
use OCP\Files\File;
@ -64,12 +65,7 @@ class TokenManager {
* @throws \Exception
*/
public function getToken($fileId, $shareToken = null) {
$arr = explode('_', $fileId, 2);
$version = '0';
if (count($arr) === 2) {
list($fileId, $version) = $arr;
}
list($fileId,, $version) = Helper::parseFileId($fileId);
// if the user is not logged-in do use the sharers storage
if($shareToken !== null) {
/** @var File $file */

View File

@ -56,12 +56,12 @@ class Wopi extends \OCA\Richdocuments\Db{
* constructs and validates the path.
* Returns the path, if valid, else false.
*/
public function getPathForToken($fileId, $version, $token){
public function getPathForToken($fileId, $token){
$wopi = new Wopi();
$row = $wopi->loadBy('token', $token)->getData();
\OC::$server->getLogger()->debug('Loaded WOPI Token record: {row}.', [ 'row' => $row ]);
if (count($row) == 0)
if (count($row) === 0)
{
// Invalid token.
http_response_code(401);
@ -75,11 +75,6 @@ class Wopi extends \OCA\Richdocuments\Db{
//$wopi->deleteBy('id', $row['id']);
//return false;
}
if ($row['fileid'] != $fileId || $row['version'] != $version){
// File unknown / user unauthorized (for the requested file).
http_response_code(404);
return false;
}
return array(
'owner' => $row['owner_uid'],

View File

@ -14,6 +14,34 @@ namespace OCA\Richdocuments;
class Helper {
const APP_ID = 'richdocuments';
/**
* @param string $fileId
* @return array
* @throws \Exception
*/
public static function parseFileId($fileId) {
$arr = explode('_', $fileId);
if (count($arr) === 1) {
$fileId = $arr[0];
$instanceId = '';
$version = '0';
} else if (count($arr) === 2) {
list($fileId, $instanceId) = $arr;
$version = '0';
} else if (count($arr) === 3) {
list($fileId, $instanceId, $version) = $arr;
} else {
throw new \Exception('$fileId has not the expected format');
}
return [
$fileId,
$instanceId,
$version,
];
}
public static function getNewFileName($view, $path, $prepend = ' '){
$fileNum = 1;

View File

@ -5,6 +5,7 @@
var richdocuments_token = '<?php p($_['token']) ?>';
var richdocuments_urlsrc = '<?php p($_['urlsrc']) ?>';
var richdocuments_path = '<?php p($_['path']) ?>';
var instanceId = '<?php p($_['instanceId']) ?>';
</script>
<?php