diff options
author | Joas Schilling <nickvergessen@gmx.de> | 2016-05-20 15:38:20 +0200 |
---|---|---|
committer | Thomas Müller <DeepDiver1975@users.noreply.github.com> | 2016-05-20 15:38:20 +0200 |
commit | 94ad54ec9b96d41a614fbbad4a97b34c41a6901f (patch) | |
tree | f3eb7cdda2704aaf0cd59d58efe66bcbd34cb67d /tests/lib/Encryption | |
parent | 2ef751b1ec28f7b5c7113af60ec8c9fa0ae1cf87 (diff) | |
download | nextcloud-server-94ad54ec9b96d41a614fbbad4a97b34c41a6901f.tar.gz nextcloud-server-94ad54ec9b96d41a614fbbad4a97b34c41a6901f.zip |
Move tests/ to PSR-4 (#24731)
* Move a-b to PSR-4
* Move c-d to PSR-4
* Move e+g to PSR-4
* Move h-l to PSR-4
* Move m-r to PSR-4
* Move s-u to PSR-4
* Move files/ to PSR-4
* Move remaining tests to PSR-4
* Remove Test\ from old autoloader
Diffstat (limited to 'tests/lib/Encryption')
-rw-r--r-- | tests/lib/Encryption/DecryptAllTest.php | 347 | ||||
-rw-r--r-- | tests/lib/Encryption/EncryptionWrapperTest.php | 101 | ||||
-rw-r--r-- | tests/lib/Encryption/Keys/StorageTest.php | 513 | ||||
-rw-r--r-- | tests/lib/Encryption/ManagerTest.php | 250 | ||||
-rw-r--r-- | tests/lib/Encryption/UpdateTest.php | 236 | ||||
-rw-r--r-- | tests/lib/Encryption/UtilTest.php | 191 |
6 files changed, 1638 insertions, 0 deletions
diff --git a/tests/lib/Encryption/DecryptAllTest.php b/tests/lib/Encryption/DecryptAllTest.php new file mode 100644 index 00000000000..85fbe3e0ed9 --- /dev/null +++ b/tests/lib/Encryption/DecryptAllTest.php @@ -0,0 +1,347 @@ +<?php +/** + * @author Björn Schießle <schiessle@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 Test\Encryption; + + +use OC\Encryption\DecryptAll; +use OC\Encryption\Exceptions\DecryptionFailedException; +use OC\Encryption\Manager; +use OC\Files\View; +use OCP\IUserManager; +use Test\TestCase; + +/** + * Class DecryptAllTest + * + * @group DB + * + * @package Test\Encryption + */ +class DecryptAllTest extends TestCase { + + /** @var \PHPUnit_Framework_MockObject_MockObject | IUserManager */ + protected $userManager; + + /** @var \PHPUnit_Framework_MockObject_MockObject | Manager */ + protected $encryptionManager; + + /** @var \PHPUnit_Framework_MockObject_MockObject | View */ + protected $view; + + /** @var \PHPUnit_Framework_MockObject_MockObject | \Symfony\Component\Console\Input\InputInterface */ + protected $inputInterface; + + /** @var \PHPUnit_Framework_MockObject_MockObject | \Symfony\Component\Console\Output\OutputInterface */ + protected $outputInterface; + + /** @var \PHPUnit_Framework_MockObject_MockObject | \OCP\UserInterface */ + protected $userInterface; + + /** @var DecryptAll */ + protected $instance; + + public function setUp() { + parent::setUp(); + + $this->userManager = $this->getMockBuilder('OCP\IUserManager') + ->disableOriginalConstructor()->getMock(); + $this->encryptionManager = $this->getMockBuilder('OC\Encryption\Manager') + ->disableOriginalConstructor()->getMock(); + $this->view = $this->getMockBuilder('OC\Files\View') + ->disableOriginalConstructor()->getMock(); + $this->inputInterface = $this->getMockBuilder('Symfony\Component\Console\Input\InputInterface') + ->disableOriginalConstructor()->getMock(); + $this->outputInterface = $this->getMockBuilder('Symfony\Component\Console\Output\OutputInterface') + ->disableOriginalConstructor()->getMock(); + $this->userInterface = $this->getMockBuilder('OCP\UserInterface') + ->disableOriginalConstructor()->getMock(); + + $this->outputInterface->expects($this->any())->method('getFormatter') + ->willReturn($this->getMock('\Symfony\Component\Console\Formatter\OutputFormatterInterface')); + + $this->instance = new DecryptAll($this->encryptionManager, $this->userManager, $this->view); + + $this->invokePrivate($this->instance, 'input', [$this->inputInterface]); + $this->invokePrivate($this->instance, 'output', [$this->outputInterface]); + } + + /** + * @dataProvider dataTrueFalse + * @param bool $prepareResult + */ + public function testDecryptAll($prepareResult, $user) { + + if (!empty($user)) { + $this->userManager->expects($this->once())->method('userExists')->willReturn(true); + } else { + $this->userManager->expects($this->never())->method('userExists'); + } + /** @var DecryptAll | \PHPUnit_Framework_MockObject_MockObject | $instance */ + $instance = $this->getMockBuilder('OC\Encryption\DecryptAll') + ->setConstructorArgs( + [ + $this->encryptionManager, + $this->userManager, + $this->view + ] + ) + ->setMethods(['prepareEncryptionModules', 'decryptAllUsersFiles']) + ->getMock(); + + $instance->expects($this->once()) + ->method('prepareEncryptionModules') + ->with($user) + ->willReturn($prepareResult); + + if ($prepareResult) { + $instance->expects($this->once()) + ->method('decryptAllUsersFiles') + ->with($user); + } else { + $instance->expects($this->never())->method('decryptAllUsersFiles'); + } + + $instance->decryptAll($this->inputInterface, $this->outputInterface, $user); + } + + public function dataTrueFalse() { + return [ + [true, 'user1'], + [false, 'user1'], + [true, ''], + [true, null] + ]; + } + + /** + * test decrypt all call with a user who doesn't exists + */ + public function testDecryptAllWrongUser() { + $this->userManager->expects($this->once())->method('userExists')->willReturn(false); + $this->outputInterface->expects($this->once())->method('writeln') + ->with('User "user1" does not exist. Please check the username and try again'); + + $this->assertFalse( + $this->instance->decryptAll($this->inputInterface, $this->outputInterface, 'user1') + ); + } + + /** + * @dataProvider dataTrueFalse + */ + public function testPrepareEncryptionModules($success) { + + $user = 'user1'; + + $dummyEncryptionModule = $this->getMockBuilder('OCP\Encryption\IEncryptionModule') + ->disableOriginalConstructor()->getMock(); + + $dummyEncryptionModule->expects($this->once()) + ->method('prepareDecryptAll') + ->with($this->inputInterface, $this->outputInterface, $user) + ->willReturn($success); + + $callback = function() use ($dummyEncryptionModule) {return $dummyEncryptionModule;}; + $moduleDescription = [ + 'id' => 'id', + 'displayName' => 'displayName', + 'callback' => $callback + ]; + + $this->encryptionManager->expects($this->once()) + ->method('getEncryptionModules') + ->willReturn([$moduleDescription]); + + $this->assertSame($success, + $this->invokePrivate($this->instance, 'prepareEncryptionModules', [$user]) + ); + } + + /** + * @dataProvider dataTestDecryptAllUsersFiles + */ + public function testDecryptAllUsersFiles($user) { + + /** @var DecryptAll | \PHPUnit_Framework_MockObject_MockObject | $instance */ + $instance = $this->getMockBuilder('OC\Encryption\DecryptAll') + ->setConstructorArgs( + [ + $this->encryptionManager, + $this->userManager, + $this->view + ] + ) + ->setMethods(['decryptUsersFiles']) + ->getMock(); + + $this->invokePrivate($instance, 'input', [$this->inputInterface]); + $this->invokePrivate($instance, 'output', [$this->outputInterface]); + + if (empty($user)) { + $this->userManager->expects($this->once()) + ->method('getBackends') + ->willReturn([$this->userInterface]); + $this->userInterface->expects($this->any()) + ->method('getUsers') + ->willReturn(['user1', 'user2']); + $instance->expects($this->at(0)) + ->method('decryptUsersFiles') + ->with('user1'); + $instance->expects($this->at(1)) + ->method('decryptUsersFiles') + ->with('user2'); + } else { + $instance->expects($this->once()) + ->method('decryptUsersFiles') + ->with($user); + } + + $this->invokePrivate($instance, 'decryptAllUsersFiles', [$user]); + } + + public function dataTestDecryptAllUsersFiles() { + return [ + ['user1'], + [''] + ]; + } + + public function testDecryptUsersFiles() { + /** @var DecryptAll | \PHPUnit_Framework_MockObject_MockObject $instance */ + $instance = $this->getMockBuilder('OC\Encryption\DecryptAll') + ->setConstructorArgs( + [ + $this->encryptionManager, + $this->userManager, + $this->view + ] + ) + ->setMethods(['decryptFile']) + ->getMock(); + + $this->view->expects($this->at(0))->method('getDirectoryContent') + ->with('/user1/files')->willReturn( + [ + ['name' => 'foo', 'type'=>'dir'], + ['name' => 'bar', 'type'=>'file'], + ] + ); + + $this->view->expects($this->at(3))->method('getDirectoryContent') + ->with('/user1/files/foo')->willReturn( + [ + ['name' => 'subfile', 'type'=>'file'] + ] + ); + + $this->view->expects($this->any())->method('is_dir') + ->willReturnCallback( + function($path) { + if ($path === '/user1/files/foo') { + return true; + } + return false; + } + ); + + $instance->expects($this->at(0)) + ->method('decryptFile') + ->with('/user1/files/bar'); + $instance->expects($this->at(1)) + ->method('decryptFile') + ->with('/user1/files/foo/subfile'); + + $progressBar = $this->getMockBuilder('Symfony\Component\Console\Helper\ProgressBar') + ->disableOriginalConstructor()->getMock(); + + $this->invokePrivate($instance, 'decryptUsersFiles', ['user1', $progressBar, '']); + + } + + public function testDecryptFile() { + + $path = 'test.txt'; + + /** @var DecryptAll | \PHPUnit_Framework_MockObject_MockObject $instance */ + $instance = $this->getMockBuilder('OC\Encryption\DecryptAll') + ->setConstructorArgs( + [ + $this->encryptionManager, + $this->userManager, + $this->view + ] + ) + ->setMethods(['getTimestamp']) + ->getMock(); + + $instance->expects($this->any())->method('getTimestamp')->willReturn(42); + + $this->view->expects($this->once()) + ->method('copy') + ->with($path, $path . '.decrypted.42'); + $this->view->expects($this->once()) + ->method('rename') + ->with($path . '.decrypted.42', $path); + + $this->assertTrue( + $this->invokePrivate($instance, 'decryptFile', [$path]) + ); + } + + public function testDecryptFileFailure() { + $path = 'test.txt'; + + /** @var DecryptAll | \PHPUnit_Framework_MockObject_MockObject $instance */ + $instance = $this->getMockBuilder('OC\Encryption\DecryptAll') + ->setConstructorArgs( + [ + $this->encryptionManager, + $this->userManager, + $this->view + ] + ) + ->setMethods(['getTimestamp']) + ->getMock(); + + $instance->expects($this->any())->method('getTimestamp')->willReturn(42); + + $this->view->expects($this->once()) + ->method('copy') + ->with($path, $path . '.decrypted.42') + ->willReturnCallback(function() { throw new DecryptionFailedException();}); + + $this->view->expects($this->never())->method('rename'); + $this->view->expects($this->once()) + ->method('file_exists') + ->with($path . '.decrypted.42') + ->willReturn(true); + $this->view->expects($this->once()) + ->method('unlink') + ->with($path . '.decrypted.42'); + + $this->assertFalse( + $this->invokePrivate($instance, 'decryptFile', [$path]) + ); + } + +} diff --git a/tests/lib/Encryption/EncryptionWrapperTest.php b/tests/lib/Encryption/EncryptionWrapperTest.php new file mode 100644 index 00000000000..909187ae43b --- /dev/null +++ b/tests/lib/Encryption/EncryptionWrapperTest.php @@ -0,0 +1,101 @@ +<?php +/** + * @author Björn Schießle <schiessle@owncloud.com> + * + * @copyright Copyright (c) 2016, 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 Test\Encryption; + + +use OC\Encryption\EncryptionWrapper; +use Test\TestCase; + +class EncryptionWrapperTest extends TestCase { + + /** @var EncryptionWrapper */ + private $instance; + + /** @var \PHPUnit_Framework_MockObject_MockObject | \OCP\ILogger */ + private $logger; + + /** @var \PHPUnit_Framework_MockObject_MockObject | \OC\Encryption\Manager */ + private $manager; + + /** @var \PHPUnit_Framework_MockObject_MockObject | \OC\Memcache\ArrayCache */ + private $arrayCache; + + public function setUp() { + parent::setUp(); + + $this->arrayCache = $this->getMock('OC\Memcache\ArrayCache'); + $this->manager = $this->getMockBuilder('OC\Encryption\Manager') + ->disableOriginalConstructor()->getMock(); + $this->logger = $this->getMock('OCP\ILogger'); + + $this->instance = new EncryptionWrapper($this->arrayCache, $this->manager, $this->logger); + } + + + /** + * @dataProvider provideWrapStorage + */ + public function testWrapStorage($expectedWrapped, $wrappedStorages) { + $storage = $this->getMockBuilder('OC\Files\Storage\Storage') + ->disableOriginalConstructor() + ->getMock(); + + foreach ($wrappedStorages as $wrapper) { + $storage->expects($this->any()) + ->method('instanceOfStorage') + ->willReturnMap([ + [$wrapper, true], + ]); + } + + $mount = $this->getMockBuilder('OCP\Files\Mount\IMountPoint') + ->disableOriginalConstructor() + ->getMock(); + + $returnedStorage = $this->instance->wrapStorage('mountPoint', $storage, $mount); + + $this->assertEquals( + $expectedWrapped, + $returnedStorage->instanceOfStorage('OC\Files\Storage\Wrapper\Encryption'), + 'Asserted that the storage is (not) wrapped with encryption' + ); + } + + public function provideWrapStorage() { + return [ + // Wrap when not wrapped or not wrapped with storage + [true, []], + [true, ['OCA\Files_Trashbin\Storage']], + + // Do not wrap shared storages + [false, ['OC\Files\Storage\Shared']], + [false, ['OCA\Files_Sharing\External\Storage']], + [false, ['OC\Files\Storage\OwnCloud']], + [false, ['OC\Files\Storage\Shared', 'OCA\Files_Sharing\External\Storage']], + [false, ['OC\Files\Storage\Shared', 'OC\Files\Storage\OwnCloud']], + [false, ['OCA\Files_Sharing\External\Storage', 'OC\Files\Storage\OwnCloud']], + [false, ['OC\Files\Storage\Shared', 'OCA\Files_Sharing\External\Storage', 'OC\Files\Storage\OwnCloud']], + ]; + } + +} diff --git a/tests/lib/Encryption/Keys/StorageTest.php b/tests/lib/Encryption/Keys/StorageTest.php new file mode 100644 index 00000000000..b5b91f886a3 --- /dev/null +++ b/tests/lib/Encryption/Keys/StorageTest.php @@ -0,0 +1,513 @@ +<?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 Test\Encryption\Keys; + +use OC\Encryption\Keys\Storage; +use Test\TestCase; + +class StorageTest extends TestCase { + + /** @var Storage */ + protected $storage; + + /** @var \PHPUnit_Framework_MockObject_MockObject */ + protected $util; + + /** @var \PHPUnit_Framework_MockObject_MockObject */ + protected $view; + + /** @var \PHPUnit_Framework_MockObject_MockObject */ + protected $config; + + public function setUp() { + parent::setUp(); + + $this->util = $this->getMockBuilder('OC\Encryption\Util') + ->disableOriginalConstructor() + ->getMock(); + + $this->view = $this->getMockBuilder('OC\Files\View') + ->disableOriginalConstructor() + ->getMock(); + + $this->config = $this->getMockBuilder('OCP\IConfig') + ->disableOriginalConstructor() + ->getMock(); + + $this->storage = new Storage($this->view, $this->util); + } + + public function testSetFileKey() { + $this->util->expects($this->any()) + ->method('getUidAndFilename') + ->willReturn(array('user1', '/files/foo.txt')); + $this->util->expects($this->any()) + ->method('stripPartialFileExtension') + ->willReturnArgument(0); + $this->util->expects($this->any()) + ->method('isSystemWideMountPoint') + ->willReturn(false); + $this->view->expects($this->once()) + ->method('file_put_contents') + ->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey'), + $this->equalTo('key')) + ->willReturn(strlen('key')); + + $this->assertTrue( + $this->storage->setFileKey('user1/files/foo.txt', 'fileKey', 'key', 'encModule') + ); + } + + public function dataTestGetFileKey() { + return [ + ['/files/foo.txt', '/files/foo.txt', true, 'key'], + ['/files/foo.txt.ocTransferId2111130212.part', '/files/foo.txt', true, 'key'], + ['/files/foo.txt.ocTransferId2111130212.part', '/files/foo.txt', false, 'key2'], + ]; + } + + /** + * @dataProvider dataTestGetFileKey + * + * @param string $path + * @param string $strippedPartialName + * @param bool $originalKeyExists + * @param string $expectedKeyContent + */ + public function testGetFileKey($path, $strippedPartialName, $originalKeyExists, $expectedKeyContent) { + $this->util->expects($this->any()) + ->method('getUidAndFilename') + ->willReturnMap([ + ['user1/files/foo.txt', ['user1', '/files/foo.txt']], + ['user1/files/foo.txt.ocTransferId2111130212.part', ['user1', '/files/foo.txt.ocTransferId2111130212.part']], + ]); + // we need to strip away the part file extension in order to reuse a + // existing key if it exists, otherwise versions will break + $this->util->expects($this->once()) + ->method('stripPartialFileExtension') + ->willReturn('user1' . $strippedPartialName); + $this->util->expects($this->any()) + ->method('isSystemWideMountPoint') + ->willReturn(false); + + $this->view->expects($this->at(0)) + ->method('file_exists') + ->with($this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey')) + ->willReturn($originalKeyExists); + + if (!$originalKeyExists) { + $this->view->expects($this->at(1)) + ->method('file_exists') + ->with($this->equalTo('/user1/files_encryption/keys' . $path . '/encModule/fileKey')) + ->willReturn(true); + + $this->view->expects($this->once()) + ->method('file_get_contents') + ->with($this->equalTo('/user1/files_encryption/keys' . $path . '/encModule/fileKey')) + ->willReturn('key2'); + } else { + $this->view->expects($this->once()) + ->method('file_get_contents') + ->with($this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey')) + ->willReturn('key'); + } + + $this->assertSame($expectedKeyContent, + $this->storage->getFileKey('user1' . $path, 'fileKey', 'encModule') + ); + } + + public function testSetFileKeySystemWide() { + $this->util->expects($this->any()) + ->method('getUidAndFilename') + ->willReturn(array('user1', '/files/foo.txt')); + $this->util->expects($this->any()) + ->method('isSystemWideMountPoint') + ->willReturn(true); + $this->util->expects($this->any()) + ->method('stripPartialFileExtension') + ->willReturnArgument(0); + $this->view->expects($this->once()) + ->method('file_put_contents') + ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey'), + $this->equalTo('key')) + ->willReturn(strlen('key')); + + $this->assertTrue( + $this->storage->setFileKey('user1/files/foo.txt', 'fileKey', 'key', 'encModule') + ); + } + + public function testGetFileKeySystemWide() { + $this->util->expects($this->any()) + ->method('getUidAndFilename') + ->willReturn(array('user1', '/files/foo.txt')); + $this->util->expects($this->any()) + ->method('stripPartialFileExtension') + ->willReturnArgument(0); + $this->util->expects($this->any()) + ->method('isSystemWideMountPoint') + ->willReturn(true); + $this->view->expects($this->once()) + ->method('file_get_contents') + ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey')) + ->willReturn('key'); + $this->view->expects($this->once()) + ->method('file_exists') + ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey')) + ->willReturn(true); + + $this->assertSame('key', + $this->storage->getFileKey('user1/files/foo.txt', 'fileKey', 'encModule') + ); + } + + public function testSetSystemUserKey() { + $this->view->expects($this->once()) + ->method('file_put_contents') + ->with($this->equalTo('/files_encryption/encModule/shareKey_56884'), + $this->equalTo('key')) + ->willReturn(strlen('key')); + + $this->assertTrue( + $this->storage->setSystemUserKey('shareKey_56884', 'key', 'encModule') + ); + } + + public function testSetUserKey() { + $this->view->expects($this->once()) + ->method('file_put_contents') + ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey'), + $this->equalTo('key')) + ->willReturn(strlen('key')); + + $this->assertTrue( + $this->storage->setUserKey('user1', 'publicKey', 'key', 'encModule') + ); + } + + public function testGetSystemUserKey() { + $this->view->expects($this->once()) + ->method('file_get_contents') + ->with($this->equalTo('/files_encryption/encModule/shareKey_56884')) + ->willReturn('key'); + $this->view->expects($this->once()) + ->method('file_exists') + ->with($this->equalTo('/files_encryption/encModule/shareKey_56884')) + ->willReturn(true); + + $this->assertSame('key', + $this->storage->getSystemUserKey('shareKey_56884', 'encModule') + ); + } + + public function testGetUserKey() { + $this->view->expects($this->once()) + ->method('file_get_contents') + ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey')) + ->willReturn('key'); + $this->view->expects($this->once()) + ->method('file_exists') + ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey')) + ->willReturn(true); + + $this->assertSame('key', + $this->storage->getUserKey('user1', 'publicKey', 'encModule') + ); + } + + public function testDeleteUserKey() { + $this->view->expects($this->once()) + ->method('file_exists') + ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey')) + ->willReturn(true); + $this->view->expects($this->once()) + ->method('unlink') + ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey')) + ->willReturn(true); + + $this->assertTrue( + $this->storage->deleteUserKey('user1', 'publicKey', 'encModule') + ); + } + + public function testDeleteSystemUserKey() { + $this->view->expects($this->once()) + ->method('file_exists') + ->with($this->equalTo('/files_encryption/encModule/shareKey_56884')) + ->willReturn(true); + $this->view->expects($this->once()) + ->method('unlink') + ->with($this->equalTo('/files_encryption/encModule/shareKey_56884')) + ->willReturn(true); + + $this->assertTrue( + $this->storage->deleteSystemUserKey('shareKey_56884', 'encModule') + ); + } + + public function testDeleteFileKeySystemWide() { + $this->util->expects($this->any()) + ->method('getUidAndFilename') + ->willReturn(array('user1', '/files/foo.txt')); + $this->util->expects($this->any()) + ->method('stripPartialFileExtension') + ->willReturnArgument(0); + $this->util->expects($this->any()) + ->method('isSystemWideMountPoint') + ->willReturn(true); + $this->view->expects($this->once()) + ->method('file_exists') + ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey')) + ->willReturn(true); + $this->view->expects($this->once()) + ->method('unlink') + ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey')) + ->willReturn(true); + + $this->assertTrue( + $this->storage->deleteFileKey('user1/files/foo.txt', 'fileKey', 'encModule') + ); + } + + public function testDeleteFileKey() { + $this->util->expects($this->any()) + ->method('getUidAndFilename') + ->willReturn(array('user1', '/files/foo.txt')); + $this->util->expects($this->any()) + ->method('stripPartialFileExtension') + ->willReturnArgument(0); + $this->util->expects($this->any()) + ->method('isSystemWideMountPoint') + ->willReturn(false); + $this->view->expects($this->once()) + ->method('file_exists') + ->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey')) + ->willReturn(true); + $this->view->expects($this->once()) + ->method('unlink') + ->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey')) + ->willReturn(true); + + $this->assertTrue( + $this->storage->deleteFileKey('user1/files/foo.txt', 'fileKey', 'encModule') + ); + } + + /** + * @dataProvider dataProviderCopyRename + */ + public function testRenameKeys($source, $target, $systemWideMountSource, $systemWideMountTarget, $expectedSource, $expectedTarget) { + $this->view->expects($this->any()) + ->method('file_exists') + ->willReturn(true); + $this->view->expects($this->any()) + ->method('is_dir') + ->willReturn(true); + $this->view->expects($this->once()) + ->method('rename') + ->with( + $this->equalTo($expectedSource), + $this->equalTo($expectedTarget)) + ->willReturn(true); + $this->util->expects($this->any()) + ->method('getUidAndFilename') + ->will($this->returnCallback(array($this, 'getUidAndFilenameCallback'))); + $this->util->expects($this->any()) + ->method('isSystemWideMountPoint') + ->willReturnCallback(function($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) { + if(strpos($path, 'source.txt') !== false) { + return $systemWideMountSource; + } + return $systemWideMountTarget; + }); + + $this->storage->renameKeys($source, $target); + } + + /** + * @dataProvider dataProviderCopyRename + */ + public function testCopyKeys($source, $target, $systemWideMountSource, $systemWideMountTarget , $expectedSource, $expectedTarget) { + $this->view->expects($this->any()) + ->method('file_exists') + ->willReturn(true); + $this->view->expects($this->any()) + ->method('is_dir') + ->willReturn(true); + $this->view->expects($this->once()) + ->method('copy') + ->with( + $this->equalTo($expectedSource), + $this->equalTo($expectedTarget)) + ->willReturn(true); + $this->util->expects($this->any()) + ->method('getUidAndFilename') + ->will($this->returnCallback(array($this, 'getUidAndFilenameCallback'))); + $this->util->expects($this->any()) + ->method('isSystemWideMountPoint') + ->willReturnCallback(function($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) { + if(strpos($path, 'source.txt') !== false) { + return $systemWideMountSource; + } + return $systemWideMountTarget; + }); + + $this->storage->copyKeys($source, $target); + } + + public function getUidAndFilenameCallback() { + $args = func_get_args(); + + $path = $args[0]; + $parts = explode('/', $path); + + return array($parts[1], '/' . implode('/', array_slice($parts, 2))); + } + + public function dataProviderCopyRename() { + return array( + array('/user1/files/source.txt', '/user1/files/target.txt', false, false, + '/user1/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'), + array('/user1/files/foo/source.txt', '/user1/files/target.txt', false, false, + '/user1/files_encryption/keys/files/foo/source.txt/', '/user1/files_encryption/keys/files/target.txt/'), + array('/user1/files/source.txt', '/user1/files/foo/target.txt', false, false, + '/user1/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/foo/target.txt/'), + array('/user1/files/source.txt', '/user1/files/foo/target.txt', true, true, + '/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/foo/target.txt/'), + array('/user1/files/source.txt', '/user1/files/target.txt', false, true, + '/user1/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/target.txt/'), + array('/user1/files/source.txt', '/user1/files/target.txt', true, false, + '/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'), + + array('/user2/files/source.txt', '/user1/files/target.txt', false, false, + '/user2/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'), + array('/user2/files/foo/source.txt', '/user1/files/target.txt', false, false, + '/user2/files_encryption/keys/files/foo/source.txt/', '/user1/files_encryption/keys/files/target.txt/'), + array('/user2/files/source.txt', '/user1/files/foo/target.txt', false, false, + '/user2/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/foo/target.txt/'), + array('/user2/files/source.txt', '/user1/files/foo/target.txt', true, true, + '/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/foo/target.txt/'), + array('/user2/files/source.txt', '/user1/files/target.txt', false, true, + '/user2/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/target.txt/'), + array('/user2/files/source.txt', '/user1/files/target.txt', true, false, + '/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'), + ); + } + + /** + * @dataProvider dataTestGetPathToKeys + * + * @param string $path + * @param boolean $systemWideMountPoint + * @param string $storageRoot + * @param string $expected + */ + public function testGetPathToKeys($path, $systemWideMountPoint, $storageRoot, $expected) { + + $this->invokePrivate($this->storage, 'root_dir', [$storageRoot]); + + $this->util->expects($this->any()) + ->method('getUidAndFilename') + ->will($this->returnCallback(array($this, 'getUidAndFilenameCallback'))); + $this->util->expects($this->any()) + ->method('isSystemWideMountPoint') + ->willReturn($systemWideMountPoint); + + $this->assertSame($expected, + self::invokePrivate($this->storage, 'getPathToKeys', [$path]) + ); + } + + public function dataTestGetPathToKeys() { + return [ + ['/user1/files/source.txt', false, '', '/user1/files_encryption/keys/files/source.txt/'], + ['/user1/files/source.txt', true, '', '/files_encryption/keys/files/source.txt/'], + ['/user1/files/source.txt', false, 'storageRoot', '/storageRoot/user1/files_encryption/keys/files/source.txt/'], + ['/user1/files/source.txt', true, 'storageRoot', '/storageRoot/files_encryption/keys/files/source.txt/'], + ]; + } + + public function testKeySetPreparation() { + $this->view->expects($this->any()) + ->method('file_exists') + ->willReturn(false); + $this->view->expects($this->any()) + ->method('is_dir') + ->willReturn(false); + $this->view->expects($this->any()) + ->method('mkdir') + ->will($this->returnCallback(array($this, 'mkdirCallback'))); + + $this->mkdirStack = array( + '/user1/files_encryption/keys/foo', + '/user1/files_encryption/keys', + '/user1/files_encryption', + '/user1'); + + self::invokePrivate($this->storage, 'keySetPreparation', array('/user1/files_encryption/keys/foo')); + } + + public function mkdirCallback() { + $args = func_get_args(); + $expected = array_pop($this->mkdirStack); + $this->assertSame($expected, $args[0]); + } + + /** + * @dataProvider dataTestGetFileKeyDir + * + * @param bool $isSystemWideMountPoint + * @param string $storageRoot + * @param string $expected + */ + public function testGetFileKeyDir($isSystemWideMountPoint, $storageRoot, $expected) { + + $path = '/user1/files/foo/bar.txt'; + $owner = 'user1'; + $relativePath = '/foo/bar.txt'; + + $this->invokePrivate($this->storage, 'root_dir', [$storageRoot]); + + $this->util->expects($this->once())->method('isSystemWideMountPoint') + ->willReturn($isSystemWideMountPoint); + $this->util->expects($this->once())->method('getUidAndFilename') + ->with($path)->willReturn([$owner, $relativePath]); + + $this->assertSame($expected, + $this->invokePrivate($this->storage, 'getFileKeyDir', ['OC_DEFAULT_MODULE', $path]) + ); + + } + + public function dataTestGetFileKeyDir() { + return [ + [false, '', '/user1/files_encryption/keys/foo/bar.txt/OC_DEFAULT_MODULE/'], + [true, '', '/files_encryption/keys/foo/bar.txt/OC_DEFAULT_MODULE/'], + [false, 'newStorageRoot', '/newStorageRoot/user1/files_encryption/keys/foo/bar.txt/OC_DEFAULT_MODULE/'], + [true, 'newStorageRoot', '/newStorageRoot/files_encryption/keys/foo/bar.txt/OC_DEFAULT_MODULE/'], + ]; + } + +} diff --git a/tests/lib/Encryption/ManagerTest.php b/tests/lib/Encryption/ManagerTest.php new file mode 100644 index 00000000000..3dcfc949a18 --- /dev/null +++ b/tests/lib/Encryption/ManagerTest.php @@ -0,0 +1,250 @@ +<?php + +namespace Test\Encryption; + +use OC\Encryption\Manager; +use Test\TestCase; + +class ManagerTest extends TestCase { + + /** @var Manager */ + private $manager; + + /** @var \PHPUnit_Framework_MockObject_MockObject */ + private $config; + + /** @var \PHPUnit_Framework_MockObject_MockObject */ + private $logger; + + /** @var \PHPUnit_Framework_MockObject_MockObject */ + private $l10n; + + /** @var \PHPUnit_Framework_MockObject_MockObject */ + private $view; + + /** @var \PHPUnit_Framework_MockObject_MockObject */ + private $util; + + /** @var \PHPUnit_Framework_MockObject_MockObject | \OC\Memcache\ArrayCache */ + private $arrayCache; + + public function setUp() { + parent::setUp(); + $this->config = $this->getMock('\OCP\IConfig'); + $this->logger = $this->getMock('\OCP\ILogger'); + $this->l10n = $this->getMock('\OCP\Il10n'); + $this->view = $this->getMock('\OC\Files\View'); + $this->util = $this->getMockBuilder('\OC\Encryption\Util')->disableOriginalConstructor()->getMock(); + $this->arrayCache = $this->getMock('OC\Memcache\ArrayCache'); + $this->manager = new Manager($this->config, $this->logger, $this->l10n, $this->view, $this->util, $this->arrayCache); + } + + public function testManagerIsDisabled() { + $this->assertFalse($this->manager->isEnabled()); + } + + public function testManagerIsDisabledIfEnabledButNoModules() { + $this->config->expects($this->any())->method('getAppValue')->willReturn(true); + $this->assertFalse($this->manager->isEnabled()); + } + + public function testManagerIsDisabledIfDisabledButModules() { + $this->config->expects($this->any())->method('getAppValue')->willReturn(false); + $em = $this->getMock('\OCP\Encryption\IEncryptionModule'); + $em->expects($this->any())->method('getId')->willReturn('id'); + $em->expects($this->any())->method('getDisplayName')->willReturn('TestDummyModule0'); + $this->manager->registerEncryptionModule('id', 'TestDummyModule0', function() use ($em) {return $em;}); + $this->assertFalse($this->manager->isEnabled()); + } + + public function testManagerIsEnabled() { + $this->config->expects($this->any())->method('getSystemValue')->willReturn(true); + $this->config->expects($this->any())->method('getAppValue')->willReturn('yes'); + $this->assertTrue($this->manager->isEnabled()); + } + + public function testModuleRegistration() { + $this->config->expects($this->any())->method('getAppValue')->willReturn('yes'); + + $this->addNewEncryptionModule($this->manager, 0); + $this->assertCount(1, $this->manager->getEncryptionModules()); + + return $this->manager; + } + + /** + * @depends testModuleRegistration + * @expectedException \OC\Encryption\Exceptions\ModuleAlreadyExistsException + * @expectedExceptionMessage Id "ID0" already used by encryption module "TestDummyModule0" + */ + public function testModuleReRegistration($manager) { + $this->addNewEncryptionModule($manager, 0); + } + + public function testModuleUnRegistration() { + $this->config->expects($this->any())->method('getAppValue')->willReturn(true); + $this->addNewEncryptionModule($this->manager, 0); + $this->assertCount(1, $this->manager->getEncryptionModules()); + + $this->manager->unregisterEncryptionModule('ID0'); + $this->assertEmpty($this->manager->getEncryptionModules()); + + } + + /** + * @expectedException \OC\Encryption\Exceptions\ModuleDoesNotExistsException + * @expectedExceptionMessage Module with id: unknown does not exist. + */ + public function testGetEncryptionModuleUnknown() { + $this->config->expects($this->any())->method('getAppValue')->willReturn(true); + $this->addNewEncryptionModule($this->manager, 0); + $this->assertCount(1, $this->manager->getEncryptionModules()); + $this->manager->getEncryptionModule('unknown'); + } + + public function testGetEncryptionModuleEmpty() { + global $defaultId; + $defaultId = null; + + $this->config->expects($this->any()) + ->method('getAppValue') + ->with('core', 'default_encryption_module') + ->willReturnCallback(function() { global $defaultId; return $defaultId; }); + + $this->addNewEncryptionModule($this->manager, 0); + $this->assertCount(1, $this->manager->getEncryptionModules()); + $this->addNewEncryptionModule($this->manager, 1); + $this->assertCount(2, $this->manager->getEncryptionModules()); + + // Should return the default module + $defaultId = 'ID0'; + $this->assertEquals('ID0', $this->manager->getEncryptionModule()->getId()); + $defaultId = 'ID1'; + $this->assertEquals('ID1', $this->manager->getEncryptionModule()->getId()); + } + + public function testGetEncryptionModule() { + global $defaultId; + $defaultId = null; + + $this->config->expects($this->any()) + ->method('getAppValue') + ->with('core', 'default_encryption_module') + ->willReturnCallback(function() { global $defaultId; return $defaultId; }); + + $this->addNewEncryptionModule($this->manager, 0); + $defaultId = 'ID0'; + $this->assertCount(1, $this->manager->getEncryptionModules()); + + $en0 = $this->manager->getEncryptionModule('ID0'); + $this->assertEquals('ID0', $en0->getId()); + + $en0 = self::invokePrivate($this->manager, 'getDefaultEncryptionModule'); + $this->assertEquals('ID0', $en0->getId()); + + $this->assertEquals('ID0', $this->manager->getDefaultEncryptionModuleId()); + } + + public function testSetDefaultEncryptionModule() { + global $defaultId; + $defaultId = null; + + $this->config->expects($this->any()) + ->method('getAppValue') + ->with('core', 'default_encryption_module') + ->willReturnCallback(function() { global $defaultId; return $defaultId; }); + + $this->addNewEncryptionModule($this->manager, 0); + $this->assertCount(1, $this->manager->getEncryptionModules()); + $this->addNewEncryptionModule($this->manager, 1); + $this->assertCount(2, $this->manager->getEncryptionModules()); + + // Default module is the first we set + $defaultId = 'ID0'; + $this->assertEquals('ID0', $this->manager->getDefaultEncryptionModuleId()); + + // Set to an existing module + $this->config->expects($this->once()) + ->method('setAppValue') + ->with('core', 'default_encryption_module', 'ID1'); + $this->assertTrue($this->manager->setDefaultEncryptionModule('ID1')); + $defaultId = 'ID1'; + $this->assertEquals('ID1', $this->manager->getDefaultEncryptionModuleId()); + + // Set to an unexisting module + $this->assertFalse($this->manager->setDefaultEncryptionModule('ID2')); + $this->assertEquals('ID1', $this->manager->getDefaultEncryptionModuleId()); + } + +// /** +// * @expectedException \OC\Encryption\Exceptions\ModuleAlreadyExistsException +// * @expectedExceptionMessage Id "0" already used by encryption module "TestDummyModule0" +// */ +// public function testModuleRegistration() { +// $config = $this->getMock('\OCP\IConfig'); +// $config->expects($this->any())->method('getSystemValue')->willReturn(true); +// $em = $this->getMock('\OCP\Encryption\IEncryptionModule'); +// $em->expects($this->any())->method('getId')->willReturn(0); +// $em->expects($this->any())->method('getDisplayName')->willReturn('TestDummyModule0'); +// $m = new Manager($config); +// $m->registerEncryptionModule($em); +// $this->assertTrue($m->isEnabled()); +// $m->registerEncryptionModule($em); +// } +// +// public function testModuleUnRegistration() { +// $config = $this->getMock('\OCP\IConfig'); +// $config->expects($this->any())->method('getSystemValue')->willReturn(true); +// $em = $this->getMock('\OCP\Encryption\IEncryptionModule'); +// $em->expects($this->any())->method('getId')->willReturn(0); +// $em->expects($this->any())->method('getDisplayName')->willReturn('TestDummyModule0'); +// $m = new Manager($config); +// $m->registerEncryptionModule($em); +// $this->assertTrue($m->isEnabled()); +// $m->unregisterEncryptionModule($em); +// $this->assertFalse($m->isEnabled()); +// } +// +// /** +// * @expectedException \OC\Encryption\Exceptions\ModuleDoesNotExistsException +// * @expectedExceptionMessage Module with id: unknown does not exist. +// */ +// public function testGetEncryptionModuleUnknown() { +// $config = $this->getMock('\OCP\IConfig'); +// $config->expects($this->any())->method('getSystemValue')->willReturn(true); +// $em = $this->getMock('\OCP\Encryption\IEncryptionModule'); +// $em->expects($this->any())->method('getId')->willReturn(0); +// $em->expects($this->any())->method('getDisplayName')->willReturn('TestDummyModule0'); +// $m = new Manager($config); +// $m->registerEncryptionModule($em); +// $this->assertTrue($m->isEnabled()); +// $m->getEncryptionModule('unknown'); +// } +// +// public function testGetEncryptionModule() { +// $config = $this->getMock('\OCP\IConfig'); +// $config->expects($this->any())->method('getSystemValue')->willReturn(true); +// $em = $this->getMock('\OCP\Encryption\IEncryptionModule'); +// $em->expects($this->any())->method('getId')->willReturn(0); +// $em->expects($this->any())->method('getDisplayName')->willReturn('TestDummyModule0'); +// $m = new Manager($config); +// $m->registerEncryptionModule($em); +// $this->assertTrue($m->isEnabled()); +// $en0 = $m->getEncryptionModule(0); +// $this->assertEquals(0, $en0->getId()); +// } + + protected function addNewEncryptionModule(Manager $manager, $id) { + $encryptionModule = $this->getMock('\OCP\Encryption\IEncryptionModule'); + $encryptionModule->expects($this->any()) + ->method('getId') + ->willReturn('ID' . $id); + $encryptionModule->expects($this->any()) + ->method('getDisplayName') + ->willReturn('TestDummyModule' . $id); + /** @var \OCP\Encryption\IEncryptionModule $encryptionModule */ + $manager->registerEncryptionModule('ID' . $id, 'TestDummyModule' . $id, function() use ($encryptionModule) { + return $encryptionModule; + }); + } +} diff --git a/tests/lib/Encryption/UpdateTest.php b/tests/lib/Encryption/UpdateTest.php new file mode 100644 index 00000000000..b222bc42d7a --- /dev/null +++ b/tests/lib/Encryption/UpdateTest.php @@ -0,0 +1,236 @@ +<?php +/** + * @author Björn Schießle <schiessle@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 Test\Encryption; + + +use OC\Encryption\Update; +use Test\TestCase; + +class UpdateTest extends TestCase { + + /** @var \OC\Encryption\Update */ + private $update; + + /** @var string */ + private $uid; + + /** @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject */ + private $view; + + /** @var \OC\Encryption\Util | \PHPUnit_Framework_MockObject_MockObject */ + private $util; + + /** @var \OC\Files\Mount\Manager | \PHPUnit_Framework_MockObject_MockObject */ + private $mountManager; + + /** @var \OC\Encryption\Manager | \PHPUnit_Framework_MockObject_MockObject */ + private $encryptionManager; + + /** @var \OCP\Encryption\IEncryptionModule | \PHPUnit_Framework_MockObject_MockObject */ + private $encryptionModule; + + /** @var \OC\Encryption\File | \PHPUnit_Framework_MockObject_MockObject */ + private $fileHelper; + + protected function setUp() { + parent::setUp(); + + $this->view = $this->getMockBuilder('\OC\Files\View') + ->disableOriginalConstructor()->getMock(); + $this->util = $this->getMockBuilder('\OC\Encryption\Util') + ->disableOriginalConstructor()->getMock(); + $this->mountManager = $this->getMockBuilder('\OC\Files\Mount\Manager') + ->disableOriginalConstructor()->getMock(); + $this->encryptionManager = $this->getMockBuilder('\OC\Encryption\Manager') + ->disableOriginalConstructor()->getMock(); + $this->fileHelper = $this->getMockBuilder('\OC\Encryption\File') + ->disableOriginalConstructor()->getMock(); + $this->encryptionModule = $this->getMockBuilder('\OCP\Encryption\IEncryptionModule') + ->disableOriginalConstructor()->getMock(); + + $this->uid = 'testUser1'; + + $this->update = new Update( + $this->view, + $this->util, + $this->mountManager, + $this->encryptionManager, + $this->fileHelper, + $this->uid); + } + + /** + * @dataProvider dataTestUpdate + * + * @param string $path + * @param boolean $isDir + * @param array $allFiles + * @param integer $numberOfFiles + */ + public function testUpdate($path, $isDir, $allFiles, $numberOfFiles) { + + $this->encryptionManager->expects($this->once()) + ->method('getEncryptionModule') + ->willReturn($this->encryptionModule); + + $this->view->expects($this->once()) + ->method('is_dir') + ->willReturn($isDir); + + if($isDir) { + $this->util->expects($this->once()) + ->method('getAllFiles') + ->willReturn($allFiles); + } + + $this->fileHelper->expects($this->exactly($numberOfFiles)) + ->method('getAccessList') + ->willReturn(['users' => [], 'public' => false]); + + $this->encryptionModule->expects($this->exactly($numberOfFiles)) + ->method('update') + ->willReturn(true); + + $this->update->update($path); + } + + /** + * data provider for testUpdate() + * + * @return array + */ + public function dataTestUpdate() { + return array( + array('/user/files/foo', true, ['/user/files/foo/file1.txt', '/user/files/foo/file1.txt'], 2), + array('/user/files/test.txt', false, [], 1), + ); + } + + /** + * @dataProvider dataTestPostRename + * + * @param string $source + * @param string $target + * @param boolean $encryptionEnabled + */ + public function testPostRename($source, $target, $encryptionEnabled) { + + $updateMock = $this->getUpdateMock(['update', 'getOwnerPath']); + + $this->encryptionManager->expects($this->once()) + ->method('isEnabled') + ->willReturn($encryptionEnabled); + + if (dirname($source) === dirname($target) || $encryptionEnabled === false) { + $updateMock->expects($this->never())->method('getOwnerPath'); + $updateMock->expects($this->never())->method('update'); + } else { + $updateMock->expects($this->once()) + ->method('getOwnerPath') + ->willReturnCallback(function($path) use ($target) { + $this->assertSame( + $target, + $path, + 'update needs to be executed for the target destination'); + return ['owner', $path]; + + }); + $updateMock->expects($this->once())->method('update'); + } + + $updateMock->postRename(['oldpath' => $source, 'newpath' => $target]); + } + + /** + * test data for testPostRename() + * + * @return array + */ + public function dataTestPostRename() { + return array( + array('/test.txt', '/testNew.txt', true), + array('/test.txt', '/testNew.txt', false), + array('/folder/test.txt', '/testNew.txt', true), + array('/folder/test.txt', '/testNew.txt', false), + array('/folder/test.txt', '/testNew.txt', true), + array('/test.txt', '/folder/testNew.txt', false), + ); + } + + + /** + * @dataProvider dataTestPostRestore + * + * @param boolean $encryptionEnabled + */ + public function testPostRestore($encryptionEnabled) { + + $updateMock = $this->getUpdateMock(['update']); + + $this->encryptionManager->expects($this->once()) + ->method('isEnabled') + ->willReturn($encryptionEnabled); + + if ($encryptionEnabled) { + $updateMock->expects($this->once())->method('update'); + + } else { + $updateMock->expects($this->never())->method('update'); + } + + $updateMock->postRestore(['filePath' => '/folder/test.txt']); + } + + /** + * test data for testPostRestore() + * + * @return array + */ + public function dataTestPostRestore() { + return array( + array(true), + array(false), + ); + } + + /** + * create mock of the update method + * + * @param array$methods methods which should be set + * @return \OC\Encryption\Update | \PHPUnit_Framework_MockObject_MockObject + */ + protected function getUpdateMock($methods) { + return $this->getMockBuilder('\OC\Encryption\Update') + ->setConstructorArgs( + [ + $this->view, + $this->util, + $this->mountManager, + $this->encryptionManager, + $this->fileHelper, + $this->uid + ] + )->setMethods($methods)->getMock(); + } + +} diff --git a/tests/lib/Encryption/UtilTest.php b/tests/lib/Encryption/UtilTest.php new file mode 100644 index 00000000000..ec316a9f05a --- /dev/null +++ b/tests/lib/Encryption/UtilTest.php @@ -0,0 +1,191 @@ +<?php + +namespace Test\Encryption; + +use OC\Encryption\Util; +use Test\TestCase; + +class UtilTest extends TestCase { + + /** + * block size will always be 8192 for a PHP stream + * @see https://bugs.php.net/bug.php?id=21641 + * @var integer + */ + protected $headerSize = 8192; + + /** @var \PHPUnit_Framework_MockObject_MockObject */ + protected $view; + + /** @var \PHPUnit_Framework_MockObject_MockObject */ + protected $userManager; + + /** @var \PHPUnit_Framework_MockObject_MockObject */ + protected $groupManager; + + /** @var \PHPUnit_Framework_MockObject_MockObject */ + private $config; + + /** @var \OC\Encryption\Util */ + private $util; + + public function setUp() { + parent::setUp(); + $this->view = $this->getMockBuilder('OC\Files\View') + ->disableOriginalConstructor() + ->getMock(); + + $this->userManager = $this->getMockBuilder('OC\User\Manager') + ->disableOriginalConstructor() + ->getMock(); + + $this->groupManager = $this->getMockBuilder('OC\Group\Manager') + ->disableOriginalConstructor() + ->getMock(); + + $this->config = $this->getMockBuilder('OCP\IConfig') + ->disableOriginalConstructor() + ->getMock(); + + $this->util = new Util( + $this->view, + $this->userManager, + $this->groupManager, + $this->config + ); + + } + + /** + * @dataProvider providesHeadersForEncryptionModule + */ + public function testGetEncryptionModuleId($expected, $header) { + $id = $this->util->getEncryptionModuleId($header); + $this->assertEquals($expected, $id); + } + + public function providesHeadersForEncryptionModule() { + return [ + ['', []], + ['', ['1']], + [2, ['oc_encryption_module' => 2]], + ]; + } + + /** + * @dataProvider providesHeaders + */ + public function testCreateHeader($expected, $header, $moduleId) { + + $em = $this->getMock('\OCP\Encryption\IEncryptionModule'); + $em->expects($this->any())->method('getId')->willReturn($moduleId); + + $result = $this->util->createHeader($header, $em); + $this->assertEquals($expected, $result); + } + + public function providesHeaders() { + return [ + [str_pad('HBEGIN:oc_encryption_module:0:HEND', $this->headerSize, '-', STR_PAD_RIGHT) + , [], '0'], + [str_pad('HBEGIN:oc_encryption_module:0:custom_header:foo:HEND', $this->headerSize, '-', STR_PAD_RIGHT) + , ['custom_header' => 'foo'], '0'], + ]; + } + + /** + * @expectedException \OC\Encryption\Exceptions\EncryptionHeaderKeyExistsException + */ + public function testCreateHeaderFailed() { + + $header = array('header1' => 1, 'header2' => 2, 'oc_encryption_module' => 'foo'); + + $em = $this->getMock('\OCP\Encryption\IEncryptionModule'); + $em->expects($this->any())->method('getId')->willReturn('moduleId'); + + $this->util->createHeader($header, $em); + } + + /** + * @dataProvider providePathsForTestIsExcluded + */ + public function testIsExcluded($path, $keyStorageRoot, $expected) { + $this->config->expects($this->once()) + ->method('getAppValue') + ->with('core', 'encryption_key_storage_root', '') + ->willReturn($keyStorageRoot); + $this->userManager + ->expects($this->any()) + ->method('userExists') + ->will($this->returnCallback(array($this, 'isExcludedCallback'))); + + $this->assertSame($expected, + $this->util->isExcluded($path) + ); + } + + public function providePathsForTestIsExcluded() { + return array( + array('/files_encryption', '', true), + array('files_encryption/foo.txt', '', true), + array('test/foo.txt', '', false), + array('/user1/files_encryption/foo.txt', '', true), + array('/user1/files/foo.txt', '', false), + array('/keyStorage/user1/files/foo.txt', 'keyStorage', true), + array('/keyStorage/files_encryption', '/keyStorage', true), + array('keyStorage/user1/files_encryption', '/keyStorage/', true), + + ); + } + + public function isExcludedCallback() { + $args = func_get_args(); + if ($args[0] === 'user1') { + return true; + } + + return false; + } + + /** + * @dataProvider dataTestIsFile + */ + public function testIsFile($path, $expected) { + $this->assertSame($expected, + $this->util->isFile($path) + ); + } + + public function dataTestIsFile() { + return array( + array('/user/files/test.txt', true), + array('/user/files', true), + array('/user/files_versions/test.txt', false), + array('/user/foo/files/test.txt', false), + array('/files/foo/files/test.txt', false), + array('/user', false), + array('/user/test.txt', false), + ); + } + + /** + * @dataProvider dataTestStripPartialFileExtension + * + * @param string $path + * @param string $expected + */ + public function testStripPartialFileExtension($path, $expected) { + $this->assertSame($expected, + $this->util->stripPartialFileExtension($path)); + } + + public function dataTestStripPartialFileExtension() { + return array( + array('/foo/test.txt', '/foo/test.txt'), + array('/foo/test.txt.part', '/foo/test.txt'), + array('/foo/test.txt.ocTransferId7567846853.part', '/foo/test.txt'), + array('/foo/test.txt.ocTransferId7567.part', '/foo/test.txt'), + ); + } + +} |