support for external apps (#124)

master
Pranav Kant 7 years ago committed by Andras Timar
parent d80a97af3a
commit 21504eb5a8

@ -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.12.34</version>
<version>1.12.35</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>

@ -18,6 +18,9 @@ return [
['name' => 'document#publicPage', 'url' => '/public', 'verb' => 'GET'],
['name' => 'document#create', 'url' => 'ajax/documents/create', 'verb' => 'POST'],
// external api access
['name' => 'document#extAppGetData', 'url' => '/ajax/extapp/data/{fileId}', 'verb' => 'POST'],
// WOPI access
['name' => 'wopi#checkFileInfo', 'url' => 'wopi/files/{fileId}', 'verb' => 'GET'],
['name' => 'wopi#getFile', 'url' => 'wopi/files/{fileId}/contents', 'verb' => 'GET'],

@ -1,6 +1,31 @@
/*global OC, $ */
var documentsSettings = {
_createExtApp: function() {
var app1 = document.createElement('div');
app1.setAttribute('class', 'external-app');
var appname1 = document.createElement('input');
appname1.setAttribute('class', 'external-apps-name');
$(app1).append(appname1);
var apptoken1 = document.createElement('input');
apptoken1.setAttribute('class', 'external-apps-token');
$(app1).append(apptoken1);
var apptokenbutton = document.createElement('button');
apptokenbutton.setAttribute('class', 'external-apps-gen-token-button');
apptokenbutton.innerHTML = 'Generate Token';
$(app1).append(apptokenbutton);
var appremovebutton = document.createElement('button');
appremovebutton.setAttribute('class', 'external-apps-remove-button');
appremovebutton.innerHTML = 'Remove';
$(app1).append(appremovebutton);
return app1;
},
save : function() {
$('#wopi_apply').attr('disabled', true);
var data = {
@ -38,6 +63,23 @@ var documentsSettings = {
OC.msg.finishedAction('#documents-admin-msg', response);
},
saveExternalApps: function(externalAppsData) {
var data = {
'external_apps': externalAppsData
};
OC.msg.startAction('#enable-external-apps-section-msg', t('richdocuments', 'Saving...'));
$.post(
OC.filePath('richdocuments', 'ajax', 'admin.php'),
data,
documentsSettings.afterSaveExternalApps
);
},
afterSaveExternalApps: function(response) {
OC.msg.finishedAction('#enable-external-apps-section-msg', response);
},
initEditGroups: function() {
var groups = $('#edit_group_select').val();
if (groups !== '') {
@ -48,11 +90,97 @@ var documentsSettings = {
}
},
initExternalApps: function() {
var externalAppsRaw = $(document).find('#external-apps-raw').val();
var apps = externalAppsRaw.split(',');
for (var i = 0; i < apps.length; ++i) {
if (apps[i] !== '') {
var app = apps[i].split(':');
var app1 = this._createExtApp();
// create a placeholder for adding new app
$('#external-apps-section').append(app1);
$(app1).find('.external-apps-name').val(app[0]);
$(app1).find('.external-apps-token').val(app[1]);
}
}
},
initialize: function() {
documentsSettings.initEditGroups();
documentsSettings.initExternalApps();
$('#wopi_apply').on('click', documentsSettings.save);
// destroy or create app name and token fields depending on whether the checkbox is on or off
$(document).on('change', '#enable_external_apps_cb-richdocuments', function() {
var page = $(this).parent();
page.find('#enable-external-apps-section').toggleClass('hidden', !this.checked);
if (this.checked) {
var app1 = documentsSettings._createExtApp();
$('#external-apps-section').append(app1);
} else {
page.find('.external-app').remove();
page.find('#external-apps-raw').val('');
documentsSettings.saveExternalApps('');
}
});
$(document).on('click', '.external-apps-gen-token-button', function() {
var appSection = $(this).parent();
var appToken = appSection.find('.external-apps-token');
// generate a random string
var len = 3;
var array = new Uint32Array(len);
window.crypto.getRandomValues(array);
var random = '';
for (var i = 0; i < len; ++i) {
random += array[i].toString(36);
}
// set the token in the field
appToken.val(random);
});
$(document).on('click', '.external-apps-remove-button', function() {
$(this).parent().remove();
});
$(document).on('click', '#external-apps-save-button', function() {
// read all the data in input fields, save the data in input-raw and send to backedn
var extAppsSection = $(this).parent();
var apps = extAppsSection.find('.external-app');
// convert all values into one single string and store it in raw input field
// as well as send the data to server
var raw = '';
for (var i = 0; i < apps.length; ++i) {
var appname = $(apps[i]).find('.external-apps-name');
var apptoken = $(apps[i]).find('.external-apps-token');
raw += appname.val() + ':' + apptoken.val() + ',';
}
extAppsSection.find('#external-apps-raw').val(raw);
documentsSettings.saveExternalApps(raw);
});
$(document).on('click', '#external-apps-add-button', function() {
// create a placeholder for adding new app
var app1 = documentsSettings._createExtApp();
$('#external-apps-section').append(app1);
});
$(document).on('click', '#test_wopi_apply', function() {
var groups = $(this).parent().find('#test_server_group_select').val();
var testserver = $(this).parent().find('#test_wopi_url').val();
if (groups !== '' && testserver !== '') {
documentsSettings.saveTestWopi(groups, testserver);
} else {
OC.msg.finishedError('#test-documents-admin-msg', 'Both fields required');
}
});
$(document).on('change', '.doc-format-ooxml', function() {
var ooxml = this.checked;
documentsSettings.saveDocFormat(ooxml ? 'ooxml' : 'odf');

@ -92,6 +92,66 @@ class DocumentController extends Controller {
$this->logger = $logger;
}
/**
* @PublicPage
* @NoCSRFRequired
*
* Returns the access_token and urlsrc for WOPI access for given $fileId
* Requests is accepted only when a secret_token is provided set by admin in
* settings page
*
* @param string $fileId
* @return access_token, urlsrc
*/
public function extAppGetData($fileId) {
$secretToken = $this->request->getParam('secret_token');
$apps = array_filter(explode(',', $this->appConfig->getAppValue('external_apps')));
foreach($apps as $app) {
if ($app !== '') {
if ($secretToken === $app) {
$appName = explode(':', $app);
\OC::$server->getLogger()->debug('External app "{extApp}" authenticated; issuing access token for fileId {fileId}', [
'app' => $this->appName,
'extApp' => $appName[0],
'fileId' => $fileId
]);
try {
$folder = $this->rootFolder->getUserFolder($this->uid);
$item = $folder->getById($fileId)[0];
if(!($item instanceof Node)) {
throw new \Exception();
}
list($urlSrc, $token) = $this->tokenManager->getToken($item->getId());
return array(
'status' => 'success',
'urlsrc' => $urlSrc,
'token' => $token
);
} catch (\Exception $e) {
$this->logger->logException($e, ['app'=>'richdocuments']);
$params = [
'remoteAddr' => $this->request->getRemoteAddress(),
'requestID' => $this->request->getId(),
'debugMode' => $this->settings->getSystemValue('debug'),
'errorClass' => get_class($e),
'errorCode' => $e->getCode(),
'errorMsg' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTraceAsString()
];
return new TemplateResponse('core', 'exception', $params, 'guest');
}
}
}
return array(
'status' => 'error',
'message' => 'Permission denied'
);
}
}
/**
* @NoAdminRequired
*

@ -66,7 +66,8 @@ class SettingsController extends Controller{
*/
public function setSettings($wopi_url,
$edit_groups,
$doc_format){
$doc_format,
$external_apps){
$message = $this->l10n->t('Saved');
if ($wopi_url !== null){
@ -86,6 +87,10 @@ class SettingsController extends Controller{
$this->appConfig->setAppValue('doc_format', $doc_format);
}
if ($external_apps !== null) {
$this->appConfig->setAppValue('external_apps', $external_apps);
}
$this->discoveryManager->refretch();
$response = [

@ -49,6 +49,7 @@ 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'),
'external_apps' => $this->config->getAppValue('richdocuments', 'external_apps'),
],
'blank'
);

@ -15,4 +15,16 @@ script('richdocuments', 'admin');
<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>
<br/>
<input type="checkbox" id="enable_external_apps_cb-richdocuments" <?php p($_['external_apps'] !== '' ? 'checked' : '') ?> />
<label for="enable_external_apps_cb-richdocuments"><?php p($l->t('Enable access for external apps')) ?></label>
<div id="enable-external-apps-section" class="indent <?php if ($_['external_apps'] == '') p('hidden') ?>" >
<div id="external-apps-section">
<input type="hidden" id="external-apps-raw" name="external-apps-raw" value="<?php p($_['external_apps']) ?>">
</div>
<button type="button" id="external-apps-save-button"><?php p($l->t('Save')) ?></button>
<button type="button" id="external-apps-add-button"><?php p($l->t('Add')) ?></button>
<span id="enable-external-apps-section-msg" class="msg"></span>
</div>
</div>

Loading…
Cancel
Save