From 8ae612f6930235aa1768d3a5beeff65a3565d90a Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Tue, 10 Sep 2013 20:19:42 +0200 Subject: [PATCH 001/119] Move core setup code to controller class --- core/setup.php | 59 ----------------------------- core/setup/controller.php | 79 +++++++++++++++++++++++++++++++++++++++ lib/base.php | 3 +- 3 files changed, 81 insertions(+), 60 deletions(-) delete mode 100644 core/setup.php create mode 100644 core/setup/controller.php diff --git a/core/setup.php b/core/setup.php deleted file mode 100644 index 4758c23b045..00000000000 --- a/core/setup.php +++ /dev/null @@ -1,59 +0,0 @@ - $hasSQLite, - 'hasMySQL' => $hasMySQL, - 'hasPostgreSQL' => $hasPostgreSQL, - 'hasOracle' => $hasOracle, - 'hasMSSQL' => $hasMSSQL, - 'directory' => $datadir, - 'secureRNG' => OC_Util::secureRNGAvailable(), - 'htaccessWorking' => OC_Util::isHtAccessWorking(), - 'vulnerableToNullByte' => $vulnerableToNullByte, - 'errors' => array(), -); - -if(isset($_POST['install']) AND $_POST['install']=='true') { - // We have to launch the installation process : - $e = OC_Setup::install($_POST); - $errors = array('errors' => $e); - - if(count($e) > 0) { - //OC_Template::printGuestPage("", "error", array("errors" => $errors)); - $options = array_merge($_POST, $opts, $errors); - OC_Template::printGuestPage("", "installation", $options); - } - else { - header( 'Location: '.OC_Helper::linkToRoute( 'post_setup_check' )); - exit(); - } -} -else { - OC_Template::printGuestPage("", "installation", $opts); -} diff --git a/core/setup/controller.php b/core/setup/controller.php new file mode 100644 index 00000000000..54bfe14612a --- /dev/null +++ b/core/setup/controller.php @@ -0,0 +1,79 @@ +loadAutoConfig($post); + $opts = $this->getSystemInfo(); + + if(isset($post['install']) AND $post['install']=='true') { + // We have to launch the installation process : + $e = \OC_Setup::install($post); + $errors = array('errors' => $e); + + if(count($e) > 0) { + $options = array_merge($post, $opts, $errors); + $this->display($options); + } + else { + $this->finishSetup(); + } + } + else { + $this->display($opts); + } + } + + public function display($post) { + \OC_Util::addScript('setup'); + \OC_Template::printGuestPage('', 'installation', $post); + } + + public function finishSetup() { + header( 'Location: '.\OC_Helper::linkToRoute( 'post_setup_check' )); + exit(); + } + + public function loadAutoConfig($post) { + $autosetup_file = \OC::$SERVERROOT.'/config/autoconfig.php'; + if( file_exists( $autosetup_file )) { + \OC_Log::write('core', 'Autoconfig file found, setting up owncloud...', \OC_Log::INFO); + include $autosetup_file; + $post['install'] = 'true'; + $post = array_merge ($post, $AUTOCONFIG); + unlink($autosetup_file); + } + return $post; + } + + public function getSystemInfo() { + $hasSQLite = class_exists('SQLite3'); + $hasMySQL = is_callable('mysql_connect'); + $hasPostgreSQL = is_callable('pg_connect'); + $hasOracle = is_callable('oci_connect'); + $hasMSSQL = is_callable('sqlsrv_connect'); + $datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT.'/data'); + $vulnerableToNullByte = false; + if(@file_exists(__FILE__."\0Nullbyte")) { // Check if the used PHP version is vulnerable to the NULL Byte attack (CVE-2006-7243) + $vulnerableToNullByte = true; + } + + // Protect data directory here, so we can test if the protection is working + \OC_Setup::protectDataDirectory(); + + return array( + 'hasSQLite' => $hasSQLite, + 'hasMySQL' => $hasMySQL, + 'hasPostgreSQL' => $hasPostgreSQL, + 'hasOracle' => $hasOracle, + 'hasMSSQL' => $hasMSSQL, + 'directory' => $datadir, + 'secureRNG' => \OC_Util::secureRNGAvailable(), + 'htaccessWorking' => \OC_Util::isHtAccessWorking(), + 'vulnerableToNullByte' => $vulnerableToNullByte, + 'errors' => array(), + ); + } +} diff --git a/lib/base.php b/lib/base.php index ea5adbadc9d..aa91176d218 100644 --- a/lib/base.php +++ b/lib/base.php @@ -610,7 +610,8 @@ class OC { // Check if ownCloud is installed or in maintenance (update) mode if (!OC_Config::getValue('installed', false)) { - require_once 'core/setup.php'; + $controller = new OC\Core\Setup\Controller(); + $controller->run($_POST); exit(); } From 65aab3dc8c88f012e063ccea7cacc17f528b7d4d Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Tue, 10 Sep 2013 22:05:20 +0200 Subject: [PATCH 002/119] Check for failure in creating htaccessWorking testfile --- core/setup/controller.php | 14 ++++++++++++-- lib/util.php | 12 ++++++++---- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/core/setup/controller.php b/core/setup/controller.php index 54bfe14612a..8ddcf19bb6d 100644 --- a/core/setup/controller.php +++ b/core/setup/controller.php @@ -60,8 +60,18 @@ class Controller { $vulnerableToNullByte = true; } + $errors = array(); + // Protect data directory here, so we can test if the protection is working \OC_Setup::protectDataDirectory(); + try { + $htaccessworking = \OC_Util::isHtAccessWorking(); + } catch (\OC\HintException $e) { + $errors[] = array( + 'error' => $e->getMessage(), + 'hint' => $e->getHint() + ); + } return array( 'hasSQLite' => $hasSQLite, @@ -71,9 +81,9 @@ class Controller { 'hasMSSQL' => $hasMSSQL, 'directory' => $datadir, 'secureRNG' => \OC_Util::secureRNGAvailable(), - 'htaccessWorking' => \OC_Util::isHtAccessWorking(), + 'htaccessWorking' => $htaccessWorking, 'vulnerableToNullByte' => $vulnerableToNullByte, - 'errors' => array(), + 'errors' => $errors, ); } } diff --git a/lib/util.php b/lib/util.php index 0777643a952..e8e3bc37e5f 100755 --- a/lib/util.php +++ b/lib/util.php @@ -689,9 +689,13 @@ class OC_Util { return false; } - $fp = @fopen($testfile, 'w'); - @fwrite($fp, $testcontent); - @fclose($fp); + $fp = @fopen($testFile, 'w'); + if (!$fp) { + throw new OC\HintException('Can\'t create test file to check for working .htaccess file.', + 'Make sure it is possible for the webserver to write to '.$testFile); + } + fwrite($fp, $testContent); + fclose($fp); // accessing the file via http $url = OC_Helper::makeURLAbsolute(OC::$WEBROOT.'/data'.$fileName); @@ -700,7 +704,7 @@ class OC_Util { @fclose($fp); // cleanup - @unlink($testfile); + @unlink($testFile); // does it work ? if($content==$testContent) { From 071b8033cb59a3ed51925374e78790ecfa7a2fac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Tue, 24 Sep 2013 00:44:55 +0200 Subject: [PATCH 003/119] fixing typo on $htaccessWorking - testing own code before pushing is appreciated --- core/setup/controller.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/setup/controller.php b/core/setup/controller.php index 8ddcf19bb6d..e1ad9d60e8b 100644 --- a/core/setup/controller.php +++ b/core/setup/controller.php @@ -64,8 +64,9 @@ class Controller { // Protect data directory here, so we can test if the protection is working \OC_Setup::protectDataDirectory(); + $htaccessWorking = false; try { - $htaccessworking = \OC_Util::isHtAccessWorking(); + $htaccessWorking = \OC_Util::isHtAccessWorking(); } catch (\OC\HintException $e) { $errors[] = array( 'error' => $e->getMessage(), From 5db98aadd30b9f1218dda8f836acca0062ce1d9f Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 2 Oct 2013 18:23:47 +0200 Subject: [PATCH 004/119] Copyright and small fix --- core/setup/controller.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/setup/controller.php b/core/setup/controller.php index e1ad9d60e8b..9b35432f113 100644 --- a/core/setup/controller.php +++ b/core/setup/controller.php @@ -1,4 +1,10 @@ + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ namespace OC\Core\Setup; @@ -43,7 +49,7 @@ class Controller { include $autosetup_file; $post['install'] = 'true'; $post = array_merge ($post, $AUTOCONFIG); - unlink($autosetup_file); + @unlink($autosetup_file); } return $post; } From 09d2ba017e603fe6ac237da7830d86d74b2da61c Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Mon, 7 Oct 2013 00:36:42 +0200 Subject: [PATCH 005/119] fix undefined $htaccessWorking --- core/setup/controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/setup/controller.php b/core/setup/controller.php index 9b35432f113..679efee81bf 100644 --- a/core/setup/controller.php +++ b/core/setup/controller.php @@ -70,7 +70,6 @@ class Controller { // Protect data directory here, so we can test if the protection is working \OC_Setup::protectDataDirectory(); - $htaccessWorking = false; try { $htaccessWorking = \OC_Util::isHtAccessWorking(); } catch (\OC\HintException $e) { @@ -78,6 +77,7 @@ class Controller { 'error' => $e->getMessage(), 'hint' => $e->getHint() ); + $htaccessWorking = false; } return array( From 69f2bde324cd491937a90948a23b06a06c2f2400 Mon Sep 17 00:00:00 2001 From: Pellaeon Lin Date: Sun, 8 Dec 2013 15:41:20 +0800 Subject: [PATCH 006/119] Change misleading message when file size exceeds upload limit --- apps/files/js/file-upload.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index e9663353f74..979bb74b13f 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -235,8 +235,8 @@ $(document).ready(function() { //check max upload size if (selection.totalBytes > $('#max_upload').val()) { - data.textStatus = 'notenoughspace'; - data.errorThrown = t('files', 'Not enough space available'); + data.textStatus = 'sizeexceedlimit'; + data.errorThrown = t('files', 'File size exceeds upload limit'); } // end upload for whole selection on error From fc607e6bce76e9e2f6f52421bdddece951f629cd Mon Sep 17 00:00:00 2001 From: Pellaeon Lin Date: Sun, 8 Dec 2013 22:59:46 +0800 Subject: [PATCH 007/119] Separate PHP upload limit and free space --- lib/private/helper.php | 42 +++++++++++++++++++++++++++++------------- lib/public/util.php | 19 +++++++++++++++++++ 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/lib/private/helper.php b/lib/private/helper.php index c82d3bd4ef4..0bef427c6c1 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -828,23 +828,39 @@ class OC_Helper { * @return number of bytes representing */ public static function maxUploadFilesize($dir) { - $upload_max_filesize = OCP\Util::computerFileSize(ini_get('upload_max_filesize')); - $post_max_size = OCP\Util::computerFileSize(ini_get('post_max_size')); - $freeSpace = \OC\Files\Filesystem::free_space($dir); - if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) { - $maxUploadFilesize = \OC\Files\SPACE_UNLIMITED; - } elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) { - $maxUploadFilesize = max($upload_max_filesize, $post_max_size); //only the non 0 value counts - } else { - $maxUploadFilesize = min($upload_max_filesize, $post_max_size); - } + return min(self::freeSpace($dir), self::uploadLimit()); + } + /** + * Calculate free space left within user quota + * + * @param $dir the current folder where the user currently operates + * @return number of bytes representing + */ + public static function freeSpace($dir) { + $freeSpace = \OC\Files\Filesystem::free_space($dir); if ($freeSpace !== \OC\Files\SPACE_UNKNOWN) { $freeSpace = max($freeSpace, 0); - - return min($maxUploadFilesize, $freeSpace); + return $freeSpace; } else { - return $maxUploadFilesize; + return INF; + } + } + + /** + * Calculate PHP upload limit + * + * @return PHP upload file size limit + */ + public static function uploadLimit() { + $upload_max_filesize = OCP\Util::computerFileSize(ini_get('upload_max_filesize')); + $post_max_size = OCP\Util::computerFileSize(ini_get('post_max_size')); + if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) { + return INF; + } elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) { + return max($upload_max_filesize, $post_max_size); //only the non 0 value counts + } else { + return min($upload_max_filesize, $post_max_size); } } diff --git a/lib/public/util.php b/lib/public/util.php index 1d76fd1e1f7..cf7ac63ba51 100644 --- a/lib/public/util.php +++ b/lib/public/util.php @@ -458,4 +458,23 @@ class Util { public static function maxUploadFilesize($dir) { return \OC_Helper::maxUploadFilesize($dir); } + + /** + * Calculate free space left within user quota + * + * @param $dir the current folder where the user currently operates + * @return number of bytes representing + */ + public static function freeSpace($dir) { + return \OC_Helper::freeSpace($dir); + } + + /** + * Calculate PHP upload limit + * + * @return number of bytes representing + */ + public static function uploadLimit() { + return \OC_Helper::uploadLimit(); + } } From 64bf0fa47fe4c623672cf86e831f66974e7f650c Mon Sep 17 00:00:00 2001 From: Pellaeon Lin Date: Sun, 8 Dec 2013 23:17:35 +0800 Subject: [PATCH 008/119] Display different messages for uploadLimit and freeSpace --- apps/files/index.php | 4 ++++ apps/files/js/file-upload.js | 10 ++++++++-- apps/files/templates/index.php | 5 +++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/apps/files/index.php b/apps/files/index.php index 8f6838aa0d9..4ea0f9f2496 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -103,6 +103,8 @@ if ($needUpgrade) { } else { // information about storage capacities $storageInfo=OC_Helper::getStorageInfo($dir); + $freeSpace=OCP\Util::freeSpace($dir); + $uploadLimit=OCP\Util::uploadLimit(); $maxUploadFilesize=OCP\Util::maxUploadFilesize($dir); $publicUploadEnabled = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); // if the encryption app is disabled, than everything is fine (INIT_SUCCESSFUL status code) @@ -136,6 +138,8 @@ if ($needUpgrade) { $tmpl->assign('trashEmpty', $trashEmpty); $tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); $tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); + $tmpl->assign('freeSpace', $freeSpace); + $tmpl->assign('uploadLimit', $uploadLimit); $tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); $tmpl->assign('usedSpacePercent', (int)$storageInfo['relative']); $tmpl->assign('isPublic', false); diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index 979bb74b13f..7bd0eb81f57 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -233,11 +233,17 @@ $(document).ready(function() { // add size selection.totalBytes += file.size; - //check max upload size - if (selection.totalBytes > $('#max_upload').val()) { + // check PHP upload limit + if (selection.totalBytes > $('#upload_limit').val()) { data.textStatus = 'sizeexceedlimit'; data.errorThrown = t('files', 'File size exceeds upload limit'); } + + // check free space + if (selection.totalBytes > $('#free_space').val()) { + data.textStatus = 'notenoughspace'; + data.errorThrown = t('files', 'Not enough free space'); + } // end upload for whole selection on error if (data.errorThrown) { diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php index 00ec109621f..3d8a7f78e41 100644 --- a/apps/files/templates/index.php +++ b/apps/files/templates/index.php @@ -15,9 +15,10 @@
= 0):?> - + + + From 0aa38165a4659fedd98f752bdd99bf174ed98a76 Mon Sep 17 00:00:00 2001 From: Pellaeon Lin Date: Wed, 11 Dec 2013 12:17:28 +0800 Subject: [PATCH 009/119] Update #free_space on getstoragestats AJAX call --- apps/files/js/files.js | 1 + apps/files/lib/helper.php | 2 ++ 2 files changed, 3 insertions(+) diff --git a/apps/files/js/files.js b/apps/files/js/files.js index fdaa3aa3342..0a2f1aef013 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -41,6 +41,7 @@ Files={ } if (response.data !== undefined && response.data.uploadMaxFilesize !== undefined) { $('#max_upload').val(response.data.uploadMaxFilesize); + $('#free_space').val(response.data.freeSpace); $('#upload.button').attr('original-title', response.data.maxHumanFilesize); $('#usedSpacePercent').val(response.data.usedSpacePercent); Files.displayStorageWarnings(); diff --git a/apps/files/lib/helper.php b/apps/files/lib/helper.php index eaff28178ea..2f4a9790662 100644 --- a/apps/files/lib/helper.php +++ b/apps/files/lib/helper.php @@ -6,6 +6,7 @@ class Helper { public static function buildFileStorageStatistics($dir) { $l = new \OC_L10N('files'); + $freeSpace=OCP\Util::freeSpace($dir); $maxUploadFilesize = \OCP\Util::maxUploadFilesize($dir); $maxHumanFilesize = \OCP\Util::humanFileSize($maxUploadFilesize); $maxHumanFilesize = $l->t('Upload') . ' max. ' . $maxHumanFilesize; @@ -15,6 +16,7 @@ class Helper return array('uploadMaxFilesize' => $maxUploadFilesize, 'maxHumanFilesize' => $maxHumanFilesize, + 'freeSpace' => $freeSpace, 'usedSpacePercent' => (int)$storageInfo['relative']); } From 4b081be9569ed831c8f0fb7448bf798f004b8816 Mon Sep 17 00:00:00 2001 From: Pellaeon Lin Date: Wed, 11 Dec 2013 12:09:48 +0800 Subject: [PATCH 010/119] #max_upload is needed after all --- apps/files/templates/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php index 3d8a7f78e41..f20a3f1d073 100644 --- a/apps/files/templates/index.php +++ b/apps/files/templates/index.php @@ -15,7 +15,7 @@
= 0):?> - + From 5ddd85ff9cb64c10974804e810f8f68f275114a3 Mon Sep 17 00:00:00 2001 From: Pellaeon Lin Date: Wed, 11 Dec 2013 15:40:58 +0800 Subject: [PATCH 011/119] Contextual upload error message --- apps/files/js/file-upload.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index 7bd0eb81f57..1a36a580532 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -236,13 +236,13 @@ $(document).ready(function() { // check PHP upload limit if (selection.totalBytes > $('#upload_limit').val()) { data.textStatus = 'sizeexceedlimit'; - data.errorThrown = t('files', 'File size exceeds upload limit'); + data.errorThrown = t('files', 'Total file size {size1} exceeds upload limit {size2}').replace('{size1}', humanFileSize(selection.totalBytes)).replace('{size2}', humanFileSize($('#upload_limit').val())); } // check free space if (selection.totalBytes > $('#free_space').val()) { data.textStatus = 'notenoughspace'; - data.errorThrown = t('files', 'Not enough free space'); + data.errorThrown = t('files', 'Not enough free space, you are uploading {size1} but only {size2} is left').replace('{size1}', humanFileSize(selection.totalBytes)).replace('{size2}', humanFileSize($('#free_space').val())); } // end upload for whole selection on error From 059c3c8708c9b94df80d43ab8cac0cfc9b867cb8 Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Mon, 16 Dec 2013 15:38:12 +0100 Subject: [PATCH 012/119] fix issue with logging non utf8 chars --- lib/private/image.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/image.php b/lib/private/image.php index 7761a3c7737..314a4216b82 100644 --- a/lib/private/image.php +++ b/lib/private/image.php @@ -416,7 +416,7 @@ class OC_Image { // exif_imagetype throws "read error!" if file is less than 12 byte if(!@is_file($imagePath) || !file_exists($imagePath) || filesize($imagePath) < 12 || !is_readable($imagePath)) { // Debug output disabled because this method is tried before loadFromBase64? - OC_Log::write('core', 'OC_Image->loadFromFile, couldn\'t load: '.$imagePath, OC_Log::DEBUG); + OC_Log::write('core', 'OC_Image->loadFromFile, couldn\'t load: ' . (string) $imagePath, OC_Log::DEBUG); return false; } $iType = exif_imagetype($imagePath); From 3c21fd5bfcaedf05a6028a4585f56e4afaddf33a Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Wed, 18 Dec 2013 14:59:57 +0100 Subject: [PATCH 013/119] do not show 'Add app' and 'More apps' for themed ownCloud --- settings/templates/apps.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/settings/templates/apps.php b/settings/templates/apps.php index 0b76f775fea..bf2f178ca16 100644 --- a/settings/templates/apps.php +++ b/settings/templates/apps.php @@ -9,9 +9,11 @@
From 1df1b55b66f0bcc696a1ee9aeb8362dee9889100 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 6 Jan 2014 12:55:56 +0100 Subject: [PATCH 014/119] expose memory cache in public api --- lib/private/server.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/private/server.php b/lib/private/server.php index bee70dec2df..84ee8cadf04 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -136,6 +136,10 @@ class Server extends SimpleContainer implements IServerContainer { $this->registerService('UserCache', function($c) { return new UserCache(); }); + $this->registerService('MemCache', function ($c) { + $factory = new \OC\Memcache\Factory(); + return $factory->create(); + }); $this->registerService('ActivityManager', function($c) { return new ActivityManager(); }); @@ -295,6 +299,15 @@ class Server extends SimpleContainer implements IServerContainer { return $this->query('UserCache'); } + /** + * Returns an ICache instance + * + * @return \OCP\ICache + */ + function getMemCache() { + return $this->query('MemCache'); + } + /** * Returns the current session * From cd147bb37ae247082442f87b3cdd7d3d752e2d37 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 6 Jan 2014 12:58:43 +0100 Subject: [PATCH 015/119] Use APCIterator for Memcache\APC::clear() --- lib/private/memcache/apc.php | 27 ++++++++------------------- lib/private/memcache/apcu.php | 7 ------- 2 files changed, 8 insertions(+), 26 deletions(-) diff --git a/lib/private/memcache/apc.php b/lib/private/memcache/apc.php index 575ee4427db..d5bc1498d65 100644 --- a/lib/private/memcache/apc.php +++ b/lib/private/memcache/apc.php @@ -9,15 +9,8 @@ namespace OC\Memcache; class APC extends Cache { - /** - * entries in APC gets namespaced to prevent collisions between owncloud instances and users - */ - protected function getNameSpace() { - return $this->prefix; - } - public function get($key) { - $result = apc_fetch($this->getNamespace() . $key, $success); + $result = apc_fetch($this->getPrefix() . $key, $success); if (!$success) { return null; } @@ -25,26 +18,22 @@ class APC extends Cache { } public function set($key, $value, $ttl = 0) { - return apc_store($this->getNamespace() . $key, $value, $ttl); + return apc_store($this->getPrefix() . $key, $value, $ttl); } public function hasKey($key) { - return apc_exists($this->getNamespace() . $key); + return apc_exists($this->getPrefix() . $key); } public function remove($key) { - return apc_delete($this->getNamespace() . $key); + return apc_delete($this->getPrefix() . $key); } public function clear($prefix = '') { - $ns = $this->getNamespace() . $prefix; - $cache = apc_cache_info('user'); - foreach ($cache['cache_list'] as $entry) { - if (strpos($entry['info'], $ns) === 0) { - apc_delete($entry['info']); - } - } - return true; + $ns = $this->getPrefix() . $prefix; + $ns = preg_quote($ns, '/'); + $iter = new \APCIterator('user', '/^' . $ns . '/'); + return apc_delete($iter); } static public function isAvailable() { diff --git a/lib/private/memcache/apcu.php b/lib/private/memcache/apcu.php index dac0f5f208a..7f780f32718 100644 --- a/lib/private/memcache/apcu.php +++ b/lib/private/memcache/apcu.php @@ -9,13 +9,6 @@ namespace OC\Memcache; class APCu extends APC { - public function clear($prefix = '') { - $ns = $this->getNamespace() . $prefix; - $ns = preg_quote($ns, '/'); - $iter = new \APCIterator('user', '/^'.$ns.'/'); - return apc_delete($iter); - } - static public function isAvailable() { if (!extension_loaded('apcu')) { return false; From 4d65a8089284e4dde09181b56fb45b86c50d6fb5 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 6 Jan 2014 13:11:38 +0100 Subject: [PATCH 016/119] Remove the static dependency on OC_Util from Memcache --- lib/private/memcache/cache.php | 2 +- lib/private/memcache/factory.php | 13 +++++++++++++ lib/private/server.php | 3 ++- lib/public/iservercontainer.php | 7 +++++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/private/memcache/cache.php b/lib/private/memcache/cache.php index 0ad1cc7ec03..03671b3f240 100644 --- a/lib/private/memcache/cache.php +++ b/lib/private/memcache/cache.php @@ -18,7 +18,7 @@ abstract class Cache implements \ArrayAccess { * @param string $prefix */ public function __construct($prefix = '') { - $this->prefix = \OC_Util::getInstanceId() . '/' . $prefix; + $this->prefix = $prefix; } public function getPrefix() { diff --git a/lib/private/memcache/factory.php b/lib/private/memcache/factory.php index fde7d947567..48c97b59551 100644 --- a/lib/private/memcache/factory.php +++ b/lib/private/memcache/factory.php @@ -9,6 +9,18 @@ namespace OC\Memcache; class Factory { + /** + * @var string $globalPrefix + */ + private $globalPrefix; + + /** + * @param string $globalPrefix + */ + public function __construct($globalPrefix) { + $this->globalPrefix = $globalPrefix; + } + /** * get a cache instance, will return null if no backend is available * @@ -16,6 +28,7 @@ class Factory { * @return \OC\Memcache\Cache */ function create($prefix = '') { + $prefix = $this->globalPrefix . '/' . $prefix; if (XCache::isAvailable()) { return new XCache($prefix); } elseif (APCu::isAvailable()) { diff --git a/lib/private/server.php b/lib/private/server.php index 84ee8cadf04..6b242bddd01 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -137,7 +137,8 @@ class Server extends SimpleContainer implements IServerContainer { return new UserCache(); }); $this->registerService('MemCache', function ($c) { - $factory = new \OC\Memcache\Factory(); + $instanceId = \OC_Util::getInstanceId(); + $factory = new \OC\Memcache\Factory($instanceId); return $factory->create(); }); $this->registerService('ActivityManager', function($c) { diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php index b958d2d03f4..7ac5049ef24 100644 --- a/lib/public/iservercontainer.php +++ b/lib/public/iservercontainer.php @@ -141,6 +141,13 @@ interface IServerContainer { */ function getCache(); + /** + * Returns an ICache instance + * + * @return \OCP\ICache + */ + function getMemCache(); + /** * Returns the current session * From be7837402d55abc9a6dc801c943c9b642e821dd0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 8 Jan 2014 15:18:12 +0100 Subject: [PATCH 017/119] get the memorycache factory from OCP\Server instead of a cache instance this allows apps to specify a prefix to use --- lib/private/server.php | 11 +++++------ lib/public/cachefactory.php | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 lib/public/cachefactory.php diff --git a/lib/private/server.php b/lib/private/server.php index 6b242bddd01..b5fa9148626 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -136,10 +136,9 @@ class Server extends SimpleContainer implements IServerContainer { $this->registerService('UserCache', function($c) { return new UserCache(); }); - $this->registerService('MemCache', function ($c) { + $this->registerService('MemCacheFactory', function ($c) { $instanceId = \OC_Util::getInstanceId(); - $factory = new \OC\Memcache\Factory($instanceId); - return $factory->create(); + return new \OC\Memcache\Factory($instanceId); }); $this->registerService('ActivityManager', function($c) { return new ActivityManager(); @@ -303,10 +302,10 @@ class Server extends SimpleContainer implements IServerContainer { /** * Returns an ICache instance * - * @return \OCP\ICache + * @return \OCP\CacheFactory */ - function getMemCache() { - return $this->query('MemCache'); + function getMemCacheFactory() { + return $this->query('MemCacheFactory'); } /** diff --git a/lib/public/cachefactory.php b/lib/public/cachefactory.php new file mode 100644 index 00000000000..bb49aea7f3a --- /dev/null +++ b/lib/public/cachefactory.php @@ -0,0 +1,17 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCP; + +interface CacheFactory{ + /** + * @param string $prefix + * @return $return \OCP\ICache + */ + public function create($prefix = ''); +} From 5a2a0426a6c01cffe88c80e0529931a323c699d9 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 8 Jan 2014 15:51:40 +0100 Subject: [PATCH 018/119] Also update the OCP\IServerContainer --- lib/private/server.php | 2 +- lib/public/iservercontainer.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/private/server.php b/lib/private/server.php index b5fa9148626..6b034a5be9f 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -300,7 +300,7 @@ class Server extends SimpleContainer implements IServerContainer { } /** - * Returns an ICache instance + * Returns an \OCP\CacheFactory instance * * @return \OCP\CacheFactory */ diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php index 7ac5049ef24..67884bdc3e4 100644 --- a/lib/public/iservercontainer.php +++ b/lib/public/iservercontainer.php @@ -142,11 +142,11 @@ interface IServerContainer { function getCache(); /** - * Returns an ICache instance + * Returns an \OCP\CacheFactory instance * - * @return \OCP\ICache + * @return \OCP\CacheFactory */ - function getMemCache(); + function getMemCacheFactory(); /** * Returns the current session From d50c7391d8e78c9555b073fb9ccc6a91d5da34bc Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 9 Jan 2014 13:54:50 +0100 Subject: [PATCH 019/119] Use $server->getMemCacheFactory() in ldap connection --- apps/user_ldap/lib/connection.php | 2 +- lib/public/cachefactory.php | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php index 14dfaa1174d..92168a09ffa 100644 --- a/apps/user_ldap/lib/connection.php +++ b/apps/user_ldap/lib/connection.php @@ -51,7 +51,7 @@ class Connection extends LDAPUtility { $this->configPrefix = $configPrefix; $this->configID = $configID; $this->configuration = new Configuration($configPrefix); - $memcache = new \OC\Memcache\Factory(); + $memcache = \OC::$server->getMemCacheFactory(); if($memcache->isAvailable()) { $this->cache = $memcache->create(); } else { diff --git a/lib/public/cachefactory.php b/lib/public/cachefactory.php index bb49aea7f3a..1bb0ea3dd51 100644 --- a/lib/public/cachefactory.php +++ b/lib/public/cachefactory.php @@ -10,8 +10,17 @@ namespace OCP; interface CacheFactory{ /** + * Get a memory cache instance + * * @param string $prefix * @return $return \OCP\ICache */ public function create($prefix = ''); + + /** + * Check if a memory cache backend is available + * + * @return bool + */ + public function isAvailable(); } From 3ae17d0785e27528ce221e9c906df3127daa35fa Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 10 Dec 2013 01:45:15 +0100 Subject: [PATCH 020/119] Fix unallowed child elements --- core/templates/layout.user.php | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php index 89987625d63..dd2b209244d 100644 --- a/core/templates/layout.user.php +++ b/core/templates/layout.user.php @@ -48,15 +48,16 @@ <?php p($theme->getName()); ?> - +
From d95cab632b167c597c10da59d3b44715a9e6c2b4 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 10 Dec 2013 01:58:19 +0100 Subject: [PATCH 021/119] Extend margin to avoid displaying a scrollbar --- core/css/styles.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/css/styles.css b/core/css/styles.css index df014567087..ea98fbadb6f 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -671,7 +671,7 @@ label.infield { cursor:text !important; top:1.05em; left:.85em; } /* Apps management as sticky footer, less obtrusive in the list */ #navigation .wrapper { min-height: 100%; - margin: 0 auto -72px; + margin: 0 auto -82px 0; } #apps-management, #navigation .push { height: 72px; From 17c00f34d38d5d51f03ae1cf35d042df8eda8820 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 10 Dec 2013 01:46:20 +0100 Subject: [PATCH 022/119] Add alt attribute for img elements --- core/templates/layout.user.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php index dd2b209244d..bc1c700402e 100644 --- a/core/templates/layout.user.php +++ b/core/templates/layout.user.php @@ -51,7 +51,7 @@
- +
@@ -91,7 +91,7 @@
  • class="active"> - + @@ -110,7 +110,7 @@
  • class="active"> - + t('Apps')); ?> From 6f21da12e8c953bebdbd444460b07160821ba7a8 Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Sat, 11 Jan 2014 12:07:28 +0100 Subject: [PATCH 023/119] encode imagePath and fix documentation of loadFromFile --- lib/private/image.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/private/image.php b/lib/private/image.php index 314a4216b82..91a9f91e1d6 100644 --- a/lib/private/image.php +++ b/lib/private/image.php @@ -409,14 +409,14 @@ class OC_Image { /** * @brief Loads an image from a local file. - * @param $imageref The path to a local file. + * @param $imagePath The path to a local file. * @returns An image resource or false on error */ public function loadFromFile($imagePath=false) { // exif_imagetype throws "read error!" if file is less than 12 byte if(!@is_file($imagePath) || !file_exists($imagePath) || filesize($imagePath) < 12 || !is_readable($imagePath)) { // Debug output disabled because this method is tried before loadFromBase64? - OC_Log::write('core', 'OC_Image->loadFromFile, couldn\'t load: ' . (string) $imagePath, OC_Log::DEBUG); + OC_Log::write('core', 'OC_Image->loadFromFile, couldn\'t load: ' . (string) urlencode($imagePath), OC_Log::DEBUG); return false; } $iType = exif_imagetype($imagePath); From 2bdd014f83979d3a332775b39bb139c567c34e64 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Tue, 14 Jan 2014 22:14:06 +0100 Subject: [PATCH 024/119] first mobile style rules, hide extra columns in files view and scroll header --- apps/files_sharing/css/mobile.css | 18 ++++++++++++++++++ apps/files_sharing/public.php | 1 + 2 files changed, 19 insertions(+) create mode 100644 apps/files_sharing/css/mobile.css diff --git a/apps/files_sharing/css/mobile.css b/apps/files_sharing/css/mobile.css new file mode 100644 index 00000000000..55d244ff1e0 --- /dev/null +++ b/apps/files_sharing/css/mobile.css @@ -0,0 +1,18 @@ +@media only screen and (max-width: 600px) { + +/* make header and controls bar scroll up for more view of content on small screens */ +#header, +#controls { + position: absolute; +} + +/* hide size and date columns */ +table th#headerSize, +table td.filesize, +table th#headerDate, +table td.date { + display: none; +} + + +} diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index f4042f65248..ae0a62f1034 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -136,6 +136,7 @@ if (isset($path)) { } else { OCP\Util::addScript('files', 'file-upload'); OCP\Util::addStyle('files_sharing', 'public'); + OCP\Util::addStyle('files_sharing', 'mobile'); OCP\Util::addScript('files_sharing', 'public'); OCP\Util::addScript('files', 'fileactions'); OCP\Util::addScript('files', 'jquery.iframe-transport'); From 072ef7f010ca9f48119bc2397a82fdd0aac76beb Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Tue, 14 Jan 2014 22:14:46 +0100 Subject: [PATCH 025/119] remove min-width rule to fix mobile views --- apps/files/css/files.css | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 2fc86ca537d..74320aba32a 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -65,9 +65,6 @@ top: 44px; width: 100%; } -#filestable, #controls { - min-width: 680px; -} #filestable tbody tr { background-color:#fff; height:2.5em; } #filestable tbody tr:hover, tbody tr:active { background-color: rgb(240,240,240); From dbbbfee7deb4778e4a6c0a96a50d022a414584ae Mon Sep 17 00:00:00 2001 From: Pellaeon Lin Date: Wed, 15 Jan 2014 12:36:27 +0800 Subject: [PATCH 026/119] Fix namespace --- apps/files/lib/helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/lib/helper.php b/apps/files/lib/helper.php index 2f4a9790662..e2f545e9e3f 100644 --- a/apps/files/lib/helper.php +++ b/apps/files/lib/helper.php @@ -6,7 +6,7 @@ class Helper { public static function buildFileStorageStatistics($dir) { $l = new \OC_L10N('files'); - $freeSpace=OCP\Util::freeSpace($dir); + $freeSpace=\OCP\Util::freeSpace($dir); $maxUploadFilesize = \OCP\Util::maxUploadFilesize($dir); $maxHumanFilesize = \OCP\Util::humanFileSize($maxUploadFilesize); $maxHumanFilesize = $l->t('Upload') . ' max. ' . $maxHumanFilesize; From 807b885a0e83841b51b694afbb4b377e39215b0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 15 Jan 2014 14:36:18 +0100 Subject: [PATCH 027/119] reuse file upload as used within files app - remove public upload button --- apps/files/templates/index.php | 8 +++- apps/files_sharing/public.php | 3 +- apps/files_sharing/templates/public.php | 54 +------------------------ 3 files changed, 10 insertions(+), 55 deletions(-) diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php index 00ec109621f..d7f479b504f 100644 --- a/apps/files/templates/index.php +++ b/apps/files/templates/index.php @@ -18,6 +18,10 @@ + + + + @@ -26,7 +30,7 @@
  • - > + >
    @@ -44,7 +48,7 @@
    class="hidden">t('Nothing in here. Upload something!'))?>
    - + diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index ae0a62f1034..e3d68955439 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -225,7 +225,8 @@ if (isset($path)) { $folder->assign('fileList', $list->fetchPage()); $folder->assign('breadcrumb', $breadcrumbNav->fetchPage()); $folder->assign('dir', $getPath); - $folder->assign('isCreatable', false); + $folder->assign('isCreatable', $allowPublicUploadEnabled); + $folder->assign('dirToken', $linkItem['token']); $folder->assign('permissions', OCP\PERMISSION_READ); $folder->assign('isPublic',true); $folder->assign('publicUploadEnabled', 'no'); diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index 1d527dca8eb..d82e567182a 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -14,57 +14,7 @@ src="" alt="getName()); ?>" />
    - - t('%s shared the folder %s with you', - array($_['displayName'], $_['filename']))) ?> - - t('%s shared the file %s with you', - array($_['displayName'], $_['filename']))) ?> - - - - - Download" - />t('Download'))?> - - - - - - - - - - - = 0):?> - - - - - - -
    - -
    @@ -96,7 +46,7 @@ - +
    From 6c76b4ba1253a37316f7de964494b05099c66e21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 15 Jan 2014 15:07:24 +0100 Subject: [PATCH 028/119] fixing preview generation --- apps/files/js/files.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/js/files.js b/apps/files/js/files.js index fdaa3aa3342..d5e8450f41f 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -717,7 +717,7 @@ Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) { console.warn('Files.lazyLoadPreview(): missing etag argument'); } - if ( $('#publicUploadButtonMock').length ) { + if ( $('#isPublic').length ) { urlSpec.t = $('#dirToken').val(); previewURL = OC.Router.generate('core_ajax_public_preview', urlSpec); } else { From ce231c406dfafdedbe97baa5a3c3612b4428b79d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 15 Jan 2014 15:07:52 +0100 Subject: [PATCH 029/119] no new menu on public upload --- apps/files/templates/index.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php index d7f479b504f..a69407805d8 100644 --- a/apps/files/templates/index.php +++ b/apps/files/templates/index.php @@ -1,6 +1,7 @@
    +
    t('New'));?>
      @@ -12,6 +13,7 @@ data-type='web'>

      t('From link'));?>

    +
    = 0):?> From b3a668378484ad65c601964d84a0b70e7f93318e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 15 Jan 2014 15:22:40 +0100 Subject: [PATCH 030/119] remove unused js code and css rules --- apps/files_sharing/css/public.css | 49 ------------------------------- apps/files_sharing/js/public.js | 11 ------- 2 files changed, 60 deletions(-) diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css index 060d4dfedc7..16d115f6e9a 100644 --- a/apps/files_sharing/css/public.css +++ b/apps/files_sharing/css/public.css @@ -19,16 +19,6 @@ body { float: left; } -#public_upload, -#download { - font-weight:700; - margin: 0 0 0 .4em; - padding: 0 5px; - height: 32px; - float: left; - -} - .header-right #details { margin-right: 28px; } @@ -38,17 +28,6 @@ body { height: 32px; } -#public_upload { - margin-left: 0.3em; -} - -#public_upload img, -#download img { - padding-left:.1em; - padding-right:.3em; - vertical-align:text-bottom; -} - #controls { left: 0; } @@ -110,34 +89,6 @@ thead{ margin: 0; } -#file_upload_start { - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; - filter: alpha(opacity=0); - opacity: 0; - z-index: 20; - position: absolute !important; - top: 0; - left: 0; - width: 100% !important; -} - -#publicUploadButtonMock { - position:relative; - display:block; - width:100%; - height:32px; - cursor:pointer; - z-index:10; - background-image:url('%webroot%/core/img/actions/upload.svg'); - background-repeat:no-repeat; - background-position:7px 8px; -} - -#publicUploadButtonMock span { - margin: 0 5px 0 28px; - color: #555; -} - .directLink { margin-bottom: 20px; } diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js index eacd4096ed8..63e1ccaadfa 100644 --- a/apps/files_sharing/js/public.js +++ b/apps/files_sharing/js/public.js @@ -9,8 +9,6 @@ function fileDownloadPath(dir, file) { $(document).ready(function() { - $('#data-upload-form').tipsy({gravity:'ne', fade:true}); - if (typeof FileActions !== 'undefined') { var mimetype = $('#mimetype').val(); // Show file preview if previewer is available, images are already handled by the template @@ -58,15 +56,6 @@ $(document).ready(function() { }; }); - // Add Uploadprogress Wrapper to controls bar - $('#controls').append($('#additional_controls div#uploadprogresswrapper')); - - // Cancel upload trigger - $('#cancel_upload_button').click(function() { - OC.Upload.cancelUploads(); - procesSelection(); - }); - $('#directLink').focus(); }); From 50ae2ab14c1ae852ff98cee9ae10a4b9218bd1db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 15 Jan 2014 15:31:27 +0100 Subject: [PATCH 031/119] add download button on single file share page --- apps/files_sharing/templates/public.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index d82e567182a..e181e8a3280 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -40,13 +40,19 @@ - + +
    From db837bf696951e3c866205a2d690bf3c014babeb Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Wed, 15 Jan 2014 14:45:10 +0100 Subject: [PATCH 032/119] improvements to public files mobile view --- apps/files/css/files.css | 2 +- apps/files_sharing/css/mobile.css | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 74320aba32a..4beb01a4e6a 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -234,7 +234,7 @@ table td.filename form { font-size:.85em; margin-left:3em; margin-right:3em; } #fileList tr td.filename a.name label { position: absolute; - width: 100%; + width: 80%; height: 50px; } diff --git a/apps/files_sharing/css/mobile.css b/apps/files_sharing/css/mobile.css index 55d244ff1e0..3578aff17f2 100644 --- a/apps/files_sharing/css/mobile.css +++ b/apps/files_sharing/css/mobile.css @@ -1,10 +1,5 @@ @media only screen and (max-width: 600px) { -/* make header and controls bar scroll up for more view of content on small screens */ -#header, -#controls { - position: absolute; -} /* hide size and date columns */ table th#headerSize, @@ -14,5 +9,15 @@ table td.date { display: none; } +/* restrict length of displayed filename to prevent overflow */ +table td.filename .nametext { + max-width: 80% !important; +} +/* and to make room for download button on hover */ +table tr:hover td.filename .nametext, +table tr:focus td.filename .nametext { + max-width: 60% !important; +} + } From 5f95356592b12c81b8c2e0f32c890cdbd069e82c Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Wed, 15 Jan 2014 14:49:41 +0100 Subject: [PATCH 033/119] remove unused log icon --- settings/img/log Icon License | 2 -- settings/img/log.png | Bin 342 -> 0 bytes settings/img/log.svg | 10 ---------- 3 files changed, 12 deletions(-) delete mode 100644 settings/img/log Icon License delete mode 100644 settings/img/log.png delete mode 100644 settings/img/log.svg diff --git a/settings/img/log Icon License b/settings/img/log Icon License deleted file mode 100644 index b5c3167d733..00000000000 --- a/settings/img/log Icon License +++ /dev/null @@ -1,2 +0,0 @@ -CC BY 3.0 -http://thenounproject.com/en-us/noun/printer/#icon-No109 \ No newline at end of file diff --git a/settings/img/log.png b/settings/img/log.png deleted file mode 100644 index b34a58f844cdcb1005b58cd488da2701802ca0b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 342 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=f!eQwFr$;k>5cfkM|jT^vI!PA4Zg zFxA!7d3PM-*})L!nRI1BD#NVL(*z%~Zjg$PzyH(W&T$5nf6O1{75=#?)o~wTKfuP| zJLjl_62nWzmrK_%D%e|ESZrW;nUy1 b%D`|k;$e?l%+6atA2N8l`njxgN@xNA=P-B4 diff --git a/settings/img/log.svg b/settings/img/log.svg deleted file mode 100644 index a3939b73093..00000000000 --- a/settings/img/log.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - From 3e7cf4110dc5bce2241830ed8ab0ddb57791442a Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Wed, 15 Jan 2014 15:34:14 +0100 Subject: [PATCH 034/119] tweak color and position of username in public share --- apps/files_sharing/css/public.css | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css index 16d115f6e9a..54a25d0ce34 100644 --- a/apps/files_sharing/css/public.css +++ b/apps/files_sharing/css/public.css @@ -14,20 +14,19 @@ body { padding:7px; } -#details { - color:#fff; - float: left; -} - -.header-right #details { - margin-right: 28px; -} - .header-right { padding: 0; height: 32px; } +#details { + color:#fff; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; + filter: alpha(opacity=50); + opacity: .5; + padding-right: 5px; +} + #controls { left: 0; } From cd6ab2931325323cb59961c4327a18d934ecc72a Mon Sep 17 00:00:00 2001 From: Pellaeon Lin Date: Thu, 16 Jan 2014 17:51:00 +0800 Subject: [PATCH 035/119] Use t() 's native method --- apps/files/js/file-upload.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index 1a36a580532..a003e5eec86 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -236,13 +236,19 @@ $(document).ready(function() { // check PHP upload limit if (selection.totalBytes > $('#upload_limit').val()) { data.textStatus = 'sizeexceedlimit'; - data.errorThrown = t('files', 'Total file size {size1} exceeds upload limit {size2}').replace('{size1}', humanFileSize(selection.totalBytes)).replace('{size2}', humanFileSize($('#upload_limit').val())); + data.errorThrown = t('files', 'Total file size {size1} exceeds upload limit {size2}', { + 'size1': humanFileSize(selection.totalBytes), + 'size2': humanFileSize($('#upload_limit').val()) + }); } // check free space if (selection.totalBytes > $('#free_space').val()) { data.textStatus = 'notenoughspace'; - data.errorThrown = t('files', 'Not enough free space, you are uploading {size1} but only {size2} is left').replace('{size1}', humanFileSize(selection.totalBytes)).replace('{size2}', humanFileSize($('#free_space').val())); + data.errorThrown = t('files', 'Not enough free space, you are uploading {size1} but only {size2} is left', { + '{size1}': humanFileSize(selection.totalBytes), + '{size2}': humanFileSize($('#free_space').val()) + }); } // end upload for whole selection on error From 6ec50e4b0c435789732186eb3c6839883061e5a8 Mon Sep 17 00:00:00 2001 From: Pellaeon Lin Date: Thu, 16 Jan 2014 19:48:46 +0800 Subject: [PATCH 036/119] Comments to clarify --- apps/files/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files/index.php b/apps/files/index.php index 4ea0f9f2496..c8b04bd4627 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -136,10 +136,10 @@ if ($needUpgrade) { $tmpl->assign('files', $files); $tmpl->assign('trash', $trashEnabled); $tmpl->assign('trashEmpty', $trashEmpty); - $tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); + $tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); // minimium of freeSpace and uploadLimit $tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); $tmpl->assign('freeSpace', $freeSpace); - $tmpl->assign('uploadLimit', $uploadLimit); + $tmpl->assign('uploadLimit', $uploadLimit); // PHP upload limit $tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); $tmpl->assign('usedSpacePercent', (int)$storageInfo['relative']); $tmpl->assign('isPublic', false); From d36da7e43abc716247fcc6252466f5a848cbbbed Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 16 Jan 2014 12:58:17 +0100 Subject: [PATCH 037/119] use appstoreenabled config switch --- settings/templates/apps.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/settings/templates/apps.php b/settings/templates/apps.php index bf2f178ca16..bd387144504 100644 --- a/settings/templates/apps.php +++ b/settings/templates/apps.php @@ -9,7 +9,7 @@
      - +
    • t('Add your App'));?> …
    • @@ -26,7 +26,7 @@ - +
    • t('More Apps'));?> …
    • From c0590676a005c0890e43b7a2b2950fee2758efef Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Thu, 16 Jan 2014 15:28:39 +0100 Subject: [PATCH 038/119] fix public share download button width --- apps/files_sharing/css/public.css | 9 ++++++++- apps/files_sharing/templates/public.php | 6 +++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css index 54a25d0ce34..d593d353dd7 100644 --- a/apps/files_sharing/css/public.css +++ b/apps/files_sharing/css/public.css @@ -88,13 +88,20 @@ thead{ margin: 0; } +.directDownload, .directLink { margin-bottom: 20px; } + .directDownload .button img { + vertical-align: text-bottom; + } .directLink label { font-weight: normal; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; + filter: alpha(opacity=50); + opacity: .5; } .directLink input { - margin-left: 10px; + margin-left: 5px; width: 300px; } diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index e181e8a3280..fb45401458f 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -43,9 +43,9 @@
    -
    - - Download"/> + From 5cdab5fff3bcdbeb9107960f97c9006401a9168a Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Thu, 16 Jan 2014 15:32:23 +0100 Subject: [PATCH 039/119] show publicly shared image on full width, without margin --- apps/files_sharing/css/public.css | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css index d593d353dd7..75c37f6a1c3 100644 --- a/apps/files_sharing/css/public.css +++ b/apps/files_sharing/css/public.css @@ -60,11 +60,9 @@ p.info a { } #imgframe { - height:75%; - padding-bottom:2em; - padding-top:2em; - width:80%; - margin:0 auto; + width: 100%; + padding: 0; + margin-bottom: 35px; } #imgframe img { From d463edaf0943b82b2f3faeb0f134f9b88d28c32c Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Thu, 16 Jan 2014 15:56:18 +0100 Subject: [PATCH 040/119] on mobile, show single shared image at full width without margin --- apps/files_sharing/css/mobile.css | 7 +++++++ apps/files_sharing/css/public.css | 8 +++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/apps/files_sharing/css/mobile.css b/apps/files_sharing/css/mobile.css index 3578aff17f2..2118cd31e4b 100644 --- a/apps/files_sharing/css/mobile.css +++ b/apps/files_sharing/css/mobile.css @@ -19,5 +19,12 @@ table tr:focus td.filename .nametext { max-width: 60% !important; } +/* on mobile, show single shared image at full width without margin */ +#imgframe { + width: 100%; + padding: 0; + margin-bottom: 35px; +} + } diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css index 75c37f6a1c3..d593d353dd7 100644 --- a/apps/files_sharing/css/public.css +++ b/apps/files_sharing/css/public.css @@ -60,9 +60,11 @@ p.info a { } #imgframe { - width: 100%; - padding: 0; - margin-bottom: 35px; + height:75%; + padding-bottom:2em; + padding-top:2em; + width:80%; + margin:0 auto; } #imgframe img { From 4726a2021b70f2ee70b4cb8817fd89a8532b848b Mon Sep 17 00:00:00 2001 From: Pellaeon Lin Date: Fri, 17 Jan 2014 17:10:42 +0800 Subject: [PATCH 041/119] Add $freeSpace and $uploadLimit to files_sharing --- apps/files_sharing/public.php | 4 ++++ apps/files_sharing/templates/public.php | 2 ++ 2 files changed, 6 insertions(+) diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index f4042f65248..540f2b004c6 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -141,6 +141,8 @@ if (isset($path)) { OCP\Util::addScript('files', 'jquery.iframe-transport'); OCP\Util::addScript('files', 'jquery.fileupload'); $maxUploadFilesize=OCP\Util::maxUploadFilesize($path); + $freeSpace=OCP\Util::freeSpace($dir); + $uploadLimit=OCP\Util::uploadLimit(); $tmpl = new OCP\Template('files_sharing', 'public', 'base'); $tmpl->assign('uidOwner', $shareOwner); $tmpl->assign('displayName', \OCP\User::getDisplayName($shareOwner)); @@ -161,6 +163,8 @@ if (isset($path)) { $tmpl->assign('allowPublicUploadEnabled', $allowPublicUploadEnabled); $tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); $tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); + $tmpl->assign('freeSpace', $freeSpace); + $tmpl->assign('uploadLimit', $uploadLimit); // PHP upload limit $urlLinkIdentifiers= (isset($token)?'&t='.$token:'') .(isset($_GET['dir'])?'&dir='.$_GET['dir']:'') diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index 1d527dca8eb..124b4a1ae9f 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -34,6 +34,8 @@ + + From ccadab96a686e78e3c9d7234b5c8907b5ae8b47a Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Fri, 17 Jan 2014 12:51:13 +0100 Subject: [PATCH 042/119] add icons for file list and picture view toggles --- core/img/actions/toggle-filelist.png | Bin 0 -> 208 bytes core/img/actions/toggle-filelist.svg | 135 +++++++++++++++++++++++++++ core/img/actions/toggle-pictures.png | Bin 0 -> 207 bytes core/img/actions/toggle-pictures.svg | 117 +++++++++++++++++++++++ 4 files changed, 252 insertions(+) create mode 100644 core/img/actions/toggle-filelist.png create mode 100644 core/img/actions/toggle-filelist.svg create mode 100644 core/img/actions/toggle-pictures.png create mode 100644 core/img/actions/toggle-pictures.svg diff --git a/core/img/actions/toggle-filelist.png b/core/img/actions/toggle-filelist.png new file mode 100644 index 0000000000000000000000000000000000000000..464ff0fe12643beea9be9432f3ec33136f0da6cd GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR412s*bT?q$GojU3lKI>km!f2Inal6zjru0+UtM^~H wvVg5XGxc?=O7f>;!5@6*2%hiwFY%FWcWmKv$)w_&K!X`PUHx3vIVCg!01|>livR!s literal 0 HcmV?d00001 diff --git a/core/img/actions/toggle-filelist.svg b/core/img/actions/toggle-filelist.svg new file mode 100644 index 00000000000..0f75ad8e1c7 --- /dev/null +++ b/core/img/actions/toggle-filelist.svg @@ -0,0 +1,135 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/core/img/actions/toggle-pictures.png b/core/img/actions/toggle-pictures.png new file mode 100644 index 0000000000000000000000000000000000000000..a8e1bea1918f35c363bec8864c5a3ca1177d4415 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4)%6LrrLwQ()PUxs!jgcV$VMR#6ix@heKZ4TZjW)!oc9^>gTe~DWM4fqNGFD literal 0 HcmV?d00001 diff --git a/core/img/actions/toggle-pictures.svg b/core/img/actions/toggle-pictures.svg new file mode 100644 index 00000000000..9d9077ea6f4 --- /dev/null +++ b/core/img/actions/toggle-pictures.svg @@ -0,0 +1,117 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + From 1d380a201191c12c7b860b2a80a5db12d6bf781d Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Fri, 17 Jan 2014 13:27:46 +0100 Subject: [PATCH 043/119] optimize size of toggle icons --- core/img/actions/toggle-filelist.png | Bin 208 -> 195 bytes core/img/actions/toggle-filelist.svg | 142 ++------------------------- core/img/actions/toggle-pictures.png | Bin 207 -> 193 bytes core/img/actions/toggle-pictures.svg | 122 ++--------------------- 4 files changed, 16 insertions(+), 248 deletions(-) diff --git a/core/img/actions/toggle-filelist.png b/core/img/actions/toggle-filelist.png index 464ff0fe12643beea9be9432f3ec33136f0da6cd..45d363f1934f7a40e6a43644be8a4bd2b3f73a17 100644 GIT binary patch delta 121 zcmcb>c$jg5gai{a0|P_ST=7ppin-XyGlYYKCJkL{v`jR%zXxGnm)S{4w^c3)GvJ2y-tPED&gXGsaH(tr?OY?zi?#%TY+Zk>sFQI mPsf5k_|6eL-|=7KBiruS!sn7n#W#UAF?hQAxvX - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - + + + + + + + + + diff --git a/core/img/actions/toggle-pictures.png b/core/img/actions/toggle-pictures.png index a8e1bea1918f35c363bec8864c5a3ca1177d4415..8068d17e30d95532ff0923c9848ebd5cc3c8d8ef 100644 GIT binary patch delta 119 zcmX@lc#v^|gai{a0|P_ST=7ppin-XyGlYYK+pJ7S7=$kGMWGY diff --git a/core/img/actions/toggle-pictures.svg b/core/img/actions/toggle-pictures.svg index 9d9077ea6f4..5205c0226d1 100644 --- a/core/img/actions/toggle-pictures.svg +++ b/core/img/actions/toggle-pictures.svg @@ -1,117 +1,9 @@ - - - - - image/svg+xml - - - - - - - - - - - - - - - - - + + + + + + + From 3e803b5e366563e384abde0d6e6cb6eb010bf914 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Fri, 17 Jan 2014 14:41:05 +0100 Subject: [PATCH 044/119] restrict zooming on mobile devices for the publicly accessible, optimized pages --- core/templates/layout.base.php | 2 +- core/templates/layout.guest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/templates/layout.base.php b/core/templates/layout.base.php index 8cd237deea1..bae52a73234 100644 --- a/core/templates/layout.base.php +++ b/core/templates/layout.base.php @@ -11,7 +11,7 @@ getTitle()); ?> - + diff --git a/core/templates/layout.guest.php b/core/templates/layout.guest.php index 47ca5903dab..6a96b17b100 100644 --- a/core/templates/layout.guest.php +++ b/core/templates/layout.guest.php @@ -11,7 +11,7 @@ getTitle()); ?> - + From b291fb9cd7e94009aba6023e88c5e970a4aa4e96 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Fri, 17 Jan 2014 15:47:26 +0100 Subject: [PATCH 045/119] make sure there's enough room for the file actions --- apps/files/css/files.css | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 4beb01a4e6a..eb009cf0a14 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -65,6 +65,14 @@ top: 44px; width: 100%; } +/* make sure there's enough room for the file actions */ +#body-user #filestable { + min-width: 750px; +} +#body-user #controls { + min-width: 600px; +} + #filestable tbody tr { background-color:#fff; height:2.5em; } #filestable tbody tr:hover, tbody tr:active { background-color: rgb(240,240,240); From f0a5007e9a2162d6f9d51ee4abf8791af8c0f886 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Fri, 17 Jan 2014 16:29:16 +0100 Subject: [PATCH 046/119] fix input element closing tag --- apps/files/templates/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php index a69407805d8..5188ca56281 100644 --- a/apps/files/templates/index.php +++ b/apps/files/templates/index.php @@ -32,7 +32,7 @@
    - > + />
    @@ -50,7 +50,7 @@
    class="hidden">t('Nothing in here. Upload something!'))?>
    - +
    From 4ec6debe2b145b0df106c7e5a3f4ed0cf2885957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Mon, 20 Jan 2014 17:27:03 +0100 Subject: [PATCH 047/119] remove unused variable --- apps/files_sharing/public.php | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index e3d68955439..490cea570bc 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -159,7 +159,6 @@ if (isset($path)) { if ($linkItem['item_type'] !== 'folder') { $allowPublicUploadEnabled = false; } - $tmpl->assign('allowPublicUploadEnabled', $allowPublicUploadEnabled); $tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); $tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); From b578a3359eecb4113044a32fce3878eb94d10e20 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 22 Jan 2014 13:19:39 +0100 Subject: [PATCH 048/119] revert accidental 3rdparty commit --- 3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty b/3rdparty index dbe0025a427..7c2c94c904c 160000 --- a/3rdparty +++ b/3rdparty @@ -1 +1 @@ -Subproject commit dbe0025a42773d363513fb2c80106306d5444b48 +Subproject commit 7c2c94c904c2721763e97d5bafd115f863080a60 From ade726ad324efb16c65055ce2dd5683c3109c8d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 23 Jan 2014 01:08:42 +0100 Subject: [PATCH 049/119] focus link text only on click in the input field - closes #6817 --- apps/files_sharing/js/public.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js index 31572f5ccf5..d95f6348ac0 100644 --- a/apps/files_sharing/js/public.js +++ b/apps/files_sharing/js/public.js @@ -56,6 +56,9 @@ $(document).ready(function() { }; }); - $('#directLink').focus(); + $(document).on('click', '#directLink', function() { + $(this).focus(); + $(this).select(); + }); }); From 6241655df4121619de42ba797ec076d9b6927568 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 23 Jan 2014 02:15:42 +0100 Subject: [PATCH 050/119] Bring mimetype list into alphabetical order. --- lib/private/mimetypes.list.php | 133 ++++++++++++++++----------------- 1 file changed, 66 insertions(+), 67 deletions(-) diff --git a/lib/private/mimetypes.list.php b/lib/private/mimetypes.list.php index 08228336966..72860d0e64f 100644 --- a/lib/private/mimetypes.list.php +++ b/lib/private/mimetypes.list.php @@ -21,93 +21,92 @@ */ /** - * list of mimetypes by extension + * Array mapping file extensions to mimetypes (in alphabetical order). */ - return array( + 'ai' => 'application/illustrator', + 'avi'=>'video/x-msvideo', + 'bash' => 'text/x-shellscript', + 'blend'=>'application/x-blender', + 'cc' => 'text/x-c', + 'cdr' => 'application/coreldraw', + 'cpp' => 'text/x-c++src', 'css'=>'text/css', + 'c' => 'text/x-c', + 'c++' => 'text/x-c++src', + 'doc'=>'application/msword', + 'doc'=>'application/msword', + 'docx'=>'application/msword', + 'docx'=>'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dv'=>'video/dv', + 'epub' => 'application/epub+zip', + 'exe'=>'application/x-ms-dos-executable', 'flac'=>'audio/flac', 'gif'=>'image/gif', - 'gzip'=>'application/x-gzip', 'gz'=>'application/x-gzip', + 'gzip'=>'application/x-gzip', 'html'=>'text/html', 'htm'=>'text/html', - 'ics'=>'text/calendar', 'ical'=>'text/calendar', + 'ics'=>'text/calendar', + 'impress' => 'text/impress', 'jpeg'=>'image/jpeg', 'jpg'=>'image/jpeg', 'js'=>'application/javascript', + 'keynote'=>'application/x-iwork-keynote-sffkey', + 'kra'=>'application/x-krita', + 'm2t'=>'video/mp2t', + 'm4v'=>'video/mp4', + 'markdown' => 'text/markdown', + 'mdown' => 'text/markdown', + 'md' => 'text/markdown', + 'mdwn' => 'text/markdown', + 'mobi' => 'application/x-mobipocket-ebook', + 'mov'=>'video/quicktime', + 'mp3'=>'audio/mpeg', + 'mp4'=>'video/mp4', + 'mpeg'=>'video/mpeg', + 'mpg'=>'video/mpeg', + 'msi'=>'application/x-msi', + 'numbers'=>'application/x-iwork-numbers-sffnumbers', + 'odg'=>'application/vnd.oasis.opendocument.graphics', + 'odp'=>'application/vnd.oasis.opendocument.presentation', + 'ods'=>'application/vnd.oasis.opendocument.spreadsheet', + 'odt'=>'application/vnd.oasis.opendocument.text', 'oga'=>'audio/ogg', 'ogg'=>'audio/ogg', 'ogv'=>'video/ogg', - 'pdf'=>'application/pdf', - 'png'=>'image/png', - 'svg'=>'image/svg+xml', - 'tar'=>'application/x-tar', - 'tgz'=>'application/x-compressed', - 'tar.gz'=>'application/x-compressed', - 'tif'=>'image/tiff', - 'tiff'=>'image/tiff', - 'txt'=>'text/plain', - 'zip'=>'application/zip', - 'wav'=>'audio/wav', - 'odt'=>'application/vnd.oasis.opendocument.text', - 'ods'=>'application/vnd.oasis.opendocument.spreadsheet', - 'odg'=>'application/vnd.oasis.opendocument.graphics', - 'odp'=>'application/vnd.oasis.opendocument.presentation', 'pages'=>'application/x-iwork-pages-sffpages', - 'numbers'=>'application/x-iwork-numbers-sffnumbers', - 'keynote'=>'application/x-iwork-keynote-sffkey', - 'kra'=>'application/x-krita', - 'mp3'=>'audio/mpeg', - 'doc'=>'application/msword', - 'docx'=>'application/msword', - 'xls'=>'application/msexcel', - 'xlsx'=>'application/msexcel', + 'pdf'=>'application/pdf', 'php'=>'application/x-php', - 'exe'=>'application/x-ms-dos-executable', - 'msi'=>'application/x-msi', 'pl'=>'application/x-pearl', - 'py'=>'application/x-python', - 'blend'=>'application/x-blender', - 'xcf'=>'application/x-gimp', - 'psd'=>'application/x-photoshop', - 'xml'=>'application/xml', - 'avi'=>'video/x-msvideo', - 'dv'=>'video/dv', - 'm2t'=>'video/mp2t', - 'mp4'=>'video/mp4', - 'm4v'=>'video/mp4', - 'mpg'=>'video/mpeg', - 'mpeg'=>'video/mpeg', - 'mov'=>'video/quicktime', - 'webm'=>'video/webm', - 'wmv'=>'video/x-ms-asf', - 'py'=>'text/x-script.python', - 'vcf' => 'text/vcard', - 'vcard' => 'text/vcard', - 'doc'=>'application/msword', - 'docx'=>'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'xls'=>'application/msexcel', - 'xlsx'=>'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'png'=>'image/png', 'ppt'=>'application/mspowerpoint', 'pptx'=>'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'sgf' => 'application/sgf', - 'cdr' => 'application/coreldraw', - 'impress' => 'text/impress', - 'ai' => 'application/illustrator', - 'epub' => 'application/epub+zip', - 'mobi' => 'application/x-mobipocket-ebook', - 'md' => 'text/markdown', - 'markdown' => 'text/markdown', - 'mdown' => 'text/markdown', - 'mdwn' => 'text/markdown', + 'psd'=>'application/x-photoshop', + 'py'=>'application/x-python', + 'py'=>'text/x-script.python', 'reveal' => 'text/reveal', - 'c' => 'text/x-c', - 'cc' => 'text/x-c', - 'cpp' => 'text/x-c++src', - 'c++' => 'text/x-c++src', - 'sh' => 'text/x-shellscript', - 'bash' => 'text/x-shellscript', + 'sgf' => 'application/sgf', 'sh-lib' => 'text/x-shellscript', + 'sh' => 'text/x-shellscript', + 'svg'=>'image/svg+xml', + 'tar'=>'application/x-tar', + 'tar.gz'=>'application/x-compressed', + 'tgz'=>'application/x-compressed', + 'tiff'=>'image/tiff', + 'tif'=>'image/tiff', + 'txt'=>'text/plain', + 'vcard' => 'text/vcard', + 'vcf' => 'text/vcard', + 'wav'=>'audio/wav', + 'webm'=>'video/webm', + 'wmv'=>'video/x-ms-asf', + 'xcf'=>'application/x-gimp', + 'xls'=>'application/msexcel', + 'xls'=>'application/msexcel', + 'xlsx'=>'application/msexcel', + 'xlsx'=>'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xml'=>'application/xml', + 'zip'=>'application/zip', ); From 689516ebd7a47847938420bf8715469b68fb3535 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 23 Jan 2014 02:22:46 +0100 Subject: [PATCH 051/119] Remove duplicate mimetypes while keeping previous behaviour. --- lib/private/mimetypes.list.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/private/mimetypes.list.php b/lib/private/mimetypes.list.php index 72860d0e64f..9db396e9fd2 100644 --- a/lib/private/mimetypes.list.php +++ b/lib/private/mimetypes.list.php @@ -35,8 +35,6 @@ return array( 'c' => 'text/x-c', 'c++' => 'text/x-c++src', 'doc'=>'application/msword', - 'doc'=>'application/msword', - 'docx'=>'application/msword', 'docx'=>'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'dv'=>'video/dv', 'epub' => 'application/epub+zip', @@ -84,7 +82,6 @@ return array( 'ppt'=>'application/mspowerpoint', 'pptx'=>'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'psd'=>'application/x-photoshop', - 'py'=>'application/x-python', 'py'=>'text/x-script.python', 'reveal' => 'text/reveal', 'sgf' => 'application/sgf', @@ -104,8 +101,6 @@ return array( 'wmv'=>'video/x-ms-asf', 'xcf'=>'application/x-gimp', 'xls'=>'application/msexcel', - 'xls'=>'application/msexcel', - 'xlsx'=>'application/msexcel', 'xlsx'=>'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'xml'=>'application/xml', 'zip'=>'application/zip', From 47ea7704ca796a23fc5e9ec8f4a7668d1bbe9446 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 23 Jan 2014 02:46:05 +0100 Subject: [PATCH 052/119] Fix icons for xml,ppt,dot,dotx files. --- lib/private/helper.php | 2 ++ lib/private/mimetypes.list.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lib/private/helper.php b/lib/private/helper.php index 1c8d01c141f..90ef704c3cc 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -161,6 +161,7 @@ class OC_Helper { 'application/vnd.oasis.opendocument.text-template' => 'x-office/document', 'application/vnd.oasis.opendocument.text-web' => 'x-office/document', 'application/vnd.oasis.opendocument.text-master' => 'x-office/document', + 'application/mspowerpoint' => 'x-office/presentation', 'application/vnd.ms-powerpoint' => 'x-office/presentation', 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'x-office/presentation', 'application/vnd.openxmlformats-officedocument.presentationml.template' => 'x-office/presentation', @@ -171,6 +172,7 @@ class OC_Helper { 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12' => 'x-office/presentation', 'application/vnd.oasis.opendocument.presentation' => 'x-office/presentation', 'application/vnd.oasis.opendocument.presentation-template' => 'x-office/presentation', + 'application/msexcel' => 'x-office/spreadsheet', 'application/vnd.ms-excel' => 'x-office/spreadsheet', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'x-office/spreadsheet', 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => 'x-office/spreadsheet', diff --git a/lib/private/mimetypes.list.php b/lib/private/mimetypes.list.php index 9db396e9fd2..1ad333b5084 100644 --- a/lib/private/mimetypes.list.php +++ b/lib/private/mimetypes.list.php @@ -36,6 +36,8 @@ return array( 'c++' => 'text/x-c++src', 'doc'=>'application/msword', 'docx'=>'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dot'=>'application/msword', + 'dotx'=>'application/vnd.openxmlformats-officedocument.wordprocessingml.template', 'dv'=>'video/dv', 'epub' => 'application/epub+zip', 'exe'=>'application/x-ms-dos-executable', From 96f194c0f6038444aae4270d2481a2ee1ccd7691 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 23 Jan 2014 03:06:14 +0100 Subject: [PATCH 053/119] Add icons for mdb and accdb files. --- lib/private/helper.php | 1 + lib/private/mimetypes.list.php | 2 ++ 2 files changed, 3 insertions(+) diff --git a/lib/private/helper.php b/lib/private/helper.php index 90ef704c3cc..58bee9c6300 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -182,6 +182,7 @@ class OC_Helper { 'application/vnd.ms-excel.sheet.binary.macroEnabled.12' => 'x-office/spreadsheet', 'application/vnd.oasis.opendocument.spreadsheet' => 'x-office/spreadsheet', 'application/vnd.oasis.opendocument.spreadsheet-template' => 'x-office/spreadsheet', + 'application/msaccess' => 'database', ); if (isset($alias[$mimetype])) { diff --git a/lib/private/mimetypes.list.php b/lib/private/mimetypes.list.php index 1ad333b5084..40fb1d2d97d 100644 --- a/lib/private/mimetypes.list.php +++ b/lib/private/mimetypes.list.php @@ -24,6 +24,7 @@ * Array mapping file extensions to mimetypes (in alphabetical order). */ return array( + 'accdb'=>'application/msaccess', 'ai' => 'application/illustrator', 'avi'=>'video/x-msvideo', 'bash' => 'text/x-shellscript', @@ -60,6 +61,7 @@ return array( 'markdown' => 'text/markdown', 'mdown' => 'text/markdown', 'md' => 'text/markdown', + 'mdb'=>'application/msaccess', 'mdwn' => 'text/markdown', 'mobi' => 'application/x-mobipocket-ebook', 'mov'=>'video/quicktime', From 4b7dfd34f8adb5db9b7e67206da384973ebdc767 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Thu, 23 Jan 2014 13:51:51 +0100 Subject: [PATCH 054/119] fix conflicts and add missing closing tag --- apps/files_sharing/css/public.css | 8 -------- apps/files_sharing/templates/public.php | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css index 7bcafd542ca..a5762799ac4 100644 --- a/apps/files_sharing/css/public.css +++ b/apps/files_sharing/css/public.css @@ -105,11 +105,3 @@ thead{ margin-left: 5px; width: 300px; } - -/*.directLink label {*/ - /*font-weight: normal;*/ -/*}*/ -/*.directLink input {*/ - /*margin-left: 10px;*/ - /*width: 300px;*/ -/*}*/ diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index fd0e0ad6412..f8a31005cdf 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -16,7 +16,7 @@
    t('shared by %s', array($_['displayName']))) ?>
    - +
    From 799e744ad77c3f8ae7aac63125a3af17880bb9d5 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Thu, 23 Jan 2014 15:35:30 +0100 Subject: [PATCH 055/119] remove background and width from multiselect bar, fix Download button not showing on mobile --- apps/files/css/files.css | 1 - apps/files_sharing/css/public.css | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index eb009cf0a14..74e625f371d 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -145,7 +145,6 @@ table.multiselect thead th { } table.multiselect #headerName { position: relative; - width: 100%; } table td.selection, table th.selection, table td.fileaction { width:2em; text-align:center; } table td.filename a.name { diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css index a5762799ac4..a3bc36dcc76 100644 --- a/apps/files_sharing/css/public.css +++ b/apps/files_sharing/css/public.css @@ -72,9 +72,8 @@ p.info a { max-width:100%; } -thead{ - background-color: white; - padding-left:0 !important; /* fixes multiselect bar offset on shared page */ +thead { + padding-left: 0 !important; /* fixes multiselect bar offset on shared page */ } #data-upload-form { From 5ad28f4d1ff952c17f3ca13c8ea7e2e118965846 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 27 Nov 2013 12:46:12 +0100 Subject: [PATCH 056/119] Allow getting info or renaming part files through WebDAV When mounting an ownCloud (backend OC) inside another ownCloud (frontend OC), the frontend OC will use WebDAV to upload file, which will create part files. These part files need to be accessible for the frontend OC to rename them to the actual file name. This fix leaves the file cache untouched but gives direct access to part file info when requested. This means that part file can be accessed only when their path and name are known. These won't appear in file listtings. Fixes #6068 --- lib/private/connector/sabre/objecttree.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php index cd3f081f7cc..d1e179af2ec 100644 --- a/lib/private/connector/sabre/objecttree.php +++ b/lib/private/connector/sabre/objecttree.php @@ -38,7 +38,20 @@ class ObjectTree extends \Sabre_DAV_ObjectTree { return $this->rootNode; } - $info = $this->getFileView()->getFileInfo($path); + if (pathinfo($path, PATHINFO_EXTENSION) === 'part') { + // read from storage + $absPath = $this->getFileView()->getAbsolutePath($path); + list($storage, $internalPath) = Filesystem::resolvePath('/' . $absPath); + if ($storage) { + $scanner = $storage->getScanner($internalPath); + // get data directly + $info = $scanner->getData($internalPath); + } + } + else { + // read from cache + $info = $this->getFileView()->getFileInfo($path); + } if (!$info) { throw new \Sabre_DAV_Exception_NotFound('File with name ' . $path . ' could not be located'); From 617aa3cf29955a23eed2ececc8e1876d77002223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 23 Jan 2014 20:15:10 +0100 Subject: [PATCH 057/119] Instead of 'No preview available for ...' we simple display the mieme-type icon --- apps/files_sharing/js/public.js | 9 +-------- apps/files_sharing/templates/public.php | 20 ++++++++------------ 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js index d95f6348ac0..730649c6378 100644 --- a/apps/files_sharing/js/public.js +++ b/apps/files_sharing/js/public.js @@ -15,14 +15,7 @@ $(document).ready(function() { if (mimetype.substr(0, mimetype.indexOf('/')) != 'image' && $('.publicpreview').length === 0) { // Trigger default action if not download TODO var action = FileActions.getDefault(mimetype, 'file', OC.PERMISSION_READ); - if (typeof action === 'undefined') { - $('#noPreview').show(); - if (mimetype != 'httpd/unix-directory') { - // NOTE: Remove when a better file previewer solution exists - $('#content').remove(); - $('table').remove(); - } - } else { + if (typeof action !== 'undefined') { action($('#filename').val()); } } diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index f8a31005cdf..652cd74eaff 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -32,16 +32,10 @@
    - +
    - -
      -
    • - t('No preview available for').' '.$_['filename']); ?>
      -
    • -
    -
    -

    - getLongFooter()); ?> -

    -
    + + +
    +

    + getLongFooter()); ?> +

    +
    From 41b6d4b702e8ed32f7ea51edffd0005639f77138 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 24 Jan 2014 12:44:31 +0100 Subject: [PATCH 058/119] Added OC.buidQueryString() utility function Makes it possible to create query strings by passing a JavaScript hash map and automatically encodes the keys and values. --- core/js/js.js | 28 +++++++++++++++++++++++++ core/js/tests/specs/coreSpec.js | 37 +++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/core/js/js.js b/core/js/js.js index e84f482d672..976027dd06b 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -364,6 +364,34 @@ var OC={ } return result; }, + + /** + * Builds a URL query from a JS map. + * @param params parameter map + * @return string containing a URL query (without question) mark + */ + buildQueryString: function(params) { + var s = ''; + var first = true; + if (!params) { + return s; + } + for (var key in params) { + var value = params[key]; + if (first) { + first = false; + } + else { + s += '&'; + } + s += encodeURIComponent(key); + if (value !== null && typeof(value) !== 'undefined') { + s += '=' + encodeURIComponent(value); + } + } + return s; + }, + /** * Opens a popup with the setting for an app. * @param appid String. The ID of the app e.g. 'calendar', 'contacts' or 'files'. diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js index 827669f270b..28c20a0642e 100644 --- a/core/js/tests/specs/coreSpec.js +++ b/core/js/tests/specs/coreSpec.js @@ -67,4 +67,41 @@ describe('Core base tests', function() { }); }); }); + describe('Query string building', function() { + it('Returns empty string when empty params', function() { + expect(OC.buildQueryString()).toEqual(''); + expect(OC.buildQueryString({})).toEqual(''); + }); + it('Encodes regular query strings', function() { + expect(OC.buildQueryString({ + a: 'abc', + b: 'def' + })).toEqual('a=abc&b=def'); + }); + it('Encodes special characters', function() { + expect(OC.buildQueryString({ + unicode: '汉字', + })).toEqual('unicode=%E6%B1%89%E5%AD%97'); + expect(OC.buildQueryString({ + b: 'spaace value', + 'space key': 'normalvalue', + 'slash/this': 'amp&ersand' + })).toEqual('b=spaace%20value&space%20key=normalvalue&slash%2Fthis=amp%26ersand'); + }); + it('Encodes data types and empty values', function() { + expect(OC.buildQueryString({ + 'keywithemptystring': '', + 'keywithnull': null, + 'keywithundefined': null, + something: 'else' + })).toEqual('keywithemptystring=&keywithnull&keywithundefined&something=else'); + expect(OC.buildQueryString({ + 'booleanfalse': false, + 'booleantrue': true + })).toEqual('booleanfalse=false&booleantrue=true'); + expect(OC.buildQueryString({ + 'number': 123, + })).toEqual('number=123'); + }); + }); }); From 0671c58e361f2ccf2cd23d73a9712c1a31e838ce Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 24 Jan 2014 13:19:44 +0100 Subject: [PATCH 059/119] Fixed filelist unit tests hidden params Also added dummy table --- apps/files/tests/js/filelistSpec.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js index 6b28a02989e..be848e0e0b0 100644 --- a/apps/files/tests/js/filelistSpec.js +++ b/apps/files/tests/js/filelistSpec.js @@ -21,11 +21,14 @@ describe('FileList tests', function() { beforeEach(function() { // init horrible parameters - $('').append('body'); - $('').append('body'); + var $body = $('body'); + $body.append(''); + $body.append(''); + // dummy files table + $body.append('
    '); }); afterEach(function() { - $('#dir, #permissions').remove(); + $('#dir, #permissions, #filestable').remove(); }); it('generates file element with correct attributes when calling addFile', function() { var lastMod = new Date(10000); @@ -36,7 +39,7 @@ describe('FileList tests', function() { expect($tr.attr('data-type')).toEqual('file'); expect($tr.attr('data-file')).toEqual('testName.txt'); expect($tr.attr('data-size')).toEqual('1234'); - //expect($tr.attr('data-permissions')).toEqual('31'); + expect($tr.attr('data-permissions')).toEqual('31'); //expect($tr.attr('data-mime')).toEqual('plain/text'); }); it('generates dir element with correct attributes when calling addDir', function() { @@ -48,7 +51,7 @@ describe('FileList tests', function() { expect($tr.attr('data-type')).toEqual('dir'); expect($tr.attr('data-file')).toEqual('testFolder'); expect($tr.attr('data-size')).toEqual('1234'); - //expect($tr.attr('data-permissions')).toEqual('31'); + expect($tr.attr('data-permissions')).toEqual('31'); //expect($tr.attr('data-mime')).toEqual('httpd/unix-directory'); }); }); From c6695bbd764be9f43067c09894e36422c2b92b49 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 24 Jan 2014 13:32:31 +0100 Subject: [PATCH 060/119] Fixed download URL in public page - Refactored download URL building to make it overridable - Added download URL override in public page - Added JS unit tests for download URL - Added OC.redirect() method to facilitate unit testing --- apps/files/js/fileactions.js | 5 ++- apps/files/js/filelist.js | 14 ++++++ apps/files/tests/js/fileactionsSpec.js | 61 ++++++++++++++++++++++++++ apps/files/tests/js/filelistSpec.js | 6 +++ apps/files_sharing/js/public.js | 16 +++---- core/js/js.js | 6 +++ 6 files changed, 98 insertions(+), 10 deletions(-) create mode 100644 apps/files/tests/js/fileactionsSpec.js diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js index 74bb711ef3d..eb59e71a030 100644 --- a/apps/files/js/fileactions.js +++ b/apps/files/js/fileactions.js @@ -173,7 +173,10 @@ $(document).ready(function () { FileActions.register(downloadScope, 'Download', OC.PERMISSION_READ, function () { return OC.imagePath('core', 'actions/download'); }, function (filename) { - window.location = OC.filePath('files', 'ajax', 'download.php') + '?files=' + encodeURIComponent(filename) + '&dir=' + encodeURIComponent($('#dir').val()); + var url = FileList.getDownloadUrl(filename); + if (url) { + OC.redirect(url); + } }); } $('#fileList tr').each(function () { diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 66968ab54c7..63fd0f4ce05 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -780,6 +780,20 @@ var FileList={ $('#fileList tr.searchresult').each(function(i,e) { $(e).removeClass("searchresult"); }); + }, + + /** + * Returns the download URL of the given file + * @param filename file name of the file + * @param dir optional directory in which the file name is, defaults to the current directory + */ + getDownloadUrl: function(filename, dir) { + var params = { + files: filename, + dir: dir || FileList.getCurrentDirectory(), + download: null + }; + return OC.filePath('files', 'ajax', 'download.php') + '?' + OC.buildQueryString(params); } }; diff --git a/apps/files/tests/js/fileactionsSpec.js b/apps/files/tests/js/fileactionsSpec.js new file mode 100644 index 00000000000..23f7b58dcd9 --- /dev/null +++ b/apps/files/tests/js/fileactionsSpec.js @@ -0,0 +1,61 @@ +/** +* ownCloud +* +* @author Vincent Petry +* @copyright 2014 Vincent Petry +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +* License as published by the Free Software Foundation; either +* version 3 of the License, or any later version. +* +* This library 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 library. If not, see . +* +*/ +describe('FileActions tests', function() { + beforeEach(function() { + // init horrible parameters + var $body = $('body'); + $body.append(''); + $body.append(''); + // dummy files table + $filesTable = $body.append('
    '); + }); + afterEach(function() { + $('#dir, #permissions, #filestable').remove(); + }); + it('calling display() sets file actions', function() { + // note: download_url is actually the link target, not the actual download URL... + var $tr = FileList.addFile('testName.txt', 1234, new Date(), false, false, {download_url: 'test/download/url'}); + + // no actions before call + expect($tr.find('.action[data-action=Download]').length).toEqual(0); + expect($tr.find('.action[data-action=Rename]').length).toEqual(0); + expect($tr.find('.action.delete').length).toEqual(0); + + FileActions.display($tr.find('td.filename'), true); + + // actions defined after cal + expect($tr.find('.action[data-action=Download]').length).toEqual(1); + expect($tr.find('.action[data-action=Rename]').length).toEqual(1); + expect($tr.find('.action.delete').length).toEqual(1); + }); + it('redirects to download URL when clicking download', function() { + var redirectStub = sinon.stub(OC, 'redirect'); + // note: download_url is actually the link target, not the actual download URL... + var $tr = FileList.addFile('test download File.txt', 1234, new Date(), false, false, {download_url: 'test/download/url'}); + FileActions.display($tr.find('td.filename'), true); + + $tr.find('.action[data-action=Download]').click(); + + expect(redirectStub.calledOnce).toEqual(true); + expect(redirectStub.getCall(0).args[0]).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?files=test%20download%20File.txt&dir=%2Fsubdir&download'); + redirectStub.restore(); + }); +}); diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js index be848e0e0b0..61e026c0725 100644 --- a/apps/files/tests/js/filelistSpec.js +++ b/apps/files/tests/js/filelistSpec.js @@ -32,10 +32,12 @@ describe('FileList tests', function() { }); it('generates file element with correct attributes when calling addFile', function() { var lastMod = new Date(10000); + // note: download_url is actually the link target, not the actual download URL... var $tr = FileList.addFile('testName.txt', 1234, lastMod, false, false, {download_url: 'test/download/url'}); expect($tr).toBeDefined(); expect($tr[0].tagName.toLowerCase()).toEqual('tr'); + expect($tr.find('a:first').attr('href')).toEqual('test/download/url'); expect($tr.attr('data-type')).toEqual('file'); expect($tr.attr('data-file')).toEqual('testName.txt'); expect($tr.attr('data-size')).toEqual('1234'); @@ -54,4 +56,8 @@ describe('FileList tests', function() { expect($tr.attr('data-permissions')).toEqual('31'); //expect($tr.attr('data-mime')).toEqual('httpd/unix-directory'); }); + it('returns correct download URL', function() { + expect(FileList.getDownloadUrl('some file.txt')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?files=some%20file.txt&dir=%2Fsubdir&download'); + expect(FileList.getDownloadUrl('some file.txt', '/anotherpath/abc')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?files=some%20file.txt&dir=%2Fanotherpath%2Fabc&download'); + }); }); diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js index 4c0b0ad9d48..79c15623c0c 100644 --- a/apps/files_sharing/js/public.js +++ b/apps/files_sharing/js/public.js @@ -34,18 +34,16 @@ $(document).ready(function() { window.location = $(tr).find('a.name').attr('href'); } }); - FileActions.register('file', 'Download', OC.PERMISSION_READ, '', function(filename) { + + // override since the format is different + FileList.getDownloadUrl = function(filename, dir) { + // we use this because we need the service and token attributes var tr = FileList.findFileEl(filename); if (tr.length > 0) { - window.location = $(tr).find('a.name').attr('href'); + return $(tr).find('a.name').attr('href') + '&download'; } - }); - FileActions.register('dir', 'Download', OC.PERMISSION_READ, '', function(filename) { - var tr = FileList.findFileEl(filename); - if (tr.length > 0) { - window.location = $(tr).find('a.name').attr('href')+'&download'; - } - }); + return null; + }; } var file_upload_start = $('#file_upload_start'); diff --git a/core/js/js.js b/core/js/js.js index 976027dd06b..1c7d89ea055 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -252,6 +252,12 @@ var OC={ } return link; }, + /** + * Redirect to the target URL, can also be used for downloads. + */ + redirect: function(targetUrl) { + window.location = targetUrl; + }, /** * get the absolute path to an image file * @param app the app id to which the image belongs From 19675c2c9de3580c32ee24b22b8ded11dc110b1c Mon Sep 17 00:00:00 2001 From: Pellaeon Lin Date: Fri, 24 Jan 2014 22:54:16 +0800 Subject: [PATCH 061/119] Fix variable name --- apps/files/js/file-upload.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index a003e5eec86..0d7df31f355 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -246,8 +246,8 @@ $(document).ready(function() { if (selection.totalBytes > $('#free_space').val()) { data.textStatus = 'notenoughspace'; data.errorThrown = t('files', 'Not enough free space, you are uploading {size1} but only {size2} is left', { - '{size1}': humanFileSize(selection.totalBytes), - '{size2}': humanFileSize($('#free_space').val()) + 'size1': humanFileSize(selection.totalBytes), + 'size2': humanFileSize($('#free_space').val()) }); } From 1ab7ca0a19d5f3984e87f99945d81aecffbbae19 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 24 Jan 2014 16:01:19 +0100 Subject: [PATCH 062/119] Fix some phpdoc errors and rename interface --- lib/private/memcache/factory.php | 4 +++- lib/public/{cachefactory.php => icachefactory.php} | 8 +++++--- lib/public/iservercontainer.php | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) rename lib/public/{cachefactory.php => icachefactory.php} (64%) diff --git a/lib/private/memcache/factory.php b/lib/private/memcache/factory.php index 48c97b59551..334cf9a1f0e 100644 --- a/lib/private/memcache/factory.php +++ b/lib/private/memcache/factory.php @@ -8,7 +8,9 @@ namespace OC\Memcache; -class Factory { +use \OCP\ICacheFactory; + +class Factory implements ICacheFactory { /** * @var string $globalPrefix */ diff --git a/lib/public/cachefactory.php b/lib/public/icachefactory.php similarity index 64% rename from lib/public/cachefactory.php rename to lib/public/icachefactory.php index 1bb0ea3dd51..874f1ec0a59 100644 --- a/lib/public/cachefactory.php +++ b/lib/public/icachefactory.php @@ -8,17 +8,19 @@ namespace OCP; -interface CacheFactory{ +interface ICacheFactory{ /** * Get a memory cache instance * + * All entries added trough the cache instance will be namespaced by $prefix to prevent collisions between apps + * * @param string $prefix - * @return $return \OCP\ICache + * @return \OCP\ICache */ public function create($prefix = ''); /** - * Check if a memory cache backend is available + * Check if any memory cache backend is available * * @return bool */ diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php index 67884bdc3e4..5473f3ee334 100644 --- a/lib/public/iservercontainer.php +++ b/lib/public/iservercontainer.php @@ -144,7 +144,7 @@ interface IServerContainer { /** * Returns an \OCP\CacheFactory instance * - * @return \OCP\CacheFactory + * @return \OCP\ICacheFactory */ function getMemCacheFactory(); From c767ebcc03c604f3141af4c286ad099fdf64c561 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Fri, 24 Jan 2014 18:20:52 +0100 Subject: [PATCH 063/119] fix multiselect bar being too short on big displays --- apps/files/css/files.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 74e625f371d..1c48d61c4e8 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -103,7 +103,7 @@ table td { } table th#headerName { position: relative; - width: 100em; /* not really sure why this works better than 100% … table styling */ + width: 9999px; /* not really sure why this works better than 100% … table styling */ padding: 0; } #headerName-container { @@ -145,6 +145,7 @@ table.multiselect thead th { } table.multiselect #headerName { position: relative; + width: 9999px; /* when we use 100%, the styling breaks on mobile … table styling */ } table td.selection, table th.selection, table td.fileaction { width:2em; text-align:center; } table td.filename a.name { From c2ed8d5aa111ac537cf37bbf0d60fd503a62c24a Mon Sep 17 00:00:00 2001 From: Martial Saunois Date: Sun, 26 Jan 2014 18:46:09 +0100 Subject: [PATCH 064/119] New user agent added for the Freebox. The Freebox is the multimedia device of a french Internet provider: Free. This device provides a seedbox which uses the user agent "Mozilla/5.0". In the "Content-Disposition" header, if the "filename" key is used with the "filename*=UTF-8''" value, the seedbox does not take care about the header and saves the file name with the origin URL. This patch brings the support for the Freebox users. --- lib/private/request.php | 1 + lib/private/response.php | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/private/request.php b/lib/private/request.php index d9d5ae08e28..855148ac25a 100755 --- a/lib/private/request.php +++ b/lib/private/request.php @@ -11,6 +11,7 @@ class OC_Request { const USER_AGENT_IE = '/MSIE/'; // Android Chrome user agent: https://developers.google.com/chrome/mobile/docs/user-agent const USER_AGENT_ANDROID_MOBILE_CHROME = '#Android.*Chrome/[.0-9]*#'; + const USER_AGENT_FREEBOX = '#Mozilla/5\.0$#'; /** * @brief Check overwrite condition diff --git a/lib/private/response.php b/lib/private/response.php index 04746437347..52dbb9d90f8 100644 --- a/lib/private/response.php +++ b/lib/private/response.php @@ -153,7 +153,11 @@ class OC_Response { * @param string $type disposition type, either 'attachment' or 'inline' */ static public function setContentDispositionHeader( $filename, $type = 'attachment' ) { - if (OC_Request::isUserAgent(array(OC_Request::USER_AGENT_IE, OC_Request::USER_AGENT_ANDROID_MOBILE_CHROME))) { + if (OC_Request::isUserAgent(array( + OC_Request::USER_AGENT_IE, + OC_Request::USER_AGENT_ANDROID_MOBILE_CHROME, + OC_Request::USER_AGENT_FREEBOX + ))) { header( 'Content-Disposition: ' . rawurlencode($type) . '; filename="' . rawurlencode( $filename ) . '"' ); } else { header( 'Content-Disposition: ' . rawurlencode($type) . '; filename*=UTF-8\'\'' . rawurlencode( $filename ) From 11ef12a1060f3e34312ae40c690f95765d7c5f89 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Thu, 23 Jan 2014 12:11:53 +0100 Subject: [PATCH 065/119] Added exception logger plugin for sabre connector Whenever an exception occurs in the sabre connector code or code called by it, it will be logged. This plugin approach is needed because Sabre already catches exceptions to return them to the client in the XML response, so they don't appear logged in the web server log. This will make it much easier to debug syncing issues. --- apps/files/appinfo/remote.php | 1 + .../connector/sabre/exceptionloggerplugin.php | 50 +++++++++++++++++++ lib/private/connector/sabre/file.php | 6 +-- lib/public/util.php | 8 ++- 4 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 lib/private/connector/sabre/exceptionloggerplugin.php diff --git a/apps/files/appinfo/remote.php b/apps/files/appinfo/remote.php index 9f290796205..ef22fe92188 100644 --- a/apps/files/appinfo/remote.php +++ b/apps/files/appinfo/remote.php @@ -52,6 +52,7 @@ $server->addPlugin(new OC_Connector_Sabre_FilesPlugin()); $server->addPlugin(new OC_Connector_Sabre_AbortedUploadDetectionPlugin()); $server->addPlugin(new OC_Connector_Sabre_QuotaPlugin()); $server->addPlugin(new OC_Connector_Sabre_MaintenancePlugin()); +$server->addPlugin(new OC_Connector_Sabre_ExceptionLoggerPlugin('webdav')); // And off we go! $server->exec(); diff --git a/lib/private/connector/sabre/exceptionloggerplugin.php b/lib/private/connector/sabre/exceptionloggerplugin.php new file mode 100644 index 00000000000..8e77afaf207 --- /dev/null +++ b/lib/private/connector/sabre/exceptionloggerplugin.php @@ -0,0 +1,50 @@ + + * + * @license AGPL3 + */ + +class OC_Connector_Sabre_ExceptionLoggerPlugin extends Sabre_DAV_ServerPlugin +{ + private $appName; + + /** + * @param string $loggerAppName app name to use when logging + */ + public function __construct($loggerAppName = 'webdav') { + $this->appName = $loggerAppName; + } + + /** + * This initializes the plugin. + * + * This function is called by Sabre_DAV_Server, after + * addPlugin is called. + * + * This method should set up the required event subscriptions. + * + * @param Sabre_DAV_Server $server + * @return void + */ + public function initialize(Sabre_DAV_Server $server) { + + $server->subscribeEvent('exception', array($this, 'logException'), 10); + } + + /** + * Log exception + * + * @internal param Exception $e exception + */ + public function logException($e) { + $exceptionClass = get_class($e); + if ($exceptionClass !== 'Sabre_DAV_Exception_NotAuthenticated') { + \OCP\Util::logException($this->appName, $e); + } + } +} diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php index c3b59007295..ed27cef440d 100644 --- a/lib/private/connector/sabre/file.php +++ b/lib/private/connector/sabre/file.php @@ -79,7 +79,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D \OC_Log::write('webdav', '\OC\Files\Filesystem::file_put_contents() failed', \OC_Log::ERROR); $fs->unlink($partpath); // because we have no clue about the cause we can only throw back a 500/Internal Server Error - throw new Sabre_DAV_Exception(); + throw new Sabre_DAV_Exception('Could not write file contents'); } } catch (\OCP\Files\NotPermittedException $e) { // a more general case - due to whatever reason the content could not be written @@ -105,7 +105,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D if ($renameOkay === false || $fileExists === false) { \OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR); $fs->unlink($partpath); - throw new Sabre_DAV_Exception(); + throw new Sabre_DAV_Exception('Could not rename part file to final file'); } // allow sync clients to send the mtime along in a header @@ -246,7 +246,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D if ($fileExists) { $fs->unlink($targetPath); } - throw new Sabre_DAV_Exception(); + throw new Sabre_DAV_Exception('Could not rename part file assembled from chunks'); } // allow sync clients to send the mtime along in a header diff --git a/lib/public/util.php b/lib/public/util.php index 8e85f9afc3f..e893a76d811 100644 --- a/lib/public/util.php +++ b/lib/public/util.php @@ -88,14 +88,18 @@ class Util { * @param Exception $ex exception to log */ public static function logException( $app, \Exception $ex ) { - $message = $ex->getMessage(); + $class = get_class($ex); + if ($class !== 'Exception') { + $message = $class . ': '; + } + $message .= $ex->getMessage(); if ($ex->getCode()) { $message .= ' [' . $ex->getCode() . ']'; } \OCP\Util::writeLog($app, 'Exception: ' . $message, \OCP\Util::FATAL); if (defined('DEBUG') and DEBUG) { // also log stack trace - $stack = explode('#', $ex->getTraceAsString()); + $stack = explode("\n", $ex->getTraceAsString()); // first element is empty array_shift($stack); foreach ($stack as $s) { From 2bb13a8db96f8e17d04274b77f5062dca0df5b0e Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 27 Jan 2014 12:47:54 +0100 Subject: [PATCH 066/119] use localised date in notification mails --- core/ajax/share.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/core/ajax/share.php b/core/ajax/share.php index 268cd4f53a7..8b48effb458 100644 --- a/core/ajax/share.php +++ b/core/ajax/share.php @@ -121,7 +121,7 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo if (isset($items[0]['expiration'])) { try { $date = new DateTime($items[0]['expiration']); - $expiration = $date->format('Y-m-d'); + $expiration = $l->l('date', $date->getTimestamp()); } catch (Exception $e) { \OCP\Util::writeLog('sharing', "Couldn't read date: " . $e->getMessage(), \OCP\Util::ERROR); } @@ -187,6 +187,8 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo break; case 'email': + // enable l10n support + $l = OC_L10N::get('core'); // read post variables $user = OCP\USER::getUser(); $displayName = OCP\User::getDisplayName(); @@ -199,16 +201,13 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo if (isset($_POST['expiration']) && $_POST['expiration'] !== '') { try { $date = new DateTime($_POST['expiration']); - $expiration = $date->format('Y-m-d'); + $expiration = $l->l('date', $date->getTimestamp()); } catch (Exception $e) { \OCP\Util::writeLog('sharing', "Couldn't read date: " . $e->getMessage(), \OCP\Util::ERROR); } } - // enable l10n support - $l = OC_L10N::get('core'); - // setup the email $subject = (string)$l->t('%s shared »%s« with you', array($displayName, $file)); From b590f019f66c6b540edcf90c35092bf389619c87 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 27 Jan 2014 16:51:32 +0100 Subject: [PATCH 067/119] Remove unused $freeSpace --- apps/files/index.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/files/index.php b/apps/files/index.php index 8f6838aa0d9..2ce8fdb065f 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -63,7 +63,6 @@ $files = array(); $user = OC_User::getUser(); if (\OC\Files\Cache\Upgrade::needUpgrade($user)) { //dont load anything if we need to upgrade the cache $needUpgrade = true; - $freeSpace = 0; } else { if ($isIE8){ // after the redirect above, the URL will have a format @@ -77,7 +76,6 @@ if (\OC\Files\Cache\Upgrade::needUpgrade($user)) { //dont load anything if we ne else{ $files = \OCA\Files\Helper::getFiles($dir); } - $freeSpace = \OC\Files\Filesystem::free_space($dir); $needUpgrade = false; } From 7f83f2a8f2e6e3f280c3562ebdbeae9331ab5f01 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 28 Jan 2014 11:25:12 +0100 Subject: [PATCH 068/119] use more accurate error codes --- apps/files_sharing/lib/api.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/files_sharing/lib/api.php b/apps/files_sharing/lib/api.php index 84e90c71681..cb3d3e42c34 100644 --- a/apps/files_sharing/lib/api.php +++ b/apps/files_sharing/lib/api.php @@ -162,7 +162,7 @@ class Api { $view = new \OC\Files\View('/'.\OCP\User::getUser().'/files'); if(!$view->is_dir($path)) { - return new \OC_OCS_Result(null, 404, "not a directory"); + return new \OC_OCS_Result(null, 400, "not a directory"); } $content = $view->getDirectoryContent($path); @@ -223,7 +223,7 @@ class Api { $encryptionEnabled = \OC_App::isEnabled('files_encryption'); if(isset($_POST['publicUpload']) && ($encryptionEnabled || $publicUploadEnabled !== 'yes')) { - return new \OC_OCS_Result(null, 404, "public upload disabled by the administrator"); + return new \OC_OCS_Result(null, 403, "public upload disabled by the administrator"); } $publicUpload = isset($_POST['publicUpload']) ? $_POST['publicUpload'] : 'false'; // read, create, update (7) if public upload is enabled or @@ -231,7 +231,7 @@ class Api { $permissions = $publicUpload === 'true' ? 7 : 1; break; default: - return new \OC_OCS_Result(null, 404, "unknown share type"); + return new \OC_OCS_Result(null, 400, "unknown share type"); } try { @@ -243,7 +243,7 @@ class Api { $permissions ); } catch (\Exception $e) { - return new \OC_OCS_Result(null, 404, $e->getMessage()); + return new \OC_OCS_Result(null, 403, $e->getMessage()); } if ($token) { @@ -365,7 +365,7 @@ class Api { $publicUploadEnabled = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); $encryptionEnabled = \OC_App::isEnabled('files_encryption'); if($encryptionEnabled || $publicUploadEnabled !== 'yes') { - return new \OC_OCS_Result(null, 404, "public upload disabled by the administrator"); + return new \OC_OCS_Result(null, 403, "public upload disabled by the administrator"); } if ($share['item_type'] !== 'folder' || From cd4e044f66c62fc070b48fea40f9a96585f93269 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 28 Jan 2014 17:28:20 +0100 Subject: [PATCH 069/119] public upload is also possible with encryption enabled, since OC6 --- apps/files_sharing/lib/api.php | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/apps/files_sharing/lib/api.php b/apps/files_sharing/lib/api.php index cb3d3e42c34..f828a4e840d 100644 --- a/apps/files_sharing/lib/api.php +++ b/apps/files_sharing/lib/api.php @@ -220,9 +220,7 @@ class Api { $shareWith = isset($_POST['password']) ? $_POST['password'] : null; //check public link share $publicUploadEnabled = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); - $encryptionEnabled = \OC_App::isEnabled('files_encryption'); - if(isset($_POST['publicUpload']) && - ($encryptionEnabled || $publicUploadEnabled !== 'yes')) { + if(isset($_POST['publicUpload']) && $publicUploadEnabled !== 'yes') { return new \OC_OCS_Result(null, 403, "public upload disabled by the administrator"); } $publicUpload = isset($_POST['publicUpload']) ? $_POST['publicUpload'] : 'false'; @@ -321,11 +319,8 @@ class Api { $permissions = isset($params['_put']['permissions']) ? (int)$params['_put']['permissions'] : null; $publicUploadStatus = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); - $encryptionEnabled = \OC_App::isEnabled('files_encryption'); - $publicUploadEnabled = false; - if(!$encryptionEnabled && $publicUploadStatus === 'yes') { - $publicUploadEnabled = true; - } + $publicUploadEnabled = ($publicUploadStatus === 'yes') ? true : false; + // only change permissions for public shares if public upload is enabled // and we want to set permissions to 1 (read only) or 7 (allow upload) @@ -363,8 +358,7 @@ class Api { private static function updatePublicUpload($share, $params) { $publicUploadEnabled = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); - $encryptionEnabled = \OC_App::isEnabled('files_encryption'); - if($encryptionEnabled || $publicUploadEnabled !== 'yes') { + if($publicUploadEnabled !== 'yes') { return new \OC_OCS_Result(null, 403, "public upload disabled by the administrator"); } From 8507efc4273aa87e32090bcabb31b7bc5b98ec35 Mon Sep 17 00:00:00 2001 From: Martial Saunois Date: Tue, 28 Jan 2014 21:08:27 +0100 Subject: [PATCH 070/119] Unit tests added for the new Freebox user agent. --- tests/lib/request.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/lib/request.php b/tests/lib/request.php index c6401a57144..3cb58674d3e 100644 --- a/tests/lib/request.php +++ b/tests/lib/request.php @@ -118,6 +118,16 @@ class Test_Request extends PHPUnit_Framework_TestCase { ), true ), + array( + 'Mozilla/5.0 (X11; Linux i686; rv:24.0) Gecko/20100101 Firefox/24.0', + OC_Request::USER_AGENT_FREEBOX, + false + ), + array( + 'Mozilla/5.0', + OC_Request::USER_AGENT_FREEBOX, + true + ), ); } } From e6f93fc84140931d13c8e77b12fd6ec53a04457a Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 29 Jan 2014 10:43:13 +0100 Subject: [PATCH 071/119] Fix warnings in logs when renaming over the web UI The determineIcon() method was expecting attributes to be set which caused warnings about undefined indices in the error log. This fix pre-initializes the array with 'directory' and 'isPreviewAvailable' to make them disappear. --- apps/files/lib/app.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/files/lib/app.php b/apps/files/lib/app.php index e04ac173d55..1ac266073db 100644 --- a/apps/files/lib/app.php +++ b/apps/files/lib/app.php @@ -83,14 +83,17 @@ class App { else { $meta['type'] = 'file'; } + // these need to be set for determineIcon() + $meta['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($meta['mimetype']); + $meta['directory'] = $dir; $fileinfo = array( 'id' => $meta['fileid'], 'mime' => $meta['mimetype'], 'size' => $meta['size'], 'etag' => $meta['etag'], - 'directory' => $dir, + 'directory' => $meta['directory'], 'name' => $newname, - 'isPreviewAvailable' => \OC::$server->getPreviewManager()->isMimeSupported($meta['mimetype']), + 'isPreviewAvailable' => $meta['isPreviewAvailable'], 'icon' => \OCA\Files\Helper::determineIcon($meta) ); $result['success'] = true; From 0f1c587e6baaa201f01683b6adac8cc907c4f3e3 Mon Sep 17 00:00:00 2001 From: Martial Saunois Date: Wed, 29 Jan 2014 10:58:34 +0100 Subject: [PATCH 072/119] The regexp of the Freebox user agent is now more strict. A new unit test has been added in consequence. --- lib/private/request.php | 2 +- tests/lib/request.php | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/private/request.php b/lib/private/request.php index 855148ac25a..2c5b907846e 100755 --- a/lib/private/request.php +++ b/lib/private/request.php @@ -11,7 +11,7 @@ class OC_Request { const USER_AGENT_IE = '/MSIE/'; // Android Chrome user agent: https://developers.google.com/chrome/mobile/docs/user-agent const USER_AGENT_ANDROID_MOBILE_CHROME = '#Android.*Chrome/[.0-9]*#'; - const USER_AGENT_FREEBOX = '#Mozilla/5\.0$#'; + const USER_AGENT_FREEBOX = '#^Mozilla/5\.0$#'; /** * @brief Check overwrite condition diff --git a/tests/lib/request.php b/tests/lib/request.php index 3cb58674d3e..1d77acc70ae 100644 --- a/tests/lib/request.php +++ b/tests/lib/request.php @@ -128,6 +128,11 @@ class Test_Request extends PHPUnit_Framework_TestCase { OC_Request::USER_AGENT_FREEBOX, true ), + array( + 'Fake Mozilla/5.0', + OC_Request::USER_AGENT_FREEBOX, + false + ), ); } } From 8f81f007cd8189af0b3920c0c5cdf5b7e705c930 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Wed, 29 Jan 2014 11:06:19 +0100 Subject: [PATCH 073/119] fix horizontal scrollbar appearing when footer is too long, footer wraps now --- apps/files_sharing/css/public.css | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css index c50624e20b1..87e3ed78e1a 100644 --- a/apps/files_sharing/css/public.css +++ b/apps/files_sharing/css/public.css @@ -49,9 +49,8 @@ footer { p.info { color: #777; text-align: center; - width: 352px; margin: 0 auto; - padding: 20px; + padding: 20px 0; } p.info a { From d310df505c0de1ed0ba4067a0c8304b8a675fa8c Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Wed, 29 Jan 2014 11:43:34 +0100 Subject: [PATCH 074/119] permanently show download action on mobile, only icon --- apps/files/js/fileactions.js | 4 ++-- apps/files_sharing/css/mobile.css | 23 +++++++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js index eb59e71a030..d0ef2491bdf 100644 --- a/apps/files/js/fileactions.js +++ b/apps/files/js/fileactions.js @@ -103,9 +103,9 @@ var FileActions = { } var html = '
    '; if (img) { - html += ' '; + html += ''; } - html += t('files', name) + ''; + html += ' ' + t('files', name) + ''; var element = $(html); element.data('action', name); diff --git a/apps/files_sharing/css/mobile.css b/apps/files_sharing/css/mobile.css index 2118cd31e4b..3c06d0650e3 100644 --- a/apps/files_sharing/css/mobile.css +++ b/apps/files_sharing/css/mobile.css @@ -11,12 +11,7 @@ table td.date { /* restrict length of displayed filename to prevent overflow */ table td.filename .nametext { - max-width: 80% !important; -} -/* and to make room for download button on hover */ -table tr:hover td.filename .nametext, -table tr:focus td.filename .nametext { - max-width: 60% !important; + max-width: 75% !important; } /* on mobile, show single shared image at full width without margin */ @@ -26,5 +21,21 @@ table tr:focus td.filename .nametext { margin-bottom: 35px; } +/* always show actions on mobile */ +#fileList a.action { + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)" !important; + filter: alpha(opacity=20) !important; + opacity: .2 !important; + display: inline !important; +} +/* some padding for better clickability */ +#fileList a.action img { + padding: 0 6px 0 12px; +} +/* hide text of the actions on mobile */ +#fileList a.action span { + display: none; +} + } From 58c7042e708172b8e2fe252fc53abe87bcf8c1f1 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 22 Jan 2014 17:17:58 +0100 Subject: [PATCH 075/119] Added error message for when target folder was removed Whent trying to upload/rename/create files in a folder that was removed or rename, the correct error message is now shown. In the case of upload of multiple files, the upload is cancelled. This situation can happen if the target folder was renamed or removed from another browser window or client. --- apps/files/ajax/newfile.php | 9 ++++++ apps/files/ajax/newfolder.php | 9 ++++++ apps/files/ajax/upload.php | 6 ++-- apps/files/js/file-upload.js | 7 +++++ apps/files/lib/app.php | 7 +++++ apps/files/tests/ajax_rename.php | 49 ++++++++++++++++++++++++++++++-- 6 files changed, 83 insertions(+), 4 deletions(-) diff --git a/apps/files/ajax/newfile.php b/apps/files/ajax/newfile.php index ec5b716fb2a..1853098c507 100644 --- a/apps/files/ajax/newfile.php +++ b/apps/files/ajax/newfile.php @@ -64,6 +64,15 @@ if(strpos($filename, '/') !== false) { exit(); } +if (!\OC\Files\Filesystem::file_exists($dir . '/')) { + $result['data'] = array('message' => (string)$l10n->t( + 'The target folder has been moved or deleted.'), + 'code' => 'targetnotfound' + ); + OCP\JSON::error($result); + exit(); +} + //TODO why is stripslashes used on foldername in newfolder.php but not here? $target = $dir.'/'.$filename; diff --git a/apps/files/ajax/newfolder.php b/apps/files/ajax/newfolder.php index 2cbc8cfeba5..4cfcae3090d 100644 --- a/apps/files/ajax/newfolder.php +++ b/apps/files/ajax/newfolder.php @@ -29,6 +29,15 @@ if(strpos($foldername, '/') !== false) { exit(); } +if (!\OC\Files\Filesystem::file_exists($dir . '/')) { + $result['data'] = array('message' => (string)$l10n->t( + 'The target folder has been moved or deleted.'), + 'code' => 'targetnotfound' + ); + OCP\JSON::error($result); + exit(); +} + //TODO why is stripslashes used on foldername here but not in newfile.php? $target = $dir . '/' . stripslashes($foldername); diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php index bdaf6a77d14..8f6c42d6620 100644 --- a/apps/files/ajax/upload.php +++ b/apps/files/ajax/upload.php @@ -8,6 +8,7 @@ OCP\JSON::setContentTypeHeader('text/plain'); // If no token is sent along, rely on login only $allowedPermissions = OCP\PERMISSION_ALL; +$errorCode = null; $l = OC_L10N::get('files'); if (empty($_POST['dirToken'])) { @@ -125,7 +126,8 @@ if (strpos($dir, '..') === false) { $meta = \OC\Files\Filesystem::getFileInfo($target); if ($meta === false) { - $error = $l->t('Upload failed. Could not get file info.'); + $error = $l->t('The target folder has been moved or deleted.'); + $errorCode = 'targetnotfound'; } else { $result[] = array('status' => 'success', 'mime' => $meta['mimetype'], @@ -177,5 +179,5 @@ if ($error === false) { OCP\JSON::encodedPrint($result); exit(); } else { - OCP\JSON::error(array(array('data' => array_merge(array('message' => $error), $storageStats)))); + OCP\JSON::error(array(array('data' => array_merge(array('message' => $error, 'code' => $errorCode), $storageStats)))); } diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index 225c3319107..486273a910c 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -315,6 +315,13 @@ $(document).ready(function() { } else { // HTTP connection problem OC.Notification.show(data.errorThrown); + if (data.result) { + var result = JSON.parse(data.result); + if (result && result[0] && result[0].data && result[0].data.code === 'targetnotfound') { + // abort upload of next files if any + OC.Upload.cancelUploads(); + } + } } //hide notification after 10 sec setTimeout(function() { diff --git a/apps/files/lib/app.php b/apps/files/lib/app.php index 1ac266073db..fea88faa92a 100644 --- a/apps/files/lib/app.php +++ b/apps/files/lib/app.php @@ -59,6 +59,13 @@ class App { $result['data'] = array( 'message' => $this->l10n->t("Invalid folder name. Usage of 'Shared' is reserved.") ); + // rename to non-existing folder is denied + } else if (!$this->view->file_exists($dir)) { + $result['data'] = array('message' => (string)$this->l10n->t( + 'The target folder has been moved or deleted.', + array($dir)), + 'code' => 'targetnotfound' + ); // rename to existing file is denied } else if ($this->view->file_exists($dir . '/' . $newname)) { diff --git a/apps/files/tests/ajax_rename.php b/apps/files/tests/ajax_rename.php index 350ff5d3687..a1a5c8983ba 100644 --- a/apps/files/tests/ajax_rename.php +++ b/apps/files/tests/ajax_rename.php @@ -38,7 +38,7 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { $l10nMock->expects($this->any()) ->method('t') ->will($this->returnArgument(0)); - $viewMock = $this->getMock('\OC\Files\View', array('rename', 'normalizePath', 'getFileInfo'), array(), '', false); + $viewMock = $this->getMock('\OC\Files\View', array('rename', 'normalizePath', 'getFileInfo', 'file_exists'), array(), '', false); $viewMock->expects($this->any()) ->method('normalizePath') ->will($this->returnArgument(0)); @@ -63,6 +63,11 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { $oldname = 'Shared'; $newname = 'new_name'; + $this->viewMock->expects($this->at(0)) + ->method('file_exists') + ->with('/') + ->will($this->returnValue(true)); + $result = $this->files->rename($dir, $oldname, $newname); $expected = array( 'success' => false, @@ -80,6 +85,11 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { $oldname = 'Shared'; $newname = 'new_name'; + $this->viewMock->expects($this->at(0)) + ->method('file_exists') + ->with('/test') + ->will($this->returnValue(true)); + $this->viewMock->expects($this->any()) ->method('getFileInfo') ->will($this->returnValue(array( @@ -129,6 +139,11 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { $oldname = 'oldname'; $newname = 'newname'; + $this->viewMock->expects($this->at(0)) + ->method('file_exists') + ->with('/') + ->will($this->returnValue(true)); + $this->viewMock->expects($this->any()) ->method('getFileInfo') ->will($this->returnValue(array( @@ -141,7 +156,6 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { 'name' => 'new_name', ))); - $result = $this->files->rename($dir, $oldname, $newname); $this->assertTrue($result['success']); @@ -154,4 +168,35 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { $this->assertEquals(\OC_Helper::mimetypeIcon('dir'), $result['data']['icon']); $this->assertFalse($result['data']['isPreviewAvailable']); } + + /** + * Test rename inside a folder that doesn't exist any more + */ + function testRenameInNonExistingFolder() { + $dir = '/unexist'; + $oldname = 'oldname'; + $newname = 'newname'; + + $this->viewMock->expects($this->at(0)) + ->method('file_exists') + ->with('/unexist') + ->will($this->returnValue(false)); + + $this->viewMock->expects($this->any()) + ->method('getFileInfo') + ->will($this->returnValue(array( + 'fileid' => 123, + 'type' => 'dir', + 'mimetype' => 'httpd/unix-directory', + 'size' => 18, + 'etag' => 'abcdef', + 'directory' => '/unexist', + 'name' => 'new_name', + ))); + + $result = $this->files->rename($dir, $oldname, $newname); + + $this->assertFalse($result['success']); + $this->assertEquals('targetnotfound', $result['data']['code']); + } } From f798ad9a205ce43265e01e670f5a57611ee65711 Mon Sep 17 00:00:00 2001 From: jbtbnl Date: Wed, 29 Jan 2014 13:47:37 +0100 Subject: [PATCH 076/119] Add white color variant of checkmark icon --- core/css/icons.css | 4 ++++ core/img/actions/checkmark-white.png | Bin 0 -> 286 bytes core/img/actions/checkmark-white.svg | 4 ++++ 3 files changed, 8 insertions(+) create mode 100644 core/img/actions/checkmark-white.png create mode 100644 core/img/actions/checkmark-white.svg diff --git a/core/css/icons.css b/core/css/icons.css index 57c37c5c51c..2dc35084122 100644 --- a/core/css/icons.css +++ b/core/css/icons.css @@ -47,6 +47,10 @@ background-image: url('../img/actions/checkmark.svg'); } +.icon-checkmark-white { + background-image: url('../img/actions/checkmark-white.svg'); +} + .icon-clock { background-image: url('../img/actions/clock.svg'); } diff --git a/core/img/actions/checkmark-white.png b/core/img/actions/checkmark-white.png new file mode 100644 index 0000000000000000000000000000000000000000..08b8783649f2a4cd77c29b96674fe2e78afc53c8 GIT binary patch literal 286 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4()zHt)6I2xKt)eO%Q>6UV+nj3E=!kueBt{rxZ{b1rT9tRBVJ+K|J&cR zzRBt|^@`TT{Q@RV9FxWQ?r-aEb~jt`INMR&ef`X(O?+ZA7XM}3w`eBUw2KG$)|!9# zaPnwVsL_tI2gG?EeN8&ZVgA%|d4U#(#B>k87t0I$CQP1l;q<}OrUuP#5#4;#vLC*m b|B_Fu;{~gV^3$zAXEJ!Y`njxgN@xNAF(_;n literal 0 HcmV?d00001 diff --git a/core/img/actions/checkmark-white.svg b/core/img/actions/checkmark-white.svg new file mode 100644 index 00000000000..5e8fe8abccc --- /dev/null +++ b/core/img/actions/checkmark-white.svg @@ -0,0 +1,4 @@ +image/svg+xml + + + From 929c930b0afd682bb98eb389d7ebad91bb34d643 Mon Sep 17 00:00:00 2001 From: Pellaeon Lin Date: Wed, 29 Jan 2014 21:24:31 +0800 Subject: [PATCH 077/119] Use $storageInfo['free'] --- apps/files/index.php | 2 +- apps/files/lib/helper.php | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/files/index.php b/apps/files/index.php index c8b04bd4627..61b32bc6fe3 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -103,7 +103,7 @@ if ($needUpgrade) { } else { // information about storage capacities $storageInfo=OC_Helper::getStorageInfo($dir); - $freeSpace=OCP\Util::freeSpace($dir); + $freeSpace=$storageInfo['free']; $uploadLimit=OCP\Util::uploadLimit(); $maxUploadFilesize=OCP\Util::maxUploadFilesize($dir); $publicUploadEnabled = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); diff --git a/apps/files/lib/helper.php b/apps/files/lib/helper.php index e2f545e9e3f..21d1f50e587 100644 --- a/apps/files/lib/helper.php +++ b/apps/files/lib/helper.php @@ -6,7 +6,6 @@ class Helper { public static function buildFileStorageStatistics($dir) { $l = new \OC_L10N('files'); - $freeSpace=\OCP\Util::freeSpace($dir); $maxUploadFilesize = \OCP\Util::maxUploadFilesize($dir); $maxHumanFilesize = \OCP\Util::humanFileSize($maxUploadFilesize); $maxHumanFilesize = $l->t('Upload') . ' max. ' . $maxHumanFilesize; @@ -16,7 +15,7 @@ class Helper return array('uploadMaxFilesize' => $maxUploadFilesize, 'maxHumanFilesize' => $maxHumanFilesize, - 'freeSpace' => $freeSpace, + 'freeSpace' => $storageInfo['free'], 'usedSpacePercent' => (int)$storageInfo['relative']); } From 229f13adc0eca770c07646e56773f1aa93fee643 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 29 Jan 2014 14:40:59 +0100 Subject: [PATCH 078/119] change order of issubdirectory() calls to avoid error messages for non-apps --- lib/private/l10n.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/private/l10n.php b/lib/private/l10n.php index 98665c84c55..1aa1dc5ea28 100644 --- a/lib/private/l10n.php +++ b/lib/private/l10n.php @@ -132,10 +132,10 @@ class OC_L10N implements \OCP\IL10N { $i18ndir = self::findI18nDir($app); // Localization is in /l10n, Texts are in $i18ndir // (Just no need to define date/time format etc. twice) - if((OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC_App::getAppPath($app).'/l10n/') - || OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/core/l10n/') + if((OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/core/l10n/') || OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/lib/l10n/') || OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/settings') + || OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC_App::getAppPath($app).'/l10n/') ) && file_exists($i18ndir.$lang.'.php')) { // Include the file, save the data from $CONFIG From 5a869732d1e3bff7e2c1afdb7b15c77c31b4b1cc Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Wed, 29 Jan 2014 15:28:57 +0100 Subject: [PATCH 079/119] adjust file type icon placement for when no preview can be generated --- apps/files_sharing/css/mobile.css | 4 ++++ apps/files_sharing/css/public.css | 5 +++++ apps/files_sharing/templates/public.php | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/css/mobile.css b/apps/files_sharing/css/mobile.css index 3c06d0650e3..3312983b644 100644 --- a/apps/files_sharing/css/mobile.css +++ b/apps/files_sharing/css/mobile.css @@ -20,6 +20,10 @@ table td.filename .nametext { padding: 0; margin-bottom: 35px; } +/* some margin for the file type icon */ +#imgframe .publicpreview { + margin-top: 32px; +} /* always show actions on mobile */ #fileList a.action { diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css index 87e3ed78e1a..21f0c82b829 100644 --- a/apps/files_sharing/css/public.css +++ b/apps/files_sharing/css/public.css @@ -71,6 +71,11 @@ p.info a { max-width:100%; } +/* some margin for the file type icon */ +#imgframe .publicpreview { + margin-top: 10%; +} + thead { padding-left: 0 !important; /* fixes multiselect bar offset on shared page */ } diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index 2f9c7246be5..5804f606d9f 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -34,7 +34,7 @@
    - +
    From 7655728ddf4edcb02eb2e997e0d16567ee238460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 29 Jan 2014 16:52:30 +0100 Subject: [PATCH 080/119] - adding class to header div: share-folder or share-file - for supported previews are shown with a size of 500px; icons with a size of 128px --- apps/files_sharing/templates/public.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index 5804f606d9f..3ddaf4446df 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -9,7 +9,7 @@ -

    + value="" />

    From d8ec7e270167594ed407b22cb9ae78b1501ca946 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 31 Jan 2014 17:31:19 +0100 Subject: [PATCH 093/119] DRY for database type radiolist --- core/setup/controller.php | 17 +++++++++ core/templates/installation.php | 62 +++++---------------------------- 2 files changed, 25 insertions(+), 54 deletions(-) diff --git a/core/setup/controller.php b/core/setup/controller.php index 5189aba2f34..c628bda609b 100644 --- a/core/setup/controller.php +++ b/core/setup/controller.php @@ -85,6 +85,22 @@ class Controller { $hasPostgreSQL = is_callable('pg_connect'); $hasOracle = is_callable('oci_connect'); $hasMSSQL = is_callable('sqlsrv_connect'); + $databases = array(); + if ($hasSQLite) { + $databases['sqlite'] = 'SQLite'; + } + if ($hasMySQL) { + $databases['mysql'] = 'MySQL'; + } + if ($hasPostgreSQL) { + $databases['pgsql'] = 'PostgreSQL'; + } + if ($hasOracle) { + $databases['oci'] = 'Oracle'; + } + if ($hasMSSQL) { + $databases['mssql'] = 'MS SQL'; + } $datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT.'/data'); $vulnerableToNullByte = false; if(@file_exists(__FILE__."\0Nullbyte")) { // Check if the used PHP version is vulnerable to the NULL Byte attack (CVE-2006-7243) @@ -111,6 +127,7 @@ class Controller { 'hasPostgreSQL' => $hasPostgreSQL, 'hasOracle' => $hasOracle, 'hasMSSQL' => $hasMSSQL, + 'databases' => $databases, 'directory' => $datadir, 'secureRNG' => \OC_Util::secureRNGAvailable(), 'htaccessWorking' => $htaccessWorking, diff --git a/core/templates/installation.php b/core/templates/installation.php index 7e216d0ee99..9356e62aa6c 100644 --- a/core/templates/installation.php +++ b/core/templates/installation.php @@ -86,62 +86,16 @@ $hasOtherDB = true; else $hasOtherDB =false; //other than SQLite ?> t( 'Configure the database' )); ?>
    - - - -

    SQLite t( 'will be used' )); ?>.

    - + $label): ?> + +

    t( 'will be used' )); ?>.

    + - /> - - - - - - - -

    MySQL t( 'will be used' )); ?>.

    - - - /> - - - - - - -

    PostgreSQL t( 'will be used' )); ?>.

    - - - - /> - - - - - -

    Oracle t( 'will be used' )); ?>.

    - - - - /> - - - - - - -

    MS SQL t( 'will be used' )); ?>.

    - - - - /> - + /> + +
    From f1c60c7f8b12180917828775fcf4ba82ba68d573 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 31 Jan 2014 17:33:15 +0100 Subject: [PATCH 094/119] Remove unused functions from OC_Helper init_var and init_radio where only used in the installation template --- lib/private/helper.php | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/lib/private/helper.php b/lib/private/helper.php index 58bee9c6300..ce5708e2bb9 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -448,29 +448,6 @@ class OC_Helper { * */ - //FIXME: should also check for value validation (i.e. the email is an email). - public static function init_var($s, $d = "") { - $r = $d; - if (isset($_REQUEST[$s]) && !empty($_REQUEST[$s])) { - $r = OC_Util::sanitizeHTML($_REQUEST[$s]); - } - - return $r; - } - - /** - * returns "checked"-attribute if request contains selected radio element - * OR if radio element is the default one -- maybe? - * - * @param string $s Name of radio-button element name - * @param string $v Value of current radio-button element - * @param string $d Value of default radio-button element - */ - public static function init_radio($s, $v, $d) { - if ((isset($_REQUEST[$s]) && $_REQUEST[$s] == $v) || (!isset($_REQUEST[$s]) && $v == $d)) - print "checked=\"checked\" "; - } - /** * detect if a given program is found in the search PATH * From 5610842e5669ed17983d219f6c779316f209ba92 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 31 Jan 2014 20:38:35 +0100 Subject: [PATCH 095/119] move unlink proxy to a hook which handles pre and post conditions --- apps/files_encryption/hooks/hooks.php | 64 +++++++++++++++++++++++++++ apps/files_encryption/lib/helper.php | 2 + apps/files_encryption/lib/proxy.php | 41 ----------------- 3 files changed, 66 insertions(+), 41 deletions(-) diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 09d5687e226..4c4b3f2040f 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -32,6 +32,8 @@ class Hooks { // file for which we want to rename the keys after the rename operation was successful private static $renamedFiles = array(); + // file for which we want to delete the keys after the delete operation was successful + private static $deleteFiles = array(); /** * @brief Startup encryption backend upon user login @@ -630,4 +632,66 @@ class Hooks { } } + /** + * @brief if the file was really deleted we remove the encryption keys + * @param array $params + * @return boolean + */ + public static function postDelete($params) { + + if (!isset(self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]])) { + return true; + } + + $deletedFile = self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]]; + $path = $deletedFile['path']; + $user = $deletedFile['uid']; + + // we don't need to remember the file any longer + unset(self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]]); + + $view = new \OC\Files\View('/'); + + // return if the file still exists and wasn't deleted correctly + if ($view->file_exists('/' . $user . '/files/' . $path)) { + return true; + } + + // Disable encryption proxy to prevent recursive calls + $proxyStatus = \OC_FileProxy::$enabled; + \OC_FileProxy::$enabled = false; + + // Delete keyfile & shareKey so it isn't orphaned + if (!Keymanager::deleteFileKey($view, $path, $user)) { + \OCP\Util::writeLog('Encryption library', + 'Keyfile or shareKey could not be deleted for file "' . $user.'/files/'.$path . '"', \OCP\Util::ERROR); + } + + Keymanager::delAllShareKeys($view, $user, $path); + + \OC_FileProxy::$enabled = $proxyStatus; + } + + /** + * @brief remember the file which should be deleted and it's owner + * @param array $params + * @return boolean + */ + public static function preDelete($params) { + $path = $params[\OC\Files\Filesystem::signal_param_path]; + + // skip this method if the trash bin is enabled or if we delete a file + // outside of /data/user/files + if (\OCP\App::isEnabled('files_trashbin')) { + return true; + } + + $util = new Util(new \OC_FilesystemView('/'), \OCP\USER::getUser()); + list($owner, $ownerPath) = $util->getUidAndFilename($path); + + self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]] = array( + 'uid' => $owner, + 'path' => $ownerPath); + } + } diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php index 5dcb05fa196..bb06a57c714 100755 --- a/apps/files_encryption/lib/helper.php +++ b/apps/files_encryption/lib/helper.php @@ -63,6 +63,8 @@ class Helper { \OCP\Util::connectHook('OC_Filesystem', 'rename', 'OCA\Encryption\Hooks', 'preRename'); \OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Encryption\Hooks', 'postRename'); + \OCP\Util::connectHook('OC_Filesystem', 'post_delete', 'OCA\Encryption\Hooks', 'postDelete'); + \OCP\Util::connectHook('OC_Filesystem', 'delete', 'OCA\Encryption\Hooks', 'preDelete'); } /** diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 4e71ab1dd5d..11048005969 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -203,47 +203,6 @@ class Proxy extends \OC_FileProxy { } - /** - * @brief When a file is deleted, remove its keyfile also - */ - public function preUnlink($path) { - - $relPath = Helper::stripUserFilesPath($path); - - // skip this method if the trash bin is enabled or if we delete a file - // outside of /data/user/files - if (\OCP\App::isEnabled('files_trashbin') || $relPath === false) { - return true; - } - - // Disable encryption proxy to prevent recursive calls - $proxyStatus = \OC_FileProxy::$enabled; - \OC_FileProxy::$enabled = false; - - $view = new \OC_FilesystemView('/'); - - $userId = \OCP\USER::getUser(); - - $util = new Util($view, $userId); - - list($owner, $ownerPath) = $util->getUidAndFilename($relPath); - - // Delete keyfile & shareKey so it isn't orphaned - if (!Keymanager::deleteFileKey($view, $ownerPath)) { - \OCP\Util::writeLog('Encryption library', - 'Keyfile or shareKey could not be deleted for file "' . $ownerPath . '"', \OCP\Util::ERROR); - } - - Keymanager::delAllShareKeys($view, $owner, $ownerPath); - - \OC_FileProxy::$enabled = $proxyStatus; - - // If we don't return true then file delete will fail; better - // to leave orphaned keyfiles than to disallow file deletion - return true; - - } - /** * @param $path * @return bool From 4d1086c35fa8aed35ba8cdef75764564e75ba769 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 31 Jan 2014 20:39:11 +0100 Subject: [PATCH 096/119] better error detection and don't use glob() --- apps/files_encryption/lib/keymanager.php | 39 ++++++++++++++++-------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index b2c756894b4..17b8180bfdd 100755 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -214,15 +214,24 @@ class Keymanager { * * @param \OC_FilesystemView $view * @param string $path path of the file the key belongs to + * @param string $userId the user to whom the file belongs * @return bool Outcome of unlink operation * @note $path must be relative to data/user/files. e.g. mydoc.txt NOT * /data/admin/files/mydoc.txt */ - public static function deleteFileKey(\OC_FilesystemView $view, $path) { + public static function deleteFileKey($view, $path, $userId=null) { $trimmed = ltrim($path, '/'); - $userId = Helper::getUser($path); + if ($trimmed === '') { + \OCP\Util::writeLog('Encryption library', + 'Can\'t delete file-key empty path given!', \OCP\Util::ERROR); + return false; + } + + if ($userId === null) { + $userId = Helper::getUser($path); + } $util = new Util($view, $userId); if($util->isSystemWideMountPoint($path)) { @@ -402,7 +411,15 @@ class Keymanager { * @param string $userId owner of the file * @param string $filePath path to the file, relative to the owners file dir */ - public static function delAllShareKeys(\OC_FilesystemView $view, $userId, $filePath) { + public static function delAllShareKeys($view, $userId, $filePath) { + + $filePath = ltrim($filePath, '/'); + + if ($filePath === '') { + \OCP\Util::writeLog('Encryption library', + 'Can\'t delete share-keys empty path given!', \OCP\Util::ERROR); + return false; + } $util = new util($view, $userId); @@ -413,17 +430,15 @@ class Keymanager { } - if ($view->is_dir($userId . '/files/' . $filePath)) { + if ($view->is_dir($baseDir . $filePath)) { $view->unlink($baseDir . $filePath); } else { - $localKeyPath = $view->getLocalFile($baseDir . $filePath); - $escapedPath = Helper::escapeGlobPattern($localKeyPath); - $matches = glob($escapedPath . '*.shareKey'); - foreach ($matches as $ma) { - $result = unlink($ma); - if (!$result) { - \OCP\Util::writeLog('Encryption library', - 'Keyfile or shareKey could not be deleted for file "' . $filePath . '"', \OCP\Util::ERROR); + $parentDir = dirname($baseDir . $filePath); + $filename = pathinfo($filePath, PATHINFO_BASENAME); + foreach($view->getDirectoryContent($parentDir) as $content) { + $path = $content['path']; + if (strpos($content['name'], $filename) === 0) { + $view->unlink('/' . $userId . '/' . $path); } } } From bef58f5361eb5480d4633d733b3c8d3f80e034c4 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 31 Jan 2014 20:39:52 +0100 Subject: [PATCH 097/119] don't expect OC_FilesystemView, this is depreciated --- apps/files_encryption/lib/util.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 8816d4d649a..ae3e2a2e15a 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -57,7 +57,7 @@ class Util { * @param $userId * @param bool $client */ - public function __construct(\OC_FilesystemView $view, $userId, $client = false) { + public function __construct($view, $userId, $client = false) { $this->view = $view; $this->client = $client; From 5844d682a74533be8577160860758709bef706ba Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Sat, 1 Feb 2014 15:02:36 +0100 Subject: [PATCH 098/119] Use === instead of ==, add missing whitespace and CSS class --- core/templates/installation.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/templates/installation.php b/core/templates/installation.php index 9356e62aa6c..9670a5e9ee5 100644 --- a/core/templates/installation.php +++ b/core/templates/installation.php @@ -87,8 +87,8 @@ t( 'Configure the database' )); ?>
    $label): ?> - -

    t( 'will be used' )); ?>.

    + +

    t( 'will be used' )); ?>.

    Date: Fri, 31 Jan 2014 23:37:21 +0100 Subject: [PATCH 099/119] added tests for the delete hooks if the trash bin is disabled --- apps/files_encryption/tests/hooks.php | 271 ++++++++++++++++++++++++++ apps/files_encryption/tests/proxy.php | 50 ----- apps/files_encryption/tests/share.php | 44 +++-- 3 files changed, 300 insertions(+), 65 deletions(-) create mode 100644 apps/files_encryption/tests/hooks.php diff --git a/apps/files_encryption/tests/hooks.php b/apps/files_encryption/tests/hooks.php new file mode 100644 index 00000000000..c26cba6406d --- /dev/null +++ b/apps/files_encryption/tests/hooks.php @@ -0,0 +1,271 @@ + + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 library. If not, see . + * + */ + +require_once __DIR__ . '/../../../lib/base.php'; +require_once __DIR__ . '/../lib/crypt.php'; +require_once __DIR__ . '/../lib/keymanager.php'; +require_once __DIR__ . '/../lib/stream.php'; +require_once __DIR__ . '/../lib/util.php'; +require_once __DIR__ . '/../appinfo/app.php'; +require_once __DIR__ . '/util.php'; + +use OCA\Encryption; + +/** + * Class Test_Encryption_Hooks + * @brief this class provide basic hook app tests + */ +class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { + + const TEST_ENCRYPTION_HOOKS_USER1 = "test-proxy-user1"; + const TEST_ENCRYPTION_HOOKS_USER2 = "test-proxy-user2"; + + /** + * @var \OC_FilesystemView + */ + public $user1View; // view on /data/user1/files + public $user2View; // view on /data/user2/files + public $rootView; // view on /data/user + public $data; + public $filename; + + public static function setUpBeforeClass() { + // reset backend + \OC_User::clearBackends(); + \OC_User::useBackend('database'); + + \OC_Hook::clear('OC_Filesystem'); + \OC_Hook::clear('OC_User'); + + // clear share hooks + \OC_Hook::clear('OCP\\Share'); + \OC::registerShareHooks(); + \OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup'); + + // Filesystem related hooks + \OCA\Encryption\Helper::registerFilesystemHooks(); + + // Sharing related hooks + \OCA\Encryption\Helper::registerShareHooks(); + + // clear and register proxies + \OC_FileProxy::clearProxies(); + \OC_FileProxy::register(new OCA\Encryption\Proxy()); + + // create test user + \Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1, true); + \Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2, true); + } + + function setUp() { + // set user id + \Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1); + \OC_User::setUserId(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1); + + // init filesystem view + $this->user1View = new \OC_FilesystemView('/'. \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1 . '/files'); + $this->user2View = new \OC_FilesystemView('/'. \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '/files'); + $this->rootView = new \OC_FilesystemView('/'); + + // init short data + $this->data = 'hats'; + $this->filename = 'enc_hooks_tests-' . uniqid() . '.txt'; + + } + + public static function tearDownAfterClass() { + // cleanup test user + \OC_User::deleteUser(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1); + \OC_User::deleteUser(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2); + } + + function testDeleteHooks() { + + // remember files_trashbin state + $stateFilesTrashbin = OC_App::isEnabled('files_trashbin'); + + // we want to tests with app files_trashbin disabled + \OC_App::disable('files_trashbin'); + + // make sure that the trash bin is disabled + $this->assertFalse(\OC_APP::isEnabled('files_trashbin')); + + $this->user1View->file_put_contents($this->filename, $this->data); + + // check if all keys are generated + $this->assertTrue($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' + . $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey')); + $this->assertTrue($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' . $this->filename . '.key')); + + + \Test_Encryption_Util::logoutHelper(); + \Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2); + \OC_User::setUserId(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2); + + + $this->user2View->file_put_contents($this->filename, $this->data); + + // check if all keys are generated + $this->assertTrue($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/share-keys/' + . $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey')); + $this->assertTrue($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/keyfiles/' . $this->filename . '.key')); + + + // create a dummy file that we can delete something outside of data/user/files + // in this case no share or file keys should be deleted + $this->rootView->file_put_contents(self::TEST_ENCRYPTION_HOOKS_USER2 . "/" . $this->filename, $this->data); + + // delete dummy file outside of data/user/files + $this->rootView->unlink(self::TEST_ENCRYPTION_HOOKS_USER2 . "/" . $this->filename); + + // all keys should still exist + $this->assertTrue($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/share-keys/' + . $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey')); + $this->assertTrue($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/keyfiles/' . $this->filename . '.key')); + + + // delete the file in data/user/files + // now the correspondig share and file keys from user2 should be deleted + $this->user2View->unlink($this->filename); + + // check if keys from user2 are really deleted + $this->assertFalse($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/share-keys/' + . $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey')); + $this->assertFalse($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/keyfiles/' . $this->filename . '.key')); + + // but user1 keys should still exist + $this->assertTrue($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' + . $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey')); + $this->assertTrue($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' . $this->filename . '.key')); + + if ($stateFilesTrashbin) { + OC_App::enable('files_trashbin'); + } + else { + OC_App::disable('files_trashbin'); + } + } + + function testDeleteHooksForSharedFiles() { + + \Test_Encryption_Util::logoutHelper(); + \Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1); + \OC_User::setUserId(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1); + + // remember files_trashbin state + $stateFilesTrashbin = OC_App::isEnabled('files_trashbin'); + + // we want to tests with app files_trashbin disabled + \OC_App::disable('files_trashbin'); + + // make sure that the trash bin is disabled + $this->assertFalse(\OC_APP::isEnabled('files_trashbin')); + + $this->user1View->file_put_contents($this->filename, $this->data); + + // check if all keys are generated + $this->assertTrue($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' + . $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey')); + $this->assertTrue($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' . $this->filename . '.key')); + + // get the file info from previous created file + $fileInfo = $this->user1View->getFileInfo($this->filename); + + // check if we have a valid file info + $this->assertTrue(is_array($fileInfo)); + + // share the file with user2 + \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_ENCRYPTION_HOOKS_USER2, OCP\PERMISSION_ALL); + + // check if new share key exists + $this->assertTrue($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' + . $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey')); + + \Test_Encryption_Util::logoutHelper(); + \Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2); + \OC_User::setUserId(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2); + + // user2 has a local file with the same name + $this->user2View->file_put_contents($this->filename, $this->data); + + // check if all keys are generated + $this->assertTrue($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/share-keys/' + . $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey')); + $this->assertTrue($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/keyfiles/' . $this->filename . '.key')); + + // delete the Shared file from user1 in data/user2/files/Shared + $this->user2View->unlink('/Shared/' . $this->filename); + + // now keys from user1s home should be gone + $this->assertFalse($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' + . $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey')); + $this->assertFalse($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' + . $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey')); + $this->assertFalse($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' . $this->filename . '.key')); + + // but user2 keys should still exist + $this->assertTrue($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/share-keys/' + . $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey')); + $this->assertTrue($this->rootView->file_exists( + self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/keyfiles/' . $this->filename . '.key')); + + // cleanup + + $this->user2View->unlink($this->filename); + + \Test_Encryption_Util::logoutHelper(); + \Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1); + \OC_User::setUserId(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1); + + // unshare the file + \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_ENCRYPTION_HOOKS_USER2); + + $this->user1View->unlink($this->filename); + + if ($stateFilesTrashbin) { + OC_App::enable('files_trashbin'); + } + else { + OC_App::disable('files_trashbin'); + } + } + +} diff --git a/apps/files_encryption/tests/proxy.php b/apps/files_encryption/tests/proxy.php index c3006274d6d..51cc0b795e3 100644 --- a/apps/files_encryption/tests/proxy.php +++ b/apps/files_encryption/tests/proxy.php @@ -112,54 +112,4 @@ class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase { } - function testPreUnlinkWithoutTrash() { - - // remember files_trashbin state - $stateFilesTrashbin = OC_App::isEnabled('files_trashbin'); - - // we want to tests with app files_trashbin enabled - \OC_App::disable('files_trashbin'); - - $this->view->file_put_contents($this->filename, $this->data); - - // create a dummy file that we can delete something outside of data/user/files - $this->rootView->file_put_contents("dummy.txt", $this->data); - - // check if all keys are generated - $this->assertTrue($this->rootView->file_exists( - '/files_encryption/share-keys/' - . $this->filename . '.' . \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 . '.shareKey')); - $this->assertTrue($this->rootView->file_exists( - '/files_encryption/keyfiles/' . $this->filename . '.key')); - - - // delete dummy file outside of data/user/files - $this->rootView->unlink("dummy.txt"); - - // all keys should still exist - $this->assertTrue($this->rootView->file_exists( - '/files_encryption/share-keys/' - . $this->filename . '.' . \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 . '.shareKey')); - $this->assertTrue($this->rootView->file_exists( - '/files_encryption/keyfiles/' . $this->filename . '.key')); - - - // delete the file in data/user/files - $this->view->unlink($this->filename); - - // now also the keys should be gone - $this->assertFalse($this->rootView->file_exists( - '/files_encryption/share-keys/' - . $this->filename . '.' . \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 . '.shareKey')); - $this->assertFalse($this->rootView->file_exists( - '/files_encryption/keyfiles/' . $this->filename . '.key')); - - if ($stateFilesTrashbin) { - OC_App::enable('files_trashbin'); - } - else { - OC_App::disable('files_trashbin'); - } - } - } diff --git a/apps/files_encryption/tests/share.php b/apps/files_encryption/tests/share.php index e55427620a6..acf408a07f0 100755 --- a/apps/files_encryption/tests/share.php +++ b/apps/files_encryption/tests/share.php @@ -194,8 +194,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); // cleanup - $this->view->unlink( - '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename); + $this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/'); + $this->view->unlink($this->filename); + $this->view->chroot('/'); // check if share key not exists $this->assertFalse($this->view->file_exists( @@ -265,8 +266,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); // cleanup - $this->view->unlink( - '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename); + $this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/'); + $this->view->unlink($this->filename); + $this->view->chroot('/'); // check if share key not exists $this->assertFalse($this->view->file_exists( @@ -352,7 +354,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); // cleanup - $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files' . $this->folder1); + $this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files'); + $this->view->unlink($this->folder1); + $this->view->chroot('/'); // check if share key not exists $this->assertFalse($this->view->file_exists( @@ -482,9 +486,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); // cleanup - $this->view->unlink( - '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files' . $this->folder1 . $this->subfolder - . $this->subsubfolder . '/' . $this->filename); + $this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files'); + $this->view->unlink($this->folder1 . $this->subfolder . $this->subsubfolder . '/' . $this->filename); + $this->view->chroot('/'); // check if share key not exists $this->assertFalse($this->view->file_exists( @@ -559,7 +563,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { . $this->filename . '.' . $publicShareKeyId . '.shareKey')); // cleanup - $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename); + $this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/'); + $this->view->unlink($this->filename); + $this->view->chroot('/'); // check if share key not exists $this->assertFalse($this->view->file_exists( @@ -636,7 +642,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER4 . '.shareKey')); // cleanup - $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename); + $this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/'); + $this->view->unlink($this->filename); + $this->view->chroot('/'); // check if share key not exists $this->assertFalse($this->view->file_exists( @@ -731,8 +739,10 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { . $this->filename . '.' . $recoveryKeyId . '.shareKey')); // cleanup - $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename); - $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->folder1); + $this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/'); + $this->view->unlink($this->filename); + $this->view->unlink($this->folder1); + $this->view->chroot('/'); // check if share key for recovery not exists $this->assertFalse($this->view->file_exists( @@ -828,8 +838,10 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { $this->assertEquals($this->dataShort, $retrievedCryptedFile2); // cleanup - $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->folder1); - $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename); + $this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/'); + $this->view->unlink($this->folder1); + $this->view->unlink($this->filename); + $this->view->chroot('/'); // check if share key for user and recovery exists $this->assertFalse($this->view->file_exists( @@ -930,7 +942,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.shareKey')); // cleanup - $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename); + $this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/'); + $this->view->unlink($this->filename); + $this->view->chroot('/'); } } From 44b637470c57f098d328bc6d298be9385d3f30c4 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 31 Jan 2014 12:28:21 +0100 Subject: [PATCH 100/119] remove passwords in URLs from all log messages --- lib/private/log/errorhandler.php | 15 ++++++++++++--- lib/private/log/owncloud.php | 1 - 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/private/log/errorhandler.php b/lib/private/log/errorhandler.php index 69cb960de91..4460468336b 100644 --- a/lib/private/log/errorhandler.php +++ b/lib/private/log/errorhandler.php @@ -14,6 +14,15 @@ class ErrorHandler { /** @var LoggerInterface */ private static $logger; + /** + * @brief remove password in URLs + * @param string $msg + * @return string + */ + private static function removePassword($msg) { + return preg_replace('/\/\/(.*):(.*)@/', '//xxx:xxx@', $msg); + } + public static function register() { $handler = new ErrorHandler(); @@ -32,14 +41,14 @@ class ErrorHandler { if($error && self::$logger) { //ob_end_clean(); $msg = $error['message'] . ' at ' . $error['file'] . '#' . $error['line']; - self::$logger->critical($msg, array('app' => 'PHP')); + self::$logger->critical(self::removePassword($msg), array('app' => 'PHP')); } } // Uncaught exception handler public static function onException($exception) { $msg = $exception->getMessage() . ' at ' . $exception->getFile() . '#' . $exception->getLine(); - self::$logger->critical($msg, array('app' => 'PHP')); + self::$logger->critical(self::removePassword($msg), array('app' => 'PHP')); } //Recoverable errors handler @@ -48,7 +57,7 @@ class ErrorHandler { return; } $msg = $message . ' at ' . $file . '#' . $line; - self::$logger->warning($msg, array('app' => 'PHP')); + self::$logger->warning(self::removePassword($msg), array('app' => 'PHP')); } } diff --git a/lib/private/log/owncloud.php b/lib/private/log/owncloud.php index 4c86d0e45e0..3590bbd436d 100644 --- a/lib/private/log/owncloud.php +++ b/lib/private/log/owncloud.php @@ -69,7 +69,6 @@ class OC_Log_Owncloud { } $time = new DateTime(null, $timezone); // remove username/passswords from URLs before writing the to the log file - $message = preg_replace('/\/\/(.*):(.*)@/', '//xxx:xxx@', $message); $entry=array('app'=>$app, 'message'=>$message, 'level'=>$level, 'time'=> $time->format($format)); $entry = json_encode($entry); $handle = @fopen(self::$logFile, 'a'); From cf5277b558e1838a1b8126621cb8cd5a0ca60cb4 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 31 Jan 2014 13:27:51 +0100 Subject: [PATCH 101/119] also load error handler if debugging is enabled --- lib/base.php | 3 ++- lib/private/log/errorhandler.php | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/base.php b/lib/base.php index af78b4e4eb1..b54b2973551 100644 --- a/lib/base.php +++ b/lib/base.php @@ -504,11 +504,12 @@ class OC { if (!defined('PHPUNIT_RUN')) { if (defined('DEBUG') and DEBUG) { + OC\Log\ErrorHandler::register(true); set_exception_handler(array('OC_Template', 'printExceptionErrorPage')); } else { OC\Log\ErrorHandler::register(); - OC\Log\ErrorHandler::setLogger(OC_Log::$object); } + OC\Log\ErrorHandler::setLogger(OC_Log::$object); } // register the stream wrappers diff --git a/lib/private/log/errorhandler.php b/lib/private/log/errorhandler.php index 4460468336b..f6c96ef8218 100644 --- a/lib/private/log/errorhandler.php +++ b/lib/private/log/errorhandler.php @@ -23,10 +23,14 @@ class ErrorHandler { return preg_replace('/\/\/(.*):(.*)@/', '//xxx:xxx@', $msg); } - public static function register() { + public static function register($debug=false) { $handler = new ErrorHandler(); - set_error_handler(array($handler, 'onError')); + if ($debug) { + set_error_handler(array($handler, 'onAll'), E_ALL); + } else { + set_error_handler(array($handler, 'onError')); + } register_shutdown_function(array($handler, 'onShutdown')); set_exception_handler(array($handler, 'onException')); } @@ -57,7 +61,15 @@ class ErrorHandler { return; } $msg = $message . ' at ' . $file . '#' . $line; - self::$logger->warning(self::removePassword($msg), array('app' => 'PHP')); + self::$logger->error(self::removePassword($msg), array('app' => 'PHP')); } + + //Recoverable handler which catch all errors, warnings and notices + public static function onAll($number, $message, $file, $line) { + $msg = $message . ' at ' . $file . '#' . $line; + self::$logger->debug(self::removePassword($msg), array('app' => 'PHP')); + + } + } From 97921d0c25469bd905906406c70a96eeb7fd1664 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 3 Feb 2014 13:39:05 +0100 Subject: [PATCH 102/119] add function to extract filename from sharekey name + tests --- apps/files_encryption/lib/keymanager.php | 18 +++++++++++++++++- apps/files_encryption/tests/keymanager.php | 20 ++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 17b8180bfdd..7abc565f609 100755 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -437,7 +437,7 @@ class Keymanager { $filename = pathinfo($filePath, PATHINFO_BASENAME); foreach($view->getDirectoryContent($parentDir) as $content) { $path = $content['path']; - if (strpos($content['name'], $filename) === 0) { + if (self::getFilenameFromShareKey($content['name']) === $filename) { $view->unlink('/' . $userId . '/' . $path); } } @@ -538,4 +538,20 @@ class Keymanager { return $targetPath; } + + /** + * @brief extract filename from share key name + * @param string $shareKey (filename.userid.sharekey) + * @return mixed filename or false + */ + protected static function getFilenameFromShareKey($shareKey) { + $parts = explode('.', $shareKey); + + $filename = false; + if(count($parts) > 2) { + $filename = implode('.', array_slice($parts, 0, count($parts)-2)); + } + + return $filename; + } } diff --git a/apps/files_encryption/tests/keymanager.php b/apps/files_encryption/tests/keymanager.php index 58a57ee5af4..6f32c50743c 100644 --- a/apps/files_encryption/tests/keymanager.php +++ b/apps/files_encryption/tests/keymanager.php @@ -136,6 +136,17 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase { $this->assertArrayHasKey('key', $sslInfo); } + /** + * @small + */ + function testGetFilenameFromShareKey() { + $this->assertEquals("file", + \TestProtectedKeymanagerMethods::testGetFilenameFromShareKey("file.user.shareKey")); + $this->assertEquals("file.name.with.dots", + \TestProtectedKeymanagerMethods::testGetFilenameFromShareKey("file.name.with.dots.user.shareKey")); + $this->assertFalse(\TestProtectedKeymanagerMethods::testGetFilenameFromShareKey("file.txt")); + } + /** * @medium */ @@ -234,3 +245,12 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase { \OC_FileProxy::$enabled = $proxyStatus; } } + +/** + * dummy class to access protected methods of \OCA\Encryption\Keymanager for testing + */ +class TestProtectedKeymanagerMethods extends \OCA\Encryption\Keymanager { + public static function testGetFilenameFromShareKey($sharekey) { + return self::getFilenameFromShareKey($sharekey); + } +} \ No newline at end of file From 6d7d3c16d04596b0cd32ebc1aaddaaaf7c5fe481 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Mon, 3 Feb 2014 17:23:30 +0100 Subject: [PATCH 103/119] ellipsize long modified dates to make room for showing delete button, fix #7040 --- apps/files/css/files.css | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 1d254ad04ee..8c7938c79bb 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -119,7 +119,9 @@ table th#headerDate, table td.date { -moz-box-sizing: border-box; box-sizing: border-box; position: relative; + /* this can not be just width, both need to be set … table styling */ min-width: 176px; + max-width: 176px; } /* Multiselect bar */ @@ -174,6 +176,14 @@ table td.filename .nametext, .uploadtext, .modified { float:left; padding:14px 0 } .modified { position: relative; + overflow: hidden; + text-overflow: ellipsis; + width: 90%; +} +/* ellipsize long modified dates to make room for showing delete button */ +#fileList tr:hover .modified, +#fileList tr:focus .modified { + width: 75%; } /* TODO fix usability bug (accidental file/folder selection) */ From b56dbbe0e5b593f53b686d5cada5a36ef2d4f39f Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Mon, 3 Feb 2014 17:26:49 +0100 Subject: [PATCH 104/119] fix misalignment of modified dates, shift to right --- apps/files/css/files.css | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 8c7938c79bb..5526abaf6e2 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -176,6 +176,7 @@ table td.filename .nametext, .uploadtext, .modified { float:left; padding:14px 0 } .modified { position: relative; + padding-left: 8px; overflow: hidden; text-overflow: ellipsis; width: 90%; From cfcd71f3e4e8417541629de9c99e306dfd571d57 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Mon, 3 Feb 2014 18:47:25 +0100 Subject: [PATCH 105/119] better picture icon, fix https://github.com/owncloud/apps/issues/1401 --- core/img/places/picture.png | Bin 242 -> 434 bytes core/img/places/picture.svg | 5 +---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/core/img/places/picture.png b/core/img/places/picture.png index 7b3af8c7f841c99e326bedcd9cf7764906a91c6e..2b96ea518ce876eaefd2e90b7594b0b5bd3844ca 100644 GIT binary patch delta 363 zcmV-x0hIpo0kQ*-7#Ro#0001UdV2H#000DYLP=Bz2nYy#2xN$nFg$+&FG)l}R9J=W zm!WO~K@>&rLLtGRQB6g^0)=jZAwgBmhcqD-{eX&E3<)2Az}Jx#7ly;U;zqYBx?GIg{{T)niwn z+6EeujHJ}k*jTw>7utWK;XjO%b0~KN^9-aJ2GX((RC)&93dW9urv(k$^VHJV*r8>A z1V$kurd7IgQ5Q~U|*lHMhCvmPEZghNRyNrOFkPkG{!yfcu;Ch+RKHwW%B za=XA94?+#x0*joret>77WpmrWr%yc8zyt8LZ$aP#=mV1ixrIjz)PWaZQ)IzVxaR>E z9Z6G3y@25ig6}KnNm`y#T$0=hoc(-QiOpynQGc9py&GP-fnU+avmX`&)Gz=5002ov JPDHLkV1hZ8oHGCb delta 170 zcmdnQ{E2abgaivS0|P^2NcwRg#a!&<8N$KAar>eFgNcSV^$cP+Dz - - - - + From 36838b2837168b69aba82f88f110c174db25e6d7 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 4 Feb 2014 11:11:24 +0100 Subject: [PATCH 106/119] add test for password remove method --- lib/private/log/errorhandler.php | 2 +- tests/lib/errorHandler.php | 62 ++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 tests/lib/errorHandler.php diff --git a/lib/private/log/errorhandler.php b/lib/private/log/errorhandler.php index f6c96ef8218..1dde6b507fc 100644 --- a/lib/private/log/errorhandler.php +++ b/lib/private/log/errorhandler.php @@ -19,7 +19,7 @@ class ErrorHandler { * @param string $msg * @return string */ - private static function removePassword($msg) { + protected static function removePassword($msg) { return preg_replace('/\/\/(.*):(.*)@/', '//xxx:xxx@', $msg); } diff --git a/tests/lib/errorHandler.php b/tests/lib/errorHandler.php new file mode 100644 index 00000000000..68b87deccb6 --- /dev/null +++ b/tests/lib/errorHandler.php @@ -0,0 +1,62 @@ + + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 library. If not, see . + * + */ + +class Test_ErrorHandler extends \PHPUnit_Framework_TestCase { + + /** + * @brief provide username, password combinations for testRemovePassword + * @return array + */ + function passwordProvider() { + return array( + array('user', 'password'), + array('user@owncloud.org', 'password'), + array('user', 'pass@word'), + array('us:er', 'password'), + array('user', 'pass:word'), + ); + + } + + /** + * @dataProvider passwordProvider + * @param string $username + * @param string $password + */ + function testRemovePassword($username, $password) { + $url = 'http://'.$username.':'.$password.'@owncloud.org'; + $expectedResult = 'http://xxx:xxx@owncloud.org'; + $result = TestableErrorHandler::testRemovePassword($url); + + $this->assertEquals($expectedResult, $result); + } + +} + +/** + * @brief dummy class to access protected methods of \OC\Log\ErrorHandler + */ +class TestableErrorHandler extends \OC\Log\ErrorHandler { + public static function testRemovePassword($msg) { + return self::removePassword($msg); + } +} From 912da8d27756d9f0d55821338f6d8698af2dbd27 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 4 Feb 2014 13:56:10 +0100 Subject: [PATCH 107/119] Added session_keepalive setting When session_keepalive is true (default) the heartbeat will be send as often as the half of the session timeout value. --- config/config.sample.php | 7 ++++++ core/js/config.php | 6 +++++ core/js/js.js | 53 ++++++++++++++++++++++++++++------------ 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/config/config.sample.php b/config/config.sample.php index 01abc583688..ef5fb7ea5a5 100755 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -184,6 +184,13 @@ $CONFIG = array( /* Life time of a session after inactivity */ "session_lifetime" => 60 * 60 * 24, +/* + * Enable/disable session keep alive when a user is logged in in the Web UI. + * This is achieved by sending a "heartbeat" to the server to prevent + * the session timing out. + */ +"session_keepalive" => true, + /* Custom CSP policy, changing this will overwrite the standard policy */ "custom_csp_policy" => "default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src *; img-src *; font-src 'self' data:; media-src *", diff --git a/core/js/config.php b/core/js/config.php index dd46f7889d1..517ea1615a8 100644 --- a/core/js/config.php +++ b/core/js/config.php @@ -55,6 +55,12 @@ $array = array( ) ), "firstDay" => json_encode($l->l('firstday', 'firstday')) , + "oc_config" => json_encode( + array( + 'session_lifetime' => \OCP\Config::getSystemValue('session_lifetime', 60 * 60 * 24), + 'session_keepalive' => \OCP\Config::getSystemValue('session_keepalive', true) + ) + ) ); // Echo it diff --git a/core/js/js.js b/core/js/js.js index 1c7d89ea055..cd9b8bd3010 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -11,6 +11,8 @@ var oc_webroot; var oc_current_user = document.getElementsByTagName('head')[0].getAttribute('data-user'); var oc_requesttoken = document.getElementsByTagName('head')[0].getAttribute('data-requesttoken'); +window.oc_config = window.oc_config || {}; + if (typeof oc_webroot === "undefined") { oc_webroot = location.pathname; var pos = oc_webroot.indexOf('/index.php/'); @@ -742,8 +744,39 @@ function fillWindow(selector) { console.warn("This function is deprecated! Use CSS instead"); } -$(document).ready(function(){ - sessionHeartBeat(); +/** + * Initializes core + */ +function initCore() { + + /** + * Calls the server periodically to ensure that session doesnt + * time out + */ + function initSessionHeartBeat(){ + // interval in seconds + var interval = 900; + if (oc_config.session_lifetime) { + interval = Math.floor(oc_config.session_lifetime / 2); + } + // minimum one minute + if (interval < 60) { + interval = 60; + } + OC.Router.registerLoadedCallback(function(){ + var url = OC.Router.generate('heartbeat'); + setInterval(function(){ + $.post(url); + }, interval * 1000); + }); + } + + // session heartbeat (defalts to enabled) + if (typeof(oc_config.session_keepalive) === 'undefined' || + !!oc_config.session_keepalive) { + + initSessionHeartBeat(); + } if(!SVGSupport()){ //replace all svg images with png images for browser that dont support svg replaceSVG(); @@ -856,7 +889,9 @@ $(document).ready(function(){ $('input[type=text]').focus(function(){ this.select(); }); -}); +} + +$(document).ready(initCore); /** * Filter Jquery selector by attribute value @@ -986,15 +1021,3 @@ jQuery.fn.exists = function(){ return this.length > 0; }; -/** - * Calls the server periodically every 15 mins to ensure that session doesnt - * time out - */ -function sessionHeartBeat(){ - OC.Router.registerLoadedCallback(function(){ - var url = OC.Router.generate('heartbeat'); - setInterval(function(){ - $.post(url); - }, 900000); - }); -} From e75f7e58e9778bbe5bed6ba387c781c2ece94bbf Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 4 Feb 2014 13:56:41 +0100 Subject: [PATCH 108/119] Added unit tests for session_keepalive / heartbeat --- core/js/tests/specHelper.js | 18 +++++++- core/js/tests/specs/coreSpec.js | 74 +++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/core/js/tests/specHelper.js b/core/js/tests/specHelper.js index 4a30878df51..1848d08354e 100644 --- a/core/js/tests/specHelper.js +++ b/core/js/tests/specHelper.js @@ -19,6 +19,8 @@ * */ +/* global OC */ + /** * Simulate the variables that are normally set by PHP code */ @@ -57,10 +59,15 @@ window.oc_webroot = location.href + '/'; window.oc_appswebroots = { "files": window.oc_webroot + '/apps/files/' }; +window.oc_config = { + session_lifetime: 600 * 1000, + session_keepalive: false +}; // global setup for all tests (function setupTests() { - var fakeServer = null; + var fakeServer = null, + routesRequestStub; beforeEach(function() { // enforce fake XHR, tests should not depend on the server and @@ -78,9 +85,18 @@ window.oc_appswebroots = { // make it globally available, so that other tests can define // custom responses window.fakeServer = fakeServer; + + OC.Router.routes = []; + OC.Router.routes_request = { + state: sinon.stub().returns('resolved'), + done: sinon.stub() + }; }); afterEach(function() { + OC.Router.routes_request.state.reset(); + OC.Router.routes_request.done.reset(); + // uncomment this to log requests // console.log(window.fakeServer.requests); fakeServer.restore(); diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js index 28c20a0642e..18652d4177f 100644 --- a/core/js/tests/specs/coreSpec.js +++ b/core/js/tests/specs/coreSpec.js @@ -104,4 +104,78 @@ describe('Core base tests', function() { })).toEqual('number=123'); }); }); + describe('Session heartbeat', function() { + var clock, + oldConfig, + loadedStub, + routeStub, + counter; + + beforeEach(function() { + clock = sinon.useFakeTimers(); + oldConfig = window.oc_config; + loadedStub = sinon.stub(OC.Router, 'registerLoadedCallback'); + routeStub = sinon.stub(OC.Router, 'generate').returns('/heartbeat'); + counter = 0; + + fakeServer.autoRespond = true; + fakeServer.autoRespondAfter = 0; + fakeServer.respondWith(/\/heartbeat/, function(xhr) { + counter++; + xhr.respond(200, {'Content-Type': 'application/json'}, '{}'); + }); + }); + afterEach(function() { + clock.restore(); + window.oc_config = oldConfig; + loadedStub.restore(); + routeStub.restore(); + }); + it('sends heartbeat half the session lifetime when heartbeat enabled', function() { + window.oc_config = { + session_keepalive: true, + session_lifetime: 300 + }; + window.initCore(); + expect(loadedStub.calledOnce).toEqual(true); + loadedStub.yield(); + expect(routeStub.calledWith('heartbeat')).toEqual(true); + + expect(counter).toEqual(0); + + // less than half, still nothing + clock.tick(100 * 1000); + expect(counter).toEqual(0); + + // reach past half (160), one call + clock.tick(55 * 1000); + expect(counter).toEqual(1); + + // almost there to the next, still one + clock.tick(140 * 1000); + expect(counter).toEqual(1); + + // past it, second call + clock.tick(20 * 1000); + expect(counter).toEqual(2); + }); + it('does no send heartbeat when heartbeat disabled', function() { + window.oc_config = { + session_keepalive: false, + session_lifetime: 300 + }; + window.initCore(); + expect(loadedStub.notCalled).toEqual(true); + expect(routeStub.notCalled).toEqual(true); + + expect(counter).toEqual(0); + + clock.tick(1000000); + + // still nothing + expect(counter).toEqual(0); + }); + + }); }); + From fe2a63ffd425b354ee1cf6c2faaca19ca71717bb Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 4 Feb 2014 11:14:00 +0100 Subject: [PATCH 109/119] Scroll to the top after switching dir Fixes #7061 --- apps/files/js/filelist.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 23b31e72467..027a7bb9477 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -28,7 +28,8 @@ var FileList={ } FileList.updateFileSummary(); procesSelection(); - + + $(window).scrollTop(0); $fileList.trigger(jQuery.Event("updated")); }, createRow:function(type, name, iconurl, linktarget, size, lastModified, permissions) { @@ -394,7 +395,7 @@ var FileList={ } return true; }; - + form.submit(function(event) { event.stopPropagation(); event.preventDefault(); @@ -468,7 +469,7 @@ var FileList={ var basename = newname; if (newname.indexOf('.') > 0 && tr.data('type') !== 'dir') { basename = newname.substr(0, newname.lastIndexOf('.')); - } + } td.find('a.name span.nametext').text(basename); if (newname.indexOf('.') > 0 && tr.data('type') !== 'dir') { if ( ! td.find('a.name span.extension').exists() ) { @@ -834,7 +835,7 @@ $(document).ready(function() { {name: 'requesttoken', value: oc_requesttoken} ]; }; - } + } }); file_upload_start.on('fileuploadadd', function(e, data) { @@ -873,7 +874,7 @@ $(document).ready(function() { */ file_upload_start.on('fileuploaddone', function(e, data) { OC.Upload.log('filelist handle fileuploaddone', e, data); - + var response; if (typeof data.result === 'string') { response = data.result; From 45ab9810c597939074f750f985decc6d56a38c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Tue, 4 Feb 2014 20:58:06 +0100 Subject: [PATCH 110/119] fixing typos --- core/js/js.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/js/js.js b/core/js/js.js index cd9b8bd3010..cb177712a3a 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -750,7 +750,7 @@ function fillWindow(selector) { function initCore() { /** - * Calls the server periodically to ensure that session doesnt + * Calls the server periodically to ensure that session doesn't * time out */ function initSessionHeartBeat(){ @@ -771,7 +771,7 @@ function initCore() { }); } - // session heartbeat (defalts to enabled) + // session heartbeat (defaults to enabled) if (typeof(oc_config.session_keepalive) === 'undefined' || !!oc_config.session_keepalive) { From fa5ddc3e18a7bddc5510318b34062b31831403a5 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 5 Feb 2014 12:00:08 +0100 Subject: [PATCH 111/119] Fixed searchByMime in shared cache - searchByMime now correctly returns files recursively search through all the dirs - added unit test for searchByMime --- apps/files_sharing/lib/cache.php | 37 ++++++-- apps/files_sharing/tests/cache.php | 134 +++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 8 deletions(-) create mode 100644 apps/files_sharing/tests/cache.php diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 425d51113b1..86e324409fe 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -259,17 +259,38 @@ class Shared_Cache extends Cache { * @return array */ public function searchByMime($mimetype) { - - if (strpos($mimetype, '/')) { - $where = '`mimetype` = ? AND '; - } else { - $where = '`mimepart` = ? AND '; + $mimepart = null; + if (strpos($mimetype, '/') === false) { + $mimepart = $mimetype; + $mimetype = null; } - $value = $this->getMimetypeId($mimetype); - - return $this->searchWithWhere($where, $value); + // note: searchWithWhere is currently broken as it doesn't + // recurse into subdirs nor returns the correct + // file paths, so using getFolderContents() for now + $result = array(); + $exploreDirs = array(''); + while (count($exploreDirs) > 0) { + $dir = array_pop($exploreDirs); + $files = $this->getFolderContents($dir); + // no results? + if (!$files) { + continue; + } + foreach ($files as $file) { + if ($file['mimetype'] === 'httpd/unix-directory') { + $exploreDirs[] = ltrim($dir . '/' . $file['name'], '/'); + } + else if (($mimepart && $file['mimepart'] === $mimepart) || ($mimetype && $file['mimetype'] === $mimetype)) { + // usersPath not reliable + //$file['path'] = $file['usersPath']; + $file['path'] = ltrim($dir . '/' . $file['name'], '/'); + $result[] = $file; + } + } + } + return $result; } /** diff --git a/apps/files_sharing/tests/cache.php b/apps/files_sharing/tests/cache.php new file mode 100644 index 00000000000..56a51c83f6b --- /dev/null +++ b/apps/files_sharing/tests/cache.php @@ -0,0 +1,134 @@ + + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 library. If not, see . + * + */ +require_once __DIR__ . '/base.php'; + +class Test_Files_Sharing_Cache extends Test_Files_Sharing_Base { + + function setUp() { + parent::setUp(); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + // prepare user1's dir structure + $textData = "dummy file data\n"; + $this->view->mkdir('container'); + $this->view->mkdir('container/shareddir'); + $this->view->mkdir('container/shareddir/subdir'); + $this->view->mkdir('container/shareddir/emptydir'); + + $textData = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $this->view->file_put_contents('container/not shared.txt', $textData); + $this->view->file_put_contents('container/shared single file.txt', $textData); + $this->view->file_put_contents('container/shareddir/bar.txt', $textData); + $this->view->file_put_contents('container/shareddir/subdir/another.txt', $textData); + $this->view->file_put_contents('container/shareddir/subdir/another too.txt', $textData); + $this->view->file_put_contents('container/shareddir/subdir/not a text file.xml', ''); + + list($this->ownerStorage, $internalPath) = $this->view->resolvePath(''); + $this->ownerCache = $this->ownerStorage->getCache(); + $this->ownerStorage->getScanner()->scan(''); + + // share "shareddir" with user2 + $fileinfo = $this->view->getFileInfo('container/shareddir'); + \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2, 31); + + $fileinfo = $this->view->getFileInfo('container/shared single file.txt'); + \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2, 31); + + // login as user2 + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + + // retrieve the shared storage + $secondView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2); + list($this->sharedStorage, $internalPath) = $secondView->resolvePath('files/Shared/shareddir'); + $this->sharedCache = $this->sharedStorage->getCache(); + } + + function tearDown() { + $this->sharedCache->clear(); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + $fileinfo = $this->view->getFileInfo('container/shareddir'); + \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2); + + $fileinfo = $this->view->getFileInfo('container/shared single file.txt'); + \OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2); + + $this->view->deleteAll('container'); + + $this->ownerCache->clear(); + + parent::tearDown(); + } + + /** + * Test searching by mime type + */ + function testSearchByMime() { + $results = $this->sharedStorage->getCache()->searchByMime('text'); + $check = array( + array( + 'name' => 'shared single file.txt', + 'path' => 'shared single file.txt' + ), + array( + 'name' => 'bar.txt', + 'path' => 'shareddir/bar.txt' + ), + array( + 'name' => 'another too.txt', + 'path' => 'shareddir/subdir/another too.txt' + ), + array( + 'name' => 'another.txt', + 'path' => 'shareddir/subdir/another.txt' + ), + ); + $this->verifyFiles($check, $results); + + $results2 = $this->sharedStorage->getCache()->searchByMime('text/plain'); + + $this->verifyFiles($check, $results); + } + + /** + * Checks that all provided attributes exist in the files list, + * only the values provided in $examples will be used to check against + * the file list. The files order also needs to be the same. + * + * @param array $examples array of example files + * @param array $files array of files + */ + private function verifyFiles($examples, $files) { + $this->assertEquals(count($examples), count($files)); + foreach ($files as $i => $file) { + foreach ($examples[$i] as $key => $value) { + $this->assertEquals($value, $file[$key]); + } + } + } +} From 20935f4e2496b23c07d76d5ce2daf85bb60f0cce Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 5 Feb 2014 15:34:08 +0100 Subject: [PATCH 112/119] Catch setup errors during autotest --- autotest.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/autotest.sh b/autotest.sh index 94fc692a94d..b88e9cf68b4 100755 --- a/autotest.sh +++ b/autotest.sh @@ -185,19 +185,23 @@ EOF cp $BASEDIR/tests/autoconfig-$1.php $BASEDIR/config/autoconfig.php # trigger installation - php -f index.php + echo "INDEX" + php -f index.php | grep -i -C9999 error && echo "Error during setup" && exit 101 + echo "END INDEX" #test execution echo "Testing with $1 ..." cd tests rm -rf coverage-html-$1 mkdir coverage-html-$1 - php -f enable_all.php + php -f enable_all.php | grep -i -C9999 error && echo "Error during setup" && exit 101 if [ -z "$NOCOVERAGE" ]; then $PHPUNIT --configuration phpunit-autotest.xml --log-junit autotest-results-$1.xml --coverage-clover autotest-clover-$1.xml --coverage-html coverage-html-$1 $2 $3 + RESULT=$? else echo "No coverage" $PHPUNIT --configuration phpunit-autotest.xml --log-junit autotest-results-$1.xml $2 $3 + RESULT=$? fi } From e2625ae7aafc52f4b2869f2296d2de74a9b2c3a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 5 Feb 2014 18:23:40 +0100 Subject: [PATCH 113/119] fixing autoconfig handling --- core/setup/controller.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/core/setup/controller.php b/core/setup/controller.php index c628bda609b..58ed4d28dc0 100644 --- a/core/setup/controller.php +++ b/core/setup/controller.php @@ -56,17 +56,18 @@ class Controller { } public function loadAutoConfig($post) { - $dbIsSet = isset($post['dbtype']); - $directoryIsSet = isset($post['directory']); - $adminAccountIsSet = isset($post['adminlogin']); - $autosetup_file = \OC::$SERVERROOT.'/config/autoconfig.php'; if( file_exists( $autosetup_file )) { \OC_Log::write('core', 'Autoconfig file found, setting up owncloud...', \OC_Log::INFO); + $AUTOCONFIG = array(); include $autosetup_file; $post = array_merge ($post, $AUTOCONFIG); } + $dbIsSet = isset($post['dbtype']); + $directoryIsSet = isset($post['directory']); + $adminAccountIsSet = isset($post['adminlogin']); + if ($dbIsSet AND $directoryIsSet AND $adminAccountIsSet) { $post['install'] = 'true'; if( file_exists( $autosetup_file )) { From 8c56e21ced30f5e354b3a62c040a790a41548382 Mon Sep 17 00:00:00 2001 From: Pellaeon Lin Date: Thu, 6 Feb 2014 12:06:16 +0800 Subject: [PATCH 114/119] Move template variable assignment to correct place --- apps/files_sharing/public.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index b187da41324..fc716a514b4 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -143,8 +143,6 @@ if (isset($path)) { OCP\Util::addScript('files', 'jquery.iframe-transport'); OCP\Util::addScript('files', 'jquery.fileupload'); $maxUploadFilesize=OCP\Util::maxUploadFilesize($path); - $freeSpace=OCP\Util::freeSpace($dir); - $uploadLimit=OCP\Util::uploadLimit(); $tmpl = new OCP\Template('files_sharing', 'public', 'base'); $tmpl->assign('uidOwner', $shareOwner); $tmpl->assign('displayName', \OCP\User::getDisplayName($shareOwner)); @@ -164,8 +162,6 @@ if (isset($path)) { } $tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); $tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); - $tmpl->assign('freeSpace', $freeSpace); - $tmpl->assign('uploadLimit', $uploadLimit); // PHP upload limit $urlLinkIdentifiers= (isset($token)?'&t='.$token:'') .(isset($_GET['dir'])?'&dir='.$_GET['dir']:'') @@ -226,6 +222,9 @@ if (isset($path)) { $maxUploadFilesize=OCP\Util::maxUploadFilesize($path); $fileHeader = (!isset($files) or count($files) > 0); $emptyContent = ($allowPublicUploadEnabled and !$fileHeader); + + $freeSpace=OCP\Util::freeSpace($path); + $uploadLimit=OCP\Util::uploadLimit(); $folder = new OCP\Template('files', 'index', ''); $folder->assign('fileList', $list->fetchPage()); $folder->assign('breadcrumb', $breadcrumbNav->fetchPage()); @@ -238,6 +237,8 @@ if (isset($path)) { $folder->assign('files', $files); $folder->assign('uploadMaxFilesize', $maxUploadFilesize); $folder->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); + $folder->assign('freeSpace', $freeSpace); + $folder->assign('uploadLimit', $uploadLimit); // PHP upload limit $folder->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); $folder->assign('usedSpacePercent', 0); $folder->assign('fileHeader', $fileHeader); From 946fccc0dd5b7e51203d51fd2c60161cad7050ba Mon Sep 17 00:00:00 2001 From: Pellaeon Lin Date: Thu, 6 Feb 2014 12:26:12 +0800 Subject: [PATCH 115/119] Remove unused template variable assignment of files_sharing/template/public.php --- apps/files_sharing/public.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index fc716a514b4..f03ac7205a3 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -144,15 +144,12 @@ if (isset($path)) { OCP\Util::addScript('files', 'jquery.fileupload'); $maxUploadFilesize=OCP\Util::maxUploadFilesize($path); $tmpl = new OCP\Template('files_sharing', 'public', 'base'); - $tmpl->assign('uidOwner', $shareOwner); $tmpl->assign('displayName', \OCP\User::getDisplayName($shareOwner)); $tmpl->assign('filename', $file); $tmpl->assign('directory_path', $linkItem['file_target']); $tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path)); - $tmpl->assign('fileTarget', basename($linkItem['file_target'])); $tmpl->assign('dirToken', $linkItem['token']); $tmpl->assign('sharingToken', $token); - $tmpl->assign('disableSharing', true); $allowPublicUploadEnabled = (bool) ($linkItem['permissions'] & OCP\PERMISSION_CREATE); if (OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes') === 'no') { $allowPublicUploadEnabled = false; @@ -160,8 +157,6 @@ if (isset($path)) { if ($linkItem['item_type'] !== 'folder') { $allowPublicUploadEnabled = false; } - $tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); - $tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); $urlLinkIdentifiers= (isset($token)?'&t='.$token:'') .(isset($_GET['dir'])?'&dir='.$_GET['dir']:'') From 88087b21c7dad792a73a764248829e2c83faa49e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Fri, 7 Feb 2014 00:40:08 +0100 Subject: [PATCH 116/119] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ca7b04a925a..47778c8c932 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ A personal cloud which runs on your own server. ### Build Status on [Jenkins CI](https://ci.owncloud.org/) -Git master: [![Build Status](https://ci.owncloud.org/buildStatus/icon?job=ownCloud-Server%28master%29)](https://ci.owncloud.org/job/ownCloud-Server%28master%29/) +Git master: [![Build Status](https://ci.owncloud.org/job/server-master-linux/badge/icon)](https://ci.owncloud.org/job/server-master-linux/) +Quality: [![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/owncloud/core/badges/quality-score.png?s=ce2f5ded03d4ac628e9ee5c767243fa7412e644f)](https://scrutinizer-ci.com/g/owncloud/core/) ### Installation instructions http://doc.owncloud.org/server/5.0/developer_manual/app/gettingstarted.html From b9e724d4ae7635435b3cc7793237c3ab9fe2a1c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Fri, 7 Feb 2014 00:40:57 +0100 Subject: [PATCH 117/119] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 47778c8c932..3f76c1a4773 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ A personal cloud which runs on your own server. ### Build Status on [Jenkins CI](https://ci.owncloud.org/) Git master: [![Build Status](https://ci.owncloud.org/job/server-master-linux/badge/icon)](https://ci.owncloud.org/job/server-master-linux/) + Quality: [![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/owncloud/core/badges/quality-score.png?s=ce2f5ded03d4ac628e9ee5c767243fa7412e644f)](https://scrutinizer-ci.com/g/owncloud/core/) ### Installation instructions From a8943ad02207afbf142ec48f4b53cbe1be943253 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 6 Feb 2014 16:01:42 +0100 Subject: [PATCH 118/119] replace 'size' with 'unencrypted_size' if encryption is enabled --- apps/files_sharing/lib/cache.php | 15 +++++++++++++-- apps/files_sharing/lib/share/file.php | 9 ++++++++- lib/public/share.php | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 86e324409fe..1b102f9e5f8 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -92,12 +92,11 @@ class Shared_Cache extends Cache { } else { $query = \OC_DB::prepare( 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`,' - .' `size`, `mtime`, `encrypted`' + .' `size`, `mtime`, `encrypted`, `unencrypted_size`' .' FROM `*PREFIX*filecache` WHERE `fileid` = ?'); $result = $query->execute(array($file)); $data = $result->fetchRow(); $data['fileid'] = (int)$data['fileid']; - $data['size'] = (int)$data['size']; $data['mtime'] = (int)$data['mtime']; $data['storage_mtime'] = (int)$data['storage_mtime']; $data['encrypted'] = (bool)$data['encrypted']; @@ -106,6 +105,12 @@ class Shared_Cache extends Cache { if ($data['storage_mtime'] === 0) { $data['storage_mtime'] = $data['mtime']; } + if ($data['encrypted'] or ($data['unencrypted_size'] > 0 and $data['mimetype'] === 'httpd/unix-directory')) { + $data['encrypted_size'] = (int)$data['size']; + $data['size'] = (int)$data['unencrypted_size']; + } else { + $data['size'] = (int)$data['size']; + } return $data; } return false; @@ -334,6 +339,12 @@ class Shared_Cache extends Cache { } $row['mimetype'] = $this->getMimetype($row['mimetype']); $row['mimepart'] = $this->getMimetype($row['mimepart']); + if ($row['encrypted'] or ($row['unencrypted_size'] > 0 and $row['mimetype'] === 'httpd/unix-directory')) { + $row['encrypted_size'] = $row['size']; + $row['size'] = $row['unencrypted_size']; + } else { + $row['size'] = $row['size']; + } $files[] = $row; } } diff --git a/apps/files_sharing/lib/share/file.php b/apps/files_sharing/lib/share/file.php index c956c55a1df..ec0f368386f 100644 --- a/apps/files_sharing/lib/share/file.php +++ b/apps/files_sharing/lib/share/file.php @@ -91,10 +91,17 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { $file['name'] = basename($item['file_target']); $file['mimetype'] = $item['mimetype']; $file['mimepart'] = $item['mimepart']; - $file['size'] = $item['size']; $file['mtime'] = $item['mtime']; $file['encrypted'] = $item['encrypted']; $file['etag'] = $item['etag']; + $storage = \OC\Files\Filesystem::getStorage('/'); + $cache = $storage->getCache(); + if ($item['encrypted'] or ($item['unencrypted_size'] > 0 and $cache->getMimetype($item['mimetype']) === 'httpd/unix-directory')) { + $file['size'] = $item['unencrypted_size']; + $file['encrypted_size'] = $item['size']; + } else { + $file['size'] = $item['size']; + } $files[] = $file; } return $files; diff --git a/lib/public/share.php b/lib/public/share.php index f832d04a70f..ae7d29e8b87 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -1152,7 +1152,7 @@ class Share { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`, `uid_owner`, ' .'`share_type`, `share_with`, `file_source`, `path`, `file_target`, ' .'`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, ' - .'`name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`, `etag`, `mail_send`'; + .'`name`, `mtime`, `mimetype`, `mimepart`, `size`, `unencrypted_size`, `encrypted`, `etag`, `mail_send`'; } else { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`, From 91254c304d454b6f7977037dbd5dd2db5e00ff9f Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 7 Feb 2014 15:57:13 +0100 Subject: [PATCH 119/119] name users after test --- apps/files_encryption/tests/hooks.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files_encryption/tests/hooks.php b/apps/files_encryption/tests/hooks.php index c26cba6406d..44525791743 100644 --- a/apps/files_encryption/tests/hooks.php +++ b/apps/files_encryption/tests/hooks.php @@ -36,8 +36,8 @@ use OCA\Encryption; */ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { - const TEST_ENCRYPTION_HOOKS_USER1 = "test-proxy-user1"; - const TEST_ENCRYPTION_HOOKS_USER2 = "test-proxy-user2"; + const TEST_ENCRYPTION_HOOKS_USER1 = "test-encryption-hooks-user1"; + const TEST_ENCRYPTION_HOOKS_USER2 = "test-encryption-hooks-user2"; /** * @var \OC_FilesystemView