diff options
-rw-r--r-- | apps/files_external/lib/config.php | 2 | ||||
-rw-r--r-- | apps/provisioning_api/lib/users.php | 7 | ||||
-rw-r--r-- | apps/provisioning_api/tests/userstest.php | 12 | ||||
-rw-r--r-- | apps/user_ldap/lib/connection.php | 51 | ||||
-rw-r--r-- | apps/user_ldap/tests/integration/lib/integrationtestbackupserver.php | 118 | ||||
-rw-r--r-- | core/shipped.json | 1 | ||||
-rw-r--r-- | lib/private/files/storage/wrapper/encryption.php | 14 | ||||
-rw-r--r-- | lib/private/group/manager.php | 4 | ||||
-rw-r--r-- | tests/lib/files/storage/wrapper/encryption.php | 96 | ||||
-rw-r--r-- | tests/lib/group/manager.php | 26 |
10 files changed, 306 insertions, 25 deletions
diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 56a7e547ec6..6c900f0f224 100644 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -269,7 +269,7 @@ class OC_Mount_Config { } } catch (Exception $exception) { \OCP\Util::logException('files_external', $exception); - throw $e; + throw $exception; } } return self::STATUS_ERROR; diff --git a/apps/provisioning_api/lib/users.php b/apps/provisioning_api/lib/users.php index a9fafb48912..304fe901cfd 100644 --- a/apps/provisioning_api/lib/users.php +++ b/apps/provisioning_api/lib/users.php @@ -388,11 +388,16 @@ class Users { return new OC_OCS_Result(null, \OCP\API::RESPOND_UNAUTHORISED); } - $group = $this->groupManager->get(!empty($parameters['_delete']['groupid']) ? $parameters['_delete']['groupid'] : null); + $group = !empty($parameters['_delete']['groupid']) ? $parameters['_delete']['groupid'] : null; if($group === null) { return new OC_OCS_Result(null, 101); } + $group = $this->groupManager->get($group); + if($group === null) { + return new OC_OCS_Result(null, 102); + } + $targetUser = $this->userManager->get($parameters['userid']); if($targetUser === null) { return new OC_OCS_Result(null, 103); diff --git a/apps/provisioning_api/tests/userstest.php b/apps/provisioning_api/tests/userstest.php index c5a1ac3061e..ba4ed8a2e2f 100644 --- a/apps/provisioning_api/tests/userstest.php +++ b/apps/provisioning_api/tests/userstest.php @@ -1357,6 +1357,16 @@ class UsersTest extends OriginalTest { $this->assertEquals($expected, $this->api->removeFromGroup(['userid' => 'TargetUser', '_delete' => ['groupid' => 'TargetGroup']])); } + public function testRemoveFromGroupWithNoTargetGroup() { + $loggedInUser = $this->getMock('\OCP\IUser'); + $this->userSession + ->expects($this->once()) + ->method('getUser') + ->will($this->returnValue($loggedInUser)); + $expected = new \OC_OCS_Result(null, 101); + $this->assertEquals($expected, $this->api->removeFromGroup(['userid' => 'TargetUser', '_delete' => []])); + } + public function testRemoveFromGroupWithNotExistingTargetGroup() { $loggedInUser = $this->getMock('\OCP\IUser'); $this->userSession @@ -1369,7 +1379,7 @@ class UsersTest extends OriginalTest { ->with('TargetGroup') ->will($this->returnValue(null)); - $expected = new \OC_OCS_Result(null, 101); + $expected = new \OC_OCS_Result(null, 102); $this->assertEquals($expected, $this->api->removeFromGroup(['userid' => 'TargetUser', '_delete' => ['groupid' => 'TargetGroup']])); } diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php index f6b123babd0..3f3953bb28b 100644 --- a/apps/user_ldap/lib/connection.php +++ b/apps/user_ldap/lib/connection.php @@ -526,30 +526,41 @@ class Connection extends LDAPUtility { \OCP\Util::WARN); } } - if(!$this->configuration->ldapOverrideMainServer - && !$this->getFromCache('overrideMainServer')) { - $this->doConnect($this->configuration->ldapHost, - $this->configuration->ldapPort); - $bindStatus = $this->bind(); - $error = $this->ldap->isResource($this->ldapConnectionRes) ? - $this->ldap->errno($this->ldapConnectionRes) : -1; - } else { - $bindStatus = false; - $error = null; + + $bindStatus = false; + $error = null; + try { + if (!$this->configuration->ldapOverrideMainServer + && !$this->getFromCache('overrideMainServer') + ) { + $this->doConnect($this->configuration->ldapHost, + $this->configuration->ldapPort); + $bindStatus = $this->bind(); + $error = $this->ldap->isResource($this->ldapConnectionRes) ? + $this->ldap->errno($this->ldapConnectionRes) : -1; + } + if($bindStatus === true) { + return $bindStatus; + } + } catch (\OC\ServerNotAvailableException $e) { + if(trim($this->configuration->ldapBackupHost) === "") { + throw $e; + } } //if LDAP server is not reachable, try the Backup (Replica!) Server - if((!$bindStatus && ($error !== 0)) + if( $error !== 0 || $this->configuration->ldapOverrideMainServer - || $this->getFromCache('overrideMainServer')) { - $this->doConnect($this->configuration->ldapBackupHost, - $this->configuration->ldapBackupPort); - $bindStatus = $this->bind(); - if(!$bindStatus && $error === -1) { - //when bind to backup server succeeded and failed to main server, - //skip contacting him until next cache refresh - $this->writeToCache('overrideMainServer', true); - } + || $this->getFromCache('overrideMainServer')) + { + $this->doConnect($this->configuration->ldapBackupHost, + $this->configuration->ldapBackupPort); + $bindStatus = $this->bind(); + if($bindStatus && $error === -1) { + //when bind to backup server succeeded and failed to main server, + //skip contacting him until next cache refresh + $this->writeToCache('overrideMainServer', true); + } } return $bindStatus; } diff --git a/apps/user_ldap/tests/integration/lib/integrationtestbackupserver.php b/apps/user_ldap/tests/integration/lib/integrationtestbackupserver.php new file mode 100644 index 00000000000..95cb4b8f270 --- /dev/null +++ b/apps/user_ldap/tests/integration/lib/integrationtestbackupserver.php @@ -0,0 +1,118 @@ +<?php +/** + * @author Arthur Schiwon <blizzz@owncloud.com> + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OCA\user_ldap\tests\integration\lib; + +use OCA\user_ldap\lib\user\Manager as LDAPUserManager; +use OCA\user_ldap\tests\integration\AbstractIntegrationTest; +use OCA\User_LDAP\Mapping\UserMapping; +use OCA\user_ldap\USER_LDAP; + +require_once __DIR__ . '/../../../../../lib/base.php'; + +class IntegrationBackupServer extends AbstractIntegrationTest { + /** @var UserMapping */ + protected $mapping; + + /** @var USER_LDAP */ + protected $backend; + + /** + * sets up the LDAP configuration to be used for the test + */ + protected function initConnection() { + parent::initConnection(); + $originalHost = $this->connection->ldapHost; + $originalPort = $this->connection->ldapPort; + $this->connection->setConfiguration([ + 'ldapHost' => 'qwertz.uiop', + 'ldapPort' => '32123', + 'ldap_backup_host' => $originalHost, + 'ldap_backup_port' => $originalPort, + ]); + } + + /** + * tests that a backup connection is being used when the main LDAP server + * is offline + * + * Beware: after starting docker, the LDAP host might not be ready yet, thus + * causing a false positive. Retry in that case⦠or increase the sleep time + * in run-test.sh + * + * @return bool + */ + protected function case1() { + try { + $this->connection->getConnectionResource(); + } catch (\OC\ServerNotAvailableException $e) { + return false; + } + return true; + } + + /** + * ensures that an exception is thrown if LDAP main server and LDAP backup + * server are not available + * + * @return bool + */ + protected function case2() { + // reset possible LDAP connection + $this->initConnection(); + try { + $this->connection->setConfiguration([ + 'ldap_backup_host' => 'qwertz.uiop', + 'ldap_backup_port' => '32123', + ]); + $this->connection->getConnectionResource(); + } catch (\OC\ServerNotAvailableException $e) { + return true; + } + return false; + } + + /** + * ensures that an exception is thrown if main LDAP server is down and a + * backup server is not given + * + * @return bool + */ + protected function case3() { + // reset possible LDAP connection + $this->initConnection(); + try { + $this->connection->setConfiguration([ + 'ldap_backup_host' => '', + 'ldap_backup_port' => '', + ]); + $this->connection->getConnectionResource(); + } catch (\OC\ServerNotAvailableException $e) { + return true; + } + return false; + } +} + +require_once(__DIR__ . '/../setup-scripts/config.php'); +$test = new IntegrationBackupServer($host, $port, $adn, $apwd, $bdn); +$test->init(); +$test->run(); diff --git a/core/shipped.json b/core/shipped.json index b6f08a8b96d..49a649f3c9e 100644 --- a/core/shipped.json +++ b/core/shipped.json @@ -8,6 +8,7 @@ "external", "files", "files_antivirus", + "files_drop", "files_external", "files_ldap_home", "files_locking", diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php index 24b0ca4acac..8f5a7a05f01 100644 --- a/lib/private/files/storage/wrapper/encryption.php +++ b/lib/private/files/storage/wrapper/encryption.php @@ -480,6 +480,7 @@ class Encryption extends Wrapper { * @param bool $preserveMtime * @param bool $isRename * @return bool + * @throws \Exception */ private function copyBetweenStorage(Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime, $isRename) { @@ -487,7 +488,18 @@ class Encryption extends Wrapper { // key from the original file. Just create a 1:1 copy and done if ($this->isVersion($targetInternalPath) || $this->isVersion($sourceInternalPath)) { - return $this->storage->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); + $result = $this->storage->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); + if ($result) { + $info = $this->getCache('', $sourceStorage)->get($sourceInternalPath); + // make sure that we update the unencrypted size for the version + if (isset($info['encrypted']) && $info['encrypted'] === true) { + $this->updateUnencryptedSize( + $this->getFullPath($targetInternalPath), + $info['size'] + ); + } + } + return $result; } // first copy the keys that we reuse the existing file key on the target location diff --git a/lib/private/group/manager.php b/lib/private/group/manager.php index 0f6ba7f24e0..73ff0e537c6 100644 --- a/lib/private/group/manager.php +++ b/lib/private/group/manager.php @@ -263,7 +263,9 @@ class Manager extends PublicEmitter implements IGroupManager { * @return array with group ids */ public function getUserGroupIds($user) { - return array_keys($this->getUserGroups($user)); + return array_map(function($value) { + return (string) $value; + }, array_keys($this->getUserGroups($user))); } /** diff --git a/tests/lib/files/storage/wrapper/encryption.php b/tests/lib/files/storage/wrapper/encryption.php index 095405462df..2b93aa86db0 100644 --- a/tests/lib/files/storage/wrapper/encryption.php +++ b/tests/lib/files/storage/wrapper/encryption.php @@ -560,6 +560,102 @@ class Encryption extends \Test\Files\Storage\Storage { } /** + * @dataProvider dataTestCopyBetweenStorageVersions + * + * @param string $sourceInternalPath + * @param string $targetInternalPath + * @param bool $copyResult + * @param bool $encrypted + */ + public function testCopyBetweenStorageVersions($sourceInternalPath, $targetInternalPath, $copyResult, $encrypted) { + + $sourceStorage = $this->getMockBuilder('OCP\Files\Storage') + ->disableOriginalConstructor() + ->getMock(); + + $targetStorage = $this->getMockBuilder('OCP\Files\Storage') + ->disableOriginalConstructor() + ->getMock(); + + $cache = $this->getMockBuilder('\OC\Files\Cache\Cache') + ->disableOriginalConstructor()->getMock(); + + $mountPoint = '/mountPoint'; + + /** @var \OC\Files\Storage\Wrapper\Encryption |\PHPUnit_Framework_MockObject_MockObject $instance */ + $instance = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption') + ->setConstructorArgs( + [ + [ + 'storage' => $targetStorage, + 'root' => 'foo', + 'mountPoint' => $mountPoint, + 'mount' => $this->mount + ], + $this->encryptionManager, + $this->util, + $this->logger, + $this->file, + null, + $this->keyStore, + $this->update, + $this->mountManager + ] + ) + ->setMethods(['updateUnencryptedSize', 'getCache']) + ->getMock(); + + $targetStorage->expects($this->once())->method('copyFromStorage') + ->with($sourceStorage, $sourceInternalPath, $targetInternalPath) + ->willReturn($copyResult); + + if ($copyResult) { + $instance->expects($this->once())->method('getCache') + ->with('', $sourceStorage) + ->willReturn($cache); + $cache->expects($this->once())->method('get') + ->with($sourceInternalPath) + ->willReturn(['encrypted' => $encrypted, 'size' => 42]); + if ($encrypted) { + $instance->expects($this->once())->method('updateUnencryptedSize') + ->with($mountPoint . $targetInternalPath, 42); + } else { + $instance->expects($this->never())->method('updateUnencryptedSize'); + } + } else { + $instance->expects($this->never())->method('updateUnencryptedSize'); + } + + $result = $this->invokePrivate( + $instance, + 'copyBetweenStorage', + [ + $sourceStorage, + $sourceInternalPath, + $targetInternalPath, + false, + false + ] + ); + + $this->assertSame($copyResult, $result); + } + + public function dataTestCopyBetweenStorageVersions() { + return [ + ['/files/foo.txt', '/files_versions/foo.txt.768743', true, true], + ['/files/foo.txt', '/files_versions/foo.txt.768743', true, false], + ['/files/foo.txt', '/files_versions/foo.txt.768743', false, true], + ['/files/foo.txt', '/files_versions/foo.txt.768743', false, false], + ['/files_versions/foo.txt.6487634', '/files/foo.txt', true, true], + ['/files_versions/foo.txt.6487634', '/files/foo.txt', true, false], + ['/files_versions/foo.txt.6487634', '/files/foo.txt', false, true], + ['/files_versions/foo.txt.6487634', '/files/foo.txt', false, false], + + ]; + } + + /** * @dataProvider dataTestIsVersion * @param string $path * @param bool $expected diff --git a/tests/lib/group/manager.php b/tests/lib/group/manager.php index e3e2a96e46d..6cf473b9156 100644 --- a/tests/lib/group/manager.php +++ b/tests/lib/group/manager.php @@ -304,6 +304,32 @@ class Manager extends \Test\TestCase { $this->assertEquals('group1', $group1->getGID()); } + public function testGetUserGroupIds() { + /** @var \PHPUnit_Framework_MockObject_MockObject|\OC\Group\Manager $manager */ + $manager = $this->getMockBuilder('OC\Group\Manager') + ->disableOriginalConstructor() + ->setMethods(['getUserGroups']) + ->getMock(); + $manager->expects($this->once()) + ->method('getUserGroups') + ->willReturn([ + '123' => '123', + 'abc' => 'abc', + ]); + + /** @var \OC\User\User $user */ + $user = $this->getMockBuilder('OC\User\User') + ->disableOriginalConstructor() + ->getMock(); + + $groups = $manager->getUserGroupIds($user); + $this->assertEquals(2, count($groups)); + + foreach ($groups as $group) { + $this->assertInternalType('string', $group); + } + } + public function testInGroup() { /** * @var \PHPUnit_Framework_MockObject_MockObject | \OC_Group_Backend $backend |