Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoas Schilling <nickvergessen@gmx.de>2016-05-20 16:38:20 +0300
committerThomas Müller <DeepDiver1975@users.noreply.github.com>2016-05-20 16:38:20 +0300
commit94ad54ec9b96d41a614fbbad4a97b34c41a6901f (patch)
treef3eb7cdda2704aaf0cd59d58efe66bcbd34cb67d /tests/lib/Encryption
parent2ef751b1ec28f7b5c7113af60ec8c9fa0ae1cf87 (diff)
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.php347
-rw-r--r--tests/lib/Encryption/EncryptionWrapperTest.php101
-rw-r--r--tests/lib/Encryption/Keys/StorageTest.php513
-rw-r--r--tests/lib/Encryption/ManagerTest.php250
-rw-r--r--tests/lib/Encryption/UpdateTest.php236
-rw-r--r--tests/lib/Encryption/UtilTest.php191
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'),
+ );
+ }
+
+}