You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

migration.php 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. <?php
  2. /**
  3. * @author Björn Schießle <schiessle@owncloud.com>
  4. * @author Joas Schilling <nickvergessen@owncloud.com>
  5. * @author Morris Jobke <hey@morrisjobke.de>
  6. * @author Thomas Müller <thomas.mueller@tmit.eu>
  7. * @author Vincent Petry <pvince81@owncloud.com>
  8. *
  9. * @copyright Copyright (c) 2015, ownCloud, Inc.
  10. * @license AGPL-3.0
  11. *
  12. * This code is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU Affero General Public License, version 3,
  14. * as published by the Free Software Foundation.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU Affero General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Affero General Public License, version 3,
  22. * along with this program. If not, see <http://www.gnu.org/licenses/>
  23. *
  24. */
  25. namespace OCA\Files_Encryption\Tests;
  26. class Migration extends TestCase {
  27. const TEST_ENCRYPTION_MIGRATION_USER1='test_encryption_user1';
  28. const TEST_ENCRYPTION_MIGRATION_USER2='test_encryption_user2';
  29. const TEST_ENCRYPTION_MIGRATION_USER3='test_encryption_user3';
  30. /** @var \OC\Files\View */
  31. private $view;
  32. private $public_share_key_id;
  33. private $recovery_key_id;
  34. public static function setUpBeforeClass() {
  35. parent::setUpBeforeClass();
  36. self::loginHelper(self::TEST_ENCRYPTION_MIGRATION_USER1, true);
  37. self::loginHelper(self::TEST_ENCRYPTION_MIGRATION_USER2, true);
  38. self::loginHelper(self::TEST_ENCRYPTION_MIGRATION_USER3, true);
  39. }
  40. public static function tearDownAfterClass() {
  41. \OC_User::deleteUser(self::TEST_ENCRYPTION_MIGRATION_USER1);
  42. \OC_User::deleteUser(self::TEST_ENCRYPTION_MIGRATION_USER2);
  43. \OC_User::deleteUser(self::TEST_ENCRYPTION_MIGRATION_USER3);
  44. parent::tearDownAfterClass();
  45. }
  46. protected function tearDown() {
  47. if (\OC_DB::tableExists('encryption_test')) {
  48. \OC_DB::dropTable('encryption_test');
  49. }
  50. $this->assertTableNotExist('encryption_test');
  51. parent::tearDown();
  52. }
  53. public function setUp() {
  54. $this->loginHelper(self::TEST_ENCRYPTION_MIGRATION_USER1);
  55. $this->view = new \OC\Files\View();
  56. $this->public_share_key_id = \OCA\Files_Encryption\Helper::getPublicShareKeyId();
  57. $this->recovery_key_id = \OCA\Files_Encryption\Helper::getRecoveryKeyId();
  58. if (\OC_DB::tableExists('encryption_test')) {
  59. \OC_DB::dropTable('encryption_test');
  60. }
  61. $this->assertTableNotExist('encryption_test');
  62. }
  63. public function checkLastIndexId() {
  64. $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` ('
  65. .' `item_type`, `item_source`, `item_target`, `share_type`,'
  66. .' `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,'
  67. .' `file_target`, `token`, `parent`, `expiration`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)');
  68. $query->bindValue(1, 'file');
  69. $query->bindValue(2, 949);
  70. $query->bindValue(3, '/949');
  71. $query->bindValue(4, 0);
  72. $query->bindValue(5, 'migrate-test-user');
  73. $query->bindValue(6, 'migrate-test-owner');
  74. $query->bindValue(7, 23);
  75. $query->bindValue(8, 1402493312);
  76. $query->bindValue(9, 0);
  77. $query->bindValue(10, '/migration.txt');
  78. $query->bindValue(11, null);
  79. $query->bindValue(12, null);
  80. $query->bindValue(13, null);
  81. $this->assertEquals(1, $query->execute());
  82. $this->assertNotEquals('0', \OC_DB::insertid('*PREFIX*share'));
  83. // cleanup
  84. $query = \OC_DB::prepare('DELETE FROM `*PREFIX*share` WHERE `file_target` = ?');
  85. $query->bindValue(1, '/migration.txt');
  86. $this->assertEquals(1, $query->execute());
  87. }
  88. public function testBrokenLastIndexId() {
  89. // create test table
  90. $this->checkLastIndexId();
  91. \OC_DB::createDbFromStructure(__DIR__ . '/encryption_table.xml');
  92. $this->checkLastIndexId();
  93. }
  94. /**
  95. * @param string $table
  96. */
  97. public function assertTableNotExist($table) {
  98. $type = \OC_Config::getValue( "dbtype", "sqlite" );
  99. if( $type == 'sqlite' || $type == 'sqlite3' ) {
  100. // sqlite removes the tables after closing the DB
  101. $this->assertTrue(true);
  102. } else {
  103. $this->assertFalse(\OC_DB::tableExists($table), 'Table ' . $table . ' exists.');
  104. }
  105. }
  106. protected function createDummyShareKeys($uid) {
  107. $this->view->mkdir($uid . '/files_encryption/share-keys/folder1/folder2/folder3');
  108. $this->view->mkdir($uid . '/files_encryption/share-keys/folder2/');
  109. $this->view->file_put_contents($uid . '/files_encryption/share-keys/folder1/folder2/folder3/file3.' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.shareKey' , 'data');
  110. $this->view->file_put_contents($uid . '/files_encryption/share-keys/folder1/folder2/folder3/file3.' . self::TEST_ENCRYPTION_MIGRATION_USER2 . '.shareKey' , 'data');
  111. $this->view->file_put_contents($uid . '/files_encryption/share-keys/folder1/folder2/folder3/file3.' . self::TEST_ENCRYPTION_MIGRATION_USER3 . '.shareKey' , 'data');
  112. $this->view->file_put_contents($uid . '/files_encryption/share-keys/folder1/folder2/file2.' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.shareKey' , 'data');
  113. $this->view->file_put_contents($uid . '/files_encryption/share-keys/folder1/folder2/file2.' . self::TEST_ENCRYPTION_MIGRATION_USER2 . '.shareKey' , 'data');
  114. $this->view->file_put_contents($uid . '/files_encryption/share-keys/folder1/folder2/file2.' . self::TEST_ENCRYPTION_MIGRATION_USER3 . '.shareKey' , 'data');
  115. $this->view->file_put_contents($uid . '/files_encryption/share-keys/folder1/file.1.' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.shareKey' , 'data');
  116. $this->view->file_put_contents($uid . '/files_encryption/share-keys/folder1/file.1.' . self::TEST_ENCRYPTION_MIGRATION_USER2 . '.shareKey' , 'data');
  117. $this->view->file_put_contents($uid . '/files_encryption/share-keys/folder1/file.1.' . self::TEST_ENCRYPTION_MIGRATION_USER3 . '.shareKey' , 'data');
  118. $this->view->file_put_contents($uid . '/files_encryption/share-keys/folder2/file.2.1.' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.shareKey' , 'data');
  119. $this->view->file_put_contents($uid . '/files_encryption/share-keys/folder2/file.2.1.' . self::TEST_ENCRYPTION_MIGRATION_USER2 . '.shareKey' , 'data');
  120. $this->view->file_put_contents($uid . '/files_encryption/share-keys/folder2/file.2.1.' . self::TEST_ENCRYPTION_MIGRATION_USER3 . '.shareKey' , 'data');
  121. if ($this->public_share_key_id) {
  122. $this->view->file_put_contents($uid . '/files_encryption/share-keys/folder2/file.2.1.' . $this->public_share_key_id . '.shareKey' , 'data');
  123. }
  124. if ($this->recovery_key_id) {
  125. $this->view->file_put_contents($uid . '/files_encryption/share-keys/folder2/file.2.1.' . $this->recovery_key_id . '.shareKey' , 'data');
  126. }
  127. }
  128. protected function createDummyFileKeys($uid) {
  129. $this->view->mkdir($uid . '/files_encryption/keyfiles/folder1/folder2/folder3');
  130. $this->view->mkdir($uid . '/files_encryption/keyfiles/folder2/');
  131. $this->view->file_put_contents($uid . '/files_encryption/keyfiles/folder1/folder2/folder3/file3.key' , 'data');
  132. $this->view->file_put_contents($uid . '/files_encryption/keyfiles/folder1/folder2/file2.key' , 'data');
  133. $this->view->file_put_contents($uid . '/files_encryption/keyfiles/folder1/file.1.key' , 'data');
  134. $this->view->file_put_contents($uid . '/files_encryption/keyfiles/folder2/file.2.1.key' , 'data');
  135. }
  136. protected function createDummyFilesInTrash($uid) {
  137. $this->view->mkdir($uid . '/files_trashbin/share-keys');
  138. $this->view->mkdir($uid . '/files_trashbin/share-keys/folder1.d7437648723');
  139. $this->view->file_put_contents($uid . '/files_trashbin/share-keys/file1.' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.shareKey.d5457864' , 'data');
  140. $this->view->file_put_contents($uid . '/files_trashbin/share-keys/file1.' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.shareKey.d5457864' , 'data');
  141. $this->view->file_put_contents($uid . '/files_trashbin/share-keys/folder1.d7437648723/file2.' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.shareKey' , 'data');
  142. $this->view->mkdir($uid . '/files_trashbin/keyfiles');
  143. $this->view->mkdir($uid . '/files_trashbin/keyfiles/folder1.d7437648723');
  144. $this->view->file_put_contents($uid . '/files_trashbin/keyfiles/file1.key.d5457864' , 'data');
  145. $this->view->file_put_contents($uid . '/files_trashbin/keyfiles/folder1.d7437648723/file2.key' , 'data');
  146. }
  147. protected function createDummySystemWideKeys() {
  148. $this->view->mkdir('owncloud_private_key');
  149. $this->view->file_put_contents('owncloud_private_key/systemwide_1.private.key', 'data');
  150. $this->view->file_put_contents('owncloud_private_key/systemwide_2.private.key', 'data');
  151. }
  152. public function testMigrateToNewFolderStructure() {
  153. // go back to the state before migration
  154. $this->view->rename('/files_encryption/public_keys', '/public-keys');
  155. $this->view->rename('/public-keys/' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.publicKey', '/public-keys/' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.public.key');
  156. $this->view->rename('/public-keys/' . self::TEST_ENCRYPTION_MIGRATION_USER2 . '.publicKey', '/public-keys/' . self::TEST_ENCRYPTION_MIGRATION_USER2 . '.public.key');
  157. $this->view->rename('/public-keys/' . self::TEST_ENCRYPTION_MIGRATION_USER3 . '.publicKey', '/public-keys/' . self::TEST_ENCRYPTION_MIGRATION_USER3 . '.public.key');
  158. $this->view->deleteAll(self::TEST_ENCRYPTION_MIGRATION_USER1 . '/files_encryption/keys');
  159. $this->view->deleteAll(self::TEST_ENCRYPTION_MIGRATION_USER2 . '/files_encryption/keys');
  160. $this->view->deleteAll(self::TEST_ENCRYPTION_MIGRATION_USER3 . '/files_encryption/keys');
  161. $this->view->rename(self::TEST_ENCRYPTION_MIGRATION_USER1 . '/files_encryption/' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.privateKey',
  162. self::TEST_ENCRYPTION_MIGRATION_USER1 . '/files_encryption/' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.private.key');
  163. $this->view->rename(self::TEST_ENCRYPTION_MIGRATION_USER2 . '/files_encryption/' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.privateKey',
  164. self::TEST_ENCRYPTION_MIGRATION_USER2 . '/files_encryption/' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.private.key');
  165. $this->view->rename(self::TEST_ENCRYPTION_MIGRATION_USER3 . '/files_encryption/' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.privateKey',
  166. self::TEST_ENCRYPTION_MIGRATION_USER3 . '/files_encryption/' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.private.key');
  167. $this->createDummyShareKeys(self::TEST_ENCRYPTION_MIGRATION_USER1);
  168. $this->createDummyShareKeys(self::TEST_ENCRYPTION_MIGRATION_USER2);
  169. $this->createDummyShareKeys(self::TEST_ENCRYPTION_MIGRATION_USER3);
  170. $this->createDummyFileKeys(self::TEST_ENCRYPTION_MIGRATION_USER1);
  171. $this->createDummyFileKeys(self::TEST_ENCRYPTION_MIGRATION_USER2);
  172. $this->createDummyFileKeys(self::TEST_ENCRYPTION_MIGRATION_USER3);
  173. $this->createDummyFilesInTrash(self::TEST_ENCRYPTION_MIGRATION_USER2);
  174. // no user for system wide mount points
  175. $this->createDummyFileKeys('');
  176. $this->createDummyShareKeys('');
  177. $this->createDummySystemWideKeys();
  178. $m = new \OCA\Files_Encryption\Migration();
  179. $m->reorganizeFolderStructure();
  180. // TODO Verify that all files at the right place
  181. $this->assertTrue($this->view->file_exists('/files_encryption/public_keys/' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.publicKey'));
  182. $this->assertTrue($this->view->file_exists('/files_encryption/public_keys/' . self::TEST_ENCRYPTION_MIGRATION_USER2 . '.publicKey'));
  183. $this->assertTrue($this->view->file_exists('/files_encryption/public_keys/' . self::TEST_ENCRYPTION_MIGRATION_USER3 . '.publicKey'));
  184. $this->verifyNewKeyPath(self::TEST_ENCRYPTION_MIGRATION_USER1);
  185. $this->verifyNewKeyPath(self::TEST_ENCRYPTION_MIGRATION_USER2);
  186. $this->verifyNewKeyPath(self::TEST_ENCRYPTION_MIGRATION_USER3);
  187. // system wide keys
  188. $this->verifyNewKeyPath('');
  189. // trash
  190. $this->verifyFilesInTrash(self::TEST_ENCRYPTION_MIGRATION_USER2);
  191. }
  192. protected function verifyFilesInTrash($uid) {
  193. // share keys
  194. $this->view->file_exists($uid . '/files_trashbin/keys/file1.d5457864/' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.shareKey.d5457864' , 'data');
  195. $this->view->file_exists($uid . '/files_trashbin/keys/file1.d5457864/' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.shareKey.d5457864' , 'data');
  196. $this->view->file_exists($uid . '/files_trashbin/keys/folder1.d7437648723/file2/' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.shareKey' , 'data');
  197. // file keys
  198. $this->view->file_exists($uid . '/files_trashbin/keys/file1.d5457864/fileKey.d5457864' , 'data');
  199. $this->view->file_exists($uid . '/files_trashbin/keyfiles/file1.d5457864/fileKey.d5457864' , 'data');
  200. $this->view->file_exists($uid . '/files_trashbin/keyfiles/folder1.d7437648723/file2/fileKey' , 'data');
  201. }
  202. protected function verifyNewKeyPath($uid) {
  203. // private key
  204. if ($uid !== '') {
  205. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/' . $uid . '.privateKey'));
  206. }
  207. // file keys
  208. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder1/folder2/folder3/file3/fileKey'));
  209. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder1/folder2/file2/fileKey'));
  210. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder1/file.1/fileKey'));
  211. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder2/file.2.1/fileKey'));
  212. // share keys
  213. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder1/folder2/folder3/file3/' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.shareKey'));
  214. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder1/folder2/folder3/file3/' . self::TEST_ENCRYPTION_MIGRATION_USER2 . '.shareKey'));
  215. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder1/folder2/folder3/file3/' . self::TEST_ENCRYPTION_MIGRATION_USER3 . '.shareKey'));
  216. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder1/folder2/file2/' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.shareKey'));
  217. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder1/folder2/file2/' . self::TEST_ENCRYPTION_MIGRATION_USER2 . '.shareKey'));
  218. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder1/folder2/file2/' . self::TEST_ENCRYPTION_MIGRATION_USER3 . '.shareKey'));
  219. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder1/file.1/' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.shareKey'));
  220. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder1/file.1/' . self::TEST_ENCRYPTION_MIGRATION_USER2 . '.shareKey'));
  221. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder1/file.1/' . self::TEST_ENCRYPTION_MIGRATION_USER3 . '.shareKey'));
  222. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder2/file.2.1/' . self::TEST_ENCRYPTION_MIGRATION_USER1 . '.shareKey'));
  223. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder2/file.2.1/' . self::TEST_ENCRYPTION_MIGRATION_USER2 . '.shareKey'));
  224. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder2/file.2.1/' . self::TEST_ENCRYPTION_MIGRATION_USER3 . '.shareKey'));
  225. if ($this->public_share_key_id) {
  226. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder2/file.2.1/' . $this->public_share_key_id . '.shareKey'));
  227. }
  228. if ($this->recovery_key_id) {
  229. $this->assertTrue($this->view->file_exists($uid . '/files_encryption/keys/folder2/file.2.1/' . $this->recovery_key_id . '.shareKey'));
  230. }
  231. }
  232. }