diff --git a/appinfo/Application.php b/appinfo/Application.php
new file mode 100644
index 000000000..0a4c0a984
--- /dev/null
+++ b/appinfo/Application.php
@@ -0,0 +1,46 @@
+
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+namespace OCA\Richdocuments\AppInfo;
+
+use OC\AppFramework\Utility\TimeFactory;
+use OCA\Richdocuments\WOPI\DiscoveryManager;
+use OCP\AppFramework\App;
+use OCP\AppFramework\IAppContainer;
+
+class Application extends App {
+ public function __construct (array $urlParams = array()) {
+ parent::__construct('richdocuments', $urlParams);
+ $container = $this->getContainer();
+ $container->registerService(
+ DiscoveryManager::class,
+ function(IAppContainer $container) {
+ return new DiscoveryManager(
+ $container->getServer()->getHTTPClientService(),
+ $container->getServer()->getAppDataDir('richdocuments'),
+ $container->getServer()->getConfig(),
+ $container->getServer()->getL10N('richdocuments'),
+ new TimeFactory()
+ );
+ }
+ );
+ }
+}
\ No newline at end of file
diff --git a/appinfo/application.php b/appinfo/application.php
deleted file mode 100644
index 6b2ca73f5..000000000
--- a/appinfo/application.php
+++ /dev/null
@@ -1,94 +0,0 @@
-getContainer();
-
- /**
- * Controllers
- */
- $container->registerService('UserController', function($c) {
- return new UserController(
- $c->query('AppName'),
- $c->query('Request')
- );
- });
- $container->registerService('SessionController', function($c) {
- return new SessionController(
- $c->query('AppName'),
- $c->query('Request'),
- $c->query('Logger'),
- $c->query('UserId')
- );
- });
- $container->registerService('DocumentController', function($c) {
- return new DocumentController(
- $c->query('AppName'),
- $c->query('Request'),
- $c->query('CoreConfig'),
- $c->query('AppConfig'),
- $c->query('L10N'),
- $c->query('UserId'),
- $c->query('ICacheFactory'),
- $c->query('Logger')
- );
- });
- $container->registerService('SettingsController', function($c) {
- return new SettingsController(
- $c->query('AppName'),
- $c->query('Request'),
- $c->query('L10N'),
- $c->query('AppConfig'),
- $c->query('UserId')
- );
- });
-
- $container->registerService('AppConfig', function($c) {
- return new AppConfig(
- $c->query('CoreConfig')
- );
- });
-
- /**
- * Core
- */
- $container->registerService('Logger', function($c) {
- return $c->query('ServerContainer')->getLogger();
- });
- $container->registerService('CoreConfig', function($c) {
- return $c->query('ServerContainer')->getConfig();
- });
- $container->registerService('L10N', function($c) {
- return $c->query('ServerContainer')->getL10N($c->query('AppName'));
- });
- $container->registerService('UserId', function($c) {
- $user = $c->query('ServerContainer')->getUserSession()->getUser();
- $uid = is_null($user) ? '' : $user->getUID();
- return $uid;
- });
- $container->registerService('ICacheFactory', function($c) {
- return $c->query('ServerContainer')->getMemCacheFactory();
- });
- }
-}
diff --git a/appinfo/database.xml b/appinfo/database.xml
index b6c272b44..128093e17 100644
--- a/appinfo/database.xml
+++ b/appinfo/database.xml
@@ -4,57 +4,6 @@
truefalseutf8
-
- *dbprefix*richdocuments_session
-
-
-
- es_id
- text
- true
- 64
- Editing session id
-
-
- genesis_url
- text
- 512
- Relative to owner documents storage /welcome.odt
-
-
- genesis_hash
- text
- 128
- true
- To be sure the genesis did not change
-
-
- file_id
- text
- 512
- Relative to storage e.g. /welcome.odt
-
-
- owner
- text
- true
- 64
- oC user who created the session
-
-
-
- richdocuments_session_ei_idx
- true
- true
-
- es_id
- ascending
-
-
-
-
-
-
*dbprefix*richdocuments_member
@@ -68,13 +17,6 @@
4Unique per user and session
-
- es_id
- text
- true
- 64
- Related editing session id
- uidtext
@@ -118,162 +60,6 @@
- *dbprefix*richdocuments_revisions
-
-
-
- es_id
- text
- true
- 64
- Related editing session id
-
-
- seq_head
- integer
- true
- true
- 4
- Sequence head number
-
-
- member_id
- integer
- true
- true
- 4
- the member that saved the revision
-
-
- file_id
- text
- 512
- Relative to storage e.g. /welcome.odt
-
-
- save_hash
- text
- 128
- true
- used to lookup revision in documents folder of member, eg hash.odt
-
-
-
- richdocuments_rev_eis_idx
- true
-
- es_id
- ascending
-
-
- seq_head
- ascending
-
-
-
-
-
-
*dbprefix*richdocuments_wopi
diff --git a/appinfo/info.xml b/appinfo/info.xml
index a30e03602..0af3e3338 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.17
+ 1.1.18Collabora Productivity based on work of Frank Karlitschek, Victor Dubiniukhttps://github.com/nextcloud/richdocuments/issueshttps://github.com/nextcloud/richdocuments.git
diff --git a/appinfo/routes.php b/appinfo/routes.php
index 37d996abd..de620d1b0 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -9,38 +9,23 @@
* later.
*/
-namespace OCA\Richdocuments;
+namespace OCA\Richdocuments\AppInfo;
-$application = new \OCA\Richdocuments\AppInfo\Application();
-$application->registerRoutes($this, [
+return [
'routes' => [
- //users
- ['name' => 'user#rename', 'url' => 'ajax/user/rename', 'verb' => 'POST'],
- ['name' => 'user#disconnectUser', 'url' => 'ajax/user/disconnect', 'verb' => 'POST'],
- ['name' => 'user#disconnectGuest', 'url' => 'ajax/user/disconnectGuest', 'verb' => 'POST'],
- //session
- ['name' => 'session#join', 'url' => 'session/user/join/{fileId}', 'verb' => 'POST'],
- ['name' => 'session#poll', 'url' => 'session/user/poll', 'verb' => 'POST'],
- ['name' => 'session#save', 'url' => 'session/user/save', 'verb' => 'POST'],
- ['name' => 'session#joinAsGuest', 'url' => 'session/guest/join/{token}', 'verb' => 'POST'],
- ['name' => 'session#pollAsGuest', 'url' => 'session/guest/poll/{token}', 'verb' => 'POST'],
- ['name' => 'session#saveAsGuest', 'url' => 'session/guest/save/{token}', 'verb' => 'POST'],
//documents
['name' => 'document#index', 'url' => 'index', 'verb' => 'GET'],
['name' => 'document#create', 'url' => 'ajax/documents/create', 'verb' => 'POST'],
- ['name' => 'document#serve', 'url' => 'ajax/genesis/{esId}', 'verb' => 'GET'],
- ['name' => 'document#rename', 'url' => 'ajax/documents/rename/{fileId}', 'verb' => 'POST'],
- ['name' => 'document#get', 'url' => 'ajax/documents/get/{fileId}', 'verb' => 'GET'],
- ['name' => 'document#listAll', 'url' => 'ajax/documents/list', 'verb' => 'GET'],
- ['name' => 'document#download', 'url' => 'ajax/download.php', 'verb' => 'GET'],
- //documents - for WOPI access
- ['name' => 'document#wopiGetToken', 'url' => 'wopi/token/{fileId}', 'verb' => 'GET'],
- ['name' => 'document#wopiCheckFileInfo', 'url' => 'wopi/files/{fileId}', 'verb' => 'GET'],
- ['name' => 'document#wopiGetFile', 'url' => 'wopi/files/{fileId}/contents', 'verb' => 'GET'],
- ['name' => 'document#wopiPutFile', 'url' => 'wopi/files/{fileId}/contents', 'verb' => 'POST'],
+
+ // WOPI access
+ ['name' => 'wopi#getToken', 'url' => 'wopi/token/{fileId}', 'verb' => 'GET'],
+ ['name' => 'wopi#checkFileInfo', 'url' => 'wopi/files/{fileId}', 'verb' => 'GET'],
+ ['name' => 'wopi#getFile', 'url' => 'wopi/files/{fileId}/contents', 'verb' => 'GET'],
+ ['name' => 'wopi#putFile', 'url' => 'wopi/files/{fileId}/contents', 'verb' => 'POST'],
+
//settings
['name' => 'settings#setSettings', 'url' => 'ajax/admin.php', 'verb' => 'POST'],
['name' => 'settings#getSupportedMimes', 'url' => 'ajax/mimes.php', 'verb' => 'GET'],
['name' => 'settings#getSettings', 'url' => 'ajax/settings.php', 'verb' => 'GET'],
]
-]);
+];
diff --git a/controller/documentcontroller.php b/controller/documentcontroller.php
deleted file mode 100644
index c56688d47..000000000
--- a/controller/documentcontroller.php
+++ /dev/null
@@ -1,753 +0,0 @@
-hint = $hint;
- }
-
- public function getHint() {
- return $this->hint;
- }
-}
-
-class DocumentController extends Controller {
-
- private $uid;
- private $l10n;
- private $settings;
- private $appConfig;
- private $cache;
- private $logger;
- const ODT_TEMPLATE_PATH = '/assets/odttemplate.odt';
-
- public function __construct($appName, IRequest $request, IConfig $settings, AppConfig $appConfig, IL10N $l10n, $uid, ICacheFactory $cache, ILogger $logger){
- parent::__construct($appName, $request);
- $this->uid = $uid;
- $this->l10n = $l10n;
- $this->settings = $settings;
- $this->appConfig = $appConfig;
- $this->cache = $cache->create($appName);
- $this->logger = $logger;
- }
-
- /**
- * @param \SimpleXMLElement $discovery
- * @param string $mimetype
- */
- private function getWopiSrcUrl($discovery_parsed, $mimetype) {
- if(is_null($discovery_parsed) || $discovery_parsed == false) {
- return null;
- }
-
- $result = $discovery_parsed->xpath(sprintf('/wopi-discovery/net-zone/app[@name=\'%s\']/action', $mimetype));
- if ($result && count($result) > 0) {
- return array(
- 'urlsrc' => (string)$result[0]['urlsrc'],
- 'action' => (string)$result[0]['name']
- );
- }
-
- return null;
- }
-
- /**
- * Log the user with given $userid.
- * This function should only be used from public controller methods where no
- * existing session exists, for example, when loolwsd is directly calling a
- * public method with its own access token. After validating the access
- * token, and retrieving the correct user with help of access token, it can
- * be set as current user with help of this method.
- *
- * @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);
- if (strcasecmp($user->getUID(), $userid) === 0) {
- // clear the existing sessions, if any
- \OC::$server->getSession()->close();
-
- // initialize a dummy memory session
- $session = new \OC\Session\Memory('');
- // wrap it
- $cryptoWrapper = \OC::$server->getSessionCryptoWrapper();
- $session = $cryptoWrapper->wrapSession($session);
- // set our session
- \OC::$server->setSession($session);
-
- \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 = ''){
- $errors = array('errors' => array(array('error' => $message, 'hint' => $hint)));
- $response = new TemplateResponse('', 'error', $errors, 'error');
- return $response;
- }
-
- /**
- * Return the original wopi url or test wopi url
- */
- private function getWopiUrl($tester) {
- $wopiurl = '';
- if ($tester) {
- $wopiurl = $this->appConfig->getAppValue('test_wopi_url');
- } else {
- $wopiurl = $this->appConfig->getAppValue('wopi_url');
- }
-
- return $wopiurl;
- }
-
- /**
- * Return true if the currently logged in user is a tester.
- * This depends on whether current user is the member of one of the groups
- * mentioned in settings (test_server_groups)
- */
- private function isTester() {
- $tester = false;
-
- $user = \OC::$server->getUserSession()->getUser()->getUID();
- $testgroups = array_filter(explode('|', $this->appConfig->getAppValue('test_server_groups')));
- \OC::$server->getLogger()->debug('Testgroups are {testgroups}', [
- 'app' => $this->appName,
- 'testgroups' => $testgroups
- ]);
- foreach ($testgroups as $testgroup) {
- $test = \OC::$server->getGroupManager()->get($testgroup);
- if ($test !== null && sizeof($test->searchUsers($user)) > 0) {
- \OC::$server->getLogger()->debug('User {user} found in {group}', [
- 'app' => $this->appName,
- 'user' => $user,
- 'group' => $testgroup
- ]);
-
- $tester = true;
- break;
- }
- }
-
- return $tester;
- }
-
- /** Return the content of discovery.xml - either from cache, or download it.
- */
- private function getDiscovery(){
- \OC::$server->getLogger()->debug('getDiscovery(): Getting discovery.xml from the cache.');
-
- $tester = $this->isTester();
- $wopiRemote = $this->getWopiUrl($tester);
- $discoveryKey = 'discovery.xml';
- if ($tester) {
- $discoveryKey = 'discovery.xml_test';
- }
- // Provides access to information about the capabilities of a WOPI client
- // and the mechanisms for invoking those abilities through URIs.
- $wopiDiscovery = $wopiRemote . '/hosting/discovery';
-
- // Read the memcached value (if the memcache is installed)
- $discovery = $this->cache->get($discoveryKey);
-
- if (is_null($discovery)) {
- $contact_admin = $this->l10n->t('Please contact the "%s" administrator.', array($wopiRemote));
-
- try {
- $wopiClient = \OC::$server->getHTTPClientService()->newClient();
- $discovery = $wopiClient->get($wopiDiscovery)->getBody();
- }
- catch (\Exception $e) {
- $error_message = $e->getMessage();
- if (preg_match('/^cURL error ([0-9]*):/', $error_message, $matches)) {
- $admin_check = $this->l10n->t('Please ask your administrator to check the Collabora Online server setting. The exact error message was: ') . $error_message;
-
- $curl_error = $matches[1];
- switch ($curl_error) {
- case '1':
- throw new ResponseException($this->l10n->t('Collabora Online: The protocol specified in "%s" is not allowed.', array($wopiRemote)), $admin_check);
- case '3':
- throw new ResponseException($this->l10n->t('Collabora Online: Malformed URL "%s".', array($wopiRemote)), $admin_check);
- case '6':
- throw new ResponseException($this->l10n->t('Collabora Online: Cannot resolve the host "%s".', array($wopiRemote)), $admin_check);
- case '7':
- throw new ResponseException($this->l10n->t('Collabora Online: Cannot connect to the host "%s".', array($wopiRemote)), $admin_check);
- case '60':
- throw new ResponseException($this->l10n->t('Collabora Online: SSL certificate is not installed.'), $this->l10n->t('Please ask your administrator to add ca-chain.cert.pem to the ca-bundle.crt, for example "cat /etc/loolwsd/ca-chain.cert.pem >> /resources/config/ca-bundle.crt" . The exact error message was: ') . $error_message);
- }
- }
- throw new ResponseException($this->l10n->t('Collabora Online unknown error: ') . $error_message, $contact_admin);
- }
-
- if (!$discovery) {
- throw new ResponseException($this->l10n->t('Collabora Online: Unable to read discovery.xml from "%s".', array($wopiRemote)), $contact_admin);
- }
-
- \OC::$server->getLogger()->debug('Storing the discovery.xml under key ' . $discoveryKey . ' to the cache.');
- $this->cache->set($discoveryKey, $discovery, 3600);
- }
-
- return $discovery;
- }
-
- /** Prepare document(s) structure
- */
- private function prepareDocuments($rawDocuments){
- $discovery_parsed = null;
- try {
- $discovery = $this->getDiscovery();
-
- $loadEntities = libxml_disable_entity_loader(true);
- $discovery_parsed = simplexml_load_string($discovery);
- libxml_disable_entity_loader($loadEntities);
-
- if ($discovery_parsed === false) {
- $this->cache->remove('discovery.xml');
- $wopiRemote = $this->getWopiUrl($this->isTester());
-
- return array(
- 'status' => 'error',
- 'message' => $this->l10n->t('Collabora Online: discovery.xml from "%s" is not a well-formed XML string.', array($wopiRemote)),
- 'hint' => $this->l10n->t('Please contact the "%s" administrator.', array($wopiRemote))
- );
- }
- }
- catch (ResponseException $e) {
- return array(
- 'status' => 'error',
- 'message' => $e->getMessage(),
- 'hint' => $e->getHint()
- );
- }
-
- $fileIds = array();
- $documents = array();
- $lolang = strtolower(str_replace('_', '-', $this->settings->getUserValue($this->uid, 'core', 'lang', 'en')));
- foreach ($rawDocuments as $key=>$document) {
- if (is_object($document)){
- $documents[] = $document->getData();
- } else {
- $documents[$key] = $document;
- }
- $documents[$key]['icon'] = preg_replace('/\.png$/', '.svg', \OCP\Template::mimetype_icon($document['mimetype']));
- $documents[$key]['hasPreview'] = \OC::$server->getPreviewManager()->isMimeSupported($document['mimetype']);
- $ret = $this->getWopiSrcUrl($discovery_parsed, $document['mimetype']);
- $documents[$key]['urlsrc'] = $ret['urlsrc'];
- $documents[$key]['action'] = $ret['action'];
- $documents[$key]['lolang'] = $lolang;
- $fileIds[] = $document['fileid'];
- }
-
- usort($documents, function($a, $b){
- return @$b['mtime']-@$a['mtime'];
- });
-
- $session = new Db\Session();
- $sessions = $session->getCollectionBy('file_id', $fileIds);
-
- $members = array();
- $member = new Db\Member();
- foreach ($sessions as $session) {
- $members[$session['es_id']] = $member->getActiveCollection($session['es_id']);
- }
-
- return array(
- 'status' => 'success', 'documents' => $documents,'sessions' => $sessions,'members' => $members
- );
- }
-
- /**
- * @NoAdminRequired
- * @NoCSRFRequired
- */
- public function index(){
- $wopiRemote = $this->getWopiUrl($this->isTester());
- if (($parts = parse_url($wopiRemote)) && isset($parts['scheme']) && isset($parts['host'])) {
- $webSocketProtocol = "ws://";
- if ($parts['scheme'] == "https") {
- $webSocketProtocol = "wss://";
- }
- $webSocket = sprintf(
- "%s%s%s",
- $webSocketProtocol,
- $parts['host'],
- isset($parts['port']) ? ":" . $parts['port'] : "");
- }
- else {
- return $this->responseError($this->l10n->t('Collabora Online: Invalid URL "%s".', array($wopiRemote)), $this->l10n->t('Please ask your administrator to check the Collabora Online server setting.'));
- }
-
- $user = \OC::$server->getUserSession()->getUser();
- $usergroups = array_filter(\OC::$server->getGroupManager()->getUserGroupIds($user));
- $usergroups = join('|', $usergroups);
- \OC::$server->getLogger()->debug('User is in groups: {groups}', [ 'app' => $this->appName, 'groups' => $usergroups ]);
-
- \OC::$server->getNavigationManager()->setActiveEntry( 'richdocuments_index' );
- $maxUploadFilesize = \OCP\Util::maxUploadFilesize("/");
- $response = new TemplateResponse('richdocuments', 'documents', [
- 'enable_previews' => $this->settings->getSystemValue('enable_previews', true),
- 'uploadMaxFilesize' => $maxUploadFilesize,
- 'uploadMaxHumanFilesize' => \OCP\Util::humanFileSize($maxUploadFilesize),
- 'allowShareWithLink' => $this->settings->getAppValue('core', 'shareapi_allow_links', 'yes'),
- 'wopi_url' => $webSocket,
- 'doc_format' => $this->appConfig->getAppValue('doc_format')
- ]);
-
- $policy = new ContentSecurityPolicy();
- $policy->addAllowedScriptDomain('\'self\' http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js http://cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.12/jquery.mousewheel.min.js \'unsafe-eval\' ' . $wopiRemote);
- /* frame-src is deprecated on Firefox, but Safari wants it! */
- $policy->addAllowedFrameDomain('\'self\' http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js http://cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.12/jquery.mousewheel.min.js \'unsafe-eval\' ' . $wopiRemote . ' blob:');
- $policy->addAllowedChildSrcDomain('\'self\' http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js http://cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.12/jquery.mousewheel.min.js \'unsafe-eval\' ' . $wopiRemote);
- $policy->addAllowedConnectDomain($webSocket);
- $policy->addAllowedImageDomain('*');
- $policy->allowInlineScript(true);
- $policy->addAllowedFontDomain('data:');
- $response->setContentSecurityPolicy($policy);
-
- return $response;
- }
-
- /**
- * @NoAdminRequired
- */
- public function create(){
- $mimetype = $this->request->post['mimetype'];
- $filename = $this->request->post['filename'];
- $dir = $this->request->post['dir'];
-
- $view = new View('/' . $this->uid . '/files');
- if (!$dir){
- $dir = '/';
- }
-
- $basename = $this->l10n->t('New Document.odt');
- switch ($mimetype) {
- case 'application/vnd.oasis.opendocument.spreadsheet':
- $basename = $this->l10n->t('New Spreadsheet.ods');
- break;
- case 'application/vnd.oasis.opendocument.presentation':
- $basename = $this->l10n->t('New Presentation.odp');
- break;
- case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
- $basename = $this->l10n->t('New Document.docx');
- break;
- case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
- $basename = $this->l10n->t('New Spreadsheet.xlsx');
- break;
- case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
- $basename = $this->l10n->t('New Presentation.pptx');
- break;
- default:
- // to be safe
- $mimetype = 'application/vnd.oasis.opendocument.text';
- break;
- }
-
- if (!$filename){
- $path = Helper::getNewFileName($view, $dir . '/' . $basename);
- } else {
- $path = $dir . '/' . $filename;
- }
-
- $content = '';
- if (class_exists('\OC\Files\Type\TemplateManager')){
- $manager = \OC_Helper::getFileTemplateManager();
- $content = $manager->getTemplate($mimetype);
- }
-
- if (!$content){
- $content = file_get_contents(dirname(__DIR__) . self::ODT_TEMPLATE_PATH);
- }
-
- $discovery_parsed = null;
- try {
- $discovery = $this->getDiscovery();
-
- $loadEntities = libxml_disable_entity_loader(true);
- $discovery_parsed = simplexml_load_string($discovery);
- libxml_disable_entity_loader($loadEntities);
-
- if ($discovery_parsed === false) {
- $this->cache->remove('discovery.xml');
- $wopiRemote = $this->getWopiUrl($this->isTester());
-
- return array(
- 'status' => 'error',
- 'message' => $this->l10n->t('Collabora Online: discovery.xml from "%s" is not a well-formed XML string.', array($wopiRemote)),
- 'hint' => $this->l10n->t('Please contact the "%s" administrator.', array($wopiRemote))
- );
- }
- }
- catch (ResponseException $e) {
- return array(
- 'status' => 'error',
- 'message' => $e->getMessage(),
- 'hint' => $e->getHint()
- );
- }
-
- if ($content && $view->file_put_contents($path, $content)){
- $info = $view->getFileInfo($path);
- $ret = $this->getWopiSrcUrl($discovery_parsed, $mimetype);
- $response = array(
- 'status' => 'success',
- 'fileid' => $info['fileid'],
- 'urlsrc' => $ret['urlsrc'],
- 'action' => $ret['action'],
- 'lolang' => $this->settings->getUserValue($this->uid, 'core', 'lang', 'en'),
- 'data' => \OCA\Files\Helper::formatFileInfo($info)
- );
- } else {
- $response = array(
- 'status' => 'error',
- 'message' => (string) $this->l10n->t('Can\'t create document')
- );
- }
- return $response;
- }
-
- /**
- * @NoAdminRequired
- * Generates and returns an access token for a given fileId.
- * Only for authenticated users!
- */
- public function wopiGetToken($fileId){
- $arr = explode('_', $fileId, 2);
- $version = '0';
- if (count($arr) == 2) {
- $fileId = $arr[0];
- $version = $arr[1];
- }
-
- \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 ($editorGroup !== null && 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;
- break;
- }
- }
- }
-
- // 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();
- $serverHost = $this->request->getServerProtocol() . '://' . $this->request->getServerHost();
- $token = $row->generateFileToken($fileId, $version, $updatable, $serverHost);
-
- // Return the token.
- return array(
- 'status' => 'success',
- 'token' => $token
- );
- }
-
- /**
- * @NoAdminRequired
- * @NoCSRFRequired
- * @PublicPage
- * Returns general info about a file.
- */
- public function wopiCheckFileInfo($fileId){
- $token = $this->request->getParam('access_token');
-
- $arr = explode('_', $fileId, 2);
- $version = '0';
- if (count($arr) == 2) {
- $fileId = $arr[0];
- $version = $arr[1];
- }
-
- \OC::$server->getLogger()->debug('Getting info about 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 == false || http_response_code() != 200)
- {
- return false;
- }
-
- // Login the user to see his mount locations
- $this->loginUser($res['owner']);
- $view = new \OC\Files\View('/' . $res['owner'] . '/files');
- $info = $view->getFileInfo($res['path']);
- $this->logoutUser();
-
- if (!$info) {
- http_response_code(404);
- return false;
- }
-
- $editorName = \OC::$server->getUserManager()->get($res['editor'])->getDisplayName();
- return array(
- 'BaseFileName' => $info['name'],
- 'Size' => $info['size'],
- 'Version' => $version,
- 'UserId' => $res['editor'],
- 'UserFriendlyName' => $editorName,
- 'UserCanWrite' => $res['canwrite'] ? true : false,
- 'PostMessageOrigin' => $res['server_host']
- );
- }
-
- /**
- * @NoAdminRequired
- * @NoCSRFRequired
- * @PublicPage
- * Given an access token and a fileId, returns the contents of the file.
- * Expects a valid token in access_token parameter.
- */
- public function wopiGetFile($fileId){
- $token = $this->request->getParam('access_token');
-
- $arr = explode('_', $fileId, 2);
- $version = '0';
- if (count($arr) == 2) {
- $fileId = $arr[0];
- $version = $arr[1];
- }
-
- \OC::$server->getLogger()->debug('Getting 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);
-
- //TODO: Support X-WOPIMaxExpectedSize header.
- $res = $row->getPathForToken($fileId, $version, $token);
- $ownerid = $res['owner'];
-
- // Login the user to see his mount locations
- $this->loginUser($ownerid);
- $view = new \OC\Files\View('/' . $res['owner'] . '/files');
- $info = $view->getFileInfo($res['path']);
-
- if (!$info) {
- http_response_code(404);
- return false;
- }
-
- $filename = '';
- // If some previous version is requested, fetch it from Files_Version app
- if ($version !== '0') {
- \OCP\JSON::checkAppEnabled('files_versions');
-
- $filename = '/files_versions/' . $info['name'] . '.v' . $version;
- } else {
- $filename = '/files' . $res['path'];
- }
-
- $this->logoutUser();
-
- return new DownloadResponse($this->request, $ownerid, $filename);
- }
-
- /**
- * @NoAdminRequired
- * @NoCSRFRequired
- * @PublicPage
- * Given an access token and a fileId, replaces the files with the request body.
- * Expects a valid token in access_token parameter.
- */
- public function wopiPutFile($fileId){
- $token = $this->request->getParam('access_token');
-
- $arr = explode('_', $fileId, 2);
- $version = '0';
- if (count($arr) == 2) {
- $fileId = $arr[0];
- $version = $arr[1];
- }
-
- \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'];
- // This call is made from loolwsd, so we need to initialize the
- // session before we can make the user who opened the document
- // login. This is necessary to make activity app register the
- // change made to this file under this user's (editorid) name.
- $this->loginUser($editorid);
-
- // Set up the filesystem view for the owner (where the file actually is).
- $userid = $res['owner'];
- $root = '/' . $userid . '/files';
- $view = new \OC\Files\View($root);
-
- // Read the contents of the file from the POST body and store.
- $content = fopen('php://input', 'r');
- \OC::$server->getLogger()->debug('Storing file {fileId} by {editor} owned by {owner}.', [ 'app' => $this->appName, 'fileId' => $fileId, 'editor' => $editorid, 'owner' => $userid ]);
-
- // Setup the FS which is needed to emit hooks (versioning).
- \OC_Util::tearDownFS();
- \OC_Util::setupFS($userid);
-
- $view->file_put_contents($res['path'], $content);
-
- $this->logoutUser();
-
- return array(
- 'status' => 'success'
- );
- }
-
- /**
- * @NoAdminRequired
- * @PublicPage
- * Process partial/complete file download
- */
- public function serve($esId){
- $session = new Db\Session();
- $session->load($esId);
-
- $filename = $session->getGenesisUrl() ? $session->getGenesisUrl() : '';
- return new DownloadResponse($this->request, $session->getOwner(), $filename);
- }
-
- /**
- * @NoAdminRequired
- */
- public function download($path){
- if (!$path){
- $response = new JSONResponse();
- $response->setStatus(Http::STATUS_BAD_REQUEST);
- return $response;
- }
-
- $fullPath = '/files' . $path;
- $fileInfo = \OC\Files\Filesystem::getFileInfo($path);
- if ($fileInfo){
- $file = new File($fileInfo->getId());
- $genesis = new Genesis($file);
- $fullPath = $genesis->getPath();
- }
- return new DownloadResponse($this->request, $this->uid, $fullPath);
- }
-
-
- /**
- * @NoAdminRequired
- */
- public function rename($fileId){
- $name = $this->request->post['name'];
-
- $view = \OC\Files\Filesystem::getView();
- $path = $view->getPath($fileId);
-
- if ($name && $view->is_file($path) && $view->isUpdatable($path)) {
- $newPath = dirname($path) . '/' . $name;
- if ($view->rename($path, $newPath)) {
- return array('status' => 'success');
- }
- }
- return array(
- 'status' => 'error',
- 'message' => (string) $this->l10n->t('You don\'t have permission to rename this document')
- );
- }
-
- /**
- * @NoAdminRequired
- * Get file information about single document with fileId
- */
- public function get($fileId){
- $documents = array();
- $documents[0] = Storage::getDocumentById($fileId);
-
- return $this->prepareDocuments($documents);
- }
-
-
- /**
- * @NoAdminRequired
- * lists the documents the user has access to (including shared files, once the code in core has been fixed)
- * also adds session and member info for these files
- */
- public function listAll(){
- return $this->prepareDocuments(Storage::getDocuments());
- }
-}
diff --git a/controller/sessioncontroller.php b/controller/sessioncontroller.php
deleted file mode 100644
index ecdc73453..000000000
--- a/controller/sessioncontroller.php
+++ /dev/null
@@ -1,314 +0,0 @@
-body = $body;
- }
-
- public function getBody(){
- return $this->body;
- }
-}
-
-class SessionController extends Controller{
-
- protected $uid;
- protected $logger;
- protected $shareToken;
-
- public function __construct($appName, IRequest $request, $logger, $uid){
- parent::__construct($appName, $request);
- $this->uid = $uid;
- $this->logger = $logger;
- }
-
- /**
- * @NoAdminRequired
- * @PublicPage
- */
- public function joinAsGuest($token, $name){
- $uid = substr($name, 0, 16);
-
- try {
- $file = File::getByShareToken($token);
- if ($file->isPasswordProtected() && !$file->checkPassword('')){
- throw new \Exception('Not authorized');
- }
-
- $response = array_merge(
- Db\Session::start($uid, $file),
- [ 'status'=>'success' ]
- );
- } catch (\Exception $e){
- $this->logger->warning('Starting a session failed. Reason: ' . $e->getMessage(), ['app' => $this->appName]);
- $response = [ 'status'=>'error' ];
- }
-
- return $response;
- }
-
- /**
- * @NoAdminRequired
- * @PublicPage
- */
- public function pollAsGuest($command, $args){
- $this->shareToken = $this->request->getParam('token');
- return $this->poll($command, $args);
- }
-
- /**
- * Store the document content to its origin
- * @NoAdminRequired
- * @PublicPage
- */
- public function saveAsGuest(){
- $this->shareToken = $this->request->getParam('token');
- return $this->save();
- }
-
- /**
- * @NoAdminRequired
- */
- public function join($fileId){
- try {
- $view = \OC\Files\Filesystem::getView();
- $path = $view->getPath($fileId);
-
- $file = new File($fileId);
- $response = Db\Session::start($this->uid, $file);
-
- $response = array_merge(
- $response,
- [ 'status'=>'success' ]
- );
- } catch (\Exception $e){
- $this->logger->warning('Starting a session failed. Reason: ' . $e->getMessage(), [ 'app' => $this->appName ]);
- $response = [ 'status'=>'error' ];
- }
-
- return $response;
- }
-
- /**
- * @NoAdminRequired
- */
- public function poll($command, $args){
- $response = new JSONResponse();
-
- try{
- $esId = isset($args['es_id']) ? $args['es_id'] : null;
- $session = $this->loadSession($esId);
-
- $memberId = isset($args['member_id']) ? $args['member_id'] : null;
- $member = $this->loadMember($memberId);
-
- $this->validateSession($session);
-
- switch ($command){
- case 'sync_ops':
- $seqHead = (string) isset($args['seq_head']) ? $args['seq_head'] : null;
- if (!is_null($seqHead)){
- $ops = isset($args['client_ops']) ? $args['client_ops'] : [];
-
- $op = new Db\Op();
- $currentHead = $op->getHeadSeq($esId);
-
- try {
- $member->updateActivity($memberId);
- } catch (\Exception $e){
- //Db error. Not critical
- }
- $response->setData(
- $session->syncOps($memberId, $currentHead, $seqHead, $ops)
- );
-
- $inactiveMembers = $member->updateByTimeout($esId);
- foreach ($inactiveMembers as $inactive){
- $op->removeCursor($esId, $inactive);
- $op->removeMember($esId, $inactive);
- }
- } else {
- // Error - no seq_head passed
- throw new BadRequestException();
- }
-
- break;
- default:
- $ex = new BadRequestException();
- $ex->setBody(
- implode(',', $this->request->getParams())
- );
- throw $ex;
- }
- } catch (BadRequestException $e){
- $response->setStatus(Http::STATUS_BAD_REQUEST);
- $response->setData(
- [ 'err' => 'bad request:[' . $e->getBody() . ']' ]
- );
- }
- return $response;
- }
-
- /**
- * Store the document content to its origin
- * @NoAdminRequired
- */
- public function save(){
- $response = new JSONResponse();
- try {
- $esId = $this->request->server['HTTP_WEBODF_SESSION_ID'];
- $session = $this->loadSession($esId);
-
- $memberId = $this->request->server['HTTP_WEBODF_MEMBER_ID'];
- $currentMember = $this->loadMember($memberId, $esId);
-
- // Extra info for future usage
- // $sessionRevision = $this->request->server['HTTP_WEBODF_SESSION_REVISION'];
-
- //NB ouch! New document content is passed as an input stream content
- $stream = fopen('php://input','r');
- if (!$stream){
- throw new \Exception('New content missing');
- }
- $content = stream_get_contents($stream);
-
- try {
- if ($currentMember->getIsGuest()){
- $file = File::getByShareToken($currentMember->getToken());
- } else {
- $file = new File($session->getFileId());
- }
-
- $view = $file->getOwnerView(true);
- $path = $file->getPath(true);
- } catch (\Exception $e){
- //File was deleted or unshared. We need to save content as new file anyway
- //Sorry, but for guests it would be lost :(
- if ($this->uid){
- $view = new View('/' . $this->uid . '/files');
-
- $dir = '/';
- $path = Helper::getNewFileName($view, $dir . 'New Document.odt');
- } else {
- throw $e;
- }
- }
-
- $member = new Db\Member();
- $members = $member->getActiveCollection($esId);
- $memberIds = array_map(
- function($x){
- return ($x['member_id']);
- },
- $members
- );
-
- // Active users except current user
- $memberCount = count($memberIds) - 1;
-
- if ($view->file_exists($path)){
- $currentHash = $view->hash('sha1', $path, false);
-
- if (!Helper::isVersionsEnabled() && $currentHash !== $session->getGenesisHash()){
- // Original file was modified externally. Save to a new one
- $path = Helper::getNewFileName($view, $path, '-conflict');
- }
-
- $mimetype = $view->getMimeType($path);
- } else {
- $mimetype = Storage::MIMETYPE_LIBREOFFICE_WORDPROCESSOR;
- }
-
- $data = Filter::write($content, $mimetype);
-
- if ($view->file_put_contents($path, $data['content'])){
- // Not a last user
- if ($memberCount>0){
- // Update genesis hash to prevent conflicts
- $this->logger->debug('Update hash', [ 'app' => $this->appName ]);
- $session->updateGenesisHash($esId, sha1($data['content']));
- } else {
- // Last user. Kill session data
- Db\Session::cleanUp($esId);
- }
-
- $view->touch($path);
- }
- $response->setData(['status'=>'success']);
- } catch (\Exception $e){
- $response->setStatus(Http::STATUS_INTERNAL_SERVER_ERROR);
- $response->setData([]);
- $this->logger->warning('Saving failed. Reason:' . $e->getMessage(), [ 'app' => $this->appName ]);
- }
-
- return $response;
- }
-
- protected function validateSession($session){
- try {
- if (is_null($this->shareToken)) {
- new File($session->getFileId());
- } else {
- File::getByShareToken($this->shareToken);
- }
- } catch (\Exception $e){
- $this->logger->warning('Error. Session no longer exists. ' . $e->getMessage(), [ 'app' => $this->appName ]);
- $ex = new BadRequestException();
- $ex->setBody(
- implode(',', $this->request->getParams())
- );
- throw $ex;
- }
- }
-
- protected function loadSession($esId){
- if (!$esId){
- throw new \Exception('Session id can not be empty');
- }
-
- $session = new Db\Session();
- $session->load($esId);
- if (!$session->getEsId()){
- throw new \Exception('Session does not exist');
- }
- return $session;
- }
-
- protected function loadMember($memberId, $expectedEsId = null){
- if (!$memberId){
- throw new \Exception('Member id can not be empty');
- }
- $member = new Db\Member();
- $member->load($memberId);
- //check if member belongs to the session
- if (!is_null($expectedEsId) && $expectedEsId !== $member->getEsId()){
- throw new \Exception($memberId . ' does not belong to session ' . $expectedEsId);
- }
- return $member;
- }
-}
diff --git a/controller/usercontroller.php b/controller/usercontroller.php
deleted file mode 100644
index 8442ada66..000000000
--- a/controller/usercontroller.php
+++ /dev/null
@@ -1,81 +0,0 @@
-disconnect($memberId, $esId);
- }
-
- /**
- * @NoAdminRequired
- * @PublicPage
- */
- public function disconnectGuest($memberId, $esId){
- return $this->disconnect($memberId, $esId);
- }
-
- private function disconnect($memberId, $esId){
- $member = new Db\Member();
- $member->loadBy('member_id', $memberId);
- if ($esId && $member->hasData()){
- if ($member->getEsId() === $esId && $member->getStatus() == Db\Member::MEMBER_STATUS_ACTIVE){
- $member->deactivate(array($memberId));
- $op = new Db\Op();
- $op->removeMember($esId, $memberId);
- }
- }
-
- return array('status'=>'success');
- }
-
- /**
- * @NoAdminRequired
- * @PublicPage
- * @param int $memberId
- * @param string $name
- */
- public function rename($memberId, $name){
- $member = new Db\Member();
- $member->load($memberId);
-
- if ($member->getEsId()
- && $member->getStatus() == Db\Member::MEMBER_STATUS_ACTIVE
- && $member->getIsGuest()
- ){
- $guestMark = Db\Member::getGuestPostfix();
- if (substr($name, -strlen($guestMark)) !== $guestMark){
- $name = $name . ' ' . $guestMark;
- }
-
- $op = new Db\Op();
- $op->changeNick($member->getEsId(), $memberId, $name);
- }
-
- return array('status'=>'success');
- }
-}
diff --git a/css/share.css b/css/share.css
deleted file mode 100644
index 79252c256..000000000
--- a/css/share.css
+++ /dev/null
@@ -1,170 +0,0 @@
-/* Copyright (c) 2011, Jan-Christoph Borchardt, http://jancborchardt.net
- This file is licensed under the Affero General Public License version 3 or later.
- See the COPYING-README file. */
-
-#dropdown {
- background: #eee;
- border-bottom-left-radius: 3px;
- border-bottom-right-radius: 3px;
- box-shadow: 0 2px 3px rgba(50, 50, 50, .4);
- display: block;
- margin-right: 0;
- position: absolute;
- right: 0;
- width: 420px;
- z-index: 500;
- padding: 16px;
-}
-
-@media only screen and (min-width: 768px) and (max-width: 990px) {
- #dropdown {
- /* this limits the dropdown to float below the sidebar for mid narrow screens */
- left: 20px;
- }
-}
-
-#dropdown.shareDropDown .unshare.icon-loading-small {
- margin-top: 1px;
-}
-
-#dropdown.shareDropDown .shareWithLoading,
-#dropdown.shareDropDown .linkShare .icon-loading-small {
- display: inline-block !important;
- padding-left: 10px;
-}
-#dropdown.shareDropDown .shareWithLoading {
- position: relative;
- right: 70px;
- top: 2px;
-}
-#dropdown.shareDropDown .icon-loading-small.hidden {
- display: none !important;
-}
-
-#dropdown .shareWithRemoteInfo {
- padding: 11px 20px;
-}
-
-#dropdown .avatar {
- margin-right: 8px;
- display: inline-block;
- overflow: hidden;
- vertical-align: middle;
- width: 32px;
- height: 32px;
-}
-
-#shareWithList {
- list-style-type:none;
- padding:8px;
-}
-
-#shareWithList li {
- padding-top: 10px;
- padding-bottom: 10px;
- font-weight: bold;
- line-height: 21px;
- white-space: normal;
-}
-
-#shareWithList .unshare img, #shareWithList .showCruds img {
- vertical-align:text-bottom; /* properly align icons */
-}
-
-#shareWithList label input[type=checkbox]{
- margin-left: 0;
- position: relative;
-}
-#shareWithList .username{
- padding-right: 8px;
- white-space: nowrap;
- text-overflow: ellipsis;
- max-width: 254px;
- display: inline-block;
- overflow: hidden;
- vertical-align: middle;
-}
-#shareWithList li label{
- margin-right: 8px;
-}
-#dropdown label {
- font-weight:400;
- white-space: nowrap;
-}
-
-#dropdown input[type="checkbox"] {
- margin:0 3px 0 8px;
- vertical-align: middle;
-}
-
-a.showCruds {
- display:inline;
- opacity:.5;
-}
-
-a.unshare {
- display:inline;
- float:right;
- opacity:.5;
- padding:5px 0 0 5px !important;
- margin-top:-5px;
-}
-
-#link {
- border-top:1px solid #ddd;
- padding-top:8px;
-}
-
-#dropdown input[type="text"],#dropdown input[type="password"] {
- width: 86%;
- margin-left: 7px;
-}
-
-#dropdown form {
- font-size: 100%;
- margin-left: 0;
- margin-right: 0;
-}
-
-#linkText,#linkPass,#expiration {
- display:none;
-}
-
-#link #showPassword img {
- padding-left:5px;
- width:12px;
-}
-
-.reshare,#link label,
-#expiration label {
- display: inline-block;
- padding: 6px 4px;
-}
-
-a.showCruds:hover,a.unshare:hover {
- opacity:1;
-}
-
-#defaultExpireMessage, /* fix expire message going out of box */
-.reshare { /* fix shared by text going out of box */
- white-space:normal;
-}
-
-#defaultExpireMessage { /* show message on new line */
- display: block;
- padding-left: 4px;
- /* TODO: style the dropdown in a proper way - border-box, etc. */
- width: 90%;
-}
-
-.ui-autocomplete { /* limit dropdown height to 4 1/2 entries */
- max-height:103px;
- overflow-y:auto;
- overflow-x:hidden;
-}
-
-.notCreatable {
- padding-left: 12px;
- padding-top: 12px;
- color: #999;
-}
\ No newline at end of file
diff --git a/js/admin.js b/js/admin.js
index 7a781f300..e460218c1 100644
--- a/js/admin.js
+++ b/js/admin.js
@@ -15,17 +15,6 @@ 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'),
@@ -33,112 +22,19 @@ var documentsSettings = {
);
},
- saveTestWopi: function(groups, server) {
- var data = {
- 'test_wopi_url': server,
- 'test_server_groups': groups
- };
-
- OC.msg.startAction('#test-documents-admin-msg', t('richdocuments', 'Saving...'));
- $.post(
- OC.filePath('richdocuments', 'ajax', 'admin.php'),
- data,
- documentsSettings.afterSaveTestWopi
- );
- },
-
- afterSaveTestWopi: function(response) {
- $('#test_wopi_apply').attr('disabled', false);
- OC.msg.finishedAction('#test-documents-admin-msg', response);
- },
-
afterSave : function(response){
$('#wopi_apply').attr('disabled', false);
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);
- }
- },
-
- initTestWopiServer: function() {
- var groups = $(document).find('#test_server_group_select').val();
- var testserver = $(document).find('#test_wopi_url').val();
-
- if (groups === '' || testserver === '') {
- $('.test-server-enable').attr('checked', null);
- } else {
- OC.Settings.setupGroupsSelect($('#test_server_group_select'));
- $('.test-server-enable').attr('checked', 'checked');
- }
- },
-
initialize: function() {
- documentsSettings.initEditGroups();
- documentsSettings.initTestWopiServer();
-
$('#wopi_apply').on('click', documentsSettings.save);
- $(document).on('change', '.test-server-enable', function() {
- var page = $(this).parent();
- var $select = page.find('#test_server_group_select');
- $select.val('');
-
- page.find('#test-server-section').toggleClass('hidden', !this.checked);
- if (this.checked) {
- OC.Settings.setupGroupsSelect($select, {
- placeholder: t('core', 'None')
- });
- } else {
- $select.select2('destroy');
- page.find('#test_wopi_url').val('');
-
- documentsSettings.saveTestWopi('', '');
- }
- });
-
- $(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');
});
- $(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();
- });
}
};
diff --git a/js/documents.js b/js/documents.js
index 4f5baaa70..f29df8c5c 100644
--- a/js/documents.js
+++ b/js/documents.js
@@ -18,40 +18,11 @@ $.widget('oc.documentGrid', {
},
_load : function (fileId){
- var that = this;
- var url = 'apps/richdocuments/ajax/documents/list';
- var dataObj = {};
- if (fileId){
- url = 'apps/richdocuments/ajax/documents/get/{fileId}';
- dataObj = { fileId: fileId };
- }
-
- return $.getJSON(OC.generateUrl(url, dataObj))
- .done(function (result) {
- if (!result || result.status === 'error') {
- documentsMain.loadError = true;
- if (result && result.message) {
- documentsMain.loadErrorMessage = result.message;
- }
- else {
- documentsMain.loadErrorMessage = t('richdocuments', 'Failed to load the document, please contact your administrator.');
- }
-
- if (result && result.hint) {
- documentsMain.loadErrorHint = result.hint;
- }
- }
- else {
- that.options.documents = result.documents;
- that.options.sessions = result.sessions;
- that.options.members = result.members;
- documentsMain.urlsrc = result.documents[0].urlsrc;
- documentsMain.fullPath = result.documents[0].path;
- }
- })
- .fail(function(data){
- console.log(t('richdocuments','Failed to load documents.'));
- });
+ var url = OC.generateUrl('apps/richdocuments/wopi/token/{file_id}', {file_id: fileId});
+ $.get(
+ url,
+ documentsMain.initSession
+ );
},
_render : function (data){
@@ -152,39 +123,36 @@ var documentsMain = {
$('#revViewerContainer').prepend($('
'));
}
- $.get(OC.generateUrl('apps/richdocuments/wopi/token/{fileId}', { fileId: fileId }),
- function (result) {
- // WOPISrc - URL that loolwsd will access (ie. pointing to ownCloud)
- var wopiurl = window.location.protocol + '//' + window.location.host + OC.generateUrl('apps/richdocuments/wopi/files/{file_id}', {file_id: fileId});
- var wopisrc = encodeURIComponent(wopiurl);
+ // WOPISrc - URL that loolwsd will access (ie. pointing to ownCloud)
+ var wopiurl = window.location.protocol + '//' + window.location.host + OC.generateUrl('apps/richdocuments/wopi/files/{file_id}', {file_id: fileId});
+ var wopisrc = encodeURIComponent(wopiurl);
- // urlsrc - the URL from discovery xml that we access for the particular
- // document; we add various parameters to that.
- // The discovery is available at
- // https://:9980/hosting/discovery
- var urlsrc = documentsMain.urlsrc +
- "WOPISrc=" + wopisrc +
- "&title=" + encodeURIComponent(title) +
- "&lang=" + OC.getLocale() +
- "&permission=readonly";
+ // urlsrc - the URL from discovery xml that we access for the particular
+ // document; we add various parameters to that.
+ // The discovery is available at
+ // https://:9980/hosting/discovery
+ var urlsrc = documentsMain.urlsrc +
+ "WOPISrc=" + wopisrc +
+ "&title=" + encodeURIComponent(title) +
+ "&lang=" + OC.getLocale() +
+ "&permission=readonly";
- // access_token - must be passed via a form post
- var access_token = encodeURIComponent(result.token);
+ // access_token - must be passed via a form post
+ var access_token = encodeURIComponent(documentsMain.token);
- // form to post the access token for WOPISrc
- var form = '';
+ // form to post the access token for WOPISrc
+ var form = '';
- // iframe that contains the Collabora Online Viewer
- var frame = '';
+ // iframe that contains the Collabora Online Viewer
+ var frame = '';
- $('#revViewer').append(form);
- $('#revViewer').append(frame);
+ $('#revViewer').append(form);
+ $('#revViewer').append(frame);
- // submit that
- $('#loleafletform_viewer').submit();
- documentsMain.isViewerMode = true;
- });
+ // submit that
+ $('#loleafletform_viewer').submit();
+ documentsMain.isViewerMode = true;
// for closing revision mode
$('#revPanelHeader .closeButton').click(function(e) {
@@ -344,91 +312,81 @@ var documentsMain = {
$('title').text(title + ' - ' + documentsMain.UI.mainTitle);
- $.get(OC.generateUrl('apps/richdocuments/wopi/token/{fileId}', { fileId: fileId }),
- function (result) {
- if (!result || result.status === 'error') {
- if (result && result.message){
- documentsMain.UI.notify(result.message);
- }
- documentsMain.onEditorShutdown(t('richdocuments', 'Failed to aquire access token. Please re-login and try again.'));
+
+ // WOPISrc - URL that loolwsd will access (ie. pointing to ownCloud)
+ var wopiurl = window.location.protocol + '//' + window.location.host + OC.generateUrl('apps/richdocuments/wopi/files/{file_id}', {file_id: documentsMain.fileId});
+ var wopisrc = encodeURIComponent(wopiurl);
+
+ // urlsrc - the URL from discovery xml that we access for the particular
+ // document; we add various parameters to that.
+ // The discovery is available at
+ // https://:9980/hosting/discovery
+ var urlsrc = documentsMain.urlsrc +
+ "WOPISrc=" + wopisrc +
+ "&title=" + encodeURIComponent(title) +
+ "&lang=" + OC.getLocale() +
+ "&closebutton=1" +
+ "&revisionhistory=1";
+ if (!documentsMain.canEdit || action === "view") {
+ urlsrc += "&permission=readonly";
+ }
+
+ // access_token - must be passed via a form post
+ var access_token = encodeURIComponent(documentsMain.token);
+
+ // form to post the access token for WOPISrc
+ var form = '';
+
+ // iframe that contains the Collabora Online
+ var frame = '';
+
+ $('#mainContainer').append(form);
+ $('#mainContainer').append(frame);
+
+ // Listen for App_LoadingStatus as soon as possible
+ $('#loleafletframe').ready(function() {
+ var editorInitListener = function(e) {
+ var msg = JSON.parse(e.data);
+ if (msg.MessageId === 'App_LoadingStatus') {
+ window.removeEventListener('message', editorInitListener, false);
+ }
+ };
+ window.addEventListener('message', editorInitListener, false);
+ });
+
+ $('#loleafletframe').load(function(){
+ // And start listening to incoming post messages
+ window.addEventListener('message', function(e){
+ if (documentsMain.isViewerMode) {
return;
}
- // WOPISrc - URL that loolwsd will access (ie. pointing to ownCloud)
- var wopiurl = window.location.protocol + '//' + window.location.host + OC.generateUrl('apps/richdocuments/wopi/files/{file_id}', {file_id: documentsMain.fileId});
- var wopisrc = encodeURIComponent(wopiurl);
-
- // urlsrc - the URL from discovery xml that we access for the particular
- // document; we add various parameters to that.
- // The discovery is available at
- // https://:9980/hosting/discovery
- var urlsrc = documentsMain.urlsrc +
- "WOPISrc=" + wopisrc +
- "&title=" + encodeURIComponent(title) +
- "&lang=" + OC.getLocale() +
- "&closebutton=1" +
- "&revisionhistory=1";
- if (!documentsMain.canEdit || action === "view") {
- urlsrc += "&permission=readonly";
+ try {
+ var msg = JSON.parse(e.data).MessageId;
+ } catch(exc) {
+ msg = e.data;
}
+ if (msg === 'UI_Close' || msg === 'close') {
+ documentsMain.onClose();
+ } else if (msg === 'rev-history') {
+ documentsMain.UI.showRevHistory(documentsMain.fullPath);
+ }
+ });
- // access_token - must be passed via a form post
- var access_token = encodeURIComponent(result.token);
-
- // form to post the access token for WOPISrc
- var form = '';
-
- // iframe that contains the Collabora Online
- var frame = '';
-
- $('#mainContainer').append(form);
- $('#mainContainer').append(frame);
-
- // Listen for App_LoadingStatus as soon as possible
- $('#loleafletframe').ready(function() {
- var editorInitListener = function(e) {
- var msg = JSON.parse(e.data);
- if (msg.MessageId === 'App_LoadingStatus') {
- window.removeEventListener('message', editorInitListener, false);
- }
- };
- window.addEventListener('message', editorInitListener, false);
- });
-
- $('#loleafletframe').load(function(){
- // And start listening to incoming post messages
- window.addEventListener('message', function(e){
- if (documentsMain.isViewerMode) {
- return;
- }
-
- try {
- var msg = JSON.parse(e.data).MessageId;
- } catch(exc) {
- msg = e.data;
- }
- if (msg === 'UI_Close' || msg === 'close') {
- documentsMain.onClose();
- } else if (msg === 'rev-history') {
- documentsMain.UI.showRevHistory(documentsMain.fullPath);
- }
- });
-
- // Tell the LOOL iframe that we are ready now
- documentsMain.WOPIPostMessage($('#loleafletframe')[0], 'Host_PostmessageReady', {});
-
- // LOOL Iframe is ready, turn off our overlay
- // This should ideally be taken off when we receive App_LoadingStatus, but
- // for backward compatibility with older lool, lets keep it here till we decide
- // to break older lools
- documentsMain.overlay.documentOverlay('hide');
- });
-
- // submit that
- $('#loleafletform').submit();
+ // Tell the LOOL iframe that we are ready now
+ documentsMain.WOPIPostMessage($('#loleafletframe')[0], 'Host_PostmessageReady', {});
+ // LOOL Iframe is ready, turn off our overlay
+ // This should ideally be taken off when we receive App_LoadingStatus, but
+ // for backward compatibility with older lool, lets keep it here till we decide
+ // to break older lools
+ documentsMain.overlay.documentOverlay('hide');
});
+
+ // submit that
+ $('#loleafletform').submit();
+
},
hideEditor : function(){
@@ -447,16 +405,6 @@ var documentsMain = {
});
},
- showSave : function (){
- $('#odf-close').hide();
- $('#saving-document').show();
- },
-
- hideSave : function(){
- $('#saving-document').hide();
- $('#odf-close').show();
- },
-
showProgress : function(message){
if (!message){
message = ' ';
@@ -479,25 +427,12 @@ var documentsMain = {
var fileId;
documentsMain.UI.init();
- if (!OC.currentUser){
- documentsMain.isGuest = true;
+ // Does anything indicate that we need to autostart a session?
+ fileId = parent.location.hash.replace(/^\W*/, '');
- if ($("[name='document']").val()){
- $(documentsMain.toolbar).appendTo('#header');
- documentsMain.prepareSession();
- documentsMain.joinSession(
- $("[name='document']").val()
- );
- }
-
- } else {
- // Does anything indicate that we need to autostart a session?
- fileId = parent.location.hash.replace(/^\W*/, '');
-
- if (fileId.indexOf('_') >= 0) {
- documentsMain.returnToDir = unescape(fileId.replace(/^[^_]*_/, ''));
- fileId = fileId.replace(/_.*/, '');
- }
+ if (fileId.indexOf('_') >= 0) {
+ documentsMain.returnToDir = unescape(fileId.replace(/^[^_]*_/, ''));
+ fileId = fileId.replace(/_.*/, '');
}
documentsMain.show(fileId);
@@ -505,7 +440,6 @@ var documentsMain = {
if (fileId) {
documentsMain.overlay.documentOverlay('show');
documentsMain.prepareSession();
- documentsMain.joinSession(fileId);
}
documentsMain.ready = true;
@@ -530,14 +464,14 @@ var documentsMain = {
},
initSession: function(response) {
- if(response && (response.id && !response.es_id)){
- return documentsMain.view(response.id);
- }
+ documentsMain.urlsrc = response.documents[0].urlsrc;
+ documentsMain.fullPath = response.documents[0].path;
+ documentsMain.token = response.documents[0].token;
$('footer,nav').hide();
$(documentsMain.toolbar).appendTo('#header');
- if (!response || !response.status || response.status==='error'){
+ if (!response) {
documentsMain.onEditorShutdown(t('richdocuments', 'Failed to load this document. Please check if it can be opened with an external editor. This might also mean it has been unshared or deleted recently.'));
return;
}
@@ -558,9 +492,8 @@ var documentsMain = {
documentsMain.fileId = response.file_id;
documentsMain.fileName = response.title;
- documentsMain.esId = response.es_id;
documentsMain.memberId = response.member_id;
- documentsMain.canEdit = response.permissions & OC.PERMISSION_UPDATE;
+ documentsMain.canEdit = Boolean(response.permissions & OC.PERMISSION_UPDATE);
documentsMain.loadDocument(response);
@@ -571,22 +504,6 @@ var documentsMain = {
});
},
-
- joinSession: function(fileId) {
- console.log('joining session '+fileId);
- var url;
- if (documentsMain.isGuest){
- url = OC.generateUrl('apps/richdocuments/session/guest/join/{token}', {token: fileId});
- } else {
- url = OC.generateUrl('apps/richdocuments/session/user/join/{file_id}', {file_id: fileId});
- }
- $.post(
- url,
- { name : $("[name='memberName']").val() },
- documentsMain.initSession
- );
- },
-
view : function(id){
OC.addScript('richdocuments', 'viewer/viewer', function() {
$(window).off('beforeunload');
@@ -680,77 +597,6 @@ var documentsMain = {
}
};
-//init
-var Files = Files || {
- // FIXME: copy/pasted from Files.isFileNameValid, needs refactor into core
- isFileNameValid:function (name) {
- if (name === '.') {
- throw t('files', '\'.\' is an invalid file name.');
- } else if (name.length === 0) {
- throw t('files', 'File name cannot be empty.');
- }
-
- // check for invalid characters
- var invalid_characters = ['\\', '/', '<', '>', ':', '"', '|', '?', '*'];
- for (var i = 0; i < invalid_characters.length; i++) {
- if (name.indexOf(invalid_characters[i]) !== -1) {
- throw t('files', "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed.");
- }
- }
- return true;
- },
-
- updateStorageStatistics: function(){}
-},
-FileList = FileList || {};
-
-FileList.getCurrentDirectory = function(){
- return $('#dir').val() || '/';
-};
-
-FileList.highlightFiles = function(files, highlightFunction) {
-};
-
-FileList.findFile = function(filename) {
- var documents = documentsMain.docs.documentGrid('option').documents;
- return _.find(documents, function(aFile) {
- return (aFile.name === filename);
- }) || false;
-};
-
-FileList.generatePreviewUrl = function(urlSpec) {
- urlSpec = urlSpec || {};
- if (!urlSpec.x) {
- urlSpec.x = 32;
- }
- if (!urlSpec.y) {
- urlSpec.y = 32;
- }
- urlSpec.x *= window.devicePixelRatio;
- urlSpec.y *= window.devicePixelRatio;
- urlSpec.x = Math.ceil(urlSpec.x);
- urlSpec.y = Math.ceil(urlSpec.y);
- urlSpec.forceIcon = 0;
- return OC.generateUrl('/core/preview.png?') + $.param(urlSpec);
-};
-
-FileList.isFileNameValid = function (name) {
- var trimmedName = name.trim();
- if (trimmedName === '.' || trimmedName === '..') {
- throw t('files', '"{name}" is an invalid file name.', {name: name});
- } else if (trimmedName.length === 0) {
- throw t('files', 'File name cannot be empty.');
- }
- return true;
-};
-
-FileList.setViewerMode = function(){
-};
-FileList.findFile = function(fileName){
- fullPath = escapeHTML(FileList.getCurrentDirectory + '/' + fileName);
- return !!$('.documentslist .document:not(.template,.progress) a[original-title="' + fullPath + '"]').length;
-};
-
$(document).ready(function() {
if (!OCA.Files) {
diff --git a/js/share.js b/js/share.js
deleted file mode 100644
index 04f9f2b2e..000000000
--- a/js/share.js
+++ /dev/null
@@ -1,1246 +0,0 @@
-/* global escapeHTML */
-
-(function(OC) {
- // copied and stripped out from the old core
- OC.Share = _.extend(OC.Share, {
- /**
- * @deprecated use OC.Share.currentShares instead
- */
- itemShares:[],
- /**
- * Full list of all share statuses
- */
- statuses:{},
- /**
- * Shares for the currently selected file.
- * (for which the dropdown is open)
- *
- * Key is item type and value is an array or
- * shares of the given item type.
- */
- currentShares: {},
- /**
- * Whether the share dropdown is opened.
- */
- droppedDown:false,
- /**
- * Loads ALL share statuses from server, stores them in
- * OC.Share.statuses then calls OC.Share.updateIcons() to update the
- * files "Share" icon to "Shared" according to their share status and
- * share type.
- *
- * If a callback is specified, the update step is skipped.
- *
- * @param itemType item type
- * @param fileList file list instance, defaults to OCA.Files.App.fileList
- * @param callback function to call after the shares were loaded
- */
- loadIcons:function(itemType, fileList, callback) {
- // Load all share icons
- $.get(
- OC.filePath('core', 'ajax', 'share.php'),
- {
- fetch: 'getItemsSharedStatuses',
- itemType: itemType
- }, function(result) {
- if (result && result.status === 'success') {
- OC.Share.statuses = {};
- $.each(result.data, function(item, data) {
- OC.Share.statuses[item] = data;
- });
- if (_.isFunction(callback)) {
- callback(OC.Share.statuses);
- } else {
- OC.Share.updateIcons(itemType, fileList);
- }
- }
- }
- );
- },
- /**
- * Updates the files' "Share" icons according to the known
- * sharing states stored in OC.Share.statuses.
- * (not reloaded from server)
- *
- * @param itemType item type
- * @param fileList file list instance
- * defaults to OCA.Files.App.fileList
- */
- updateIcons:function(itemType, fileList){
- var item;
- var $fileList;
- var currentDir;
- if (!fileList && OCA.Files) {
- fileList = OCA.Files.App.fileList;
- }
- // fileList is usually only defined in the files app
- if (fileList) {
- $fileList = fileList.$fileList;
- currentDir = fileList.getCurrentDirectory();
- }
- // TODO: iterating over the files might be more efficient
- for (item in OC.Share.statuses){
- var image = OC.imagePath('core', 'actions/share');
- var data = OC.Share.statuses[item];
- var hasLink = data.link;
- // Links override shared in terms of icon display
- if (hasLink) {
- image = OC.imagePath('core', 'actions/public');
- }
- if (itemType !== 'file' && itemType !== 'folder') {
- $('a.share[data-item="'+item+'"]').css('background', 'url('+image+') no-repeat center');
- } else {
- // TODO: ultimately this part should be moved to files_sharing app
- var file = $fileList.find('tr[data-id="'+item+'"]');
- var shareFolder = OC.imagePath('core', 'filetypes/folder-shared');
- var img;
- if (file.length > 0) {
- this.markFileAsShared(file, true, hasLink);
- } else {
- var dir = currentDir;
- if (dir.length > 1) {
- var last = '';
- var path = dir;
- // Search for possible parent folders that are shared
- while (path != last) {
- if (path === data.path && !data.link) {
- var actions = $fileList.find('.fileactions .action[data-action="Share"]');
- var files = $fileList.find('.filename');
- var i;
- for (i = 0; i < actions.length; i++) {
- // TODO: use this.markFileAsShared()
- img = $(actions[i]).find('img');
- if (img.attr('src') !== OC.imagePath('core', 'actions/public')) {
- img.attr('src', image);
- $(actions[i]).addClass('permanent');
- $(actions[i]).html(' '+t('core', 'Shared')+'').prepend(img);
- }
- }
- for(i = 0; i < files.length; i++) {
- if ($(files[i]).closest('tr').data('type') === 'dir') {
- $(files[i]).find('.thumbnail').css('background-image', 'url('+shareFolder+')');
- }
- }
- }
- last = path;
- path = OC.Share.dirname(path);
- }
- }
- }
- }
- }
- },
- updateIcon:function(itemType, itemSource) {
- var shares = false;
- var link = false;
- var image = OC.imagePath('core', 'actions/share');
- $.each(OC.Share.itemShares, function(index) {
- if (OC.Share.itemShares[index]) {
- if (index == OC.Share.SHARE_TYPE_LINK) {
- if (OC.Share.itemShares[index] == true) {
- shares = true;
- image = OC.imagePath('core', 'actions/public');
- link = true;
- return;
- }
- } else if (OC.Share.itemShares[index].length > 0) {
- shares = true;
- image = OC.imagePath('core', 'actions/share');
- }
- }
- });
- if (itemType != 'file' && itemType != 'folder') {
- $('a.share[data-item="'+itemSource+'"]').css('background', 'url('+image+') no-repeat center');
- } else {
- var $tr = $('tr').filterAttr('data-id', String(itemSource));
- if ($tr.length > 0) {
- // it might happen that multiple lists exist in the DOM
- // with the same id
- $tr.each(function() {
- OC.Share.markFileAsShared($(this), shares, link);
- });
- }
- }
- if (shares) {
- OC.Share.statuses[itemSource] = OC.Share.statuses[itemSource] || {};
- OC.Share.statuses[itemSource]['link'] = link;
- } else {
- delete OC.Share.statuses[itemSource];
- }
- },
- /**
- * Format a remote address
- *
- * @param {String} remoteAddress full remote share
- * @return {String} HTML code to display
- */
- _formatRemoteShare: function(remoteAddress) {
- var parts = this._REMOTE_OWNER_REGEXP.exec(remoteAddress);
- if (!parts) {
- // display as is, most likely to be a simple owner name
- return escapeHTML(remoteAddress);
- }
-
- var userName = parts[1];
- var userDomain = parts[3];
- var server = parts[4];
- var dir = parts[6];
- var tooltip = userName;
- if (userDomain) {
- tooltip += '@' + userDomain;
- }
- if (server) {
- if (!userDomain) {
- userDomain = '…';
- }
- tooltip += '@' + server;
- }
-
- var html = '';
- html += '' + escapeHTML(userName) + '';
- if (userDomain) {
- html += '@' + escapeHTML(userDomain) + '';
- }
- html += '';
- return html;
- },
- /**
- * Marks/unmarks a given file as shared by changing its action icon
- * and folder icon.
- *
- * @param $tr file element to mark as shared
- * @param hasShares whether shares are available
- * @param hasLink whether link share is available
- */
- loadItem:function(itemType, itemSource) {
- var data = '';
- var checkReshare = true;
- if (typeof OC.Share.statuses[itemSource] === 'undefined') {
- // NOTE: Check does not always work and misses some shares, fix later
- var checkShares = true;
- } else {
- var checkShares = true;
- }
- $.ajax({type: 'GET', url: OC.filePath('core', 'ajax', 'share.php'), data: { fetch: 'getItem', itemType: itemType, itemSource: itemSource, checkReshare: checkReshare, checkShares: checkShares }, async: false, success: function(result) {
- if (result && result.status === 'success') {
- data = result.data;
- } else {
- data = false;
- }
- }});
-
- return data;
- },
- share:function(itemType, itemSource, shareType, shareWith, permissions, itemSourceName, expirationDate, callback, errorCallback) {
- // Add a fallback for old share() calls without expirationDate.
- // We should remove this in a later version,
- // after the Apps have been updated.
- if (typeof callback === 'undefined' &&
- typeof expirationDate === 'function') {
- callback = expirationDate;
- expirationDate = '';
- console.warn(
- "Call to 'OC.Share.share()' with too few arguments. " +
- "'expirationDate' was assumed to be 'callback'. " +
- "Please revisit the call and fix the list of arguments."
- );
- }
-
- return $.post(OC.filePath('core', 'ajax', 'share.php'),
- {
- action: 'share',
- itemType: itemType,
- itemSource: itemSource,
- shareType: shareType,
- shareWith: shareWith,
- permissions: permissions,
- itemSourceName: itemSourceName,
- expirationDate: expirationDate
- }, function (result) {
- if (result && result.status === 'success') {
- if (callback) {
- callback(result.data);
- }
- } else {
- if (_.isUndefined(errorCallback)) {
- var msg = t('core', 'Error');
- if (result.data && result.data.message) {
- msg = result.data.message;
- }
- OC.dialogs.alert(msg, t('core', 'Error while sharing'));
- } else {
- errorCallback(result);
- }
- }
- }
- );
- },
- unshare:function(itemType, itemSource, shareType, shareWith, callback) {
- $.post(OC.filePath('core', 'ajax', 'share.php'), { action: 'unshare', itemType: itemType, itemSource: itemSource, shareType: shareType, shareWith: shareWith }, function(result) {
- if (result && result.status === 'success') {
- if (callback) {
- callback();
- }
- } else {
- OC.dialogs.alert(t('core', 'Error while unsharing'), t('core', 'Error'));
- }
- });
- },
- setPermissions:function(itemType, itemSource, shareType, shareWith, permissions) {
- $.post(OC.filePath('core', 'ajax', 'share.php'), { action: 'setPermissions', itemType: itemType, itemSource: itemSource, shareType: shareType, shareWith: shareWith, permissions: permissions }, function(result) {
- if (!result || result.status !== 'success') {
- OC.dialogs.alert(t('core', 'Error while changing permissions'), t('core', 'Error'));
- }
- });
- },
- showDropDown:function(itemType, itemSource, appendTo, link, possiblePermissions, filename) {
- var data = OC.Share.loadItem(itemType, itemSource);
- var dropDownEl;
- var html = '
';
- if (data !== false && data.reshare !== false && data.reshare.uid_owner !== undefined && data.reshare.uid_owner !== OC.currentUser) {
- html += '';
- if (oc_config.enable_avatars === true) {
- html += ' ';
- }
-
- if (data.reshare.share_type == OC.Share.SHARE_TYPE_GROUP) {
- html += t('core', 'Shared with you and the group {group} by {owner}', {group: data.reshare.share_with, owner: data.reshare.displayname_owner});
- } else {
- html += t('core', 'Shared with you by {owner}', {owner: data.reshare.displayname_owner});
- }
- html += ' ';
- // reduce possible permissions to what the original share allowed
- possiblePermissions = possiblePermissions & data.reshare.permissions;
- }
-
- if (possiblePermissions & OC.PERMISSION_SHARE) {
- // Determine the Allow Public Upload status.
- // Used later on to determine if the
- // respective checkbox should be checked or
- // not.
-
- var publicUploadEnabled = $('#filestable').data('allow-public-upload');
- if (typeof publicUploadEnabled == 'undefined') {
- publicUploadEnabled = 'no';
- }
- var allowPublicUploadStatus = false;
-
- $.each(data.shares, function(key, value) {
- if (value.share_type === OC.Share.SHARE_TYPE_LINK) {
- allowPublicUploadStatus = (value.permissions & OC.PERMISSION_CREATE) ? true : false;
- return true;
- }
- });
-
- var sharePlaceholder = t('core', 'Share with users or groups …');
- if(oc_appconfig.core.remoteShareAllowed) {
- sharePlaceholder = t('core', 'Share with users, groups or remote users …');
- }
-
- html += '';
- html += '';
- if(oc_appconfig.core.remoteShareAllowed) {
- var federatedCloudSharingDoc = '';
- html += federatedCloudSharingDoc.replace('{docLink}', oc_appconfig.core.federatedCloudShareDoc);
- }
- html += '';
- html += '
';
- html += '
';
- var linksAllowed = $('#allowShareWithLink').val() === 'yes';
- if (link && linksAllowed) {
- html += '
';
- html += '';
- html += '';
- html += ' ';
-
- var defaultExpireMessage = '';
- if ((itemType === 'folder' || itemType === 'file') && oc_appconfig.core.defaultExpireDateEnforced) {
- defaultExpireMessage = t('core', 'The public link will expire no later than {days} days after it is created', {'days': oc_appconfig.core.defaultExpireDate}) + ' ';
- }
-
- html += '';
- html += '';
- html += '';
- html += '
';
- html += '';
- html += '';
- html += '';
- html += '
';
-
- if (itemType === 'folder' && (possiblePermissions & OC.PERMISSION_CREATE) && publicUploadEnabled === 'yes') {
- html += '
';
- html += '';
- html += '';
- html += '';
- html += '
';
- }
- html += '
';
- var mailPublicNotificationEnabled = $('input:hidden[name=mailPublicNotificationEnabled]').val();
- if (mailPublicNotificationEnabled === 'yes') {
- html += '';
- }
- }
-
- html += '
';
- html += '';
- html += '';
- html += '';
- html += ''+defaultExpireMessage+'';
- html += '
';
- var showCrudsButton;
- html += '';
- if (oc_config.enable_avatars === true) {
- html += '';
- }
- html += '' + escapeHTML(shareWithDisplayName) + '';
- var mailNotificationEnabled = $('input:hidden[name=mailNotificationEnabled]').val();
- if (mailNotificationEnabled === 'yes' && shareType !== OC.Share.SHARE_TYPE_REMOTE) {
- var checked = '';
- if (mailSend === '1') {
- checked = 'checked';
- }
- html += ' ';
- }
- if (oc_appconfig.core.resharingAllowed && (possiblePermissions & OC.PERMISSION_SHARE)) {
- html += '';
- html += '';
- }
- if (possiblePermissions & OC.PERMISSION_CREATE || possiblePermissions & OC.PERMISSION_UPDATE || possiblePermissions & OC.PERMISSION_DELETE) {
- html += '';
- html += '';
- }
- if (shareType !== OC.Share.SHARE_TYPE_REMOTE) {
- showCrudsButton = '';
- }
- html += '
';
- if (possiblePermissions & OC.PERMISSION_CREATE) {
- html += '';
- html += '';
- }
- if (possiblePermissions & OC.PERMISSION_UPDATE) {
- html += '';
- html += '';
- }
- if (possiblePermissions & OC.PERMISSION_DELETE) {
- html += '';
- html += '';
- }
- html += '
';
- html += '
';
- html = $(html).appendTo('#shareWithList');
- if (oc_config.enable_avatars === true) {
- if (shareType === OC.Share.SHARE_TYPE_USER) {
- html.find('.avatar').avatar(escapeHTML(shareWith), 32);
- } else {
- //Add sharetype to generate different seed if there is a group and use with the same name
- html.find('.avatar').imageplaceholder(escapeHTML(shareWith) + ' ' + shareType);
- }
- }
- // insert cruds button into last label element
- var lastLabel = html.find('>label:last');
- if (lastLabel.exists()){
- lastLabel.append(showCrudsButton);
- }
- else{
- html.find('.cruds').before(showCrudsButton);
- }
- if (!OC.Share.currentShares[shareType]) {
- OC.Share.currentShares[shareType] = [];
- }
- OC.Share.currentShares[shareType].push(shareItem);
- }
- },
- showLink:function(token, password, itemSource) {
- OC.Share.itemShares[OC.Share.SHARE_TYPE_LINK] = true;
- $('#linkCheckbox').attr('checked', true);
-
- //check itemType
- var linkSharetype=$('#dropdown').data('item-type');
-
- if (! token) {
- //fallback to pre token link
- var filename = $('tr').filterAttr('data-id', String(itemSource)).data('file');
- var type = $('tr').filterAttr('data-id', String(itemSource)).data('type');
- if ($('#dir').val() == '/') {
- var file = $('#dir').val() + filename;
- } else {
- var file = $('#dir').val() + '/' + filename;
- }
- file = '/'+OC.currentUser+'/files'+file;
- // TODO: use oc webroot ?
- var link = parent.location.protocol+'//'+location.host+OC.linkTo('', 'public.php')+'?service=files&'+type+'='+encodeURIComponent(file);
- } else {
- //TODO add path param when showing a link to file in a subfolder of a public link share
- var service='';
- if(linkSharetype === 'folder' || linkSharetype === 'file'){
- service='files';
- }else{
- service=linkSharetype;
- }
-
- // TODO: use oc webroot ?
- if (service !== 'files') {
- var link = parent.location.protocol+'//'+location.host+OC.linkTo('', 'public.php')+'?service='+service+'&t='+token;
- } else {
- var link = parent.location.protocol+'//'+location.host+OC.generateUrl('/s/')+token;
- }
- }
- $('#linkText').val(link);
- $('#linkText').slideDown(OC.menuSpeed);
- $('#linkText').css('display','block');
- if (oc_appconfig.core.enforcePasswordForPublicLink === false || password === null) {
- $('#showPassword').show();
- $('#showPassword+label').show();
- }
- if (password != null) {
- $('#linkPass').slideDown(OC.menuSpeed);
- $('#showPassword').attr('checked', true);
- $('#linkPassText').attr('placeholder', '**********');
- }
- $('#expiration').show();
- $('#emailPrivateLink #email').show();
- $('#emailPrivateLink #emailButton').show();
- $('#allowPublicUploadWrapper').show();
- },
- hideLink:function() {
- $('#linkText').slideUp(OC.menuSpeed);
- $('#defaultExpireMessage').hide();
- $('#showPassword').hide();
- $('#showPassword+label').hide();
- $('#linkPass').slideUp(OC.menuSpeed);
- $('#emailPrivateLink #email').hide();
- $('#emailPrivateLink #emailButton').hide();
- $('#allowPublicUploadWrapper').hide();
- },
- dirname:function(path) {
- return path.replace(/\\/g,'/').replace(/\/[^\/]*$/, '');
- },
- /**
- * Parses a string to an valid integer (unix timestamp)
- * @param time
- * @returns {*}
- * @internal Only used to work around a bug in the backend
- */
- _parseTime: function(time) {
- if (_.isString(time)) {
- // skip empty strings and hex values
- if (time === '' || (time.length > 1 && time[0] === '0' && time[1] === 'x')) {
- return null;
- }
- time = parseInt(time, 10);
- if(isNaN(time)) {
- time = null;
- }
- }
- return time;
- },
- /**
- * Displays the expiration date field
- *
- * @param {Date} date current expiration date
- * @param {int} [shareTime] share timestamp in seconds, defaults to now
- */
- showExpirationDate:function(date, shareTime) {
- var now = new Date();
- // min date should always be the next day
- var minDate = new Date();
- minDate.setDate(minDate.getDate()+1);
- var datePickerOptions = {
- minDate: minDate,
- maxDate: null
- };
- // TODO: hack: backend returns string instead of integer
- shareTime = OC.Share._parseTime(shareTime);
- if (_.isNumber(shareTime)) {
- shareTime = new Date(shareTime * 1000);
- }
- if (!shareTime) {
- shareTime = now;
- }
- $('#expirationCheckbox').attr('checked', true);
- $('#expirationDate').val(date);
- $('#expirationDate').slideDown(OC.menuSpeed);
- $('#expirationDate').css('display','block');
- $('#expirationDate').datepicker({
- dateFormat : 'dd-mm-yy'
- });
- if (oc_appconfig.core.defaultExpireDateEnforced) {
- $('#expirationCheckbox').attr('disabled', true);
- shareTime = OC.Util.stripTime(shareTime).getTime();
- // max date is share date + X days
- datePickerOptions.maxDate = new Date(shareTime + oc_appconfig.core.defaultExpireDate * 24 * 3600 * 1000);
- }
- if(oc_appconfig.core.defaultExpireDateEnabled) {
- $('#defaultExpireMessage').slideDown(OC.menuSpeed);
- }
- $.datepicker.setDefaults(datePickerOptions);
- },
- /**
- * Get the default Expire date
- *
- * @return {String} The expire date
- */
- getDefaultExpirationDate:function() {
- var expireDateString = '';
- if (oc_appconfig.core.defaultExpireDateEnabled) {
- var date = new Date().getTime();
- var expireAfterMs = oc_appconfig.core.defaultExpireDate * 24 * 60 * 60 * 1000;
- var expireDate = new Date(date + expireAfterMs);
- var month = expireDate.getMonth() + 1;
- var year = expireDate.getFullYear();
- var day = expireDate.getDate();
- expireDateString = year + "-" + month + '-' + day + ' 00:00:00';
- }
- return expireDateString;
- }
- });
-
- $(document).ready(function() {
-
- if(typeof monthNames != 'undefined'){
- // min date should always be the next day
- var minDate = new Date();
- minDate.setDate(minDate.getDate()+1);
- $.datepicker.setDefaults({
- monthNames: monthNames,
- monthNamesShort: $.map(monthNames, function(v) { return v.slice(0,3)+'.'; }),
- dayNames: dayNames,
- dayNamesMin: $.map(dayNames, function(v) { return v.slice(0,2); }),
- dayNamesShort: $.map(dayNames, function(v) { return v.slice(0,3)+'.'; }),
- firstDay: firstDay,
- minDate : minDate
- });
- }
- $(document).on('click', 'a.share', function(event) {
- event.stopPropagation();
- if ($(this).data('item-type') !== undefined && $(this).data('item') !== undefined) {
- var itemType = $(this).data('item-type');
- var itemSource = $(this).data('item');
- var appendTo = $(this).parent().parent();
- var link = false;
- var possiblePermissions = $(this).data('possible-permissions');
- if ($(this).data('link') !== undefined && $(this).data('link') == true) {
- link = true;
- }
- if (OC.Share.droppedDown) {
- if (itemSource != $('#dropdown').data('item')) {
- OC.Share.hideDropDown(function () {
- OC.Share.showDropDown(itemType, itemSource, appendTo, link, possiblePermissions);
- });
- } else {
- OC.Share.hideDropDown();
- }
- } else {
- OC.Share.showDropDown(itemType, itemSource, appendTo, link, possiblePermissions);
- }
- }
- });
-
- $(this).click(function(event) {
- var target = $(event.target);
- var isMatched = !target.is('.drop, .ui-datepicker-next, .ui-datepicker-prev, .ui-icon')
- && !target.closest('#ui-datepicker-div').length && !target.closest('.ui-autocomplete').length;
- if (OC.Share.droppedDown && isMatched && $('#dropdown').has(event.target).length === 0) {
- OC.Share.hideDropDown();
- }
- });
-
- $(document).on('click', '#dropdown .showCruds', function() {
- $(this).closest('li').find('.cruds').toggle();
- return false;
- });
-
- $(document).on('click', '#dropdown .unshare', function() {
- var $li = $(this).closest('li');
- var itemType = $('#dropdown').data('item-type');
- var itemSource = $('#dropdown').data('item-source');
- var shareType = $li.data('share-type');
- var shareWith = $li.attr('data-share-with');
- var $button = $(this);
-
- if (!$button.is('a')) {
- $button = $button.closest('a');
- }
-
- if ($button.hasClass('icon-loading-small')) {
- // deletion in progress
- return false;
- }
- $button.empty().addClass('icon-loading-small');
-
- OC.Share.unshare(itemType, itemSource, shareType, shareWith, function() {
- $li.remove();
- var index = OC.Share.itemShares[shareType].indexOf(shareWith);
- OC.Share.itemShares[shareType].splice(index, 1);
- // updated list of shares
- OC.Share.currentShares[shareType].splice(index, 1);
- $('#dropdown').trigger(new $.Event('sharesChanged', {shares: OC.Share.currentShares}));
- OC.Share.updateIcon(itemType, itemSource);
- if (typeof OC.Share.statuses[itemSource] === 'undefined') {
- $('#expiration').slideUp(OC.menuSpeed);
- }
- });
-
- return false;
- });
-
- $(document).on('change', '#dropdown .permissions', function() {
- var li = $(this).closest('li');
- if ($(this).attr('name') == 'edit') {
- var checkboxes = $('.permissions', li);
- var checked = $(this).is(':checked');
- // Check/uncheck Create, Update, and Delete checkboxes if Edit is checked/unck
- $(checkboxes).filter('input[name="create"]').attr('checked', checked);
- $(checkboxes).filter('input[name="update"]').attr('checked', checked);
- $(checkboxes).filter('input[name="delete"]').attr('checked', checked);
- } else {
- var checkboxes = $('.permissions', li);
- // Uncheck Edit if Create, Update, and Delete are not checked
- if (!$(this).is(':checked')
- && !$(checkboxes).filter('input[name="create"]').is(':checked')
- && !$(checkboxes).filter('input[name="update"]').is(':checked')
- && !$(checkboxes).filter('input[name="delete"]').is(':checked'))
- {
- $(checkboxes).filter('input[name="edit"]').attr('checked', false);
- // Check Edit if Create, Update, or Delete is checked
- } else if (($(this).attr('name') == 'create'
- || $(this).attr('name') == 'update'
- || $(this).attr('name') == 'delete'))
- {
- $(checkboxes).filter('input[name="edit"]').attr('checked', true);
- }
- }
- var permissions = OC.PERMISSION_READ;
- $(checkboxes).filter(':not(input[name="edit"])').filter(':checked').each(function(index, checkbox) {
- permissions |= $(checkbox).data('permissions');
- });
- OC.Share.setPermissions($('#dropdown').data('item-type'),
- $('#dropdown').data('item-source'),
- li.data('share-type'),
- li.attr('data-share-with'),
- permissions);
- });
-
- $(document).on('change', '#dropdown #linkCheckbox', function() {
- var $dropDown = $('#dropdown');
- var itemType = $dropDown.data('item-type');
- var itemSource = $dropDown.data('item-source');
- var itemSourceName = $dropDown.data('item-source-name');
- var $loading = $dropDown.find('#link .icon-loading-small');
- var $button = $(this);
-
- if (!$loading.hasClass('hidden')) {
- // already in progress
- return false;
- }
-
- if (this.checked) {
- // Reset password placeholder
- $('#linkPassText').attr('placeholder', t('core', 'Choose a password for the public link'));
- // Reset link
- $('#linkText').val('');
- $('#showPassword').prop('checked', false);
- $('#linkPass').hide();
- $('#sharingDialogAllowPublicUpload').prop('checked', false);
- $('#expirationCheckbox').prop('checked', false);
- $('#expirationDate').hide();
- var expireDateString = '';
- // Create a link
- if (oc_appconfig.core.enforcePasswordForPublicLink === false) {
- expireDateString = OC.Share.getDefaultExpirationDate();
- $loading.removeClass('hidden');
- $button.addClass('hidden');
- $button.prop('disabled', true);
-
- OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', OC.PERMISSION_READ, itemSourceName, expireDateString, function(data) {
- $loading.addClass('hidden');
- $button.removeClass('hidden');
- $button.prop('disabled', false);
- OC.Share.showLink(data.token, null, itemSource);
- $('#dropdown').trigger(new $.Event('sharesChanged', {shares: OC.Share.currentShares}));
- OC.Share.updateIcon(itemType, itemSource);
- });
- } else {
- $('#linkPass').slideToggle(OC.menuSpeed);
- // TODO drop with IE8 drop
- if($('html').hasClass('ie8')) {
- $('#linkPassText').attr('placeholder', null);
- $('#linkPassText').val('');
- }
- $('#linkPassText').focus();
- }
- if (expireDateString !== '') {
- OC.Share.showExpirationDate(expireDateString);
- }
- } else {
- // Delete private link
- OC.Share.hideLink();
- $('#expiration').slideUp(OC.menuSpeed);
- if ($('#linkText').val() !== '') {
- $loading.removeClass('hidden');
- $button.addClass('hidden');
- $button.prop('disabled', true);
- OC.Share.unshare(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', function() {
- $loading.addClass('hidden');
- $button.removeClass('hidden');
- $button.prop('disabled', false);
- OC.Share.itemShares[OC.Share.SHARE_TYPE_LINK] = false;
- $('#dropdown').trigger(new $.Event('sharesChanged', {shares: OC.Share.currentShares}));
- OC.Share.updateIcon(itemType, itemSource);
- if (typeof OC.Share.statuses[itemSource] === 'undefined') {
- $('#expiration').slideUp(OC.menuSpeed);
- }
- });
- }
- }
- });
-
- $(document).on('click', '#dropdown #linkText', function() {
- $(this).focus();
- $(this).select();
- });
-
- // Handle the Allow Public Upload Checkbox
- $(document).on('click', '#sharingDialogAllowPublicUpload', function() {
-
- // Gather data
- var $dropDown = $('#dropdown');
- var allowPublicUpload = $(this).is(':checked');
- var itemType = $dropDown.data('item-type');
- var itemSource = $dropDown.data('item-source');
- var itemSourceName = $dropDown.data('item-source-name');
- var expirationDate = '';
- if ($('#expirationCheckbox').is(':checked') === true) {
- expirationDate = $( "#expirationDate" ).val();
- }
- var permissions = 0;
- var $button = $(this);
- var $loading = $dropDown.find('#allowPublicUploadWrapper .icon-loading-small');
-
- if (!$loading.hasClass('hidden')) {
- // already in progress
- return false;
- }
-
- // Calculate permissions
- if (allowPublicUpload) {
- permissions = OC.PERMISSION_UPDATE + OC.PERMISSION_CREATE + OC.PERMISSION_READ;
- } else {
- permissions = OC.PERMISSION_READ;
- }
-
- // Update the share information
- $button.addClass('hidden');
- $button.prop('disabled', true);
- $loading.removeClass('hidden');
- OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', permissions, itemSourceName, expirationDate, function(data) {
- $loading.addClass('hidden');
- $button.removeClass('hidden');
- $button.prop('disabled', false);
- });
- });
-
- $(document).on('click', '#dropdown #showPassword', function() {
- $('#linkPass').slideToggle(OC.menuSpeed);
- if (!$('#showPassword').is(':checked') ) {
- var itemType = $('#dropdown').data('item-type');
- var itemSource = $('#dropdown').data('item-source');
- var itemSourceName = $('#dropdown').data('item-source-name');
- var allowPublicUpload = $('#sharingDialogAllowPublicUpload').is(':checked');
- var permissions = 0;
- var $loading = $('#showPassword .icon-loading-small');
-
- // Calculate permissions
- if (allowPublicUpload) {
- permissions = OC.PERMISSION_UPDATE + OC.PERMISSION_CREATE + OC.PERMISSION_READ;
- } else {
- permissions = OC.PERMISSION_READ;
- }
-
- $loading.removeClass('hidden');
- OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', permissions, itemSourceName).then(function() {
- $loading.addClass('hidden');
- $('#linkPassText').attr('placeholder', t('core', 'Choose a password for the public link'));
- });
- } else {
- $('#linkPassText').focus();
- }
- });
-
- $(document).on('focusout keyup', '#dropdown #linkPassText', function(event) {
- var linkPassText = $('#linkPassText');
- if ( linkPassText.val() != '' && (event.type == 'focusout' || event.keyCode == 13) ) {
- var allowPublicUpload = $('#sharingDialogAllowPublicUpload').is(':checked');
- var dropDown = $('#dropdown');
- var itemType = dropDown.data('item-type');
- var itemSource = dropDown.data('item-source');
- var itemSourceName = $('#dropdown').data('item-source-name');
- var permissions = 0;
- var $loading = dropDown.find('#linkPass .icon-loading-small');
-
- // Calculate permissions
- if (allowPublicUpload) {
- permissions = OC.PERMISSION_UPDATE + OC.PERMISSION_CREATE + OC.PERMISSION_READ;
- } else {
- permissions = OC.PERMISSION_READ;
- }
-
- var expireDateString = OC.Share.getDefaultExpirationDate();
-
- $loading.removeClass('hidden');
- OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, $('#linkPassText').val(), permissions, itemSourceName, expireDateString, function(data) {
- $loading.addClass('hidden');
- linkPassText.val('');
- linkPassText.attr('placeholder', t('core', 'Password protected'));
-
- if (oc_appconfig.core.enforcePasswordForPublicLink) {
- OC.Share.showLink(data.token, "password set", itemSource);
- OC.Share.updateIcon(itemType, itemSource);
- }
- $('#dropdown').trigger(new $.Event('sharesChanged', {shares: OC.Share.currentShares}));
- }, function(result) {
- $loading.addClass('hidden');
- linkPassText.val('');
- linkPassText.attr('placeholder', result.data.message);
- });
-
- if (expireDateString !== '') {
- OC.Share.showExpirationDate(expireDateString);
- }
- }
- });
-
- $(document).on('click', '#dropdown #expirationCheckbox', function() {
- if (this.checked) {
- OC.Share.showExpirationDate('');
- } else {
- var itemType = $('#dropdown').data('item-type');
- var itemSource = $('#dropdown').data('item-source');
- $.post(OC.filePath('core', 'ajax', 'share.php'), { action: 'setExpirationDate', itemType: itemType, itemSource: itemSource, date: '' }, function(result) {
- if (!result || result.status !== 'success') {
- OC.dialogs.alert(t('core', 'Error unsetting expiration date'), t('core', 'Error'));
- }
- $('#expirationDate').slideUp(OC.menuSpeed);
- if (oc_appconfig.core.defaultExpireDateEnforced === false) {
- $('#defaultExpireMessage').slideDown(OC.menuSpeed);
- }
- });
- }
- });
-
- $(document).on('change', '#dropdown #expirationDate', function() {
- var itemType = $('#dropdown').data('item-type');
- var itemSource = $('#dropdown').data('item-source');
-
- $(this).tipsy('hide');
- $(this).removeClass('error');
-
- $.post(OC.filePath('core', 'ajax', 'share.php'), { action: 'setExpirationDate', itemType: itemType, itemSource: itemSource, date: $(this).val() }, function(result) {
- if (!result || result.status !== 'success') {
- var expirationDateField = $('#dropdown #expirationDate');
- if (!result.data.message) {
- expirationDateField.attr('original-title', t('core', 'Error setting expiration date'));
- } else {
- expirationDateField.attr('original-title', result.data.message);
- }
- expirationDateField.tipsy({gravity: 'n'});
- expirationDateField.tipsy('show');
- expirationDateField.addClass('error');
- } else {
- if (oc_appconfig.core.defaultExpireDateEnforced === 'no') {
- $('#defaultExpireMessage').slideUp(OC.menuSpeed);
- }
- }
- });
- });
-
-
- $(document).on('submit', '#dropdown #emailPrivateLink', function(event) {
- event.preventDefault();
- var link = $('#linkText').val();
- var itemType = $('#dropdown').data('item-type');
- var itemSource = $('#dropdown').data('item-source');
- var file = $('tr').filterAttr('data-id', String(itemSource)).data('file');
- var email = $('#email').val();
- var expirationDate = '';
- if ( $('#expirationCheckbox').is(':checked') === true ) {
- expirationDate = $( "#expirationDate" ).val();
- }
- if (email != '') {
- $('#email').prop('disabled', true);
- $('#email').val(t('core', 'Sending ...'));
- $('#emailButton').prop('disabled', true);
-
- $.post(OC.filePath('core', 'ajax', 'share.php'), { action: 'email', toaddress: email, link: link, itemType: itemType, itemSource: itemSource, file: file, expiration: expirationDate},
- function(result) {
- $('#email').prop('disabled', false);
- $('#emailButton').prop('disabled', false);
- if (result && result.status == 'success') {
- $('#email').css('font-weight', 'bold').val(t('core','Email sent'));
- setTimeout(function() {
- $('#email').css('font-weight', 'normal').val('');
- }, 2000);
- } else {
- OC.dialogs.alert(result.data.message, t('core', 'Error while sharing'));
- }
- });
- }
- });
-
- $(document).on('click', '#dropdown input[name=mailNotification]', function() {
- var $li = $(this).closest('li');
- var itemType = $('#dropdown').data('item-type');
- var itemSource = $('#dropdown').data('item-source');
- var action = '';
- if (this.checked) {
- action = 'informRecipients';
- } else {
- action = 'informRecipientsDisabled';
- }
-
- var shareType = $li.data('share-type');
- var shareWith = $li.attr('data-share-with');
-
- $.post(OC.filePath('core', 'ajax', 'share.php'), {action: action, recipient: shareWith, shareType: shareType, itemSource: itemSource, itemType: itemType}, function(result) {
- if (result.status !== 'success') {
- OC.dialogs.alert(t('core', result.data.message), t('core', 'Warning'));
- }
- });
-
- });
-
- });
-
-})(OC);
diff --git a/lib/Controller/DocumentController.php b/lib/Controller/DocumentController.php
new file mode 100644
index 000000000..b961b1264
--- /dev/null
+++ b/lib/Controller/DocumentController.php
@@ -0,0 +1,166 @@
+uid = $UserId;
+ $this->l10n = $l10n;
+ $this->settings = $settings;
+ $this->appConfig = $appConfig;
+ $this->cache = $cache->create($appName);
+ $this->discoveryManager = $discoveryManager;
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
+ * @return TemplateResponse
+ */
+ public function index(){
+ $response = new TemplateResponse('richdocuments', 'documents');
+ $policy = new ContentSecurityPolicy();
+ $policy->addAllowedFrameDomain($this->appConfig->getAppValue('wopi_url'));
+ $response->setContentSecurityPolicy($policy);
+ return $response;
+ }
+
+ /**
+ * @NoAdminRequired
+ */
+ public function create(){
+ $mimetype = $this->request->post['mimetype'];
+ $filename = $this->request->post['filename'];
+ $dir = $this->request->post['dir'];
+
+ $view = new View('/' . $this->uid . '/files');
+ if (!$dir){
+ $dir = '/';
+ }
+
+ $basename = $this->l10n->t('New Document.odt');
+ switch ($mimetype) {
+ case 'application/vnd.oasis.opendocument.spreadsheet':
+ $basename = $this->l10n->t('New Spreadsheet.ods');
+ break;
+ case 'application/vnd.oasis.opendocument.presentation':
+ $basename = $this->l10n->t('New Presentation.odp');
+ break;
+ case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
+ $basename = $this->l10n->t('New Document.docx');
+ break;
+ case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
+ $basename = $this->l10n->t('New Spreadsheet.xlsx');
+ break;
+ case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
+ $basename = $this->l10n->t('New Presentation.pptx');
+ break;
+ default:
+ // to be safe
+ $mimetype = 'application/vnd.oasis.opendocument.text';
+ break;
+ }
+
+ if (!$filename){
+ $path = Helper::getNewFileName($view, $dir . '/' . $basename);
+ } else {
+ $path = $dir . '/' . $filename;
+ }
+
+ $content = '';
+ if (class_exists('\OC\Files\Type\TemplateManager')){
+ $manager = \OC_Helper::getFileTemplateManager();
+ $content = $manager->getTemplate($mimetype);
+ }
+
+ if (!$content){
+ $content = file_get_contents(dirname(__DIR__) . self::ODT_TEMPLATE_PATH);
+ }
+
+ $discovery_parsed = null;
+ try {
+ $discovery = $this->discoveryManager->get();
+
+ $loadEntities = libxml_disable_entity_loader(true);
+ $discovery_parsed = simplexml_load_string($discovery);
+ libxml_disable_entity_loader($loadEntities);
+
+ if ($discovery_parsed === false) {
+ $this->cache->remove('discovery.xml');
+ $wopiRemote = $this->getWopiUrl(false);
+
+ return array(
+ 'status' => 'error',
+ 'message' => $this->l10n->t('Collabora Online: discovery.xml from "%s" is not a well-formed XML string.', array($wopiRemote)),
+ 'hint' => $this->l10n->t('Please contact the "%s" administrator.', array($wopiRemote))
+ );
+ }
+ }
+ catch (ResponseException $e) {
+ return array(
+ 'status' => 'error',
+ 'message' => $e->getMessage(),
+ 'hint' => $e->getHint()
+ );
+ }
+
+ if ($content && $view->file_put_contents($path, $content)){
+ $info = $view->getFileInfo($path);
+ $ret = $this->getWopiSrcUrl($discovery_parsed, $mimetype);
+ $response = array(
+ 'status' => 'success',
+ 'fileid' => $info['fileid'],
+ 'urlsrc' => $ret['urlsrc'],
+ 'action' => $ret['action'],
+ 'lolang' => $this->settings->getUserValue($this->uid, 'core', 'lang', 'en'),
+ 'data' => \OCA\Files\Helper::formatFileInfo($info)
+ );
+ } else {
+ $response = array(
+ 'status' => 'error',
+ 'message' => (string) $this->l10n->t('Can\'t create document')
+ );
+ }
+ return $response;
+ }
+}
diff --git a/controller/settingscontroller.php b/lib/Controller/SettingsController.php
similarity index 63%
rename from controller/settingscontroller.php
rename to lib/Controller/SettingsController.php
index 22440bf3e..69b280849 100644
--- a/controller/settingscontroller.php
+++ b/lib/Controller/SettingsController.php
@@ -12,23 +12,32 @@
namespace OCA\Richdocuments\Controller;
use \OCP\AppFramework\Controller;
+use OCP\AppFramework\Http\JSONResponse;
use \OCP\IRequest;
use \OCP\IL10N;
-use \OCP\AppFramework\Http\JSONResponse;
-use OCP\AppFramework\Http\TemplateResponse;
use OCA\Richdocuments\AppConfig;
use OCA\Richdocuments\Filter;
class SettingsController extends Controller{
-
- private $userId;
+ /** @var IL10N */
private $l10n;
+ /** @var AppConfig */
private $appConfig;
- public function __construct($appName, IRequest $request, IL10N $l10n, AppConfig $appConfig, $userId){
+ /**
+ * @param string $appName
+ * @param IRequest $request
+ * @param IL10N $l10n
+ * @param AppConfig $appConfig
+ * @param string $userId
+ */
+ public function __construct($appName,
+ IRequest $request,
+ IL10N $l10n,
+ AppConfig $appConfig,
+ $userId) {
parent::__construct($appName, $request);
- $this->userId = $userId;
$this->l10n = $l10n;
$this->appConfig = $appConfig;
}
@@ -45,20 +54,26 @@ class SettingsController extends Controller{
/**
* @NoAdminRequired
+ *
+ * @return JSONResponse
*/
public function getSettings() {
- return array(
+ return new JSONResponse([
'doc_format' => $this->appConfig->getAppValue('doc_format'),
'wopi_url' => $this->appConfig->getAppValue('wopi_url'),
- 'test_wopi_url' => $this->appConfig->getAppValue('test_wopi_url'),
- 'test_server_groups' => $this->appConfig->getAppValue('test_server_groups')
- );
+ ]);
}
- public function setSettings($wopi_url, $edit_groups, $doc_format, $test_wopi_url, $test_server_groups){
+ /**
+ * @param string $wopi_url
+ * @param string $doc_format
+ * @return JSONResponse
+ */
+ public function setSettings($wopi_url,
+ $doc_format){
$message = $this->l10n->t('Saved');
- if (!is_null($wopi_url)){
+ if ($wopi_url !== null){
$this->appConfig->setAppValue('wopi_url', $wopi_url);
$colon = strpos($wopi_url, ':', 0);
@@ -67,22 +82,10 @@ class SettingsController extends Controller{
}
}
- if (!is_null($edit_groups)){
- $this->appConfig->setAppValue('edit_groups', $edit_groups);
- }
-
- if (!is_null($doc_format)){
+ if ($doc_format !== null) {
$this->appConfig->setAppValue('doc_format', $doc_format);
}
- if (!is_null($test_wopi_url)){
- $this->appConfig->setAppValue('test_wopi_url', $test_wopi_url);
- }
-
- if (!is_null($test_server_groups)){
- $this->appConfig->setAppValue('test_server_groups', $test_server_groups);
- }
-
$richMemCache = \OC::$server->getMemCacheFactory()->create('richdocuments');
$richMemCache->clear('discovery.xml');
@@ -91,6 +94,6 @@ class SettingsController extends Controller{
'data' => array('message' => (string) $message)
);
- return $response;
+ return new JSONResponse($response);
}
}
diff --git a/lib/Controller/WopiController.php b/lib/Controller/WopiController.php
new file mode 100644
index 000000000..676fb0e92
--- /dev/null
+++ b/lib/Controller/WopiController.php
@@ -0,0 +1,245 @@
+
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+namespace OCA\Richdocuments\Controller;
+
+use OCA\Richdocuments\Db\Wopi;
+use OCA\Richdocuments\WOPI\Parser;
+use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\Files\File;
+use OCP\Files\IRootFolder;
+use OCP\IRequest;
+use OCP\IUserManager;
+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) {
+ parent::__construct($appName, $request);
+ $this->rootFolder = $rootFolder;
+ $this->userId = $UserId;
+ $this->userManager = $userManager;
+ $this->wopiParser = $wopiParser;
+ }
+
+ /**
+ * Generates and returns an access token for a given fileId
+ *
+ * @NoAdminRequired
+ *
+ * @param string $fileId
+ * @return JSONResponse
+ */
+ public function getToken($fileId) {
+ $arr = explode('_', $fileId, 2);
+ $version = '0';
+ if (count($arr) === 2) {
+ list($fileId, $version) = $arr;
+ }
+
+ try {
+ /** @var File $file */
+ $file = $this->rootFolder->getUserFolder($this->userId)->getById($fileId)[0];
+ $updatable = $file->isUpdateable();
+ } catch (\Exception $e) {
+ return new JSONResponse([], Http::STATUS_FORBIDDEN);
+ }
+
+ // If token is for some versioned file
+ if ($version !== '0') {
+ $updatable = false;
+ }
+
+ $row = new Wopi();
+ $serverHost = $this->request->getServerProtocol() . '://' . $this->request->getServerHost();
+ $token = $row->generateFileToken($fileId, $version, $updatable, $serverHost);
+
+ try {
+ $userFolder = $this->rootFolder->getUserFolder($this->userId);
+ /** @var File $file */
+ $file = $userFolder->getById($fileId)[0];
+ $sessionData['title'] = basename($file->getPath());
+ $sessionData['permissions'] = $file->getPermissions();
+ $sessionData['file_id'] = $file->getId();
+
+ $sessionData['documents'] = [
+ 0 => [
+ 'urlsrc' => $this->wopiParser->getUrlSrc($file->getMimeType())['urlsrc'],
+ 'path' => $file->getPath(),
+ 'token' => $token,
+ ],
+ ];
+
+ return new JSONResponse($sessionData);
+ } catch (\Exception $e){
+ return new JSONResponse([], Http::STATUS_FORBIDDEN);
+ }
+ }
+
+ /**
+ * Returns general info about a file.
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ * @PublicPage
+ *
+ * @param string $fileId
+ * @return JSONResponse
+ */
+ 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);
+ if ($res === false) {
+ return new JSONResponse();
+ }
+
+ // Login the user to see his mount locations
+ try {
+ /** @var File $file */
+ $userFolder = $this->rootFolder->getUserFolder($res['editor']);
+ $file = $userFolder->getById($fileId)[0];
+ } catch (\Exception $e) {
+ return new JSONResponse([], Http::STATUS_FORBIDDEN);
+ }
+
+ return new JSONResponse(
+ [
+ 'BaseFileName' => $file->getName(),
+ 'Size' => $file->getSize(),
+ 'Version' => $version,
+ 'UserId' => $res['editor'],
+ 'UserFriendlyName' => $this->userManager->get($res['editor'])->getDisplayName(),
+ 'UserCanWrite' => $res['canwrite'] ? true : false,
+ 'PostMessageOrigin' => $res['server_host'],
+ ]
+ );
+ }
+
+ /**
+ * Given an access token and a fileId, returns the contents of the file.
+ * Expects a valid token in access_token parameter.
+ *
+ * @PublicPage
+ * @NoCSRFRequired
+ *
+ * @param string $fileId
+ * @param string $access_token
+ * @return Http\Response
+ */
+ public function getFile($fileId,
+ $access_token) {
+ $arr = explode('_', $fileId, 2);
+ $version = '0';
+ if (count($arr) === 2) {
+ list($fileId, $version) = $arr;
+ }
+
+ $row = new Wopi();
+ $row->loadBy('token', $access_token);
+
+ $res = $row->getPathForToken($fileId, $version, $access_token);
+
+ try {
+ /** @var File $file */
+ $userFolder = $this->rootFolder->getUserFolder($res['editor']);
+ $file = $userFolder->getById($fileId)[0];
+ $response = new StreamResponse($file->fopen('rb'));
+ $response->addHeader('Content-Disposition', 'attachment');
+ $response->addHeader('Content-Type', 'application/octet-stream');
+ return $response;
+ } catch (\Exception $e) {
+ return new JSONResponse([], Http::STATUS_FORBIDDEN);
+ }
+ }
+
+
+
+ /**
+ * Given an access token and a fileId, replaces the files with the request body.
+ * Expects a valid token in access_token parameter.
+ *
+ * @PublicPage
+ * @NoCSRFRequired
+ *
+ * @param string $fileId
+ * @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;
+ }
+
+ $row = new Wopi();
+ $row->loadBy('token', $access_token);
+
+ $res = $row->getPathForToken($fileId, $version, $access_token);
+ if (!$res['canwrite']) {
+ return new JSONResponse([], Http::STATUS_FORBIDDEN);
+ }
+
+ try {
+ /** @var File $file */
+ $userFolder = $this->rootFolder->getUserFolder($res['editor']);
+ $file = $userFolder->getById($fileId)[0];
+ $content = fopen('php://input', 'rb');
+ $file->putContent($content);
+ return new JSONResponse();
+ } catch (\Exception $e) {
+ return new JSONResponse([], Http::STATUS_INTERNAL_SERVER_ERROR);
+ }
+ }
+}
diff --git a/lib/WOPI/DiscoveryManager.php b/lib/WOPI/DiscoveryManager.php
new file mode 100644
index 000000000..39326c17e
--- /dev/null
+++ b/lib/WOPI/DiscoveryManager.php
@@ -0,0 +1,117 @@
+
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+namespace OCA\Richdocuments\WOPI;
+
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\Files\IAppData;
+use OCP\Files\NotFoundException;
+use OCP\Files\SimpleFS\ISimpleFolder;
+use OCP\Http\Client\IClientService;
+use OCP\IConfig;
+use OCP\IL10N;
+use OCP\Notification\IApp;
+
+class DiscoveryManager {
+ /** @var IClientService */
+ private $clientService;
+ /** @var ISimpleFolder */
+ private $appData;
+ /** @var IConfig */
+ private $config;
+ /** @var IL10N */
+ private $l10n;
+ /** @var ITimeFactory */
+ private $timeFactory;
+
+ /**
+ * @param IClientService $clientService
+ * @param IAppData $appData
+ * @param IConfig $config
+ * @param IL10N $l10n
+ * @param ITimeFactory $timeFactory
+ */
+ public function __construct(IClientService $clientService,
+ IAppData $appData,
+ IConfig $config,
+ IL10N $l10n,
+ ITimeFactory $timeFactory) {
+ $this->clientService = $clientService;
+ try {
+ $this->appData = $appData->getFolder('richdocuments');
+ } catch (NotFoundException $e) {
+ $this->appData = $appData->newFolder('richdocuments');
+ }
+ $this->config = $config;
+ $this->l10n = $l10n;
+ $this->timeFactory = $timeFactory;
+ }
+
+ public function get() {
+ // First check if there is a local valid discovery file
+ try {
+ $file = $this->appData->getFile('discovery.xml');
+ $decodedFile = json_decode($file->getContent(), true);
+ if($decodedFile['timestamp'] + 3600 > $this->timeFactory->getTime()) {
+ return $decodedFile['data'];
+ }
+ } catch (NotFoundException $e) {
+ $file = $this->appData->newFile('discovery.xml');
+ }
+
+ $remoteHost = $this->config->getAppValue('richdocuments', 'wopi_url');
+ $wopiDiscovery = $remoteHost . '/hosting/discovery';
+
+ $client = $this->clientService->newClient();
+ try {
+ $response = $client->get($wopiDiscovery);
+ } catch (\Exception $e) {
+ $error_message = $e->getMessage();
+ if (preg_match('/^cURL error ([0-9]*):/', $error_message, $matches)) {
+ $admin_check = $this->l10n->t('Please ask your administrator to check the Collabora Online server setting. The exact error message was: ') . $error_message;
+
+ $curl_error = $matches[1];
+ switch ($curl_error) {
+ case '1':
+ throw new ResponseException($this->l10n->t('Collabora Online: The protocol specified in "%s" is not allowed.', array($wopiRemote)), $admin_check);
+ case '3':
+ throw new ResponseException($this->l10n->t('Collabora Online: Malformed URL "%s".', array($wopiRemote)), $admin_check);
+ case '6':
+ throw new ResponseException($this->l10n->t('Collabora Online: Cannot resolve the host "%s".', array($wopiRemote)), $admin_check);
+ case '7':
+ throw new ResponseException($this->l10n->t('Collabora Online: Cannot connect to the host "%s".', array($wopiRemote)), $admin_check);
+ case '60':
+ throw new ResponseException($this->l10n->t('Collabora Online: SSL certificate is not installed.'), $this->l10n->t('Please ask your administrator to add ca-chain.cert.pem to the ca-bundle.crt, for example "cat /etc/loolwsd/ca-chain.cert.pem >> /resources/config/ca-bundle.crt" . The exact error message was: ') . $error_message);
+ }
+ }
+ throw new ResponseException($this->l10n->t('Collabora Online unknown error: ') . $error_message, $contact_admin);
+ }
+
+ $responseBody = $response->getBody();
+ $file->putContent(
+ json_encode([
+ 'data' => $responseBody,
+ 'timestamp' => $this->timeFactory->getTime(),
+ ])
+ );
+ return $responseBody;
+ }
+}
diff --git a/lib/WOPI/Parser.php b/lib/WOPI/Parser.php
new file mode 100644
index 000000000..934ead697
--- /dev/null
+++ b/lib/WOPI/Parser.php
@@ -0,0 +1,58 @@
+
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+namespace OCA\Richdocuments\WOPI;
+
+class Parser {
+ /** @var DiscoveryManager */
+ private $discoveryManager;
+
+ /**
+ * @param DiscoveryManager $discoveryManager
+ */
+ public function __construct(DiscoveryManager $discoveryManager) {
+ $this->discoveryManager = $discoveryManager;
+ }
+
+ /**
+ * @param $mimetype
+ * @return array
+ * @throws \Exception
+ */
+ public function getUrlSrc($mimetype) {
+ $discovery = $this->discoveryManager->get();
+ $loadEntities = libxml_disable_entity_loader(true);
+ $discoveryParsed = simplexml_load_string($discovery);
+ libxml_disable_entity_loader($loadEntities);
+
+ $result = $discoveryParsed->xpath(sprintf('/wopi-discovery/net-zone/app[@name=\'%s\']/action', $mimetype));
+ if ($result && count($result) > 0) {
+ return [
+ 'urlsrc' => (string)$result[0]['urlsrc'],
+ 'action' => (string)$result[0]['name'],
+ ];
+ }
+
+ throw new \Exception('Could not find urlsrc in WOPI');
+
+ }
+
+}
\ No newline at end of file
diff --git a/lib/db/member.php b/lib/db/member.php
deleted file mode 100644
index d44f420aa..000000000
--- a/lib/db/member.php
+++ /dev/null
@@ -1,130 +0,0 @@
-getL10n('richdocuments')->t('guest') . ')';
- }
-
-
- public function updateActivity($memberId){
- return $this->execute(
- 'UPDATE ' . $this->tableName . ' SET `last_activity`=?, `status`=? WHERE `member_id`=?',
- array(
- time(),
- self::MEMBER_STATUS_ACTIVE,
- $memberId
- )
- );
- }
-
-
- public function getActiveCollection($esId){
- $result = $this->execute('
- SELECT `es_id`, `member_id`
- FROM ' . self::DB_TABLE . '
- WHERE `es_id`= ?
- AND `status`=?
- ',
- array(
- $esId,
- self::MEMBER_STATUS_ACTIVE
- )
- );
- $members = $result->fetchAll();
- if (!is_array($members)){
- $members = array();
- }
- return $members;
-
- }
-
- /**
- * Mark members as inactive
- * @param string $esId - session Id
- * @return array - list of memberId that were marked as inactive
- */
- public function updateByTimeout($esId){
- $time = $this->getInactivityPeriod();
-
- $result = $this->execute('
- SELECT `member_id`
- FROM ' . self::DB_TABLE . '
- WHERE `es_id`= ?
- AND `last_activity`
- AND `status`=?
- ',
- array(
- $esId,
- $time,
- self::MEMBER_STATUS_ACTIVE
- )
- );
-
- $deactivated = $result->fetchAll();
- if (is_array($deactivated) && count($deactivated)){
- $deactivated = array_map(
- function($x){
- return ($x['member_id']);
- }, $deactivated
- );
- $this->deactivate($deactivated);
- } else {
- $deactivated = array();
- }
-
- return $deactivated;
- }
-
- /**
- * Update members to inactive state
- * @param array $memberIds
- */
- public function deactivate($memberIds){
- $stmt = $this->buildInQuery('member_id', $memberIds);
- array_unshift($memberIds, self::MEMBER_STATUS_INACTIVE);
- $this->execute('
- UPDATE ' . $this->tableName . '
- SET `status`=?
- WHERE ' . $stmt,
- $memberIds
- );
- }
-
- protected function getInactivityPeriod(){
- return time() - self::ACTIVITY_THRESHOLD;
- }
-}
diff --git a/lib/db/op.php b/lib/db/op.php
deleted file mode 100644
index ee8cf760e..000000000
--- a/lib/db/op.php
+++ /dev/null
@@ -1,190 +0,0 @@
-canInsertOp($esId, $memberId, $op)){
- continue;
- }
- $opObj->setData(array(
- $esId,
- $op['optype'],
- $memberId,
- json_encode($op)
- ));
- $opObj->insert();
- }
-
- return $opObj->getHeadSeq($esId);
- }
-
- /**
- * @returns "" when there are no Ops, or the seq of the last Op
- */
- public function getHeadSeq($esId){
- $query = \OC::$server->getDatabaseConnection()->prepare('
- SELECT `seq`
- FROM ' . $this->tableName . '
- WHERE `es_id`=?
- ORDER BY `seq` DESC
- ', 1);
- $result = $query->execute([$esId]);
- return !$result ? "" : $query->fetchColumn();
- }
-
- public function getOpsAfterJson($esId, $seq){
- $ops = $this->getOpsAfter($esId, $seq);
- if (!is_array($ops)){
- $ops = array();
- }
- $ops = array_map(
- function($x){
- $decoded = json_decode($x['opspec'], true);
- $decoded['memberid'] = strval($decoded['memberid']);
- return $decoded;
- },
- $ops
- );
- return $ops;
- }
-
- public function getOpsAfter($esId, $seq){
- if ($seq == ""){
- $seq = -1;
- }
- $query = \OC::$server->getDatabaseConnection()->prepare('
- SELECT `opspec`
- FROM ' . self::DB_TABLE . '
- WHERE `es_id`=?
- AND `seq`>?
- ORDER BY `seq` ASC
- ');
- $query->execute(array($esId, $seq));
- return $query->fetchAll();
- }
-
- public function addMember($esId, $memberId, $fullName, $userId, $color, $imageUrl){
- $op = array(
- 'optype' => 'AddMember',
- 'memberid' => (string) $memberId,
- 'timestamp' => $this->getMillisecondsAsString(),
- 'setProperties' => array(
- 'fullName' => $fullName,
- 'color' => $color,
- 'imageUrl' => $imageUrl,
- 'uid' => $userId,
- )
- );
- $this->insertOp($esId, $memberId, $op);
- }
-
- public function removeCursor($esId, $memberId){
- $op = array(
- 'optype' => 'RemoveCursor',
- 'memberid' => (string) $memberId,
- 'reason' => 'server-idle',
- 'timestamp' => $this->getMillisecondsAsString()
- );
- $this->insertOp($esId, $memberId, $op);
- }
-
- public function removeMember($esId, $memberId){
- $op = array(
- 'optype' => 'RemoveMember',
- 'memberid' => (string) $memberId,
- 'timestamp' => $this->getMillisecondsAsString()
- );
- $this->insertOp($esId, $memberId, $op);
- }
-
- //TODO: Implement https://github.com/kogmbh/WebODF/blob/master/webodf/lib/ops/OpUpdateMember.js#L95
- public function changeNick($esId, $memberId, $fullName){
- $op = array(
- 'optype' => 'UpdateMember',
- 'memberid' => (string) $memberId,
- 'timestamp' => $this->getMillisecondsAsString(),
- 'setProperties' => array(
- 'fullName' => $fullName,
- )
- );
- $this->insertOp($esId, $memberId, $op);
- }
-
- protected function insertOp($esId, $memberId, $op){
- if ($this->canInsertOp($esId, $memberId, $op)){
- $op = new Op(array(
- $esId,
- $op['optype'],
- $memberId,
- json_encode($op)
- ));
- $op->insert();
- }
- }
-
- protected function canInsertOp($esId, $memberId, $op){
- $cursorOps = array('AddCursor', 'RemoveCursor');
- $memberOps = array('AddMember', 'RemoveMember');
- $result = true;
-
- switch ($op['optype']){
- case 'AddCursor':
- $ops = $this->getFilteredMemberOps($esId, $memberId, $cursorOps);
- $result = !count($ops) || $ops[0]['optype'] === 'RemoveCursor';
- break;
- case 'RemoveCursor':
- $ops = $this->getFilteredMemberOps($esId, $memberId, $cursorOps);
- $result = count($ops) && $ops[0]['optype'] === 'AddCursor';
- break;
- case 'AddMember':
- $ops = $this->getFilteredMemberOps($esId, $memberId, $memberOps);
- $result = !count($ops) || $ops[0]['optype'] === 'RemoveMember';
- break;
- case 'RemoveMember':
- $ops = $this->getFilteredMemberOps($esId, $memberId, $memberOps);
- $result = count($ops) && $ops[0]['optype'] === 'AddMember';
- break;
- }
- return $result;
- }
-
- protected function getFilteredMemberOps($esId, $memberId, $targetOps){
- $stmt = $this->buildInQuery('optype', $targetOps);
- $result = $this->execute('
- SELECT `optype` FROM ' . $this->tableName . '
- WHERE es_id=? AND member=? AND ' . $stmt . 'ORDER BY `seq` DESC',
- array_merge(array($esId, $memberId), $targetOps)
- );
- $ops = $result->fetchAll();
- if (!is_array($ops)){
- $ops = array();
- }
- return $ops;
- }
-
- protected function getMillisecondsAsString(){
- $microtime = microtime();
- list($usec, $sec) = explode(" ", $microtime);
- $milliseconds = $sec.substr($usec, 2, 3);
- return $milliseconds;
- }
-}
diff --git a/lib/db/session.php b/lib/db/session.php
deleted file mode 100644
index 583cd3429..000000000
--- a/lib/db/session.php
+++ /dev/null
@@ -1,212 +0,0 @@
-loadBy('file_id', $file->getFileId());
-
- //If there is no existing session we need to start a new one
- if (!$oldSession->hasData()){
- $newSession = new Session(array(
- $genesis->getPath(),
- $genesis->getHash(),
- $file->getOwner(),
- $file->getFileId()
- ));
-
- if (!$newSession->insert()){
- throw new \Exception('Failed to add session into database');
- }
- }
-
- $sessionData = $oldSession
- ->loadBy('file_id', $file->getFileId())
- ->getData()
- ;
-
- $memberColor = \OCA\Richdocuments\Helper::getMemberColor($uid);
- $member = new \OCA\Richdocuments\Db\Member([
- $sessionData['es_id'],
- $uid,
- $memberColor,
- time(),
- intval($file->isPublicShare()),
- $file->getToken()
- ]);
-
- if (!$member->insert()){
- throw new \Exception('Failed to add member into database');
- }
- $sessionData['member_id'] = (string) $member->getLastInsertId();
-
- // Do we have OC_Avatar in out disposal?
- if (\OC::$server->getConfig()->getSystemValue('enable_avatars', true) !== true){
- $imageUrl = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==';
- } else {
- $imageUrl = $uid;
- }
-
- $displayName = $file->isPublicShare()
- ? $uid . ' ' . \OCA\Richdocuments\Db\Member::getGuestPostfix()
- : \OC::$server->getUserSession()->getUser()->getDisplayName($uid)
- ;
- $userId = $file->isPublicShare() ? $displayName : \OC::$server->getUserSession()->getUser()->getUID();
- $op = new \OCA\Richdocuments\Db\Op();
- $op->addMember(
- $sessionData['es_id'],
- $sessionData['member_id'],
- $displayName,
- $userId,
- $memberColor,
- $imageUrl
- );
-
- $sessionData['title'] = basename($file->getPath());
- $sessionData['permissions'] = $file->getPermissions();
-
- return $sessionData;
- }
-
- public static function cleanUp($esId){
- $session = new Session();
- $session->deleteBy('es_id', $esId);
-
- $member = new \OCA\Richdocuments\Db\Member();
- $member->deleteBy('es_id', $esId);
-
- $op= new \OCA\Richdocuments\Db\Op();
- $op->deleteBy('es_id', $esId);
- }
-
-
- public function syncOps($memberId, $currentHead, $clientHead, $clientOps){
- $hasOps = count($clientOps)>0;
- $op = new \OCA\Richdocuments\Db\Op();
-
- // TODO handle the case ($currentHead == "") && ($seqHead != "")
- if ($clientHead == $currentHead) {
- // matching heads
- if ($hasOps) {
- // incoming ops without conflict
- // Add incoming ops, respond with a new head
- $newHead = \OCA\Richdocuments\Db\Op::addOpsArray($this->getEsId(), $memberId, $clientOps);
- $result = array(
- 'result' => 'added',
- 'head_seq' => $newHead ? $newHead : $currentHead
- );
- } else {
- // no incoming ops (just checking for new ops...)
- $result = array(
- 'result' => 'new_ops',
- 'ops' => array(),
- 'head_seq' => $currentHead
- );
- }
- } else { // HEADs do not match
- $result = array(
- 'result' => $hasOps ? 'conflict' : 'new_ops',
- 'ops' => $op->getOpsAfterJson($this->getEsId(), $clientHead),
- 'head_seq' => $currentHead,
- );
- }
-
- return $result;
- }
-
- public function insert(){
- $esId = $this->getUniqueSessionId();
- array_unshift($this->data, $esId);
- return parent::insert();
- }
-
- public function updateGenesisHash($esId, $genesisHash){
- return $this->execute(
- 'UPDATE `*PREFIX*richdocuments_session` SET `genesis_hash`=? WHERE `es_id`=?',
- array(
- $genesisHash, $esId
- )
- );
- }
-
- public function getInfo($esId){
- $result = $this->execute('
- SELECT `s`.*, COUNT(`m`.`member_id`) AS `users`
- FROM ' . $this->tableName . ' AS `s`
- LEFT JOIN `*PREFIX*richdocuments_member` AS `m` ON `s`.`es_id`=`m`.`es_id`
- AND `m`.`status`=' . Db\Member::MEMBER_STATUS_ACTIVE . '
- AND `m`.`uid` != ?
- WHERE `s`.`es_id` = ?
- GROUP BY `m`.`es_id`
- ',
- [
- \OC::$server->getUserSession()->getUser()->getUID(),
- $esId
- ]
- );
-
- $info = $result->fetch();
- if (!is_array($info)){
- $info = array();
- }
- return $info;
- }
-
- protected function getUniqueSessionId(){
- $testSession = new Session();
- do{
- $id = \OC::$server->getSecureRandom()
- ->getMediumStrengthGenerator()
- ->generate(30, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS);
- } while ($testSession->load($id)->hasData());
-
- return $id;
- }
-}
diff --git a/lib/db/wopi.php b/lib/db/wopi.php
index 36cda195a..e30de4cf7 100644
--- a/lib/db/wopi.php
+++ b/lib/db/wopi.php
@@ -1,5 +1,4 @@
request = $request;
- $this->user = $user;
- $this->path = $path;
-
- $this->view = new View('/' . $user);
- if (!$this->view->file_exists($path)){
- $this->setStatus(Http::STATUS_NOT_FOUND);
- }
- }
-
- public function render(){
- if ($this->getStatus() === Http::STATUS_NOT_FOUND){
- return '';
- }
- $info = $this->view->getFileInfo($this->path);
- $this->ETag = $info['etag'];
-
- $content = $this->view->file_get_contents($this->path);
- $data = \OCA\Richdocuments\Filter::read($content, $info['mimetype']);
- $size = strlen($data['content']);
-
-
- if (isset($this->request->server['HTTP_RANGE']) && !is_null($this->request->server['HTTP_RANGE'])){
- $isValidRange = preg_match('/^bytes=\d*-\d*(,\d*-\d*)*$/', $this->request->server['HTTP_RANGE']);
- if (!$isValidRange){
- return $this->sendRangeNotSatisfiable($size);
- }
-
- $ranges = explode(',', substr($this->request->server['HTTP_RANGE'], 6));
- foreach ($ranges as $range){
- $parts = explode('-', $range);
-
- if ($parts[0]==='' && $parts[1]=='') {
- $this->sendNotSatisfiable($size);
- }
- if ($parts[0]==='') {
- $start = $size - $parts[1];
- $end = $size - 1;
- } else {
- $start = $parts[0];
- $end = ($parts[1]==='') ? $size - 1 : $parts[1];
- }
-
- if ($start > $end){
- $this->sendNotSatisfiable($size);
- }
-
- $buffer = substr($data['content'], $start, $end - $start);
- $md5Sum = md5($buffer);
-
- // send the headers and data
- $this->addHeader('Content-Length', $end - $start);
- $this->addHeader('Content-md5', $md5Sum);
- $this->addHeader('Accept-Ranges', 'bytes');
- $this->addHeader('Content-Range', 'bytes ' . $start . '-' . ($end) . '/' . $size);
- $this->addHeader('Connection', 'close');
- $this->addHeader('Content-Type', $data['mimetype']);
- $this->addContentDispositionHeader();
- return $buffer;
- }
- }
-
- $this->addHeader('Content-Type', $data['mimetype']);
- $this->addContentDispositionHeader();
- $this->addHeader('Content-Length', $size);
-
- return $data['content'];
- }
-
- /**
- * Send 416 if we can't satisfy the requested ranges
- * @param integer $filesize
- */
- protected function sendRangeNotSatisfiable($filesize){
- $this->setStatus(Http::STATUS_REQUEST_RANGE_NOT_SATISFIABLE);
- $this->addHeader('Content-Range', 'bytes */' . $filesize); // Required in 416.
- return '';
- }
-
- protected function addContentDispositionHeader(){
- $encodedName = rawurlencode(basename($this->path));
- $isIE = preg_match("/MSIE/", $this->request->server["HTTP_USER_AGENT"]);
- if ($isIE){
- $this->addHeader(
- 'Content-Disposition',
- 'attachment; filename="' . $encodedName . '"'
- );
- } else {
- $this->addHeader(
- 'Content-Disposition',
- 'attachment; filename*=UTF-8\'\'' . $encodedName . '; filepath="' . $encodedName . '"'
- );
- }
- }
-}
diff --git a/lib/file.php b/lib/file.php
deleted file mode 100644
index 4668e569c..000000000
--- a/lib/file.php
+++ /dev/null
@@ -1,200 +0,0 @@
-.
- *
- */
-
-namespace OCA\Richdocuments;
-
-use \OC\Files\View;
-
-class File {
- protected $fileId;
- protected $owner;
- protected $sharing;
- protected $token;
- protected $passwordProtected = false;
- protected $ownerView;
- protected $ownerViewFiles;
- protected $path;
- protected $pathFiles;
-
- public function __construct($fileId, $shareOps = null, $token = ''){
- if (!$fileId){
- throw new \Exception('No valid file has been passed');
- }
-
- $this->fileId = $fileId;
- $this->sharing = $shareOps;
- $this->token = $token;
-
- if ($this->isPublicShare()) {
- if (isset($this->sharing['uid_owner'])){
- $this->owner = $this->sharing['uid_owner'];
- if (!\OC::$server->getUserManager()->userExists($this->sharing['uid_owner'])) {
- throw new \Exception('Share owner' . $this->sharing['uid_owner'] . ' does not exist ');
- }
-
- \OC_Util::tearDownFS();
- \OC_Util::setupFS($this->sharing['uid_owner']);
- } else {
- throw new \Exception($this->fileId . ' is a broken share');
- }
- } else {
- $this->owner = \OC::$server->getUserSession()->getUser()->getUID();
- }
- $this->initViews();
- }
-
-
- public static function getByShareToken($token){
- $linkItem = \OCP\Share::getShareByToken($token, false);
- if (is_array($linkItem) && isset($linkItem['uid_owner'])) {
- // seems to be a valid share
- $rootLinkItem = \OCP\Share::resolveReShare($linkItem);
- } else {
- throw new \Exception('This file was probably unshared');
- }
-
- $file = new File($rootLinkItem['file_source'], $rootLinkItem, $token);
-
- if (isset($linkItem['share_with']) && !empty($linkItem['share_with'])){
- $file->setPasswordProtected(true);
- }
-
- return $file;
- }
-
- public function getToken(){
- return $this->token;
- }
-
- public function getFileId(){
- return $this->fileId;
- }
-
- public function setToken($token){
- $this->token = $token;
- }
-
- public function isPublicShare(){
- return !empty($this->token);
- }
-
- public function isPasswordProtected(){
- return $this->passwordProtected;
- }
-
- /**
- * @param string $password
- * @return boolean
- */
- public function checkPassword($password){
- $shareId = $this->sharing['id'];
- if (!$this->isPasswordProtected()
- || (\OC::$server->getSession()->exists('public_link_authenticated')
- && \OC::$server->getSession()->get('public_link_authenticated') === $shareId
- )
- ){
- return true;
- }
-
- // Check Password
- $newHash = '';
- if(\OC::$server->getHasher()->verify($password, $this->getPassword(), $newHash)) {
- \OC::$server->getSession()->set('public_link_authenticated', $shareId);
-
- /**
- * FIXME: Migrate old hashes to new hash format
- * Due to the fact that there is no reasonable functionality to update the password
- * of an existing share no migration is yet performed there.
- * The only possibility is to update the existing share which will result in a new
- * share ID and is a major hack.
- *
- * In the future the migration should be performed once there is a proper method
- * to update the share's password. (for example `$share->updatePassword($password)`
- *
- * @link https://github.com/owncloud/core/issues/10671
- */
- if(!empty($newHash)) {
-
- }
-
- return true;
- }
- return false;
- }
-
- /**
- * @param boolean $value
- */
- public function setPasswordProtected($value){
- $this->passwordProtected = $value;
- }
-
- public function getOwner(){
- return $this->owner;
- }
-
- public function getOwnerView($relativeToFiles = false){
- return $relativeToFiles ? $this->ownerViewFiles : $this->ownerView;
- }
-
- public function getPath($relativeToFiles = false){
- return $relativeToFiles ? $this->pathFiles : $this->path;
- }
-
- public function getPermissions(){
- $fileInfo = $this->ownerView->getFileInfo($this->path);
- return $fileInfo->getPermissions();
- }
-
- protected function initViews(){
- $this->ownerView = new View('/' . $this->owner);
- $this->ownerViewFiles = new View('/' . $this->owner . '/files');
- $this->path = $this->ownerView->getPath($this->fileId);
- $this->pathFiles = $this->ownerViewFiles->getPath($this->fileId);
-
- if (!$this->path || !$this->pathFiles) {
- throw new \Exception($this->fileId . ' can not be resolved');
- }
-
- if (!$this->ownerView->file_exists($this->path)) {
- throw new \Exception($this->path . ' doesn\'t exist');
- }
-
- if (!$this->ownerViewFiles->file_exists($this->pathFiles)) {
- throw new \Exception($this->pathFiles . ' doesn\'t exist');
- }
-
- if (!$this->ownerView->is_file($this->path)){
- throw new \Exception('Object ' . $this->path . ' is not a file.');
- }
- //TODO check if it is a valid odt
-
- $mimetype = $this->ownerView->getMimeType($this->path);
- if (!Filter::isSupportedMimetype($mimetype)){
- throw new \Exception( $this->path . ' is ' . $mimetype . ' and is not supported by RichDocuments app');
- }
- }
-
- protected function getPassword(){
- return $this->sharing['share_with'];
- }
-}
diff --git a/lib/genesis.php b/lib/genesis.php
deleted file mode 100644
index de0e0c87e..000000000
--- a/lib/genesis.php
+++ /dev/null
@@ -1,97 +0,0 @@
-.
- *
- */
-
-namespace OCA\Richdocuments;
-
-use \OC\Files\View;
-
-class Genesis {
-
- const DOCUMENTS_DIRNAME='/documents';
-
- protected $view;
-
- protected $path;
-
- protected $hash;
-
-
- /**
- * Create new genesis document
- * @param File $file
- * */
- public function __construct(File $file){
- $view = $file->getOwnerView();
- $path = $file->getPath();
- $owner = $file->getOwner();
-
- $this->view = new View('/' . $owner);
-
- if (!$this->view->file_exists(self::DOCUMENTS_DIRNAME)){
- $this->view->mkdir(self::DOCUMENTS_DIRNAME );
- }
- $this->validate($view, $path);
-
- $this->hash = $view->hash('sha1', $path, false);
- $this->path = self::DOCUMENTS_DIRNAME . '/' . $this->hash . '.odt';
- if (!$this->view->file_exists($this->path)){
- //copy new genesis to /user/documents/{hash}.odt
- // get decrypted content
- $content = $view->file_get_contents($path);
- $mimetype = $view->getMimeType($path);
-
- $data = Filter::read($content, $mimetype);
- $this->view->file_put_contents($this->path, $data['content']);
- }
-
- try {
- $this->validate($this->view, $this->path);
- } catch (\Exception $e){
- throw new \Exception('Failed to copy genesis');
- }
- }
-
- public function getPath(){
- return $this->path;
- }
-
- public function getHash(){
- return $this->hash;
- }
-
- /**
- * Check if genesis is valid
- * @param \OC\Files\View $view
- * @param string $path relative to the view
- * @throws \Exception
- */
- protected function validate($view, $path){
- if (!$view->file_exists($path)){
- throw new \Exception('Document not found ' . $path);
- }
- if (!$view->is_file($path)){
- throw new \Exception('Object ' . $path . ' is not a file.');
- }
- //TODO check if it is a valid odt
- }
-
-}
diff --git a/lib/helper.php b/lib/helper.php
index db61a6ad2..35866e8da 100644
--- a/lib/helper.php
+++ b/lib/helper.php
@@ -1,5 +1,4 @@
360){
- $iH = 360; // 0-360
- }
- if ($iS < 0){
- $iS = 0; // Saturation:
- }
- if ($iS > 100){
- $iS = 100; // 0-100
- }
- if ($iV < 0){
- $iV = 0; // Lightness:
- }
- if ($iV > 100){
- $iV = 100; // 0-100
- }
-
- $dS = $iS / 100.0; // Saturation: 0.0-1.0
- $dV = $iV / 100.0; // Lightness: 0.0-1.0
- $dC = $dV * $dS; // Chroma: 0.0-1.0
- $dH = $iH / 60.0; // H-Prime: 0.0-6.0
- $dT = $dH; // Temp variable
-
- while ($dT >= 2.0)
- $dT -= 2.0; // php modulus does not work with float
- $dX = $dC * (1 - abs($dT - 1)); // as used in the Wikipedia link
-
- switch ($dH){
- case($dH >= 0.0 && $dH < 1.0):
- $dR = $dC;
- $dG = $dX;
- $dB = 0.0;
- break;
- case($dH >= 1.0 && $dH < 2.0):
- $dR = $dX;
- $dG = $dC;
- $dB = 0.0;
- break;
- case($dH >= 2.0 && $dH < 3.0):
- $dR = 0.0;
- $dG = $dC;
- $dB = $dX;
- break;
- case($dH >= 3.0 && $dH < 4.0):
- $dR = 0.0;
- $dG = $dX;
- $dB = $dC;
- break;
- case($dH >= 4.0 && $dH < 5.0):
- $dR = $dX;
- $dG = 0.0;
- $dB = $dC;
- break;
- case($dH >= 5.0 && $dH < 6.0):
- $dR = $dC;
- $dG = 0.0;
- $dB = $dX;
- break;
- default:
- $dR = 0.0;
- $dG = 0.0;
- $dB = 0.0;
- break;
- }
-
- $dM = $dV - $dC;
- $dR += $dM;
- $dG += $dM;
- $dB += $dM;
- $dR *= 255;
- $dG *= 255;
- $dB *= 255;
-
- $dR = str_pad(dechex(round($dR)), 2, "0", STR_PAD_LEFT);
- $dG = str_pad(dechex(round($dG)), 2, "0", STR_PAD_LEFT);
- $dB = str_pad(dechex(round($dB)), 2, "0", STR_PAD_LEFT);
- return $dR.$dG.$dB;
- }
-
}
diff --git a/lib/storage.php b/lib/storage.php
index cf888ed98..fc450fa11 100644
--- a/lib/storage.php
+++ b/lib/storage.php
@@ -136,7 +136,6 @@ class Storage {
}
}
- Db\Session::cleanUp($session->getEsId());
}
private static function processDocuments($rawDocuments){
diff --git a/templates/admin.php b/templates/admin.php
index efdc57b03..d3c01fcd3 100644
--- a/templates/admin.php
+++ b/templates/admin.php
@@ -10,23 +10,6 @@ script('richdocuments', 'admin');
-
-
-
-
-
-
-
-
- t('URL (and port) of the Collabora Online test server.')) ?>
-
-
-
-
-
-
-
-
/>
\ No newline at end of file
diff --git a/templates/documents.php b/templates/documents.php
index 33978dc70..ccf29b84a 100644
--- a/templates/documents.php
+++ b/templates/documents.php
@@ -1,10 +1,6 @@