Compare commits

...

46 Commits
master ... nc11

Author SHA1 Message Date
Andras Timar
93f8b0da47 Bump version to 1.11.34 2017-07-31 15:25:27 +02:00
Pranav Kant
3eba8b7644 Use fileId instead of dir
(cherry picked from commit e9f9711421ed1eba9cdb3b787b1a49eaed7373d1)
2017-07-31 15:21:45 +02:00
Andreas Böhler
909053b299 Fix editing publicly shared documents
(cherry picked from commit c4b794360a571680201f285713a977391848b594)
2017-07-31 15:21:39 +02:00
Andras Timar
29d587293d Delete creator/last modifier name from document templates
(cherry picked from commit 3af4174ce08ce5f909a251f242d0adbc8e05929c)
2017-07-31 15:21:18 +02:00
Andras Timar
9d2563d545 Bump version to 1.11.33 2017-06-15 13:04:28 +02:00
Andras Timar
3a8a629d10 Restore 'Enable edit for specific groups' feature, fixes #66
(cherry picked from commit aa4df2e800e3038d1621d5fc7451bbe2ac32d699)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-06-15 12:59:46 +02:00
Patrik Kernstock
d76740bc75 only edit textfiles when texteditorapp is disabled
Signed-off-by: Patrik Kernstock <info@pkern.at>
(cherry picked from commit 4db76d6f015bd3efd0ef35a4ebba2372828dd76e)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-06-15 12:59:33 +02:00
Patrik Kernstock
5855b7de9e Do not open text files using Collabora app
Signed-off-by: Patrik Kernstock <info@pkern.at>(cherry picked from commit dee49910913d2ec8060e72fe67522ad37d9b666d)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-06-15 12:59:25 +02:00
Pranav Kant
9d4cff8f97 Include support for X-LOOL-WOPI-Timestamp
See for more detailed message:
https://github.com/owncloud/richdocuments/pull/178

(cherry picked from commit 65769bd861adb9daf8b393e1b0451f52b796d726)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-06-15 12:58:44 +02:00
Andras Timar
ba25db2b4d Merge pull request #95 from pranavk/nc11-undefined
Undefined owneruid
2017-06-07 17:30:45 +02:00
Pranav Kant
fc24ac3319 Undefined owneruid 2017-06-07 20:47:31 +05:30
Andras Timar
bbefee2e4f Update CHAMGELOG.md. for 1.11.32 2017-06-06 09:29:18 +02:00
Pranav Kant
49a73108e9 Shorter db index name
Fixes #54

(cherry picked from commit 2058ec84e583e03d5c0670953e0475f8894b55ae)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-06-06 09:25:57 +02:00
Pranav Kant
32755343ed Use the file owner from the share object, if available
Fixes #85

When a link is shared on external storage and user is not logged in, the
owner returned by the $file object is null. Use owner information from
the $share object whenever available.

(cherry picked from commit ee09fb07482e288c3245fb0948220ad6cedf3c32)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-06-06 09:24:51 +02:00
Pranav Kant
2c1dd44651 Don't throw exception when user not found
It might be a public link share.

