From 7c264c88fe06c61ef602fa8a241428c99f220061 Mon Sep 17 00:00:00 2001 From: Carlos Cerrillo Date: Sun, 15 Dec 2013 17:22:52 +0100 Subject: [PATCH 01/28] Fixing Issue #6301 on master branch Added private var $certPath to store the user root cert Move logic to determine the $certPath path to the constructor and modify to get the path from OC_User::getHome() Add curl options to use the certificate to avoid certificate errors with self-signed certicates in the downdload/upload method so we don't get blank files --- apps/files_external/lib/webdav.php | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 02f6cb5fc4..2308c7873b 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -14,6 +14,7 @@ class DAV extends \OC\Files\Storage\Common{ private $host; private $secure; private $root; + private $certPath; private $ready; /** * @var \Sabre_DAV_Client @@ -40,6 +41,12 @@ class DAV extends \OC\Files\Storage\Common{ } else { $this->secure = false; } + if ($this->secure === true) { + $certPath=\OC_User::getHome(\OC_User::getUser()) . '/files_external/rootcerts.crt'; + if (file_exists($certPath)) { + $this->certPath=$certPath; + } + } $this->root=isset($params['root'])?$params['root']:'/'; if ( ! $this->root || $this->root[0]!='/') { $this->root='/'.$this->root; @@ -66,12 +73,8 @@ class DAV extends \OC\Files\Storage\Common{ $this->client = new \Sabre_DAV_Client($settings); - $caview = \OCP\Files::getStorage('files_external'); - if ($caview) { - $certPath=\OCP\Config::getSystemValue('datadirectory').$caview->getAbsolutePath("").'rootcerts.crt'; - if (file_exists($certPath)) { - $this->client->addTrustedCertificates($certPath); - } + if ($this->certPath) { + $this->client->addTrustedCertificates($this->certPath); } } @@ -166,6 +169,11 @@ class DAV extends \OC\Files\Storage\Common{ curl_setopt($curl, CURLOPT_URL, $this->createBaseUri().str_replace(' ', '%20', $path)); curl_setopt($curl, CURLOPT_FILE, $fp); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); + if($this->certPath){ + curl_setopt($curl, CURLOPT_CAINFO, $this->certPath); + } curl_exec ($curl); curl_close ($curl); @@ -254,6 +262,11 @@ class DAV extends \OC\Files\Storage\Common{ curl_setopt($curl, CURLOPT_INFILE, $source); // file pointer curl_setopt($curl, CURLOPT_INFILESIZE, filesize($path)); curl_setopt($curl, CURLOPT_PUT, true); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); + if($this->certPath){ + curl_setopt($curl, CURLOPT_CAINFO, $this->certPath); + } curl_exec ($curl); curl_close ($curl); } @@ -331,3 +344,4 @@ class DAV extends \OC\Files\Storage\Common{ } } } + From b245e2e3d86299092448e3223b0d658d88206873 Mon Sep 17 00:00:00 2001 From: Carlos Cerrillo Date: Tue, 17 Dec 2013 09:38:43 +0100 Subject: [PATCH 02/28] Fixing tab/space coding style Only set SSL things when ```$this->secure``` is ```true``` --- apps/files_external/lib/webdav.php | 38 +++++++++++++++++------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 2308c7873b..9d56be8472 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -65,15 +65,15 @@ class DAV extends \OC\Files\Storage\Common{ } $this->ready = true; - $settings = array( - 'baseUri' => $this->createBaseUri(), - 'userName' => $this->user, - 'password' => $this->password, - ); + $settings = array( + 'baseUri' => $this->createBaseUri(), + 'userName' => $this->user, + 'password' => $this->password, + ); $this->client = new \Sabre_DAV_Client($settings); - if ($this->certPath) { + if ($this->secure === true && $this->certPath) { $this->client->addTrustedCertificates($this->certPath); } } @@ -169,12 +169,14 @@ class DAV extends \OC\Files\Storage\Common{ curl_setopt($curl, CURLOPT_URL, $this->createBaseUri().str_replace(' ', '%20', $path)); curl_setopt($curl, CURLOPT_FILE, $fp); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); - curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); - if($this->certPath){ - curl_setopt($curl, CURLOPT_CAINFO, $this->certPath); - } - + if ($this->secure === true) { + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); + if($this->certPath){ + curl_setopt($curl, CURLOPT_CAINFO, $this->certPath); + } + } + curl_exec ($curl); curl_close ($curl); rewind($fp); @@ -262,11 +264,13 @@ class DAV extends \OC\Files\Storage\Common{ curl_setopt($curl, CURLOPT_INFILE, $source); // file pointer curl_setopt($curl, CURLOPT_INFILESIZE, filesize($path)); curl_setopt($curl, CURLOPT_PUT, true); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); - curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); - if($this->certPath){ - curl_setopt($curl, CURLOPT_CAINFO, $this->certPath); - } + if ($this->secure === true) { + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); + if($this->certPath){ + curl_setopt($curl, CURLOPT_CAINFO, $this->certPath); + } + } curl_exec ($curl); curl_close ($curl); } From c06844c374c145b2f05ae0800678f68acc9ae2e3 Mon Sep 17 00:00:00 2001 From: Carlos Cerrillo Date: Tue, 17 Dec 2013 10:13:14 +0100 Subject: [PATCH 03/28] Fix ```createCertificateBundle``` and ```getCertificates``` methods from ```OC_Mount_config``` to use ```OC_User::getHome``` to get the path --- apps/files_external/lib/config.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 12836c7b88..373246a429 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -382,8 +382,7 @@ class OC_Mount_Config { * @return array */ public static function getCertificates() { - $view = \OCP\Files::getStorage('files_external'); - $path=\OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath("").'uploads/'; + $path=OC_User::getHome(OC_User::getUser()) . '/files_external/uploads/'; \OCP\Util::writeLog('files_external', 'checking path '.$path, \OCP\Util::INFO); if ( ! is_dir($path)) { //path might not exist (e.g. non-standard OC_User::getHome() value) @@ -405,8 +404,7 @@ class OC_Mount_Config { * creates certificate bundle */ public static function createCertificateBundle() { - $view = \OCP\Files::getStorage("files_external"); - $path = \OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath(""); + $path=OC_User::getHome(OC_User::getUser()) . '/files_external'; $certs = OC_Mount_Config::getCertificates(); $fh_certs = fopen($path."/rootcerts.crt", 'w'); From 8eaa39f4e2fb7bb1036aca5727db320de00960e2 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 8 Jan 2014 18:43:20 +0100 Subject: [PATCH 04/28] Removed special handling of part files in shared storage rename This fixes the issue introduced by the transfer id which itself wasn't taken into account by the shortcut code for part file in the shared storage class. --- apps/files_sharing/lib/sharedstorage.php | 33 +++++++++--------------- lib/private/connector/sabre/file.php | 5 +++- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 3116cd717f..6b4db9763f 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -293,29 +293,20 @@ class Shared extends \OC\Files\Storage\Common { } public function rename($path1, $path2) { - // Check for partial files - if (pathinfo($path1, PATHINFO_EXTENSION) === 'part') { - if ($oldSource = $this->getSourcePath($path1)) { + // Renaming/moving is only allowed within shared folders + $pos1 = strpos($path1, '/', 1); + $pos2 = strpos($path2, '/', 1); + if ($pos1 !== false && $pos2 !== false && ($oldSource = $this->getSourcePath($path1))) { + $newSource = $this->getSourcePath(dirname($path2)) . '/' . basename($path2); + // Within the same folder, we only need UPDATE permissions + if (dirname($path1) == dirname($path2) and $this->isUpdatable($path1)) { list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource); - $newInternalPath = substr($oldInternalPath, 0, -5); + list(, $newInternalPath) = \OC\Files\Filesystem::resolvePath($newSource); return $storage->rename($oldInternalPath, $newInternalPath); - } - } else { - // Renaming/moving is only allowed within shared folders - $pos1 = strpos($path1, '/', 1); - $pos2 = strpos($path2, '/', 1); - if ($pos1 !== false && $pos2 !== false && ($oldSource = $this->getSourcePath($path1))) { - $newSource = $this->getSourcePath(dirname($path2)) . '/' . basename($path2); - // Within the same folder, we only need UPDATE permissions - if (dirname($path1) == dirname($path2) and $this->isUpdatable($path1)) { - list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource); - list(, $newInternalPath) = \OC\Files\Filesystem::resolvePath($newSource); - return $storage->rename($oldInternalPath, $newInternalPath); - // otherwise DELETE and CREATE permissions required - } elseif ($this->isDeletable($path1) && $this->isCreatable(dirname($path2))) { - $rootView = new \OC\Files\View(''); - return $rootView->rename($oldSource, $newSource); - } + // otherwise DELETE and CREATE permissions required + } elseif ($this->isDeletable($path1) && $this->isCreatable(dirname($path2))) { + $rootView = new \OC\Files\View(''); + return $rootView->rename($oldSource, $newSource); } } return false; diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php index 53524ec9e5..c3b5900729 100644 --- a/lib/private/connector/sabre/file.php +++ b/lib/private/connector/sabre/file.php @@ -242,7 +242,10 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D $fileExists = $fs->file_exists($targetPath); if ($renameOkay === false || $fileExists === false) { \OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR); - $fs->unlink($targetPath); + // only delete if an error occurred and the target file was already created + if ($fileExists) { + $fs->unlink($targetPath); + } throw new Sabre_DAV_Exception(); } From 9b7c3a5c66a9f987ff572aaece2ef6e895bf4ab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 9 Jan 2014 10:27:47 +0100 Subject: [PATCH 05/28] fixing PHPDoc and use cameCase names --- lib/private/user/session.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/private/user/session.php b/lib/private/user/session.php index c2885d0041..1e299416fb 100644 --- a/lib/private/user/session.php +++ b/lib/private/user/session.php @@ -115,13 +115,13 @@ class Session implements Emitter, \OCP\IUserSession { /** * set the login name * - * @param string login name for the logged in user + * @param string $loginName for the logged in user */ - public function setLoginname($loginname) { - if (is_null($loginname)) { + public function setLoginName($loginName) { + if (is_null($loginName)) { $this->session->remove('loginname'); } else { - $this->session->set('loginname', $loginname); + $this->session->set('loginname', $loginName); } } @@ -130,7 +130,7 @@ class Session implements Emitter, \OCP\IUserSession { * * @return string */ - public function getLoginname() { + public function getLoginName() { if ($this->activeUser) { return $this->session->get('loginname'); } else { @@ -158,7 +158,7 @@ class Session implements Emitter, \OCP\IUserSession { if (!is_null($user)) { if ($user->isEnabled()) { $this->setUser($user); - $this->setLoginname($uid); + $this->setLoginName($uid); $this->manager->emit('\OC\User', 'postLogin', array($user, $password)); return true; } else { @@ -176,7 +176,7 @@ class Session implements Emitter, \OCP\IUserSession { public function logout() { $this->manager->emit('\OC\User', 'logout'); $this->setUser(null); - $this->setLoginname(null); + $this->setLoginName(null); $this->unsetMagicInCookie(); } From 22bd69f75cc91a79653038d20143aff9ee8b226a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 9 Jan 2014 10:28:24 +0100 Subject: [PATCH 06/28] set login name within apache auth backend --- lib/private/user.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/private/user.php b/lib/private/user.php index e0d6b9f3f5..98ebebbe5c 100644 --- a/lib/private/user.php +++ b/lib/private/user.php @@ -246,6 +246,8 @@ class OC_User { session_regenerate_id(true); self::setUserId($uid); self::setDisplayName($uid); + self::getUserSession()->setLoginName($uid); + OC_Hook::emit( "OC_User", "post_login", array( "uid" => $uid, 'password'=>'' )); return true; } From c3829dfa61ce9d884f8c7d9c81381ac5987e8250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 9 Jan 2014 10:29:21 +0100 Subject: [PATCH 07/28] rename user-id to loginname to stay consistent --- lib/base.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/base.php b/lib/base.php index a8e9e90184..f30575c7b1 100644 --- a/lib/base.php +++ b/lib/base.php @@ -544,12 +544,12 @@ class OC { OC_User::useBackend(new OC_User_Database()); OC_Group::useBackend(new OC_Group_Database()); - if (isset($_SERVER['PHP_AUTH_USER']) && self::$session->exists('user_id') + if (isset($_SERVER['PHP_AUTH_USER']) && self::$session->exists('loginname') && $_SERVER['PHP_AUTH_USER'] !== self::$session->get('loginname')) { $sessionUser = self::$session->get('loginname'); $serverUser = $_SERVER['PHP_AUTH_USER']; OC_Log::write('core', - "Session user-id ($sessionUser) doesn't match SERVER[PHP_AUTH_USER] ($serverUser).", + "Session loginname ($sessionUser) doesn't match SERVER[PHP_AUTH_USER] ($serverUser).", OC_Log::WARN); OC_User::logout(); } From 76a7ae77a8ca18f8fcac03099b6e53cc8838ea31 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Thu, 9 Jan 2014 10:54:23 +0100 Subject: [PATCH 08/28] fix email template l10n, emphasize filename --- core/templates/mail.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/templates/mail.php b/core/templates/mail.php index 4fa54aa528..b8b0a2bfe9 100644 --- a/core/templates/mail.php +++ b/core/templates/mail.php @@ -12,7 +12,7 @@   t('Hey there,

