diff options
-rwxr-xr-x | apps/files_encryption/tests/trashbin.php | 40 | ||||
-rw-r--r-- | apps/files_sharing/tests/share.php | 1 | ||||
-rw-r--r-- | apps/files_sharing/tests/sharedmount.php | 1 | ||||
-rw-r--r-- | apps/files_sharing/tests/sharedstorage.php | 2 | ||||
-rw-r--r-- | apps/files_sharing/tests/updater.php | 12 | ||||
-rw-r--r-- | apps/files_trashbin/lib/hooks.php | 15 | ||||
-rw-r--r-- | apps/files_trashbin/lib/storage.php | 67 | ||||
-rw-r--r-- | apps/files_trashbin/lib/trashbin.php | 22 | ||||
-rw-r--r-- | apps/files_versions/lib/storage.php | 2 | ||||
-rw-r--r-- | apps/user_ldap/js/experiencedAdmin.js | 2 | ||||
-rw-r--r-- | apps/user_ldap/js/ldapFilter.js | 32 | ||||
-rw-r--r-- | apps/user_ldap/js/settings.js | 96 | ||||
-rw-r--r-- | lib/private/share/share.php | 27 | ||||
-rw-r--r-- | tests/lib/share/share.php | 35 |
14 files changed, 254 insertions, 100 deletions
diff --git a/apps/files_encryption/tests/trashbin.php b/apps/files_encryption/tests/trashbin.php index d924b8ac77a..b759c8e32fd 100755 --- a/apps/files_encryption/tests/trashbin.php +++ b/apps/files_encryption/tests/trashbin.php @@ -158,31 +158,30 @@ class Trashbin extends TestCase { . $filename2 . '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); // get files - $trashFiles = $this->view->getDirectoryContent( - '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/files/'); + $trashFiles = \OCA\Files_Trashbin\Helper::getTrashFiles('/', self::TEST_ENCRYPTION_TRASHBIN_USER1); - $trashFileSuffix = null; // find created file with timestamp + $timestamp = null; foreach ($trashFiles as $file) { - if (strpos($file['path'], $filename . '.d') !== false) { - $path_parts = pathinfo($file['name']); - $trashFileSuffix = $path_parts['extension']; + if ($file['name'] === $filename) { + $timestamp = $file['mtime']; + break; } } // check if we found the file we created - $this->assertNotNull($trashFileSuffix); + $this->assertNotNull($timestamp); - $this->assertTrue($this->view->is_dir('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keys/' . $filename . '.' . $trashFileSuffix)); + $this->assertTrue($this->view->is_dir('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keys/' . $filename . '.d' . $timestamp)); // check if key for admin not exists $this->assertTrue($this->view->file_exists( - '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keys/' . $filename . '.' . $trashFileSuffix . '/fileKey')); + '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keys/' . $filename . '.d' . $timestamp . '/fileKey')); // check if share key for admin not exists $this->assertTrue($this->view->file_exists( '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keys/' . $filename - . '.' . $trashFileSuffix . '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); + . '.d' . $timestamp . '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); } /** @@ -195,27 +194,26 @@ class Trashbin extends TestCase { $filename2 = $filename . '.backup'; // a second file with similar name // save file with content - $cryptedFile = file_put_contents('crypt:///' . self::TEST_ENCRYPTION_TRASHBIN_USER1. '/files/'. $filename, $this->dataShort); - $cryptedFile2 = file_put_contents('crypt:///' . self::TEST_ENCRYPTION_TRASHBIN_USER1. '/files/'. $filename2, $this->dataShort); + file_put_contents('crypt:///' . self::TEST_ENCRYPTION_TRASHBIN_USER1. '/files/'. $filename, $this->dataShort); + file_put_contents('crypt:///' . self::TEST_ENCRYPTION_TRASHBIN_USER1. '/files/'. $filename2, $this->dataShort); // delete both files \OC\Files\Filesystem::unlink($filename); \OC\Files\Filesystem::unlink($filename2); - $trashFiles = $this->view->getDirectoryContent('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/files/'); + $trashFiles = \OCA\Files_Trashbin\Helper::getTrashFiles('/', self::TEST_ENCRYPTION_TRASHBIN_USER1); - $trashFileSuffix = null; - $trashFileSuffix2 = null; // find created file with timestamp + $timestamp = null; foreach ($trashFiles as $file) { - if (strpos($file['path'], $filename . '.d') !== false) { - $path_parts = pathinfo($file['name']); - $trashFileSuffix = $path_parts['extension']; + if ($file['name'] === $filename) { + $timestamp = $file['mtime']; + break; } } - // prepare file information - $timestamp = str_replace('d', '', $trashFileSuffix); + // make sure that we have a timestamp + $this->assertNotNull($timestamp); // before calling the restore operation the keys shouldn't be there $this->assertFalse($this->view->file_exists( @@ -225,7 +223,7 @@ class Trashbin extends TestCase { . $filename . '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); // restore first file - $this->assertTrue(\OCA\Files_Trashbin\Trashbin::restore($filename . '.' . $trashFileSuffix, $filename, $timestamp)); + $this->assertTrue(\OCA\Files_Trashbin\Trashbin::restore($filename . '.d' . $timestamp, $filename, $timestamp)); // check if file exists $this->assertTrue($this->view->file_exists( diff --git a/apps/files_sharing/tests/share.php b/apps/files_sharing/tests/share.php index b8c8b70bd1f..9ae2e330649 100644 --- a/apps/files_sharing/tests/share.php +++ b/apps/files_sharing/tests/share.php @@ -50,6 +50,7 @@ class Test_Files_Sharing extends OCA\Files_sharing\Tests\TestCase { } protected function tearDown() { + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); $this->view->unlink($this->filename); $this->view->deleteAll($this->folder); diff --git a/apps/files_sharing/tests/sharedmount.php b/apps/files_sharing/tests/sharedmount.php index dd66ca05d38..715c22cf4ae 100644 --- a/apps/files_sharing/tests/sharedmount.php +++ b/apps/files_sharing/tests/sharedmount.php @@ -186,6 +186,7 @@ class Test_Files_Sharing_Mount extends OCA\Files_sharing\Tests\TestCase { $this->assertFalse(\OC\Files\Filesystem::file_exists("newFileName")); //cleanup + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); \OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, 'testGroup'); \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER1, 'testGroup'); \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup'); diff --git a/apps/files_sharing/tests/sharedstorage.php b/apps/files_sharing/tests/sharedstorage.php index 75373244508..7ab1564bc3d 100644 --- a/apps/files_sharing/tests/sharedstorage.php +++ b/apps/files_sharing/tests/sharedstorage.php @@ -29,7 +29,7 @@ class Test_Files_Sharing_Storage extends OCA\Files_sharing\Tests\TestCase { protected function setUp() { parent::setUp(); - + \OCA\Files_Trashbin\Trashbin::registerHooks(); $this->folder = '/folder_share_storage_test'; $this->filename = '/share-api-storage.txt'; diff --git a/apps/files_sharing/tests/updater.php b/apps/files_sharing/tests/updater.php index bc8deaf19b0..1d6ec8caa61 100644 --- a/apps/files_sharing/tests/updater.php +++ b/apps/files_sharing/tests/updater.php @@ -98,12 +98,12 @@ class Test_Files_Sharing_Updater extends OCA\Files_sharing\Tests\TestCase { // trashbin should contain the local file but not the mount point $rootView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2); - $dirContent = $rootView->getDirectoryContent('files_trashbin/files'); - $this->assertSame(1, count($dirContent)); - $firstElement = reset($dirContent); - $ext = pathinfo($firstElement['path'], PATHINFO_EXTENSION); - $this->assertTrue($rootView->file_exists('files_trashbin/files/localFolder.' . $ext . '/localFile.txt')); - $this->assertFalse($rootView->file_exists('files_trashbin/files/localFolder.' . $ext . '/' . $this->folder)); + $trashContent = \OCA\Files_Trashbin\Helper::getTrashFiles('/', self::TEST_FILES_SHARING_API_USER2); + $this->assertSame(1, count($trashContent)); + $firstElement = reset($trashContent); + $timestamp = $firstElement['mtime']; + $this->assertTrue($rootView->file_exists('files_trashbin/files/localFolder.d' . $timestamp . '/localFile.txt')); + $this->assertFalse($rootView->file_exists('files_trashbin/files/localFolder.d' . $timestamp . '/' . $this->folder)); //cleanup $rootView->deleteAll('files_trashin'); diff --git a/apps/files_trashbin/lib/hooks.php b/apps/files_trashbin/lib/hooks.php index b6f0fb7e547..c6c69aaa23f 100644 --- a/apps/files_trashbin/lib/hooks.php +++ b/apps/files_trashbin/lib/hooks.php @@ -29,21 +29,6 @@ namespace OCA\Files_Trashbin; class Hooks { /** - * Copy files to trash bin - * @param array $params - * - * This function is connected to the delete signal of OC_Filesystem - * to copy the file to the trash bin - */ - public static function remove_hook($params) { - - if ( \OCP\App::isEnabled('files_trashbin') ) { - $path = $params['path']; - Trashbin::move2trash($path); - } - } - - /** * clean up user specific settings if user gets deleted * @param array $params array with uid * diff --git a/apps/files_trashbin/lib/storage.php b/apps/files_trashbin/lib/storage.php new file mode 100644 index 00000000000..aa5d48b5fbe --- /dev/null +++ b/apps/files_trashbin/lib/storage.php @@ -0,0 +1,67 @@ +<?php + +/** + * ownCloud + * + * @copyright (C) 2015 ownCloud, Inc. + * + * @author Bjoern Schiessle <schiessle@owncloud.com> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +namespace OCA\Files_Trashbin; + +use OC\Files\Storage\Wrapper\Wrapper; + +class Storage extends Wrapper { + + private $mountPoint; + // remember already deleted files to avoid infinite loops if the trash bin + // move files across storages + private $deletedFiles = array(); + + function __construct($parameters) { + $this->mountPoint = $parameters['mountPoint']; + parent::__construct($parameters); + } + + public function unlink($path) { + $normalized = \OC\Files\Filesystem::normalizePath($this->mountPoint . '/' . $path); + $result = true; + if (!isset($this->deletedFiles[$normalized])) { + $this->deletedFiles[$normalized] = $normalized; + $parts = explode('/', $normalized); + if (count($parts) > 3 && $parts[2] === 'files') { + $filesPath = implode('/', array_slice($parts, 3)); + $result = \OCA\Files_Trashbin\Trashbin::move2trash($filesPath); + } else { + $result = $this->storage->unlink($path); + } + unset($this->deletedFiles[$normalized]); + } + + return $result; + } + + /** + * Setup the storate wrapper callback + */ + public static function setupStorage() { + \OC\Files\Filesystem::addStorageWrapper('oc_trashbin', function ($mountPoint, $storage) { + return new \OCA\Files_Trashbin\Storage(array('storage' => $storage, 'mountPoint' => $mountPoint)); + }); + } + +} diff --git a/apps/files_trashbin/lib/trashbin.php b/apps/files_trashbin/lib/trashbin.php index 26257bd3817..f5cebea6b78 100644 --- a/apps/files_trashbin/lib/trashbin.php +++ b/apps/files_trashbin/lib/trashbin.php @@ -144,9 +144,10 @@ class Trashbin { $size = 0; list($owner, $ownerPath) = self::getUidAndFilename($file_path); + $view = new \OC\Files\View('/' . $user); // file has been deleted in between - if (empty($ownerPath)) { - return false; + if (!$view->file_exists('/files/' . $file_path)) { + return true; } self::setUpTrash($user); @@ -165,7 +166,8 @@ class Trashbin { \OC_FileProxy::$enabled = false; $trashPath = '/files_trashbin/files/' . $filename . '.d' . $timestamp; try { - $sizeOfAddedFiles = self::copy_recursive('/files/'.$file_path, $trashPath, $view); + $sizeOfAddedFiles = $view->filesize('/files/' . $file_path); + $view->rename('/files/' . $file_path, $trashPath); } catch (\OCA\Files_Trashbin\Exceptions\CopyRecursiveException $e) { $sizeOfAddedFiles = false; if ($view->file_exists($trashPath)) { @@ -203,6 +205,8 @@ class Trashbin { $ownerTrashSize += $size; $ownerTrashSize -= self::expire($ownerTrashSize, $owner); } + + return ($sizeOfAddedFiles === false) ? false : true; } /** @@ -321,8 +325,8 @@ class Trashbin { } else { // if location no longer exists, restore file in the root directory if ($location !== '/' && - (!$view->is_dir('files' . $location) || - !$view->isCreatable('files' . $location)) + (!$view->is_dir('files/' . $location) || + !$view->isCreatable('files/' . $location)) ) { $location = ''; } @@ -918,12 +922,12 @@ class Trashbin { * register hooks */ public static function registerHooks() { - //Listen to delete file signal - \OCP\Util::connectHook('OC_Filesystem', 'delete', "OCA\Files_Trashbin\Hooks", "remove_hook"); + // create storage wrapper on setup + \OCP\Util::connectHook('OC_Filesystem', 'setup', 'OCA\Files_Trashbin\Storage', 'setupStorage'); //Listen to delete user signal - \OCP\Util::connectHook('OC_User', 'pre_deleteUser', "OCA\Files_Trashbin\Hooks", "deleteUser_hook"); + \OCP\Util::connectHook('OC_User', 'pre_deleteUser', 'OCA\Files_Trashbin\Hooks', 'deleteUser_hook'); //Listen to post write hook - \OCP\Util::connectHook('OC_Filesystem', 'post_write', "OCA\Files_Trashbin\Hooks", "post_write_hook"); + \OCP\Util::connectHook('OC_Filesystem', 'post_write', 'OCA\Files_Trashbin\Hooks', 'post_write_hook'); } /** diff --git a/apps/files_versions/lib/storage.php b/apps/files_versions/lib/storage.php index 0fbb80f425f..60a4c463fd5 100644 --- a/apps/files_versions/lib/storage.php +++ b/apps/files_versions/lib/storage.php @@ -327,7 +327,7 @@ class Storage { } else { $versions[$key]['preview'] = \OCP\Util::linkToRoute('core_ajax_versions_preview', array('file' => $userFullPath, 'version' => $timestamp)); } - $versions[$key]['path'] = $pathinfo['dirname'] . '/' . $filename; + $versions[$key]['path'] = \OC\Files\Filesystem::normalizePath($pathinfo['dirname'] . '/' . $filename); $versions[$key]['name'] = $versionedFile; $versions[$key]['size'] = $view->filesize($dir . '/' . $entryName); } diff --git a/apps/user_ldap/js/experiencedAdmin.js b/apps/user_ldap/js/experiencedAdmin.js index 8d138eecc41..7dc5a4e503d 100644 --- a/apps/user_ldap/js/experiencedAdmin.js +++ b/apps/user_ldap/js/experiencedAdmin.js @@ -25,7 +25,7 @@ function ExperiencedAdmin(wizard, initialState) { /** * toggles whether the admin is an experienced one or not * - * @param {boolean} whether the admin is experienced or not + * @param {boolean} isExperienced whether the admin is experienced or not */ ExperiencedAdmin.prototype.setExperienced = function(isExperienced) { this._isExperienced = isExperienced; diff --git a/apps/user_ldap/js/ldapFilter.js b/apps/user_ldap/js/ldapFilter.js index 0f7d240adac..dc65858217d 100644 --- a/apps/user_ldap/js/ldapFilter.js +++ b/apps/user_ldap/js/ldapFilter.js @@ -19,6 +19,8 @@ function LdapFilter(target, determineModeCallback) { LdapFilter.prototype.activate = function() { if(this.activated) { + // might be necessary, if configuration changes happened. + this.findFeatures(); return; } this.activated = true; @@ -70,14 +72,6 @@ LdapFilter.prototype.compose = function(updateCount) { }; /** - * this function is triggered after attribute detectors have completed in - * LdapWizard - */ -LdapFilter.prototype.afterDetectorsRan = function() { - this.updateCount(); -}; - -/** * this function is triggered after LDAP filters have been composed successfully * @param {object} result returned by the ajax call */ @@ -99,11 +93,15 @@ LdapFilter.prototype.determineMode = function() { function(result) { var property = 'ldap' + filter.target + 'FilterMode'; filter.mode = parseInt(result.changes[property], 10); - if(filter.mode === LdapWizard.filterModeRaw && - $('#raw'+filter.target+'FilterContainer').hasClass('invisible')) { + var rawContainerIsInvisible = + $('#raw'+filter.target+'FilterContainer').hasClass('invisible'); + if ( filter.mode === LdapWizard.filterModeRaw + && rawContainerIsInvisible + ) { LdapWizard['toggleRaw'+filter.target+'Filter'](); - } else if(filter.mode === LdapWizard.filterModeAssisted && - !$('#raw'+filter.target+'FilterContainer').hasClass('invisible')) { + } else if ( filter.mode === LdapWizard.filterModeAssisted + && !rawContainerIsInvisible + ) { LdapWizard['toggleRaw'+filter.target+'Filter'](); } else { console.log('LDAP Wizard determineMode: returned mode was ยป' + @@ -142,8 +140,15 @@ LdapFilter.prototype.unlock = function() { } }; +/** + * resets this.foundFeatures so that LDAP queries can be fired again to retrieve + * objectClasses, groups, etc. + */ +LdapFilter.prototype.reAllowFeatureLookup = function () { + this.foundFeatures = false; +}; + LdapFilter.prototype.findFeatures = function() { - //TODO: reset this.foundFeatures when any base DN changes if(!this.foundFeatures && !this.locked && this.mode === LdapWizard.filterModeAssisted) { this.foundFeatures = true; var objcEl, avgrEl; @@ -167,7 +172,6 @@ LdapFilter.prototype.findFeatures = function() { /** * this function is triggered before user and group counts are executed * resolving the passed status variable will fire up counting - * @param {object} status an instance of $.Deferred */ LdapFilter.prototype.beforeUpdateCount = function() { var status = $.Deferred(); diff --git a/apps/user_ldap/js/settings.js b/apps/user_ldap/js/settings.js index 6db210fe435..b1abb0994ba 100644 --- a/apps/user_ldap/js/settings.js +++ b/apps/user_ldap/js/settings.js @@ -149,6 +149,7 @@ var LdapWizard = { loginFilter: false, groupFilter: false, ajaxRequests: {}, + lastTestSuccessful: true, ajax: function(param, fnOnSuccess, fnOnError, reqID) { if(!_.isUndefined(reqID)) { @@ -207,7 +208,7 @@ var LdapWizard = { }, basicStatusCheck: function() { - //criterias to continue from the first tab + //criteria to continue from the first tab // - host, port, user filter, agent dn, password, base dn var host = $('#ldap_host').val(); var port = $('#ldap_port').val(); @@ -224,7 +225,7 @@ var LdapWizard = { blacklistAdd: function(id) { - obj = $('#'+id); + var obj = $('#' + id); if(!(obj[0].hasOwnProperty('multiple') && obj[0]['multiple'] === true)) { //no need to blacklist multiselect LdapWizard.saveBlacklist[id] = true; @@ -242,14 +243,14 @@ var LdapWizard = { }, checkBaseDN: function() { - host = $('#ldap_host').val(); - port = $('#ldap_port').val(); - user = $('#ldap_dn').val(); - pass = $('#ldap_agent_password').val(); + var host = $('#ldap_host').val(); + var port = $('#ldap_port').val(); + var user = $('#ldap_dn').val(); + var pass = $('#ldap_agent_password').val(); //FIXME: determine base dn with anonymous access if(host && port && user && pass) { - param = 'action=guessBaseDN'+ + var param = 'action=guessBaseDN'+ '&ldap_serverconfig_chooser='+ encodeURIComponent($('#ldap_serverconfig_chooser').val()); @@ -276,11 +277,11 @@ var LdapWizard = { }, checkPort: function() { - host = $('#ldap_host').val(); - port = $('#ldap_port').val(); + var host = $('#ldap_host').val(); + var port = $('#ldap_port').val(); if(host && !port) { - param = 'action=guessPortAndTLS'+ + var param = 'action=guessPortAndTLS'+ '&ldap_serverconfig_chooser='+ encodeURIComponent($('#ldap_serverconfig_chooser').val()); @@ -307,7 +308,7 @@ var LdapWizard = { }, controlBack: function() { - curTabIndex = $('#ldapSettings').tabs('option', 'active'); + var curTabIndex = $('#ldapSettings').tabs('option', 'active'); if(curTabIndex == 0) { return; } @@ -316,7 +317,7 @@ var LdapWizard = { }, controlContinue: function() { - curTabIndex = $('#ldapSettings').tabs('option', 'active'); + var curTabIndex = $('#ldapSettings').tabs('option', 'active'); if(curTabIndex == 3) { return; } @@ -529,7 +530,7 @@ var LdapWizard = { if(type !== 'User' && type !== 'Group') { return false; } - param = 'action=determine'+encodeURIComponent(type)+'ObjectClasses'+ + var param = 'action=determine'+encodeURIComponent(type)+'ObjectClasses'+ '&ldap_serverconfig_chooser='+ encodeURIComponent($('#ldap_serverconfig_chooser').val()); @@ -571,11 +572,11 @@ var LdapWizard = { functionalityCheck: function() { //criteria to enable the connection: // - host, port, basedn, user filter, login filter - host = $('#ldap_host').val(); - port = $('#ldap_port').val(); - base = $('#ldap_base').val(); - userfilter = $('#ldap_userlist_filter').val(); - loginfilter = $('#ldap_login_filter').val(); + var host = $('#ldap_host').val(); + var port = $('#ldap_port').val(); + var base = $('#ldap_base').val(); + var userfilter = $('#ldap_userlist_filter').val(); + var loginfilter = $('#ldap_login_filter').val(); //FIXME: activates a manually deactivated configuration. if(host && port && base && userfilter && loginfilter) { @@ -619,6 +620,7 @@ var LdapWizard = { LdapWizard.detectorsRunInXPMode = 0; LdapWizard.instantiateFilters(); LdapWizard.admin.setExperienced($('#ldap_experienced_admin').is(':checked')); + LdapWizard.lastTestSuccessful = true; LdapWizard.basicStatusCheck(); LdapWizard.functionalityCheck(); LdapWizard.isConfigurationActiveControlLocked = false; @@ -760,7 +762,19 @@ var LdapWizard = { } }, - processChanges: function(triggerObj) { + /** + * allows UserFilter, LoginFilter and GroupFilter to lookup objectClasses + * and similar again. This should be called after essential changes, e.g. + * Host or BaseDN changes, or positive functionality check + * + */ + allowFilterFeatureSearch: function () { + LdapWizard.userFilter.reAllowFeatureLookup(); + LdapWizard.loginFilter.reAllowFeatureLookup(); + LdapWizard.groupFilter.reAllowFeatureLookup(); + }, + + processChanges: function (triggerObj) { LdapWizard.hideInfoBox(); if(triggerObj.id === 'ldap_host' @@ -771,6 +785,7 @@ var LdapWizard = { if($('#ldap_port').val()) { //if Port is already set, check BaseDN LdapWizard.checkBaseDN(); + LdapWizard.allowFilterFeatureSearch(); } } @@ -804,15 +819,33 @@ var LdapWizard = { LdapWizard._save(inputObj, val); }, + /** + * updates user or group count on multiSelect close. Resets the event + * function subsequently. + * + * @param {LdapFilter} filter + * @param {Object} $multiSelectObj + */ + onMultiSelectClose: function(filter, $multiSelectObj) { + filter.updateCount(); + $multiSelectObj.multiselect({close: function(){}}); + }, + saveMultiSelect: function(originalObj, resultObj) { - values = ''; - for(i = 0; i < resultObj.length; i++) { + var values = ''; + for(var i = 0; i < resultObj.length; i++) { values = values + "\n" + resultObj[i].value; } LdapWizard._save($('#'+originalObj)[0], $.trim(values)); + var $multiSelectObj = $('#'+originalObj); + var updateCount = !$multiSelectObj.multiselect("isOpen"); + var applyUpdateOnCloseToFilter; if(originalObj === 'ldap_userfilter_objectclass' || originalObj === 'ldap_userfilter_groups') { - LdapWizard.userFilter.compose(true); + LdapWizard.userFilter.compose(updateCount); + if(!updateCount) { + applyUpdateOnCloseToFilter = LdapWizard.userFilter; + } //when user filter is changed afterwards, login filter needs to //be adjusted, too if(!LdapWizard.loginFilter) { @@ -823,7 +856,19 @@ var LdapWizard = { LdapWizard.loginFilter.compose(); } else if(originalObj === 'ldap_groupfilter_objectclass' || originalObj === 'ldap_groupfilter_groups') { - LdapWizard.groupFilter.compose(true); + LdapWizard.groupFilter.compose(updateCount); + if(!updateCount) { + applyUpdateOnCloseToFilter = LdapWizard.groupFilter; + } + } + + if(applyUpdateOnCloseToFilter instanceof LdapFilter) { + $multiSelectObj.multiselect({ + close: function () { + LdapWizard.onMultiSelectClose( + applyUpdateOnCloseToFilter, $multiSelectObj); + } + }); } }, @@ -1002,6 +1047,10 @@ var LdapWizard = { $('.ldap_config_state_indicator').addClass('ldap_grey'); $('.ldap_config_state_indicator_sign').removeClass('error'); $('.ldap_config_state_indicator_sign').addClass('success'); + if(!LdapWizard.lastTestSuccessful) { + LdapWizard.lastTestSuccessful = true; + LdapWizard.allowFilterFeatureSearch(); + } }, //onError function(result) { @@ -1011,6 +1060,7 @@ var LdapWizard = { $('.ldap_config_state_indicator').removeClass('ldap_grey'); $('.ldap_config_state_indicator_sign').addClass('error'); $('.ldap_config_state_indicator_sign').removeClass('success'); + LdapWizard.lastTestSuccessful = false; } ); } else { diff --git a/lib/private/share/share.php b/lib/private/share/share.php index f61f65f35a7..e85f9f06ed3 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -337,17 +337,26 @@ class Share extends \OC\Share\Constants { if(empty($shares) && $user !== null) { $groups = \OC_Group::getUserGroups($user); - $query = \OC_DB::prepare( - 'SELECT * - FROM - `*PREFIX*share` - WHERE - `' . $column . '` = ? AND `item_type` = ? AND `share_with` in (?)' + $where = 'WHERE `' . $column . '` = ? AND `item_type` = ? AND `share_with` in (?)'; + $arguments = array($itemSource, $itemType, $groups); + $types = array(null, null, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY); + + if ($owner !== null) { + $where .= ' AND `uid_owner` = ?'; + $arguments[] = $owner; + $types[] = null; + } + + // TODO: inject connection, hopefully one day in the future when this + // class isn't static anymore... + $conn = \OC_DB::getConnection(); + $result = $conn->executeQuery( + 'SELECT * FROM `*PREFIX*share` ' . $where, + $arguments, + $types ); - $result = \OC_DB::executeAudited($query, array($itemSource, $itemType, implode(',', $groups))); - - while ($row = $result->fetchRow()) { + while ($row = $result->fetch()) { $shares[] = $row; } } diff --git a/tests/lib/share/share.php b/tests/lib/share/share.php index b8abfa29a81..b1261b0afbd 100644 --- a/tests/lib/share/share.php +++ b/tests/lib/share/share.php @@ -692,6 +692,41 @@ class Test_Share extends \Test\TestCase { $this->verifyResult($result4, array('target1', 'target2', 'target3', 'target4')); } + public function testGetItemSharedWithUserFromGroupShare() { + OC_User::setUserId($this->user1); + + //add dummy values to the share table + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (' + .' `item_type`, `item_source`, `item_target`, `share_type`,' + .' `share_with`, `uid_owner`) VALUES (?,?,?,?,?,?)'); + $args = array('test', 99, 'target1', OCP\Share::SHARE_TYPE_GROUP, $this->group1, $this->user1); + $query->execute($args); + $args = array('test', 99, 'target2', OCP\Share::SHARE_TYPE_GROUP, $this->group2, $this->user1); + $query->execute($args); + $args = array('test', 99, 'target3', OCP\Share::SHARE_TYPE_GROUP, $this->group1, $this->user2); + $query->execute($args); + $args = array('test', 99, 'target4', OCP\Share::SHARE_TYPE_GROUP, $this->group1, $this->user4); + $query->execute($args); + + // user2 is in group1 and group2 + $result1 = \OCP\Share::getItemSharedWithUser('test', 99, $this->user2, $this->user1); + $this->assertSame(2, count($result1)); + $this->verifyResult($result1, array('target1', 'target2')); + + $result2 = \OCP\Share::getItemSharedWithUser('test', 99, null, $this->user1); + $this->assertSame(2, count($result2)); + $this->verifyResult($result2, array('target1', 'target2')); + + // user3 is in group1 and group2 + $result3 = \OCP\Share::getItemSharedWithUser('test', 99, $this->user3); + $this->assertSame(3, count($result3)); + $this->verifyResult($result3, array('target1', 'target3', 'target4')); + + $result4 = \OCP\Share::getItemSharedWithUser('test', 99, null, null); + $this->assertSame(4, count($result4)); + $this->verifyResult($result4, array('target1', 'target2', 'target3', 'target4')); + } + public function verifyResult($result, $expected) { foreach ($result as $r) { if (in_array($r['item_target'], $expected)) { |