(cherry picked from commit 3f4aa7b23ec997457e244fa94464b11dfe08aa08)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-06-06 09:24:29 +02:00
Andras Timar
57f6a5ba32 Merge pull request #81 from pranavk/nc11-usernames
Show Display Name of user, not its uid in userlist
2017-05-29 08:32:17 +02:00
Pranav Kant
654c8e988d Show Display Name of user, not its uid in userlist
(cherry picked from commit 3940ec64c7cf99ffaf70fcfc594fc49e5c2c415a)
2017-05-25 19:08:52 +05:30
Andras Timar
257e9f2020 Bump version to 1.11.31 2017-05-25 13:52:13 +02:00
Pranav Kant
9afe6fb69c Guard encryption support
(cherry picked from commit c14ff8fee8b3a64212aed0de0aa832581edb6e8d)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-05-25 13:50:58 +02:00
Andras Timar
c99ec2d615 Bump version to 1.11.30 2017-05-25 12:01:14 +02:00
Pranav Kant
0a4c5816ee Register the change under user's name when saving the document
(cherry picked from commit 0f086cfe87294a62f6ae0501c1b55a5011ed71a3)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-05-25 11:57:01 +02:00
Pranav Kant
6b112402f9 Support opening encrypted files
(cherry picked from commit eef417f05bf942a3b658bbd0db0b94d9fed3f53f)
Signed-off-by: Andras Timar <andras.timar@collabora.com>
2017-05-25 11:55:52 +02:00
Andras Timar
b44c4da9a5 Merge pull request #61 from pranavk/nc11
Revert "Remove unrequired route"; respect OOXML settings again
2017-05-25 11:46:16 +02:00
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
Pranav Kant
d6c90226b9 Revert "Remove unrequired route"; respect OOXML settings again
This reverts commit aa89c908a70dddabb39ea7d0a166e147e31d3f5d.

(cherry picked from commit 0c14789cc35acd0a487e24ef220f96b5207a6118)
2017-05-19 23:57:30 +05:30
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
19 changed files with 308 additions and 124 deletions

View File

@ -1,3 +1,46 @@
**1.11.34**
- Bug: Fix editing publicly shared documents
- Bug: Delete creator/last modifier name from document templates
**1.11.33**
- Feature: Restore 'Enable edit for specific groups' feature, fixes #66
- Feature: Only edit textfiles with Collabora Online, when texteditorapp is disabled
- Feature: Include support for X-LOOL-WOPI-Timestamp
- Bug: Undefined variable 'owneruid'
**1.11.32**
- Bug: Show Display Name of user, not its uid in userlist
- Bug: Do not throw exception when user not found. It might be a public link share.
- Bug: Use the file owner from the share object, if available. Fixes #85.
- Bug: Shorter db index name. Fixes #54.
**1.11.31**
- Bug: Guard encryption support
**1.11.30**
- Feature: Support opening encrypted files
- Bug: Respect OOXML settings again
- Bug: Register the change under users name when saving the document
**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
- Security: Properly check for password on password protected shares

View File

@ -121,7 +121,7 @@
</field>
<index>
<name>richdocuments_wopi_token_idx</name>
<name>rd_wopi_token_idx</name>
<unique>true</unique>
<field>
<name>token</name>

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.34</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

@ -25,5 +25,6 @@ return [
//settings
['name' => 'settings#setSettings', 'url' => 'ajax/admin.php', 'verb' => 'POST'],
['name' => 'settings#getSettings', 'url' => 'ajax/settings.php', 'verb' => 'GET'],
]
];

Binary file not shown.

