Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. <?php
  2. /**
  3. * Copyright (c) 2012 Sam Tuke <samtuke@owncloud.com>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. use OCA\Encryption;
  9. /**
  10. * Class Test_Encryption_Util
  11. */
  12. class Test_Encryption_Util extends \OCA\Files_Encryption\Tests\TestCase {
  13. const TEST_ENCRYPTION_UTIL_USER1 = "test-util-user1";
  14. const TEST_ENCRYPTION_UTIL_USER2 = "test-util-user2";
  15. const TEST_ENCRYPTION_UTIL_GROUP1 = "test-util-group1";
  16. const TEST_ENCRYPTION_UTIL_GROUP2 = "test-util-group2";
  17. const TEST_ENCRYPTION_UTIL_LEGACY_USER = "test-legacy-user";
  18. public $userId;
  19. public $encryptionDir;
  20. public $publicKeyDir;
  21. public $pass;
  22. /**
  23. * @var OC\Files\View
  24. */
  25. public $view;
  26. public $keyfilesPath;
  27. public $publicKeyPath;
  28. public $privateKeyPath;
  29. /**
  30. * @var \OCA\Encryption\Util
  31. */
  32. public $util;
  33. public $dataShort;
  34. public $legacyEncryptedData;
  35. public $legacyEncryptedDataKey;
  36. public $legacyKey;
  37. public $stateFilesTrashbin;
  38. public static function setUpBeforeClass() {
  39. parent::setUpBeforeClass();
  40. // create test user
  41. self::loginHelper(self::TEST_ENCRYPTION_UTIL_USER1, true);
  42. self::loginHelper(self::TEST_ENCRYPTION_UTIL_USER2, true);
  43. self::loginHelper(self::TEST_ENCRYPTION_UTIL_LEGACY_USER, true);
  44. // create groups
  45. \OC_Group::createGroup(self::TEST_ENCRYPTION_UTIL_GROUP1);
  46. \OC_Group::createGroup(self::TEST_ENCRYPTION_UTIL_GROUP2);
  47. // add user 1 to group1
  48. \OC_Group::addToGroup(self::TEST_ENCRYPTION_UTIL_USER1, self::TEST_ENCRYPTION_UTIL_GROUP1);
  49. }
  50. protected function setUp() {
  51. parent::setUp();
  52. // login user
  53. self::loginHelper(self::TEST_ENCRYPTION_UTIL_USER1);
  54. \OC_User::setUserId(self::TEST_ENCRYPTION_UTIL_USER1);
  55. $this->userId = self::TEST_ENCRYPTION_UTIL_USER1;
  56. $this->pass = self::TEST_ENCRYPTION_UTIL_USER1;
  57. // set content for encrypting / decrypting in tests
  58. $this->dataUrl = __DIR__ . '/../lib/crypt.php';
  59. $this->dataShort = 'hats';
  60. $this->dataLong = file_get_contents(__DIR__ . '/../lib/crypt.php');
  61. $this->legacyData = __DIR__ . '/legacy-text.txt';
  62. $this->legacyEncryptedData = __DIR__ . '/legacy-encrypted-text.txt';
  63. $this->legacyEncryptedDataKey = __DIR__ . '/encryption.key';
  64. $this->legacyKey = "30943623843030686906\0\0\0\0";
  65. $keypair = Encryption\Crypt::createKeypair();
  66. $this->genPublicKey = $keypair['publicKey'];
  67. $this->genPrivateKey = $keypair['privateKey'];
  68. $this->publicKeyDir = \OCA\Encryption\Keymanager::getPublicKeyPath();
  69. $this->encryptionDir = '/' . $this->userId . '/' . 'files_encryption';
  70. $this->keysPath = $this->encryptionDir . '/' . 'keys';
  71. $this->publicKeyPath =
  72. $this->publicKeyDir . '/' . $this->userId . '.publicKey'; // e.g. data/public-keys/admin.publicKey
  73. $this->privateKeyPath =
  74. $this->encryptionDir . '/' . $this->userId . '.privateKey'; // e.g. data/admin/admin.privateKey
  75. $this->view = new \OC\Files\View('/');
  76. $this->util = new Encryption\Util($this->view, $this->userId);
  77. // remember files_trashbin state
  78. $this->stateFilesTrashbin = OC_App::isEnabled('files_trashbin');
  79. // we don't want to tests with app files_trashbin enabled
  80. \OC_App::disable('files_trashbin');
  81. }
  82. protected function tearDown() {
  83. // reset app files_trashbin
  84. if ($this->stateFilesTrashbin) {
  85. OC_App::enable('files_trashbin');
  86. }
  87. else {
  88. OC_App::disable('files_trashbin');
  89. }
  90. parent::tearDown();
  91. }
  92. public static function tearDownAfterClass() {
  93. // cleanup test user
  94. \OC_User::deleteUser(self::TEST_ENCRYPTION_UTIL_USER1);
  95. \OC_User::deleteUser(self::TEST_ENCRYPTION_UTIL_USER2);
  96. \OC_User::deleteUser(self::TEST_ENCRYPTION_UTIL_LEGACY_USER);
  97. //cleanup groups
  98. \OC_Group::deleteGroup(self::TEST_ENCRYPTION_UTIL_GROUP1);
  99. \OC_Group::deleteGroup(self::TEST_ENCRYPTION_UTIL_GROUP2);
  100. parent::tearDownAfterClass();
  101. }
  102. /**
  103. * @medium
  104. * test that paths set during User construction are correct
  105. */
  106. function testKeyPaths() {
  107. $util = new Encryption\Util($this->view, $this->userId);
  108. $this->assertEquals($this->publicKeyDir, $util->getPath('publicKeyDir'));
  109. $this->assertEquals($this->encryptionDir, $util->getPath('encryptionDir'));
  110. $this->assertEquals($this->keysPath, $util->getPath('keysPath'));
  111. $this->assertEquals($this->publicKeyPath, $util->getPath('publicKeyPath'));
  112. $this->assertEquals($this->privateKeyPath, $util->getPath('privateKeyPath'));
  113. }
  114. /**
  115. * @medium
  116. * test detection of encrypted files
  117. */
  118. function testIsEncryptedPath() {
  119. $util = new Encryption\Util($this->view, $this->userId);
  120. self::loginHelper($this->userId);
  121. $unencryptedFile = '/tmpUnencrypted-' . $this->getUniqueID() . '.txt';
  122. $encryptedFile = '/tmpEncrypted-' . $this->getUniqueID() . '.txt';
  123. // Disable encryption proxy to write a unencrypted file
  124. $proxyStatus = \OC_FileProxy::$enabled;
  125. \OC_FileProxy::$enabled = false;
  126. $this->view->file_put_contents($this->userId . '/files/' . $unencryptedFile, $this->dataShort);
  127. // Re-enable proxy - our work is done
  128. \OC_FileProxy::$enabled = $proxyStatus;
  129. // write a encrypted file
  130. $this->view->file_put_contents($this->userId . '/files/' . $encryptedFile, $this->dataShort);
  131. // test if both files are detected correctly
  132. $this->assertFalse($util->isEncryptedPath($this->userId . '/files/' . $unencryptedFile));
  133. $this->assertTrue($util->isEncryptedPath($this->userId . '/files/' . $encryptedFile));
  134. // cleanup
  135. $this->view->unlink($this->userId . '/files/' . $unencryptedFile);
  136. $this->view->unlink($this->userId . '/files/' . $encryptedFile);
  137. }
  138. /**
  139. * @medium
  140. * test setup of encryption directories
  141. */
  142. function testSetupServerSide() {
  143. $this->assertEquals(true, $this->util->setupServerSide($this->pass));
  144. }
  145. /**
  146. * @medium
  147. * test checking whether account is ready for encryption,
  148. */
  149. function testUserIsReady() {
  150. $this->assertEquals(true, $this->util->ready());
  151. }
  152. /**
  153. * test checking whether account is not ready for encryption,
  154. */
  155. // function testUserIsNotReady() {
  156. // $this->view->unlink($this->publicKeyDir);
  157. //
  158. // $params['uid'] = $this->userId;
  159. // $params['password'] = $this->pass;
  160. // $this->assertFalse(OCA\Encryption\Hooks::login($params));
  161. //
  162. // $this->view->unlink($this->privateKeyPath);
  163. // }
  164. /**
  165. * @medium
  166. */
  167. function testRecoveryEnabledForUser() {
  168. $util = new Encryption\Util($this->view, $this->userId);
  169. // Record the value so we can return it to it's original state later
  170. $enabled = $util->recoveryEnabledForUser();
  171. $this->assertTrue($util->setRecoveryForUser(!$enabled));
  172. $this->assertEquals(!$enabled, $util->recoveryEnabledForUser());
  173. $this->assertTrue($util->setRecoveryForUser($enabled));
  174. $this->assertEquals($enabled, $util->recoveryEnabledForUser());
  175. }
  176. /**
  177. * @medium
  178. */
  179. function testGetUidAndFilename() {
  180. \OC_User::setUserId(self::TEST_ENCRYPTION_UTIL_USER1);
  181. $filename = '/tmp-' . $this->getUniqueID() . '.test';
  182. // Disable encryption proxy to prevent recursive calls
  183. $proxyStatus = \OC_FileProxy::$enabled;
  184. \OC_FileProxy::$enabled = false;
  185. $this->view->file_put_contents($this->userId . '/files/' . $filename, $this->dataShort);
  186. // Re-enable proxy - our work is done
  187. \OC_FileProxy::$enabled = $proxyStatus;
  188. $util = new Encryption\Util($this->view, $this->userId);
  189. list($fileOwnerUid, $file) = $util->getUidAndFilename($filename);
  190. $this->assertEquals(self::TEST_ENCRYPTION_UTIL_USER1, $fileOwnerUid);
  191. $this->assertEquals($file, $filename);
  192. $this->view->unlink($this->userId . '/files/' . $filename);
  193. }
  194. /**
  195. * Test that data that is read by the crypto stream wrapper
  196. */
  197. function testGetFileSize() {
  198. self::loginHelper(self::TEST_ENCRYPTION_UTIL_USER1);
  199. $filename = 'tmp-' . $this->getUniqueID();
  200. $externalFilename = '/' . $this->userId . '/files/' . $filename;
  201. // Test for 0 byte files
  202. $problematicFileSizeData = "";
  203. $cryptedFile = $this->view->file_put_contents($externalFilename, $problematicFileSizeData);
  204. $this->assertTrue(is_int($cryptedFile));
  205. $this->assertEquals($this->util->getFileSize($externalFilename), 0);
  206. $decrypt = $this->view->file_get_contents($externalFilename);
  207. $this->assertEquals($problematicFileSizeData, $decrypt);
  208. $this->view->unlink($this->userId . '/files/' . $filename);
  209. // Test a file with 18377 bytes as in https://github.com/owncloud/mirall/issues/1009
  210. $problematicFileSizeData = str_pad("", 18377, "abc");
  211. $cryptedFile = $this->view->file_put_contents($externalFilename, $problematicFileSizeData);
  212. $this->assertTrue(is_int($cryptedFile));
  213. $this->assertEquals($this->util->getFileSize($externalFilename), 18377);
  214. $decrypt = $this->view->file_get_contents($externalFilename);
  215. $this->assertEquals($problematicFileSizeData, $decrypt);
  216. $this->view->unlink($this->userId . '/files/' . $filename);
  217. }
  218. function testEncryptAll() {
  219. $filename = "/encryptAll" . $this->getUniqueID() . ".txt";
  220. $util = new Encryption\Util($this->view, $this->userId);
  221. // disable encryption to upload a unencrypted file
  222. \OC_App::disable('files_encryption');
  223. $this->view->file_put_contents($this->userId . '/files/' . $filename, $this->dataShort);
  224. $fileInfoUnencrypted = $this->view->getFileInfo($this->userId . '/files/' . $filename);
  225. $this->assertTrue($fileInfoUnencrypted instanceof \OC\Files\FileInfo);
  226. // enable file encryption again
  227. \OC_App::enable('files_encryption');
  228. // encrypt all unencrypted files
  229. $util->encryptAll('/' . $this->userId . '/' . 'files');
  230. $fileInfoEncrypted = $this->view->getFileInfo($this->userId . '/files/' . $filename);
  231. $this->assertTrue($fileInfoEncrypted instanceof \OC\Files\FileInfo);
  232. // check if mtime and etags unchanged
  233. $this->assertEquals($fileInfoEncrypted['mtime'], $fileInfoUnencrypted['mtime']);
  234. $this->assertSame($fileInfoEncrypted['etag'], $fileInfoUnencrypted['etag']);
  235. $this->view->unlink($this->userId . '/files/' . $filename);
  236. }
  237. function testDecryptAll() {
  238. $filename = "/decryptAll" . $this->getUniqueID() . ".txt";
  239. $datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT . '/data/');
  240. $userdir = $datadir . '/' . $this->userId . '/files/';
  241. $this->view->file_put_contents($this->userId . '/files/' . $filename, $this->dataShort);
  242. $fileInfoEncrypted = $this->view->getFileInfo($this->userId . '/files/' . $filename);
  243. $this->assertTrue($fileInfoEncrypted instanceof \OC\Files\FileInfo);
  244. $this->assertEquals($fileInfoEncrypted['encrypted'], 1);
  245. $encContent = file_get_contents($userdir . $filename);
  246. \OC_App::disable('files_encryption');
  247. $user = \OCP\User::getUser();
  248. $this->logoutHelper();
  249. $this->loginHelper($user, false, false, false);
  250. $content = file_get_contents($userdir . $filename);
  251. //content should be encrypted
  252. $this->assertSame($encContent, $content);
  253. // now we load the encryption app again
  254. OC_App::loadApp('files_encryption');
  255. // init encryption app
  256. $params = array('uid' => \OCP\User::getUser(),
  257. 'password' => \OCP\User::getUser());
  258. $view = new OC\Files\View('/');
  259. $util = new \OCA\Encryption\Util($view, \OCP\User::getUser());
  260. $result = $util->initEncryption($params);
  261. $this->assertTrue($result instanceof \OCA\Encryption\Session);
  262. $successful = $util->decryptAll();
  263. $this->assertTrue($successful);
  264. $this->logoutHelper();
  265. $this->loginHelper($user, false, false, false);
  266. // file should be unencrypted and fileInfo should contain the correct values
  267. $content = file_get_contents($userdir . $filename);
  268. // now we should get the plain data
  269. $this->assertSame($this->dataShort, $content);
  270. $fileInfoUnencrypted = $this->view->getFileInfo($this->userId . '/files/' . $filename);
  271. $this->assertTrue($fileInfoUnencrypted instanceof \OC\Files\FileInfo);
  272. // check if mtime and etags unchanged
  273. $this->assertEquals($fileInfoEncrypted['mtime'], $fileInfoUnencrypted['mtime']);
  274. $this->assertSame($fileInfoEncrypted['etag'], $fileInfoUnencrypted['etag']);
  275. // file should no longer be encrypted
  276. $this->assertEquals(0, $fileInfoUnencrypted['encrypted']);
  277. $backupPath = $this->getBackupPath('decryptAll');
  278. // check if the keys where moved to the backup location
  279. $this->assertTrue($this->view->is_dir($backupPath . '/keys'));
  280. $this->assertTrue($this->view->file_exists($backupPath . '/keys/' . $filename . '/fileKey'));
  281. $this->assertTrue($this->view->file_exists($backupPath . '/keys/' . $filename . '/' . $user . '.shareKey'));
  282. $this->assertTrue($this->view->file_exists($backupPath . '/' . $user . '.privateKey'));
  283. $this->assertTrue($this->view->file_exists($backupPath . '/' . $user . '.publicKey'));
  284. // cleanup
  285. $this->view->unlink($this->userId . '/files/' . $filename);
  286. $this->view->deleteAll($backupPath);
  287. OC_App::enable('files_encryption');
  288. }
  289. /**
  290. * test if all keys get moved to the backup folder correctly
  291. */
  292. function testBackupAllKeys() {
  293. self::loginHelper(self::TEST_ENCRYPTION_UTIL_USER1);
  294. // create some dummy key files
  295. $encPath = '/' . self::TEST_ENCRYPTION_UTIL_USER1 . '/files_encryption';
  296. $this->view->mkdir($encPath . '/keys/foo');
  297. $this->view->file_put_contents($encPath . '/keys/foo/fileKey', 'key');
  298. $this->view->file_put_contents($encPath . '/keys/foo/user1.shareKey', 'share key');
  299. $util = new \OCA\Encryption\Util($this->view, self::TEST_ENCRYPTION_UTIL_USER1);
  300. $util->backupAllKeys('testBackupAllKeys');
  301. $backupPath = $this->getBackupPath('testBackupAllKeys');
  302. // check backupDir Content
  303. $this->assertTrue($this->view->is_dir($backupPath . '/keys'));
  304. $this->assertTrue($this->view->is_dir($backupPath . '/keys/foo'));
  305. $this->assertTrue($this->view->file_exists($backupPath . '/keys/foo/fileKey'));
  306. $this->assertTrue($this->view->file_exists($backupPath . '/keys/foo/user1.shareKey'));
  307. $this->assertTrue($this->view->file_exists($backupPath . '/' . self::TEST_ENCRYPTION_UTIL_USER1 . '.privateKey'));
  308. $this->assertTrue($this->view->file_exists($backupPath . '/' . self::TEST_ENCRYPTION_UTIL_USER1 . '.publicKey'));
  309. //cleanup
  310. $this->view->deleteAll($backupPath);
  311. $this->view->unlink($encPath . '/keys/foo/fileKey');
  312. $this->view->unlink($encPath . '/keys/foo/user1.shareKey');
  313. }
  314. function testDescryptAllWithBrokenFiles() {
  315. $file1 = "/decryptAll1" . $this->getUniqueID() . ".txt";
  316. $file2 = "/decryptAll2" . $this->getUniqueID() . ".txt";
  317. $util = new Encryption\Util($this->view, $this->userId);
  318. $this->view->file_put_contents($this->userId . '/files/' . $file1, $this->dataShort);
  319. $this->view->file_put_contents($this->userId . '/files/' . $file2, $this->dataShort);
  320. $fileInfoEncrypted1 = $this->view->getFileInfo($this->userId . '/files/' . $file1);
  321. $fileInfoEncrypted2 = $this->view->getFileInfo($this->userId . '/files/' . $file2);
  322. $this->assertTrue($fileInfoEncrypted1 instanceof \OC\Files\FileInfo);
  323. $this->assertTrue($fileInfoEncrypted2 instanceof \OC\Files\FileInfo);
  324. $this->assertEquals($fileInfoEncrypted1['encrypted'], 1);
  325. $this->assertEquals($fileInfoEncrypted2['encrypted'], 1);
  326. // rename keyfile for file1 so that the decryption for file1 fails
  327. // Expected behaviour: decryptAll() returns false, file2 gets decrypted anyway
  328. $this->view->rename($this->userId . '/files_encryption/keys/' . $file1 . '/fileKey',
  329. $this->userId . '/files_encryption/keys/' . $file1 . '/fileKey.moved');
  330. // decrypt all encrypted files
  331. $result = $util->decryptAll();
  332. $this->assertFalse($result);
  333. $fileInfoUnencrypted1 = $this->view->getFileInfo($this->userId . '/files/' . $file1);
  334. $fileInfoUnencrypted2 = $this->view->getFileInfo($this->userId . '/files/' . $file2);
  335. $this->assertTrue($fileInfoUnencrypted1 instanceof \OC\Files\FileInfo);
  336. $this->assertTrue($fileInfoUnencrypted2 instanceof \OC\Files\FileInfo);
  337. // file1 should be still encrypted; file2 should be decrypted
  338. $this->assertEquals(1, $fileInfoUnencrypted1['encrypted']);
  339. $this->assertEquals(0, $fileInfoUnencrypted2['encrypted']);
  340. // keyfiles and share keys should still exist
  341. $this->assertTrue($this->view->is_dir($this->userId . '/files_encryption/keys/'));
  342. $this->assertTrue($this->view->file_exists($this->userId . '/files_encryption/keys/' . $file1 . '/fileKey.moved'));
  343. $this->assertTrue($this->view->file_exists($this->userId . '/files_encryption/keys/' . $file1 . '/' . $this->userId . '.shareKey'));
  344. // rename the keyfile for file1 back
  345. $this->view->rename($this->userId . '/files_encryption/keys/' . $file1 . '/fileKey.moved',
  346. $this->userId . '/files_encryption/keys/' . $file1 . '/fileKey');
  347. // try again to decrypt all encrypted files
  348. $result = $util->decryptAll();
  349. $this->assertTrue($result);
  350. $fileInfoUnencrypted1 = $this->view->getFileInfo($this->userId . '/files/' . $file1);
  351. $fileInfoUnencrypted2 = $this->view->getFileInfo($this->userId . '/files/' . $file2);
  352. $this->assertTrue($fileInfoUnencrypted1 instanceof \OC\Files\FileInfo);
  353. $this->assertTrue($fileInfoUnencrypted2 instanceof \OC\Files\FileInfo);
  354. // now both files should be decrypted
  355. $this->assertEquals(0, $fileInfoUnencrypted1['encrypted']);
  356. $this->assertEquals(0, $fileInfoUnencrypted2['encrypted']);
  357. // keyfiles and share keys should be deleted
  358. $this->assertFalse($this->view->is_dir($this->userId . '/files_encryption/keys/'));
  359. //cleanup
  360. $backupPath = $this->getBackupPath('decryptAll');
  361. $this->view->unlink($this->userId . '/files/' . $file1);
  362. $this->view->unlink($this->userId . '/files/' . $file2);
  363. $this->view->deleteAll($backupPath);
  364. }
  365. function getBackupPath($extension) {
  366. $encPath = '/' . self::TEST_ENCRYPTION_UTIL_USER1 . '/files_encryption';
  367. $encFolderContent = $this->view->getDirectoryContent($encPath);
  368. $backupPath = '';
  369. foreach ($encFolderContent as $c) {
  370. $name = $c['name'];
  371. if (substr($name, 0, strlen('backup.' . $extension)) === 'backup.' . $extension) {
  372. $backupPath = $encPath . '/'. $c['name'];
  373. break;
  374. }
  375. }
  376. return $backupPath;
  377. }
  378. /**
  379. * @dataProvider dataProviderFortestIsMountPointApplicableToUser
  380. */
  381. function testIsMountPointApplicableToUser($mount, $expectedResult) {
  382. self::loginHelper(self::TEST_ENCRYPTION_UTIL_USER1);
  383. $dummyClass = new DummyUtilClass($this->view, self::TEST_ENCRYPTION_UTIL_USER1);
  384. $result = $dummyClass->testIsMountPointApplicableToUser($mount);
  385. $this->assertSame($expectedResult, $result);
  386. }
  387. function dataProviderFortestIsMountPointApplicableToUser() {
  388. return array(
  389. array(array('applicable' => array('groups' => array(), 'users' => array(self::TEST_ENCRYPTION_UTIL_USER1))), true),
  390. array(array('applicable' => array('groups' => array(), 'users' => array(self::TEST_ENCRYPTION_UTIL_USER2))), false),
  391. array(array('applicable' => array('groups' => array(self::TEST_ENCRYPTION_UTIL_GROUP1), 'users' => array())), true),
  392. array(array('applicable' => array('groups' => array(self::TEST_ENCRYPTION_UTIL_GROUP1), 'users' => array(self::TEST_ENCRYPTION_UTIL_USER2))), true),
  393. array(array('applicable' => array('groups' => array(self::TEST_ENCRYPTION_UTIL_GROUP2), 'users' => array(self::TEST_ENCRYPTION_UTIL_USER2))), false),
  394. array(array('applicable' => array('groups' => array(self::TEST_ENCRYPTION_UTIL_GROUP2), 'users' => array(self::TEST_ENCRYPTION_UTIL_USER2, 'all'))), true),
  395. array(array('applicable' => array('groups' => array(self::TEST_ENCRYPTION_UTIL_GROUP2), 'users' => array('all'))), true),
  396. );
  397. }
  398. /**
  399. * Tests that filterShareReadyUsers() returns the correct list of
  400. * users that are ready or not ready for encryption
  401. */
  402. public function testFilterShareReadyUsers() {
  403. $appConfig = \OC::$server->getAppConfig();
  404. $publicShareKeyId = $appConfig->getValue('files_encryption', 'publicShareKeyId');
  405. $recoveryKeyId = $appConfig->getValue('files_encryption', 'recoveryKeyId');
  406. $usersToTest = array(
  407. 'readyUser',
  408. 'notReadyUser',
  409. 'nonExistingUser',
  410. $publicShareKeyId,
  411. $recoveryKeyId,
  412. );
  413. \Test_Encryption_Util::loginHelper('readyUser', true);
  414. \Test_Encryption_Util::loginHelper('notReadyUser', true);
  415. // delete encryption dir to make it not ready
  416. $this->view->unlink('notReadyUser/files_encryption/');
  417. // login as user1
  418. \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1);
  419. $result = $this->util->filterShareReadyUsers($usersToTest);
  420. $this->assertEquals(
  421. array('readyUser', $publicShareKeyId, $recoveryKeyId),
  422. $result['ready']
  423. );
  424. $this->assertEquals(
  425. array('notReadyUser', 'nonExistingUser'),
  426. $result['unready']
  427. );
  428. \OC_User::deleteUser('readyUser');
  429. }
  430. /**
  431. * @param string $user
  432. * @param bool $create
  433. * @param bool $password
  434. */
  435. public static function loginHelper($user, $create = false, $password = false, $loadEncryption = true) {
  436. if ($create) {
  437. try {
  438. \OC_User::createUser($user, $user);
  439. } catch(\Exception $e) { // catch username is already being used from previous aborted runs
  440. }
  441. }
  442. if ($password === false) {
  443. $password = $user;
  444. }
  445. \OC_Util::tearDownFS();
  446. \OC_User::setUserId('');
  447. \OC\Files\Filesystem::tearDown();
  448. \OC_User::setUserId($user);
  449. \OC_Util::setupFS($user);
  450. if ($loadEncryption) {
  451. $params['uid'] = $user;
  452. $params['password'] = $password;
  453. OCA\Encryption\Hooks::login($params);
  454. }
  455. }
  456. public static function logoutHelper() {
  457. \OC_Util::tearDownFS();
  458. \OC_User::setUserId(false);
  459. \OC\Files\Filesystem::tearDown();
  460. }
  461. /**
  462. * helper function to set migration status to the right value
  463. * to be able to test the migration path
  464. *
  465. * @param integer $status needed migration status for test
  466. * @param string $user for which user the status should be set
  467. * @return boolean
  468. */
  469. private function setMigrationStatus($status, $user) {
  470. \OC::$server->getConfig()->setUserValue($user, 'files_encryption', 'migration_status', (string)$status);
  471. // the update will definitely be executed -> return value is always true
  472. return true;
  473. }
  474. }
  475. /**
  476. * dummy class extends \OCA\Encryption\Util to access protected methods for testing
  477. */
  478. class DummyUtilClass extends \OCA\Encryption\Util {
  479. public function testIsMountPointApplicableToUser($mount) {
  480. return $this->isMountPointApplicableToUser($mount);
  481. }
  482. }