just letting you know that %s shared »%s« with you.
View it!

', array($_['user_displayname'], $_['filename'], $_['link']))); +print_unescaped($l->t('Hey there,

just letting you know that %s shared %s with you.
View it!

', array($_['user_displayname'], $_['filename'], $_['link']))); if ( isset($_['expiration']) ) { p($l->t("The share will expire on %s.", array($_['expiration']))); print_unescaped('

'); From 4faba49f0a38427e96ef8393900f799c5a5ba6aa Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Thu, 9 Jan 2014 17:27:55 +0100 Subject: [PATCH 09/28] Fix calculated folder size to use unencrypted size The encrypted size was used when calculating folder sizes. This fix now also sums up the unencrypted size and shows that one when available. --- lib/private/files/cache/cache.php | 22 +++++++++++---- tests/lib/files/cache/cache.php | 45 +++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php index 8e682a96b7..1e7936ca26 100644 --- a/lib/private/files/cache/cache.php +++ b/lib/private/files/cache/cache.php @@ -178,7 +178,7 @@ class Cache { if ($file['storage_mtime'] == 0) { $file['storage_mtime'] = $file['mtime']; } - if ($file['encrypted']) { + if ($file['encrypted'] or ($file['unencrypted_size'] > 0 and $file['mimetype'] === 'httpd/unix-directory')) { $file['encrypted_size'] = $file['size']; $file['size'] = $file['unencrypted_size']; } @@ -511,22 +511,34 @@ class Cache { $entry = $this->get($path); if ($entry && $entry['mimetype'] === 'httpd/unix-directory') { $id = $entry['fileid']; - $sql = 'SELECT SUM(`size`) AS f1, MIN(`size`) AS f2 FROM `*PREFIX*filecache` '. + $sql = 'SELECT SUM(`size`) AS f1, MIN(`size`) AS f2, ' . + 'SUM(`unencrypted_size`) AS f3 ' . + 'FROM `*PREFIX*filecache` ' . 'WHERE `parent` = ? AND `storage` = ?'; $result = \OC_DB::executeAudited($sql, array($id, $this->getNumericStorageId())); if ($row = $result->fetchRow()) { - list($sum, $min) = array_values($row); + list($sum, $min, $unencryptedSum) = array_values($row); $sum = (int)$sum; $min = (int)$min; + $unencryptedSum = (int)$unencryptedSum; if ($min === -1) { $totalSize = $min; } else { $totalSize = $sum; } + $update = array(); if ($entry['size'] !== $totalSize) { - $this->update($id, array('size' => $totalSize)); + $update['size'] = $totalSize; + } + if ($entry['unencrypted_size'] !== $unencryptedSum) { + $update['unencrypted_size'] = $unencryptedSum; + } + if (count($update) > 0) { + $this->update($id, $update); + } + if ($totalSize !== -1 and $unencryptedSum > 0) { + $totalSize = $unencryptedSum; } - } } return $totalSize; diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 052d70dd0b..7d9329328a 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -137,6 +137,51 @@ class Cache extends \PHPUnit_Framework_TestCase { $this->assertFalse($this->cache->inCache('folder/bar')); } + public function testEncryptedFolder() { + $file1 = 'folder'; + $file2 = 'folder/bar'; + $file3 = 'folder/foo'; + $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory'); + $fileData = array(); + $fileData['bar'] = array('size' => 1000, 'unencrypted_size' => 900, 'encrypted' => 1, 'mtime' => 20, 'mimetype' => 'foo/file'); + $fileData['foo'] = array('size' => 20, 'unencrypted_size' => 16, 'encrypted' => 1, 'mtime' => 25, 'mimetype' => 'foo/file'); + + $this->cache->put($file1, $data1); + $this->cache->put($file2, $fileData['bar']); + $this->cache->put($file3, $fileData['foo']); + + $content = $this->cache->getFolderContents($file1); + $this->assertEquals(count($content), 2); + foreach ($content as $cachedData) { + $data = $fileData[$cachedData['name']]; + // indirect retrieval swaps unencrypted_size and size + $this->assertEquals($data['unencrypted_size'], $cachedData['size']); + } + + $file4 = 'folder/unkownSize'; + $fileData['unkownSize'] = array('size' => -1, 'mtime' => 25, 'mimetype' => 'foo/file'); + $this->cache->put($file4, $fileData['unkownSize']); + + $this->assertEquals(-1, $this->cache->calculateFolderSize($file1)); + + $fileData['unkownSize'] = array('size' => 5, 'mtime' => 25, 'mimetype' => 'foo/file'); + $this->cache->put($file4, $fileData['unkownSize']); + + $this->assertEquals(916, $this->cache->calculateFolderSize($file1)); + // direct cache entry retrieval returns the original values + $this->assertEquals(1025, $this->cache->get($file1)['size']); + $this->assertEquals(916, $this->cache->get($file1)['unencrypted_size']); + + $this->cache->remove($file2); + $this->cache->remove($file3); + $this->cache->remove($file4); + $this->assertEquals(0, $this->cache->calculateFolderSize($file1)); + + $this->cache->remove('folder'); + $this->assertFalse($this->cache->inCache('folder/foo')); + $this->assertFalse($this->cache->inCache('folder/bar')); + } + public function testRootFolderSizeForNonHomeStorage() { $dir1 = 'knownsize'; $dir2 = 'unknownsize'; From 1042733634622b234beb52e24505d56a9883b4eb Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 10 Jan 2014 15:02:26 +0100 Subject: [PATCH 10/28] Fixed various file name escaping issues in core apps - Refactored file tr lookup into FileList.findFileEl that uses filterAttr to avoid escaping issues in jQuery selectors - Fixed versions and sharing app to properly escape file names in attributes --- apps/files/js/file-upload.js | 12 ++++++-- apps/files/js/fileactions.js | 2 +- apps/files/js/filelist.js | 49 ++++++++++++++++++------------ apps/files/js/files.js | 14 +++++---- apps/files_sharing/js/public.js | 6 ++-- apps/files_sharing/js/share.js | 2 +- apps/files_trashbin/js/trash.js | 14 ++++----- apps/files_versions/js/versions.js | 16 +++++----- core/js/share.js | 10 ++++-- 9 files changed, 75 insertions(+), 50 deletions(-) diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index 196817432d..225c331910 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -222,6 +222,14 @@ $(document).ready(function() { //examine file var file = data.files[0]; + try { + // FIXME: not so elegant... need to refactor that method to return a value + Files.isFileNameValid(file.name); + } + catch (errorMessage) { + data.textStatus = 'invalidcharacters'; + data.errorThrown = errorMessage; + } if (file.type === '' && file.size === 4096) { data.textStatus = 'dirorzero'; @@ -605,7 +613,7 @@ $(document).ready(function() { if (result.status === 'success') { var date=new Date(); FileList.addDir(name, 0, date, hidden); - var tr=$('tr[data-file="'+name+'"]'); + var tr = FileList.findFileEl(name); tr.attr('data-id', result.data.id); } else { OC.dialogs.alert(result.data.message, t('core', 'Could not create folder')); @@ -647,7 +655,7 @@ $(document).ready(function() { $('#uploadprogressbar').fadeOut(); var date = new Date(); FileList.addFile(localName, size, date, false, hidden); - var tr = $('tr[data-file="'+localName+'"]'); + var tr = FileList.findFileEl(localName); tr.data('mime', mime).data('id', id); tr.attr('data-id', id); var path = $('#dir').val()+'/'+localName; diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js index 03e23189a9..74bb711ef3 100644 --- a/apps/files/js/fileactions.js +++ b/apps/files/js/fileactions.js @@ -71,7 +71,7 @@ var FileActions = { FileActions.currentFile = parent; var actions = FileActions.get(FileActions.getCurrentMimeType(), FileActions.getCurrentType(), FileActions.getCurrentPermissions()); var file = FileActions.getCurrentFile(); - if ($('tr[data-file="'+file+'"]').data('renaming')) { + if (FileList.findFileEl(file).data('renaming')) { return; } diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 473bcf25f2..c02ab70ce8 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -6,6 +6,13 @@ var FileList={ $(this).attr('data-file',decodeURIComponent($(this).attr('data-file'))); }); }, + /** + * Returns the tr element for a given file name + */ + findFileEl: function(fileName){ + // use filterAttr to avoid escaping issues + return $('#fileList tr').filterAttr('data-file', fileName); + }, update:function(fileListHtml) { var $fileList = $('#fileList'); $fileList.empty().html(fileListHtml); @@ -292,8 +299,9 @@ var FileList={ $('#filestable').toggleClass('hidden', show); }, remove:function(name){ - $('tr').filterAttr('data-file',name).find('td.filename').draggable('destroy'); - $('tr').filterAttr('data-file',name).remove(); + var fileEl = FileList.findFileEl(name); + fileEl.find('td.filename').draggable('destroy'); + fileEl.remove(); FileList.updateFileSummary(); if ( ! $('tr[data-file]').exists() ) { $('#emptycontent').removeClass('hidden'); @@ -334,7 +342,7 @@ var FileList={ FileList.updateFileSummary(); }, loadingDone:function(name, id) { - var mime, tr = $('tr[data-file="'+name+'"]'); + var mime, tr = FileList.findFileEl(name); tr.data('loading', false); mime = tr.data('mime'); tr.attr('data-mime', mime); @@ -347,12 +355,12 @@ var FileList={ }, null, null, tr.attr('data-etag')); tr.find('td.filename').draggable(dragOptions); }, - isLoading:function(name) { - return $('tr[data-file="'+name+'"]').data('loading'); + isLoading:function(file) { + return FileList.findFileEl(file).data('loading'); }, rename:function(oldname) { var tr, td, input, form; - tr = $('tr[data-file="'+oldname+'"]'); + tr = FileList.findFileEl(oldname); tr.data('renaming',true); td = tr.children('td.filename'); input = $('').val(oldname); @@ -500,14 +508,16 @@ var FileList={ form.trigger('submit'); }); }, - inList:function(filename) { - return $('#fileList tr[data-file="'+filename+'"]').length; + inList:function(file) { + return FileList.findFileEl(file).length; }, replace:function(oldName, newName, isNewFile) { // Finish any existing actions - $('tr[data-file="'+oldName+'"]').hide(); - $('tr[data-file="'+newName+'"]').hide(); - var tr = $('tr[data-file="'+oldName+'"]').clone(); + var oldFileEl = FileList.findFileEl(oldName); + var newFileEl = FileList.findFileEl(newName); + oldFileEl.hide(); + newFileEl.hide(); + var tr = oldFileEl.clone(); tr.attr('data-replace', 'true'); tr.attr('data-file', newName); var td = tr.children('td.filename'); @@ -559,7 +569,7 @@ var FileList={ files=[files]; } for (var i=0; i span').attr('data-oldName'); + FileList.findFileEl(file).show(); OC.Notification.hide(); }); $('#notification:first-child').on('click', '.cancel', function() { diff --git a/apps/files/js/files.js b/apps/files/js/files.js index fdaa3aa334..1f12ade8d7 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -282,7 +282,7 @@ $(document).ready(function() { procesSelection(); } else { var filename=$(this).parent().parent().attr('data-file'); - var tr=$('tr[data-file="'+filename+'"]'); + var tr = FileList.findFileEl(filename); var renaming=tr.data('renaming'); if (!renaming && !FileList.isLoading(filename)) { FileActions.currentFile = $(this).parent(); @@ -541,10 +541,12 @@ var folderDropOptions={ if (result) { if (result.status === 'success') { //recalculate folder size - var oldSize = $('#fileList tr[data-file="'+target+'"]').data('size'); - var newSize = oldSize + $('#fileList tr[data-file="'+file+'"]').data('size'); - $('#fileList tr[data-file="'+target+'"]').data('size', newSize); - $('#fileList tr[data-file="'+target+'"]').find('td.filesize').text(humanFileSize(newSize)); + var oldFile = FileList.findFileEl(target); + var newFile = FileList.findFileEl(file); + var oldSize = oldFile.data('size'); + var newSize = oldSize + newFile.data('size'); + oldFile.data('size', newSize); + oldFile.find('td.filesize').text(humanFileSize(newSize)); FileList.remove(file); procesSelection(); @@ -738,7 +740,7 @@ Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) { } function getUniqueName(name) { - if ($('tr[data-file="'+name+'"]').exists()) { + if (FileList.findFileEl(name).exists()) { var parts=name.split('.'); var extension = ""; if (parts.length > 1) { diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js index eacd4096ed..2e34e6f9bc 100644 --- a/apps/files_sharing/js/public.js +++ b/apps/files_sharing/js/public.js @@ -29,19 +29,19 @@ $(document).ready(function() { } } FileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function(filename) { - var tr = $('tr').filterAttr('data-file', filename); + var tr = FileList.findFileEl(filename); if (tr.length > 0) { window.location = $(tr).find('a.name').attr('href'); } }); FileActions.register('file', 'Download', OC.PERMISSION_READ, '', function(filename) { - var tr = $('tr').filterAttr('data-file', filename); + var tr = FileList.findFileEl(filename); if (tr.length > 0) { window.location = $(tr).find('a.name').attr('href'); } }); FileActions.register('dir', 'Download', OC.PERMISSION_READ, '', function(filename) { - var tr = $('tr').filterAttr('data-file', filename); + var tr = FileList.findFileEl(filename); if (tr.length > 0) { window.location = $(tr).find('a.name').attr('href')+'&download'; } diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js index 340e093944..36de452a55 100644 --- a/apps/files_sharing/js/share.js +++ b/apps/files_sharing/js/share.js @@ -22,7 +22,7 @@ $(document).ready(function() { } else { var item = $('#dir').val() + '/' + filename; } - var tr = $('tr').filterAttr('data-file', filename); + var tr = FileList.findFileEl(filename); if ($(tr).data('type') == 'dir') { var itemType = 'folder'; } else { diff --git a/apps/files_trashbin/js/trash.js b/apps/files_trashbin/js/trash.js index 1ff5bac613..46d8b56308 100644 --- a/apps/files_trashbin/js/trash.js +++ b/apps/files_trashbin/js/trash.js @@ -3,8 +3,8 @@ $(document).ready(function() { if (typeof FileActions !== 'undefined') { FileActions.register('all', 'Restore', OC.PERMISSION_READ, OC.imagePath('core', 'actions/history'), function(filename) { - var tr = $('tr').filterAttr('data-file', filename); - var deleteAction = $('tr').filterAttr('data-file', filename).children("td.date").children(".action.delete"); + var tr = FileList.findFileEl(filename); + var deleteAction = tr.children("td.date").children(".action.delete"); deleteAction.removeClass('delete-icon').addClass('progress-icon'); disableActions(); $.post(OC.filePath('files_trashbin', 'ajax', 'undelete.php'), @@ -30,8 +30,8 @@ $(document).ready(function() { return OC.imagePath('core', 'actions/delete'); }, function(filename) { $('.tipsy').remove(); - var tr = $('tr').filterAttr('data-file', filename); - var deleteAction = $('tr').filterAttr('data-file', filename).children("td.date").children(".action.delete"); + var tr = FileList.findFileEl(filename); + var deleteAction = tr.children("td.date").children(".action.delete"); deleteAction.removeClass('delete-icon').addClass('progress-icon'); disableActions(); $.post(OC.filePath('files_trashbin', 'ajax', 'delete.php'), @@ -73,7 +73,7 @@ $(document).ready(function() { var dirlisting = getSelectedFiles('dirlisting')[0]; disableActions(); for (var i = 0; i < files.length; i++) { - var deleteAction = $('tr').filterAttr('data-file', files[i]).children("td.date").children(".action.delete"); + var deleteAction = FileList.findFileEl(files[i]).children("td.date").children(".action.delete"); deleteAction.removeClass('delete-icon').addClass('progress-icon'); } @@ -119,7 +119,7 @@ $(document).ready(function() { } else { for (var i = 0; i < files.length; i++) { - var deleteAction = $('tr').filterAttr('data-file', files[i]).children("td.date").children(".action.delete"); + var deleteAction = FileList.findFileEl(files[i]).children("td.date").children(".action.delete"); deleteAction.removeClass('delete-icon').addClass('progress-icon'); } } @@ -169,7 +169,7 @@ $(document).ready(function() { event.preventDefault(); } var filename = $(this).parent().parent().attr('data-file'); - var tr = $('tr').filterAttr('data-file',filename); + var tr = FileList.findFileEl(filename); var renaming = tr.data('renaming'); if(!renaming && !FileList.isLoading(filename)){ if(mime.substr(0, 5) === 'text/'){ //no texteditor for now diff --git a/apps/files_versions/js/versions.js b/apps/files_versions/js/versions.js index 738a7ece6f..4adf14745d 100644 --- a/apps/files_versions/js/versions.js +++ b/apps/files_versions/js/versions.js @@ -77,6 +77,7 @@ function goToVersionPage(url){ function createVersionsDropdown(filename, files) { var start = 0; + var fileEl; var html = '