Binary file not shown.

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...'));
@ -15,6 +15,17 @@ var documentsSettings = {
);
},
saveGroups: function(groups) {
var data = {
'edit_groups': groups
};
$.post(
OC.filePath('richdocuments', 'ajax', 'admin.php'),
data
);
},
saveDocFormat: function(format) {
$.post(
OC.filePath('richdocuments', 'ajax', 'admin.php'),
@ -27,7 +38,19 @@ var documentsSettings = {
OC.msg.finishedAction('#documents-admin-msg', response);
},
initEditGroups: function() {
var groups = $('#edit_group_select').val();
if (groups !== '') {
OC.Settings.setupGroupsSelect($('#edit_group_select'));
$('.edit-groups-enable').attr('checked', 'checked');
} else {
$('.edit-groups-enable').attr('checked', null);
}
},
initialize: function() {
documentsSettings.initEditGroups();
$('#wopi_apply').on('click', documentsSettings.save);
$(document).on('change', '.doc-format-ooxml', function() {
@ -35,6 +58,27 @@ var documentsSettings = {
documentsSettings.saveDocFormat(ooxml ? 'ooxml' : 'odf');
});
$(document).on('change', '#edit_group_select', function() {
var element = $(this).parent().find('input.edit-groups-enable');
var groups = $(this).val();
documentsSettings.saveGroups(groups);
});
$(document).on('change', '.edit-groups-enable', function() {
var $select = $(this).parent().find('#edit_group_select');
$select.val('');
if (this.checked) {
OC.Settings.setupGroupsSelect($select, {
placeholder: t('core', 'All')
});
} else {
$select.select2('destroy');
}
$select.change();
});
}
};

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,8 @@ var odfViewer = {
'application/vnd.wordperfect',
'application/msonenote',
'application/msword',
'application/rtf',
'text/rtf',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
'application/vnd.ms-word.document.macroEnabled.12',
@ -35,34 +37,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');
}
},
@ -79,17 +66,17 @@ var odfViewer = {
var viewer;
if($('#isPublic').val() === '1') {
viewer = OC.generateUrl(
'apps/richdocuments/public?shareToken={shareToken}&fileName={fileName}&requesttoken={requesttoken}',
'apps/richdocuments/public?shareToken={shareToken}&fileName={fileName}&requesttoken={requesttoken}&fileId={fileId}',
{
shareToken: $('#sharingToken').val(),
fileName: fileName,
dir: fileDir,
fileId: fileId,
requesttoken: OC.requestToken
}
);
} 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 +89,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%'});
@ -122,7 +109,6 @@ var odfViewer = {
$('#app-content').append($iframe);
},
onClose: function() {
if(typeof FileList !== "undefined") {
FileList.setViewerMode(false);
@ -131,8 +117,8 @@ var odfViewer = {
$('#richdocumentsframe').remove();
},
registerFilesMenu: function() {
var ooxml = false;
registerFilesMenu: function(response) {
var ooxml = response.doc_format === 'ooxml';
var docExt, spreadsheetExt, presentationExt;
var docMime, spreadsheetMime, presentationMime;
@ -219,15 +205,28 @@ $(document).ready(function() {
&& typeof OCA.Files !== 'undefined'
&& typeof OCA.Files.fileActions !== 'undefined'
) {
// check if texteditor app is enabled and loaded...
if (_.isUndefined(OCA.Files_Texteditor)) {
// it is not, so we do open text files with this app too.
odfViewer.supportedMimes.push('text/plain');
}
// notice: when changing 'supportedMimes' interactively (e.g. dev console),
// register() needs to be re-run to re-register the fileActions.
odfViewer.register();
odfViewer.registerFilesMenu();
$.get(
OC.filePath('richdocuments', 'ajax', 'settings.php'),
{},
odfViewer.registerFilesMenu
);
}
});
// 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) {
// FIXME: Filter compatible mime types
if ($('#isPublic').val() && odfViewer.supportedMimes.indexOf($('#mimetype').val()) !== -1) {
odfViewer.onEdit($('#filename').val());
}
});
@ -244,4 +243,4 @@ $(document).ready(function() {
$('#content').removeClass('loading');
}
}, false);
});
});

View File

