diff options
Diffstat (limited to 'apps')
26 files changed, 352 insertions, 165 deletions
diff --git a/apps/files/ajax/delete.php b/apps/files/ajax/delete.php index c69f5a8860c..69f859daa97 100644 --- a/apps/files/ajax/delete.php +++ b/apps/files/ajax/delete.php @@ -9,8 +9,21 @@ OCP\JSON::callCheck(); // Get data $dir = stripslashes($_POST["dir"]); $files = isset($_POST["file"]) ? $_POST["file"] : $_POST["files"]; +$allFiles = isset($_POST["allfiles"]) ? $_POST["allfiles"] : $_POST["allfiles"]; +if ($allFiles === 'true') { + $allFiles = true; +} -$files = json_decode($files); +// delete all files in dir ? +if ($allFiles) { + $files = array(); + $fileList = \OC\Files\Filesystem::getDirectoryContent($dir); + foreach ($fileList as $fileInfo) { + $files[] = $fileInfo['name']; + } +} else { + $files = json_decode($files); +} $filesWithError = ''; $success = true; diff --git a/apps/files/ajax/newfile.php b/apps/files/ajax/newfile.php index 1853098c507..0187b200759 100644 --- a/apps/files/ajax/newfile.php +++ b/apps/files/ajax/newfile.php @@ -50,16 +50,22 @@ $l10n = \OC_L10n::get('files'); $result = array( 'success' => false, 'data' => NULL - ); +); +$trimmedFileName = trim($filename); -if(trim($filename) === '') { +if($trimmedFileName === '') { $result['data'] = array('message' => (string)$l10n->t('File name cannot be empty.')); OCP\JSON::error($result); exit(); } +if($trimmedFileName === '.' || $trimmedFileName === '..') { + $result['data'] = array('message' => (string)$l10n->t('"%s" is an invalid file name.', $trimmedFileName)); + OCP\JSON::error($result); + exit(); +} -if(strpos($filename, '/') !== false) { - $result['data'] = array('message' => (string)$l10n->t('File name must not contain "/". Please choose a different name.')); +if(!OCP\Util::isValidFileName($filename)) { + $result['data'] = array('message' => (string)$l10n->t("Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed.")); OCP\JSON::error($result); exit(); } diff --git a/apps/files/ajax/newfolder.php b/apps/files/ajax/newfolder.php index 4cfcae3090d..b2b4fb27f74 100644 --- a/apps/files/ajax/newfolder.php +++ b/apps/files/ajax/newfolder.php @@ -23,8 +23,8 @@ if(trim($foldername) === '') { exit(); } -if(strpos($foldername, '/') !== false) { - $result['data'] = array('message' => $l10n->t('Folder name must not contain "/". Please choose a different name.')); +if(!OCP\Util::isValidFileName($foldername)) { + $result['data'] = array('message' => (string)$l10n->t("Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed.")); OCP\JSON::error($result); exit(); } diff --git a/apps/files/appinfo/update.php b/apps/files/appinfo/update.php index 3503678e7c7..f920f842166 100644 --- a/apps/files/appinfo/update.php +++ b/apps/files/appinfo/update.php @@ -3,17 +3,14 @@ // fix webdav properties,add namespace in front of the property, update for OC4.5 $installedVersion=OCP\Config::getAppValue('files', 'installed_version'); if (version_compare($installedVersion, '1.1.6', '<')) { - $query = OC_DB::prepare( 'SELECT `propertyname`, `propertypath`, `userid` FROM `*PREFIX*properties`' ); - $result = $query->execute(); - $updateQuery = OC_DB::prepare('UPDATE `*PREFIX*properties`' - .' SET `propertyname` = ?' - .' WHERE `userid` = ?' - .' AND `propertypath` = ?'); - while( $row = $result->fetchRow()) { - if ( $row['propertyname'][0] != '{' ) { - $updateQuery->execute(array('{DAV:}' + $row['propertyname'], $row['userid'], $row['propertypath'])); - } - } + $concat = OC_DB::getConnection()->getDatabasePlatform()-> + getConcatExpression( '\'{DAV:}\'', '`propertyname`' ); + $query = OC_DB::prepare(' + UPDATE `*PREFIX*properties` + SET `propertyname` = ' . $concat . ' + WHERE `propertyname` NOT LIKE \'{%\' + '); + $query->execute(); } //update from OC 3 diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index a855d6cbe59..d6cffde05de 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -582,30 +582,49 @@ window.FileList={ }}); } }, - do_delete:function(files) { - if (files.substr) { + do_delete:function(files, dir) { + var params; + if (files && files.substr) { files=[files]; } - for (var i=0; i<files.length; i++) { - var deleteAction = FileList.findFileEl(files[i]).children("td.date").children(".action.delete"); - deleteAction.removeClass('delete-icon').addClass('progress-icon'); + if (files) { + for (var i=0; i<files.length; i++) { + var deleteAction = FileList.findFileEl(files[i]).children("td.date").children(".action.delete"); + deleteAction.removeClass('delete-icon').addClass('progress-icon'); + } } // Finish any existing actions if (FileList.lastAction) { FileList.lastAction(); } - var fileNames = JSON.stringify(files); + var params = { + dir: dir || FileList.getCurrentDirectory() + }; + if (files) { + params.files = JSON.stringify(files); + } + else { + // no files passed, delete all in current dir + params.allfiles = true; + } + $.post(OC.filePath('files', 'ajax', 'delete.php'), - {dir:$('#dir').val(),files:fileNames}, + params, function(result) { if (result.status === 'success') { - $.each(files,function(index,file) { - var files = FileList.findFileEl(file); - files.remove(); - files.find('input[type="checkbox"]').removeAttr('checked'); - files.removeClass('selected'); - }); + if (params.allfiles) { + // clear whole list + $('#fileList tr').remove(); + } + else { + $.each(files,function(index,file) { + var files = FileList.findFileEl(file); + files.remove(); + files.find('input[type="checkbox"]').removeAttr('checked'); + files.removeClass('selected'); + }); + } procesSelection(); checkTrashStatus(); FileList.updateFileSummary(); @@ -622,10 +641,17 @@ window.FileList={ setTimeout(function() { OC.Notification.hide(); }, 10000); - $.each(files,function(index,file) { - var deleteAction = FileList.findFileEl(file).find('.action.delete'); - deleteAction.removeClass('progress-icon').addClass('delete-icon'); - }); + if (params.allfiles) { + // reload the page as we don't know what files were deleted + // and which ones remain + FileList.reload(); + } + else { + $.each(files,function(index,file) { + var deleteAction = FileList.findFileEl(file).find('.action.delete'); + deleteAction.removeClass('progress-icon').addClass('delete-icon'); + }); + } } }); }, @@ -794,6 +820,13 @@ window.FileList={ $(e).removeClass("searchresult"); }); }, + /** + * Returns whether all files are selected + * @return true if all files are selected, false otherwise + */ + isAllSelected: function() { + return $('#select_all').prop('checked'); + }, /** * Returns the download URL of the given file @@ -801,10 +834,13 @@ window.FileList={ * @param dir optional directory in which the file name is, defaults to the current directory */ getDownloadUrl: function(filename, dir) { + var files = filename; + if ($.isArray(filename)) { + files = JSON.stringify(filename); + } var params = { - files: filename, dir: dir || FileList.getCurrentDirectory(), - download: null + files: files }; return OC.filePath('files', 'ajax', 'download.php') + '?' + OC.buildQueryString(params); } diff --git a/apps/files/js/files.js b/apps/files/js/files.js index 1ec4c4ec7ab..fbac601f67a 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -364,23 +364,26 @@ $(document).ready(function() { }); $('.download').click('click',function(event) { - var files=getSelectedFilesTrash('name'); - var fileslist = JSON.stringify(files); - var dir=$('#dir').val()||'/'; - OC.Notification.show(t('files','Your download is being prepared. This might take some time if the files are big.')); - // use special download URL if provided, e.g. for public shared files - var downloadURL = document.getElementById("downloadURL"); - if ( downloadURL ) { - window.location = downloadURL.value+"&download&files=" + encodeURIComponent(fileslist); - } else { - window.location = OC.filePath('files', 'ajax', 'download.php') + '?'+ $.param({ dir: dir, files: fileslist }); + var files; + var dir = FileList.getCurrentDirectory(); + if (FileList.isAllSelected()) { + files = OC.basename(dir); + dir = OC.dirname(dir) || '/'; } + else { + files = getSelectedFilesTrash('name'); + } + OC.Notification.show(t('files','Your download is being prepared. This might take some time if the files are big.')); + OC.redirect(FileList.getDownloadUrl(files, dir)); return false; }); $('.delete-selected').click(function(event) { var files=getSelectedFilesTrash('name'); event.preventDefault(); + if (FileList.isAllSelected()) { + files = null; + } FileList.do_delete(files); return false; }); diff --git a/apps/files/tests/js/fileactionsSpec.js b/apps/files/tests/js/fileactionsSpec.js index 8bbc1d3d141..ef7ddcb874a 100644 --- a/apps/files/tests/js/fileactionsSpec.js +++ b/apps/files/tests/js/fileactionsSpec.js @@ -69,7 +69,7 @@ describe('FileActions tests', function() { $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'); + expect(redirectStub.getCall(0).args[0]).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=test%20download%20File.txt'); redirectStub.restore(); }); }); diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js index c26e65fc4de..8f4cb86ab4a 100644 --- a/apps/files/tests/js/filelistSpec.js +++ b/apps/files/tests/js/filelistSpec.js @@ -58,8 +58,15 @@ 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'); + describe('Download Url', function() { + it('returns correct download URL for single files', function() { + expect(FileList.getDownloadUrl('some file.txt')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=some%20file.txt'); + expect(FileList.getDownloadUrl('some file.txt', '/anotherpath/abc')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fanotherpath%2Fabc&files=some%20file.txt'); + $('#dir').val('/'); + expect(FileList.getDownloadUrl('some file.txt')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2F&files=some%20file.txt'); + }); + it('returns correct download URL for multiple files', function() { + expect(FileList.getDownloadUrl(['a b c.txt', 'd e f.txt'])).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=%5B%22a%20b%20c.txt%22%2C%22d%20e%20f.txt%22%5D'); + }); }); }); diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php index 5ec09629d62..ef3775875f0 100755 --- a/apps/files_encryption/lib/helper.php +++ b/apps/files_encryption/lib/helper.php @@ -425,7 +425,7 @@ class Helper { /** * @brief glob uses different pattern than regular expressions, escape glob pattern only * @param string $path unescaped path - * @return escaped path + * @return string path */ public static function escapeGlobPattern($path) { return preg_replace('/(\*|\?|\[)/', '[$1]', $path); diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 064c1e20a93..35457f68528 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -67,7 +67,7 @@ class Google extends \OC\Files\Storage\Common { /** * Get the Google_DriveFile object for the specified path * @param string $path - * @return Google_DriveFile|false + * @return string */ private function getDriveFile($path) { // Remove leading and trailing slashes diff --git a/apps/files_external/lib/streamwrapper.php b/apps/files_external/lib/streamwrapper.php index 3e3dc3e3af5..44bd9a0161a 100644 --- a/apps/files_external/lib/streamwrapper.php +++ b/apps/files_external/lib/streamwrapper.php @@ -11,6 +11,7 @@ namespace OC\Files\Storage; abstract class StreamWrapper extends Common { /** + * @param string $path * @return string|null */ abstract public function constructUrl($path); diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index c64b2d8b73a..9afe73aebd7 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -99,7 +99,9 @@ class DAV extends \OC\Files\Storage\Common{ public function rmdir($path) { $this->init(); - $path=$this->cleanPath($path); + $path=$this->cleanPath($path) . '/'; + // FIXME: some WebDAV impl return 403 when trying to DELETE + // a non-empty folder return $this->simpleResponse('DELETE', $path, null, 204); } @@ -107,7 +109,7 @@ class DAV extends \OC\Files\Storage\Common{ $this->init(); $path=$this->cleanPath($path); try { - $response=$this->client->propfind($path, array(), 1); + $response=$this->client->propfind($this->encodePath($path), array(), 1); $id=md5('webdav'.$this->root.$path); $content = array(); $files=array_keys($response); @@ -127,8 +129,11 @@ class DAV extends \OC\Files\Storage\Common{ $this->init(); $path=$this->cleanPath($path); try { - $response=$this->client->propfind($path, array('{DAV:}resourcetype')); - $responseType=$response["{DAV:}resourcetype"]->resourceType; + $response=$this->client->propfind($this->encodePath($path), array('{DAV:}resourcetype')); + $responseType = array(); + if (isset($response["{DAV:}resourcetype"])) { + $responseType=$response["{DAV:}resourcetype"]->resourceType; + } return (count($responseType)>0 and $responseType[0]=="{DAV:}collection")?'dir':'file'; } catch(\Exception $e) { error_log($e->getMessage()); @@ -141,7 +146,7 @@ class DAV extends \OC\Files\Storage\Common{ $this->init(); $path=$this->cleanPath($path); try { - $this->client->propfind($path, array('{DAV:}resourcetype')); + $this->client->propfind($this->encodePath($path), array('{DAV:}resourcetype')); return true;//no 404 exception } catch(\Exception $e) { return false; @@ -166,7 +171,7 @@ class DAV extends \OC\Files\Storage\Common{ $curl = curl_init(); $fp = fopen('php://temp', 'r+'); curl_setopt($curl, CURLOPT_USERPWD, $this->user.':'.$this->password); - curl_setopt($curl, CURLOPT_URL, $this->createBaseUri().str_replace(' ', '%20', $path)); + curl_setopt($curl, CURLOPT_URL, $this->createBaseUri().$this->encodePath($path)); curl_setopt($curl, CURLOPT_FILE, $fp); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); if ($this->secure === true) { @@ -178,6 +183,10 @@ class DAV extends \OC\Files\Storage\Common{ } curl_exec ($curl); + $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); + if ($statusCode !== 200) { + \OCP\Util::writeLog("webdav client", 'curl GET ' . curl_getinfo($curl, CURLINFO_EFFECTIVE_URL) . ' returned status code ' . $statusCode, \OCP\Util::ERROR); + } curl_close ($curl); rewind($fp); return $fp; @@ -220,7 +229,7 @@ class DAV extends \OC\Files\Storage\Common{ $this->init(); $path=$this->cleanPath($path); try { - $response=$this->client->propfind($path, array('{DAV:}quota-available-bytes')); + $response=$this->client->propfind($this->encodePath($path), array('{DAV:}quota-available-bytes')); if (isset($response['{DAV:}quota-available-bytes'])) { return (int)$response['{DAV:}quota-available-bytes']; } else { @@ -240,7 +249,12 @@ class DAV extends \OC\Files\Storage\Common{ // if file exists, update the mtime, else create a new empty file if ($this->file_exists($path)) { - $this->client->proppatch($path, array('{DAV:}lastmodified' => $mtime)); + try { + $this->client->proppatch($this->encodePath($path), array('{DAV:}lastmodified' => $mtime)); + } + catch (\Sabre_DAV_Exception_NotImplemented $e) { + return false; + } } else { $this->file_put_contents($path, ''); } @@ -276,13 +290,17 @@ class DAV extends \OC\Files\Storage\Common{ } } curl_exec ($curl); + $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); + if ($statusCode !== 200) { + \OCP\Util::writeLog("webdav client", 'curl GET ' . curl_getinfo($curl, CURLINFO_EFFECTIVE_URL) . ' returned status code ' . $statusCode, \OCP\Util::ERROR); + } curl_close ($curl); } public function rename($path1, $path2) { $this->init(); - $path1=$this->cleanPath($path1); - $path2=$this->createBaseUri().$this->cleanPath($path2); + $path1 = $this->encodePath($this->cleanPath($path1)); + $path2 = $this->createBaseUri().$this->encodePath($this->cleanPath($path2)); try { $this->client->request('MOVE', $path1, null, array('Destination'=>$path2)); return true; @@ -293,8 +311,8 @@ class DAV extends \OC\Files\Storage\Common{ public function copy($path1, $path2) { $this->init(); - $path1=$this->cleanPath($path1); - $path2=$this->createBaseUri().$this->cleanPath($path2); + $path1 = $this->encodePath($this->cleanPath($path1)); + $path2 = $this->createBaseUri().$this->encodePath($this->cleanPath($path2)); try { $this->client->request('COPY', $path1, null, array('Destination'=>$path2)); return true; @@ -307,7 +325,7 @@ class DAV extends \OC\Files\Storage\Common{ $this->init(); $path=$this->cleanPath($path); try { - $response=$this->client->propfind($path, array('{DAV:}getlastmodified', '{DAV:}getcontentlength')); + $response = $this->client->propfind($this->encodePath($path), array('{DAV:}getlastmodified', '{DAV:}getcontentlength')); return array( 'mtime'=>strtotime($response['{DAV:}getlastmodified']), 'size'=>(int)isset($response['{DAV:}getcontentlength']) ? $response['{DAV:}getcontentlength'] : 0, @@ -321,8 +339,11 @@ class DAV extends \OC\Files\Storage\Common{ $this->init(); $path=$this->cleanPath($path); try { - $response=$this->client->propfind($path, array('{DAV:}getcontenttype', '{DAV:}resourcetype')); - $responseType=$response["{DAV:}resourcetype"]->resourceType; + $response=$this->client->propfind($this->encodePath($path), array('{DAV:}getcontenttype', '{DAV:}resourcetype')); + $responseType = array(); + if (isset($response["{DAV:}resourcetype"])) { + $responseType=$response["{DAV:}resourcetype"]->resourceType; + } $type=(count($responseType)>0 and $responseType[0]=="{DAV:}collection")?'dir':'file'; if ($type=='dir') { return 'httpd/unix-directory'; @@ -336,6 +357,9 @@ class DAV extends \OC\Files\Storage\Common{ } } + /** + * @param string $path + */ public function cleanPath($path) { $path = \OC\Files\Filesystem::normalizePath($path); // remove leading slash @@ -343,6 +367,16 @@ class DAV extends \OC\Files\Storage\Common{ } /** + * URL encodes the given path but keeps the slashes + * @param string $path to encode + * @return string encoded path + */ + private function encodePath($path) { + // slashes need to stay + return str_replace('%2F', '/', rawurlencode($path)); + } + + /** * @param string $method * @param string $path * @param integer $expected @@ -350,7 +384,7 @@ class DAV extends \OC\Files\Storage\Common{ private function simpleResponse($method, $path, $body, $expected) { $path=$this->cleanPath($path); try { - $response=$this->client->request($method, $path, $body); + $response=$this->client->request($method, $this->encodePath($path), $body); return $response['statusCode']==$expected; } catch(\Exception $e) { return false; diff --git a/apps/files_external/tests/config.php b/apps/files_external/tests/config.php index e296bfcb5b2..767c0adf58e 100644 --- a/apps/files_external/tests/config.php +++ b/apps/files_external/tests/config.php @@ -21,7 +21,11 @@ return array( 'host'=>'localhost', 'user'=>'test', 'password'=>'test', - 'root'=>'/owncloud/files/webdav.php', + 'root'=>'', + // wait delay in seconds after write operations + // (only in tests) + // set to higher value for lighttpd webdav + 'wait'=> 0 ), 'owncloud'=>array( 'run'=>true, diff --git a/apps/files_external/tests/webdav.php b/apps/files_external/tests/webdav.php index 1f9b767eca6..74e905ccc89 100644 --- a/apps/files_external/tests/webdav.php +++ b/apps/files_external/tests/webdav.php @@ -18,6 +18,9 @@ class DAV extends Storage { if ( ! is_array($this->config) or ! isset($this->config['webdav']) or ! $this->config['webdav']['run']) { $this->markTestSkipped('WebDAV backend not configured'); } + if (isset($this->config['webdav']['wait'])) { + $this->waitDelay = $this->config['webdav']['wait']; + } $this->config['webdav']['root'] .= '/' . $id; //make sure we have an new empty folder to work in $this->instance = new \OC\Files\Storage\DAV($this->config['webdav']); $this->instance->mkdir('/'); diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js index c1b7eee3fb7..06c168969de 100644 --- a/apps/files_sharing/js/public.js +++ b/apps/files_sharing/js/public.js @@ -1,3 +1,15 @@ +/* + * Copyright (c) 2014 + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ + +/* global OC, FileList, FileActions */ + // Override download path to files_sharing/public.php function fileDownloadPath(dir, file) { var url = $('#downloadURL').val(); @@ -28,12 +40,20 @@ $(document).ready(function() { // 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) { - return $(tr).find('a.name').attr('href') + '&download'; + if ($.isArray(filename)) { + filename = JSON.stringify(filename); + } + var path = dir || FileList.getCurrentDirectory(); + var params = { + service: 'files', + t: $('#sharingToken').val(), + path: path, + download: null + }; + if (filename) { + params.files = filename; } - return null; + return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params); }; } diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 7d63e7a4fe3..aadc54e4a7f 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -396,7 +396,7 @@ class Shared_Cache extends Cache { * use the one with the highest id gives the best result with the background scanner, since that is most * likely the folder where we stopped scanning previously * - * @return string|bool the path of the folder or false when no folder matched + * @return boolean the path of the folder or false when no folder matched */ public function getIncomplete() { return false; diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index ebd16f081ba..b922654e5ec 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -41,6 +41,7 @@ class Shared extends \OC\Files\Storage\Common { /** * @brief Get the source file path, permissions, and owner for a shared file * @param string Shared target file path + * @param string $target * @return Returns array with the keys path, permissions, and owner or false if not found */ public function getFile($target) { diff --git a/apps/files_trashbin/ajax/delete.php b/apps/files_trashbin/ajax/delete.php index 75d481768ad..ebabc5bc7a2 100644 --- a/apps/files_trashbin/ajax/delete.php +++ b/apps/files_trashbin/ajax/delete.php @@ -2,42 +2,38 @@ OCP\JSON::checkLoggedIn(); OCP\JSON::callCheck(); +$folder = isset($_POST['dir']) ? $_POST['dir'] : '/'; // "empty trash" command if (isset($_POST['allfiles']) and $_POST['allfiles'] === 'true'){ $deleteAll = true; - $folder = isset($_POST['dir']) ? $_POST['dir'] : '/'; if ($folder === '/' || $folder === '') { OCA\Files_Trashbin\Trashbin::deleteAll(); $list = array(); } else { - $dirname = dirname($folder); - if ( $dirname !== '/' && $dirname !== '.' ) { - $dirlisting = '1'; - } else { - $dirlisting = '0'; - } $list[] = $folder; + $folder = dirname($folder); } } else { $deleteAll = false; $files = $_POST['files']; - $dirlisting = $_POST['dirlisting']; $list = json_decode($files); } + +$folder = rtrim($folder, '/') . '/'; $error = array(); $success = array(); $i = 0; foreach ($list as $file) { - if ( $dirlisting === '0') { + if ($folder === '/') { $file = ltrim($file, '/'); $delimiter = strrpos($file, '.d'); $filename = substr($file, 0, $delimiter); $timestamp = substr($file, $delimiter+2); } else { - $filename = $file; + $filename = $folder . '/' . $file; $timestamp = null; } diff --git a/apps/files_trashbin/ajax/undelete.php b/apps/files_trashbin/ajax/undelete.php index 876ad269a70..9c3ccba7ed8 100644 --- a/apps/files_trashbin/ajax/undelete.php +++ b/apps/files_trashbin/ajax/undelete.php @@ -4,15 +4,36 @@ OCP\JSON::checkLoggedIn(); OCP\JSON::callCheck(); $files = $_POST['files']; -$dirlisting = $_POST['dirlisting']; -$list = json_decode($files); +$dir = '/'; +if (isset($_POST['dir'])) { + $dir = rtrim($_POST['dir'], '/'). '/'; +} +$allFiles = false; +if (isset($_POST['allfiles']) and $_POST['allfiles'] === 'true') { + $allFiles = true; + $list = array(); + $dirListing = true; + if ($dir === '' || $dir === '/') { + $dirListing = false; + } + foreach (OCA\Files_Trashbin\Helper::getTrashFiles($dir) as $file) { + $fileName = $file['name']; + if (!$dirListing) { + $fileName .= '.d' . $file['timestamp']; + } + $list[] = $fileName; + } +} else { + $list = json_decode($files); +} $error = array(); $success = array(); $i = 0; foreach ($list as $file) { - if ( $dirlisting === '0') { + $path = $dir . '/' . $file; + if ($dir === '/') { $file = ltrim($file, '/'); $delimiter = strrpos($file, '.d'); $filename = substr($file, 0, $delimiter); @@ -23,9 +44,9 @@ foreach ($list as $file) { $timestamp = null; } - if ( !OCA\Files_Trashbin\Trashbin::restore($file, $filename, $timestamp) ) { + if ( !OCA\Files_Trashbin\Trashbin::restore($path, $filename, $timestamp) ) { $error[] = $filename; - OC_Log::write('trashbin','can\'t restore ' . $filename, OC_Log::ERROR); + OC_Log::write('trashbin', 'can\'t restore ' . $filename, OC_Log::ERROR); } else { $success[$i]['filename'] = $file; $success[$i]['timestamp'] = $timestamp; diff --git a/apps/files_trashbin/js/trash.js b/apps/files_trashbin/js/trash.js index 46d8b56308c..6aade210505 100644 --- a/apps/files_trashbin/js/trash.js +++ b/apps/files_trashbin/js/trash.js @@ -1,5 +1,29 @@ +/* + * Copyright (c) 2014 + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ + +/* global OC, t, FileList, FileActions */ $(document).ready(function() { + function removeCallback(result) { + if (result.status !== 'success') { + OC.dialogs.alert(result.data.message, t('core', 'Error')); + } + + var files = result.data.success; + for (var i = 0; i < files.length; i++) { + FileList.findFileEl(OC.basename(files[i].filename)).remove(); + } + FileList.updateFileSummary(); + FileList.updateEmptyContent(); + enableActions(); + } if (typeof FileActions !== 'undefined') { FileActions.register('all', 'Restore', OC.PERMISSION_READ, OC.imagePath('core', 'actions/history'), function(filename) { @@ -7,22 +31,12 @@ $(document).ready(function() { 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'), - {files: JSON.stringify([$('#dir').val() + '/' + filename]), dirlisting: tr.attr('data-dirlisting')}, - function(result) { - for (var i = 0; i < result.data.success.length; i++) { - var row = document.getElementById(result.data.success[i].filename); - row.parentNode.removeChild(row); - } - if (result.status !== 'success') { - OC.dialogs.alert(result.data.message, t('core', 'Error')); - } - enableActions(); - FileList.updateFileSummary(); - FileList.updateEmptyContent(); - } + $.post(OC.filePath('files_trashbin', 'ajax', 'undelete.php'), { + files: JSON.stringify([filename]), + dir: FileList.getCurrentDirectory() + }, + removeCallback ); - }); }; @@ -34,22 +48,12 @@ $(document).ready(function() { 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'), - {files: JSON.stringify([$('#dir').val() + '/' +filename]), dirlisting: tr.attr('data-dirlisting')}, - function(result) { - for (var i = 0; i < result.data.success.length; i++) { - var row = document.getElementById(result.data.success[i].filename); - row.parentNode.removeChild(row); - } - if (result.status !== 'success') { - OC.dialogs.alert(result.data.message, t('core', 'Error')); - } - enableActions(); - FileList.updateFileSummary(); - FileList.updateEmptyContent(); - } + $.post(OC.filePath('files_trashbin', 'ajax', 'delete.php'), { + files: JSON.stringify([filename]), + dir: FileList.getCurrentDirectory() + }, + removeCallback ); - }); // Sets the select_all checkbox behaviour : @@ -68,29 +72,45 @@ $(document).ready(function() { $('.undelete').click('click', function(event) { event.preventDefault(); - var files = getSelectedFiles('file'); - var fileslist = JSON.stringify(files); - var dirlisting = getSelectedFiles('dirlisting')[0]; + var allFiles = $('#select_all').is(':checked'); + var files = []; + var params = {}; disableActions(); - for (var i = 0; i < files.length; i++) { - var deleteAction = FileList.findFileEl(files[i]).children("td.date").children(".action.delete"); - deleteAction.removeClass('delete-icon').addClass('progress-icon'); + if (allFiles) { + FileList.showMask(); + params = { + allfiles: true, + dir: FileList.getCurrentDirectory() + }; + } + else { + files = getSelectedFiles('name'); + for (var i = 0; i < files.length; i++) { + var deleteAction = FileList.findFileEl(files[i]).children("td.date").children(".action.delete"); + deleteAction.removeClass('delete-icon').addClass('progress-icon'); + } + params = { + files: JSON.stringify(files), + dir: FileList.getCurrentDirectory() + }; } $.post(OC.filePath('files_trashbin', 'ajax', 'undelete.php'), - {files: fileslist, dirlisting: dirlisting}, - function(result) { - for (var i = 0; i < result.data.success.length; i++) { - var row = document.getElementById(result.data.success[i].filename); - row.parentNode.removeChild(row); - } + params, + function(result) { + if (allFiles) { if (result.status !== 'success') { OC.dialogs.alert(result.data.message, t('core', 'Error')); } + FileList.hideMask(); + // simply remove all files + FileList.update(''); enableActions(); - FileList.updateFileSummary(); - FileList.updateEmptyContent(); } + else { + removeCallback(result); + } + } ); }); @@ -101,17 +121,17 @@ $(document).ready(function() { var params = {}; if (allFiles) { params = { - allfiles: true, - dir: $('#dir').val() + allfiles: true, + dir: FileList.getCurrentDirectory() }; } else { - files = getSelectedFiles('file'); + files = getSelectedFiles('name'); params = { files: JSON.stringify(files), - dirlisting: getSelectedFiles('dirlisting')[0] + dir: FileList.getCurrentDirectory() }; - }; + } disableActions(); if (allFiles) { @@ -128,22 +148,17 @@ $(document).ready(function() { params, function(result) { if (allFiles) { + if (result.status !== 'success') { + OC.dialogs.alert(result.data.message, t('core', 'Error')); + } FileList.hideMask(); // simply remove all files - $('#fileList').empty(); + FileList.update(''); + enableActions(); } else { - for (var i = 0; i < result.data.success.length; i++) { - var row = document.getElementById(result.data.success[i].filename); - row.parentNode.removeChild(row); - } + removeCallback(result); } - if (result.status !== 'success') { - OC.dialogs.alert(result.data.message, t('core', 'Error')); - } - enableActions(); - FileList.updateFileSummary(); - FileList.updateEmptyContent(); } ); @@ -208,11 +223,9 @@ function getSelectedFiles(property){ var files=[]; elements.each(function(i,element){ var file={ - name:$(element).attr('data-filename'), - file:$('#dir').val() + "/" + $(element).attr('data-file'), + name:$(element).attr('data-file'), timestamp:$(element).attr('data-timestamp'), - type:$(element).attr('data-type'), - dirlisting:$(element).attr('data-dirlisting') + type:$(element).attr('data-type') }; if(property){ files.push(file[property]); diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index fc0bf3bfad0..2bd9c15bae4 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -336,7 +336,7 @@ class Storage { * @brief deletes used space for files versions in db if user was deleted * * @param type $uid id of deleted user - * @return result of db delete operation + * @return \OC_DB_StatementWrapper of db delete operation */ public static function deleteUser($uid) { $query = \OC_DB::prepare('DELETE FROM `*PREFIX*files_versions` WHERE `user`=?'); @@ -420,8 +420,8 @@ class Storage { /** * @brief get list of files we want to expire - * @param integer $currentTime timestamp of current time * @param array $versions list of versions + * @param integer $time * @return array containing the list of to deleted versions and the size of them */ protected static function getExpireList($time, $versions) { diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php index 8a8d8aa5e3a..b7e4023dd73 100644 --- a/apps/user_ldap/lib/access.php +++ b/apps/user_ldap/lib/access.php @@ -164,6 +164,7 @@ class Access extends LDAPUtility { /** * gives back the database table for the query + * @param boolean $isUser */ private function getMapTable($isUser) { if($isUser) { @@ -644,6 +645,8 @@ class Access extends LDAPUtility { * @brief executes an LDAP search, optimized for Users * @param $filter the LDAP filter for the search * @param $attr optional, when a certain attribute shall be filtered out + * @param integer $limit + * @param integer $offset * @returns array with the search result * * Executes an LDAP search @@ -661,8 +664,10 @@ class Access extends LDAPUtility { /** * @brief executes an LDAP search, optimized for Groups - * @param $filter the LDAP filter for the search + * @param string $filter the LDAP filter for the search * @param $attr optional, when a certain attribute shall be filtered out + * @param integer $limit + * @param integer $offset * @returns array with the search result * * Executes an LDAP search @@ -757,7 +762,7 @@ class Access extends LDAPUtility { /** * @brief executes an LDAP search, but counts the results only - * @param $filter the LDAP filter for the search + * @param string $filter the LDAP filter for the search * @param $base an array containing the LDAP subtree(s) that shall be searched * @param $attr optional, array, one or more attributes that shall be * retrieved. Results will according to the order in the array. @@ -917,6 +922,17 @@ class Access extends LDAPUtility { } /** + * @brief escapes (user provided) parts for LDAP filter + * @param String $input, the provided value + * @returns the escaped string + */ + public function escapeFilterPart($input) { + $search = array('*', '\\', '(', ')'); + $replace = array('\\*', '\\\\', '\\(', '\\)'); + return str_replace($search, $replace, $input); + } + + /** * @brief combines the input filters with AND * @param $filters array, the filters to connect * @returns the combined filter @@ -1006,6 +1022,9 @@ class Access extends LDAPUtility { return $this->combineFilterWithOr($filter); } + /** + * @param string $password + */ public function areCredentialsValid($name, $password) { $name = $this->DNasBaseParameter($name); $testConnection = clone $this->connection; diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php index 19870550163..b2075748a3b 100644 --- a/apps/user_ldap/lib/connection.php +++ b/apps/user_ldap/lib/connection.php @@ -159,6 +159,9 @@ class Connection extends LDAPUtility { return unserialize(base64_decode($this->cache->get($key))); } + /** + * @param string $key + */ public function isCached($key) { if(!$this->configured) { $this->readConfiguration(); diff --git a/apps/user_ldap/lib/proxy.php b/apps/user_ldap/lib/proxy.php index b68910ff97f..b27233bcd19 100644 --- a/apps/user_ldap/lib/proxy.php +++ b/apps/user_ldap/lib/proxy.php @@ -56,8 +56,13 @@ abstract class Proxy { /** * @param boolean $passOnWhen + * @param string $method */ abstract protected function callOnLastSeenOn($id, $method, $parameters, $passOnWhen); + + /** + * @param string $method + */ abstract protected function walkBackends($id, $method, $parameters); /** @@ -95,6 +100,9 @@ abstract class Proxy { return unserialize(base64_decode($this->cache->get($key))); } + /** + * @param string $key + */ public function isCached($key) { $key = $this->getCacheKey($key); return $this->cache->hasKey($key); diff --git a/apps/user_ldap/lib/wizard.php b/apps/user_ldap/lib/wizard.php index 5079642d954..e79090febc1 100644 --- a/apps/user_ldap/lib/wizard.php +++ b/apps/user_ldap/lib/wizard.php @@ -865,8 +865,8 @@ class Wizard extends LDAPUtility { /** * @brief does a cumulativeSearch on LDAP to get different values of a * specified attribute - * @param $filters array, the filters that shall be used in the search - * @param $attr the attribute of which a list of values shall be returned + * @param string[] $filters array, the filters that shall be used in the search + * @param string $attr the attribute of which a list of values shall be returned * @param $lfw bool, whether the last filter is a wildcard which shall not * be processed if there were already findings, defaults to true * @param string $maxF string. if not null, this variable will have the filter that @@ -933,8 +933,8 @@ class Wizard extends LDAPUtility { * @brief determines if and which $attr are available on the LDAP server * @param string[] $objectclasses the objectclasses to use as search filter * @param string $attr the attribute to look for - * @param $dbkey the dbkey of the setting the feature is connected to - * @param $confkey the confkey counterpart for the $dbkey as used in the + * @param string $dbkey the dbkey of the setting the feature is connected to + * @param string $confkey the confkey counterpart for the $dbkey as used in the * Configuration class * @param $po boolean, whether the objectClass with most result entries * shall be pre-selected via the result diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 1088dafab71..757de6b60f4 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -25,7 +25,6 @@ namespace OCA\user_ldap; -use OCA\user_ldap\lib\ILDAPWrapper; use OCA\user_ldap\lib\BackendUtility; class USER_LDAP extends BackendUtility implements \OCP\UserInterface { @@ -139,7 +138,7 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface { * @brief reads the image from LDAP that shall be used as Avatar * @param $uid string, the ownCloud user name * @param $dn string, the user DN - * @return image data (provided by LDAP) | false + * @return string data (provided by LDAP) | false */ private function getAvatarImage($uid, $dn) { $attributes = array('jpegPhoto', 'thumbnailPhoto'); @@ -164,6 +163,8 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface { * Check if the password is correct without logging in the user */ public function checkPassword($uid, $password) { + $uid = $this->access->escapeFilterPart($uid); + //find out dn of the user name $filter = \OCP\Util::mb_str_replace( '%uid', $uid, $this->access->connection->ldapLoginFilter, 'UTF-8'); @@ -204,6 +205,7 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface { * Get a list of all users. */ public function getUsers($search = '', $limit = 10, $offset = 0) { + $search = $this->access->escapeFilterPart($search); $cachekey = 'getUsers-'.$search.'-'.$limit.'-'.$offset; //check if users are cached, if so return |