@ -104,12 +104,24 @@ 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'),
];
$encryptionManager = \OC::$server->getEncryptionManager();
if ($encryptionManager->isEnabled())
{
// Update the current file to be accessible with system public shared key
$owner = $item->getOwner()->getUID();
$absPath = '/' . $owner . '/' . $item->getInternalPath();
$accessList = \OC::$server->getEncryptionFilesHelper()->getAccessList($absPath);
$accessList['public'] = true;
$encryptionManager->getEncryptionModule()->update($absPath, $owner, $accessList);
}
$response = new TemplateResponse('richdocuments', 'documents', $params, 'empty');
$policy = new ContentSecurityPolicy();
$policy->addAllowedFrameDomain($this->appConfig->getAppValue('wopi_url'));
@ -130,7 +142,7 @@ class DocumentController extends Controller {
* @return TemplateResponse
* @throws \Exception
*/
public function publicPage($shareToken, $fileName) {
public function publicPage($shareToken, $fileName, $fileId) {
try {
$share = $this->shareManager->getShareByToken($shareToken);
// not authenticated ?
@ -144,7 +156,7 @@ class DocumentController extends Controller {
$node = $share->getNode();
if($node instanceof Folder) {
$item = $node->get($fileName);
$item = $node->getById($fileId)[0];
} else {
$item = $node;
}
@ -153,10 +165,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 +244,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

@ -45,12 +45,27 @@ class SettingsController extends Controller{
$this->discoveryManager = $discoveryManager;
}
/**
* @NoAdminRequired
*
* @return JSONResponse
*/
public function getSettings() {
return new JSONResponse([
'wopi_url' => $this->appConfig->getAppValue('wopi_url'),
'edit_groups' => $this->appConfig->getAppValue('edit_groups'),
'doc_format' => $this->appConfig->getAppValue('doc_format'),
]);
}
/**
* @param string $wopi_url
* @param string $edit_groups
* @param string $doc_format
* @return JSONResponse
*/
public function setSettings($wopi_url,
$edit_groups,
$doc_format){
$message = $this->l10n->t('Saved');
@ -63,6 +78,10 @@ class SettingsController extends Controller{
}
}
if ($edit_groups !== null){
$this->appConfig->setAppValue('edit_groups', $edit_groups);
}
if ($doc_format !== null) {
$this->appConfig->setAppValue('doc_format', $doc_format);
}

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,22 @@ 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;
// Signifies LOOL that document has been changed externally in this storage
const LOOL_STATUS_DOC_CHANGED = 1010;
/**
* @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 +68,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);
}
@ -110,9 +95,10 @@ class WopiController extends Controller {
'Version' => $version,
'UserId' => $res['editor'] !== '' ? $res['editor'] : 'Guest user',
'OwnerId' => $res['owner'],
'UserFriendlyName' => $res['editor'] !== '' ? $res['editor'] : 'Guest user',
'UserFriendlyName' => $res['editor'] !== '' ? \OC_User::getDisplayName($res['editor']) : 'Guest user',
'UserCanWrite' => $res['canwrite'] ? true : false,
'PostMessageOrigin' => $res['server_host'],
'LastModifiedTime' => Helper::toISO8601($file->getMtime())
]
);
}
@ -130,22 +116,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'));
\OC_User::setIncognitoMode(true);
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,28 +161,48 @@ 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);
}
try {
/** @var File $file */
$userFolder = $this->rootFolder->getUserFolder($res['owner']);
$file = $userFolder->getById($fileId)[0];
$wopiHeaderTime = $this->request->getHeader('X-LOOL-WOPI-Timestamp');
if (!is_null($wopiHeaderTime) && $wopiHeaderTime != Helper::toISO8601($file->getMTime())) {
\OC::$server->getLogger()->debug('Document timestamp mismatch ! WOPI client says mtime {headerTime} but storage says {storageTime}', [
'headerTime' => $wopiHeaderTime,
'storageTime' => Helper::toISO8601($file->getMtime())
]);
// Tell WOPI client about this conflict.
return new JSONResponse(['LOOLStatusCode' => self::LOOL_STATUS_DOC_CHANGED], Http::STATUS_CONFLICT);
}
$content = fopen('php://input', 'rb');
// Setup the FS which is needed to emit hooks (versioning).
\OC_Util::tearDownFS();
\OC_Util::setupFS($res['owner']);
// Set the user to register the change under his name
$editor = \OC::$server->getUserManager()->get($res['editor']);
if (!is_null($editor)) {
\OC::$server->getUserSession()->setUser($editor);
}
$file->putContent($content);
return new JSONResponse();
return new JSONResponse(['LastModifiedTime' => Helper::toISO8601($file->getMtime())]);
} catch (\Exception $e) {
return new JSONResponse([], Http::STATUS_INTERNAL_SERVER_ERROR);
}

View File

@ -49,8 +49,6 @@ class Admin implements ISettings {
'wopi_url' => $this->config->getAppValue('richdocuments', 'wopi_url'),
'edit_groups' => $this->config->getAppValue('richdocuments', 'edit_groups'),
'doc_format' => $this->config->getAppValue('richdocuments', 'doc_format'),
'test_wopi_url' => $this->config->getAppValue('richdocuments', 'test_wopi_url'),
'test_server_groups' => $this->config->getAppValue('richdocuments', 'test_server_groups')
],
'blank'
);

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;
@ -49,11 +50,13 @@ class TokenManager {
IManager $shareManager,
IURLGenerator $urlGenerator,
Parser $wopiParser,
AppConfig $appConfig,
$UserId) {
$this->rootFolder = $rootFolder;
$this->shareManager = $shareManager;
$this->urlGenerator = $urlGenerator;
$this->wopiParser = $wopiParser;
$this->appConfig = $appConfig;
$this->userId = $UserId;
}
@ -64,33 +67,49 @@ 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);
$owneruid = null;
// if the user is not logged-in do use the sharers storage
if($shareToken !== null) {
/** @var File $file */
$rootFolder = $this->rootFolder;
$share = $this->shareManager->getShareByToken($shareToken);
$updatable = (bool)($share->getPermissions() & \OCP\Constants::PERMISSION_UPDATE);
$owneruid = $share->getShareOwner();
} else {
try {
/** @var File $file */
$rootFolder = $this->rootFolder->getUserFolder($this->userId);
$updatable = $rootFolder->isUpdateable();
// 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 ($editorGroup !== null && sizeof($editorGroup->searchUsers($editorUid)) > 0) {
$updatable = true;
break;
}
}
}
} catch (\Exception $e) {
throw $e;
}
}
/** @var File $file */
$file = $rootFolder->getById($fileId)[0];
// If its a public share, use the owner from the share, otherwise check the file object
if (is_null($owneruid)) {
$owneruid = $file->getOwner()->getUID();
}
$row = new Wopi();
$serverHost = $this->urlGenerator->getAbsoluteURL('/');//$this->request->getServerProtocol() . '://' . $this->request->getServerHost();
$token = $row->generateFileToken($fileId, $file->getOwner()->getUID(), $this->userId, $version, (int)$updatable, $serverHost);
$token = $row->generateFileToken($fileId, $owneruid, $this->userId, $version, (int)$updatable, $serverHost);
try {
@ -102,4 +121,4 @@ class TokenManager {
throw $e;
}
}
}
}

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

@ -11,9 +11,53 @@
namespace OCA\Richdocuments;
use \DateTime;
use \DateTimeZone;
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,
];
}
/**
* WOPI helper function to convert to ISO 8601 round-trip format.
* @param integer $time Must be seconds since unix epoch
*/
public static function toISO8601($time)
{
// TODO: Be more precise and don't ignore milli, micro seconds ?
$datetime = DateTime::createFromFormat('U', $time, new DateTimeZone('UTC'));
if ($datetime)
return $datetime->format('Y-m-d\TH:i:s.u\Z');
return false;
}
public static function getNewFileName($view, $path, $prepend = ' '){
$fileNum = 1;

View File

@ -9,7 +9,10 @@ script('richdocuments', 'admin');
<br/><button type="button" id="wopi_apply"><?php p($l->t('Apply')) ?></button>
<span id="documents-admin-msg" class="msg"></span>
<br/>
<input type="checkbox" class="edit-groups-enable" id="edit_groups_enable-richdocuments" />
<label for="edit_groups_enable-richdocuments"><?php p($l->t('Enable edit for specific groups')) ?></label>
<input type="hidden" id="edit_group_select" value="<?php p($_['edit_groups'])?>" title="<?php p($l->t('All')); ?>" style="width: 200px">
<br/>
<input type="checkbox" class="doc-format-ooxml" id="doc_format_ooxml_enable-richdocuments" <?php p($_['doc_format'] === 'ooxml' ? 'checked' : '') ?> />
<label for="doc_format_ooxml_enable-richdocuments"><?php p($l->t('Use OOXML by default for new files')) ?></label>
</div>
</div>

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