EndToEndRandomIT.java 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. /*
  2. *
  3. * Nextcloud Android client application
  4. *
  5. * @author Tobias Kaminsky
  6. * Copyright (C) 2020 Tobias Kaminsky
  7. * Copyright (C) 2020 Nextcloud GmbH
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License
  20. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  21. */
  22. package com.nextcloud.client;
  23. import android.accounts.AccountManager;
  24. import com.nextcloud.test.RandomStringGenerator;
  25. import com.owncloud.android.AbstractOnServerIT;
  26. import com.owncloud.android.datamodel.ArbitraryDataProvider;
  27. import com.owncloud.android.datamodel.OCFile;
  28. import com.owncloud.android.db.OCUpload;
  29. import com.owncloud.android.files.services.FileUploader;
  30. import com.owncloud.android.lib.common.accounts.AccountUtils;
  31. import com.owncloud.android.lib.common.operations.RemoteOperationResult;
  32. import com.owncloud.android.lib.common.utils.Log_OC;
  33. import com.owncloud.android.lib.ocs.responses.PrivateKey;
  34. import com.owncloud.android.lib.resources.e2ee.ToggleEncryptionRemoteOperation;
  35. import com.owncloud.android.lib.resources.files.ReadFileRemoteOperation;
  36. import com.owncloud.android.lib.resources.status.OCCapability;
  37. import com.owncloud.android.lib.resources.status.OwnCloudVersion;
  38. import com.owncloud.android.lib.resources.users.GetPrivateKeyOperation;
  39. import com.owncloud.android.lib.resources.users.GetPublicKeyOperation;
  40. import com.owncloud.android.lib.resources.users.SendCSROperation;
  41. import com.owncloud.android.lib.resources.users.StorePrivateKeyOperation;
  42. import com.owncloud.android.operations.DownloadFileOperation;
  43. import com.owncloud.android.operations.GetCapabilitiesOperation;
  44. import com.owncloud.android.operations.RemoveFileOperation;
  45. import com.owncloud.android.utils.CsrHelper;
  46. import com.owncloud.android.utils.EncryptionUtils;
  47. import com.owncloud.android.utils.FileStorageUtils;
  48. import org.junit.Before;
  49. import org.junit.BeforeClass;
  50. import org.junit.Rule;
  51. import org.junit.Test;
  52. import org.junit.runner.RunWith;
  53. import java.io.File;
  54. import java.io.IOException;
  55. import java.security.KeyPair;
  56. import java.util.ArrayList;
  57. import java.util.List;
  58. import java.util.Random;
  59. import androidx.test.ext.junit.runners.AndroidJUnit4;
  60. import static com.owncloud.android.lib.resources.status.OwnCloudVersion.nextcloud_19;
  61. import static junit.framework.TestCase.assertEquals;
  62. import static junit.framework.TestCase.assertFalse;
  63. import static junit.framework.TestCase.assertNotNull;
  64. import static junit.framework.TestCase.assertTrue;
  65. import static org.junit.Assume.assumeTrue;
  66. @RunWith(AndroidJUnit4.class)
  67. public class EndToEndRandomIT extends AbstractOnServerIT {
  68. public enum Action {
  69. CREATE_FOLDER,
  70. GO_INTO_FOLDER,
  71. GO_UP,
  72. UPLOAD_FILE,
  73. DOWNLOAD_FILE,
  74. DELETE_FILE,
  75. }
  76. private static ArbitraryDataProvider arbitraryDataProvider;
  77. private OCFile currentFolder;
  78. private int actionCount = 20;
  79. private String rootEncFolder = "/e/";
  80. @Rule
  81. public RetryTestRule retryTestRule = new RetryTestRule();
  82. @BeforeClass
  83. public static void initClass() throws Exception {
  84. arbitraryDataProvider = new ArbitraryDataProvider(targetContext.getContentResolver());
  85. createKeys();
  86. }
  87. @Before
  88. public void before() throws IOException {
  89. OCCapability capability = getStorageManager().getCapability(account.name);
  90. if (capability.getVersion().equals(new OwnCloudVersion("0.0.0"))) {
  91. // fetch new one
  92. assertTrue(new GetCapabilitiesOperation(getStorageManager())
  93. .execute(client)
  94. .isSuccess());
  95. }
  96. // tests only for NC19+
  97. assumeTrue(getStorageManager()
  98. .getCapability(account.name)
  99. .getVersion()
  100. .isNewerOrEqual(nextcloud_19)
  101. );
  102. // make sure that every file is available, even after tests that remove source file
  103. createDummyFiles();
  104. }
  105. @Test
  106. public void run() throws Exception {
  107. init();
  108. for (int i = 0; i < actionCount; i++) {
  109. Action nextAction = Action.values()[new Random().nextInt(Action.values().length)];
  110. switch (nextAction) {
  111. case CREATE_FOLDER:
  112. createFolder(i);
  113. break;
  114. case GO_INTO_FOLDER:
  115. goIntoFolder(i);
  116. break;
  117. case GO_UP:
  118. goUp(i);
  119. break;
  120. case UPLOAD_FILE:
  121. uploadFile(i);
  122. break;
  123. case DOWNLOAD_FILE:
  124. downloadFile(i);
  125. break;
  126. case DELETE_FILE:
  127. deleteFile(i);
  128. break;
  129. default:
  130. Log_OC.d(this, "[" + i + "/" + actionCount + "]" + " Unknown action: " + nextAction);
  131. break;
  132. }
  133. }
  134. }
  135. @Test
  136. public void uploadOneFile() throws Exception {
  137. init();
  138. uploadFile(0);
  139. }
  140. @Test
  141. public void createFolder() throws Exception {
  142. init();
  143. currentFolder = createFolder(0);
  144. assertNotNull(currentFolder);
  145. }
  146. @Test
  147. public void createSubFolders() throws Exception {
  148. init();
  149. currentFolder = createFolder(0);
  150. assertNotNull(currentFolder);
  151. currentFolder = createFolder(1);
  152. assertNotNull(currentFolder);
  153. currentFolder = createFolder(2);
  154. assertNotNull(currentFolder);
  155. }
  156. @Test
  157. public void createSubFoldersWithFiles() throws Exception {
  158. init();
  159. currentFolder = createFolder(0);
  160. assertNotNull(currentFolder);
  161. uploadFile(1);
  162. uploadFile(1);
  163. uploadFile(2);
  164. currentFolder = createFolder(1);
  165. assertNotNull(currentFolder);
  166. uploadFile(11);
  167. uploadFile(12);
  168. uploadFile(13);
  169. currentFolder = createFolder(2);
  170. assertNotNull(currentFolder);
  171. uploadFile(21);
  172. uploadFile(22);
  173. uploadFile(23);
  174. }
  175. @Test
  176. public void pseudoRandom() throws Exception {
  177. init();
  178. uploadFile(1);
  179. createFolder(2);
  180. goIntoFolder(3);
  181. goUp(4);
  182. createFolder(5);
  183. uploadFile(6);
  184. goUp(7);
  185. goIntoFolder(8);
  186. goIntoFolder(9);
  187. uploadFile(10);
  188. }
  189. @Test
  190. public void deleteFile() throws Exception {
  191. init();
  192. uploadFile(1);
  193. deleteFile(1);
  194. }
  195. @Test
  196. public void deleteFolder() throws Exception {
  197. init();
  198. // create folder, go into it
  199. OCFile createdFolder = createFolder(0);
  200. assertNotNull(createdFolder);
  201. currentFolder = createdFolder;
  202. uploadFile(1);
  203. goUp(1);
  204. // delete folder
  205. assertTrue(new RemoveFileOperation(createdFolder,
  206. false,
  207. user,
  208. false,
  209. targetContext,
  210. getStorageManager())
  211. .execute(client)
  212. .isSuccess());
  213. }
  214. @Test
  215. public void downloadFile() throws Exception {
  216. init();
  217. uploadFile(1);
  218. downloadFile(1);
  219. }
  220. private void init() throws Exception {
  221. // create folder
  222. createFolder(rootEncFolder);
  223. OCFile encFolder = createFolder(rootEncFolder + RandomStringGenerator.make(5) + "/");
  224. // encrypt it
  225. assertTrue(new ToggleEncryptionRemoteOperation(encFolder.getLocalId(),
  226. encFolder.getRemotePath(),
  227. true)
  228. .execute(client).isSuccess());
  229. encFolder.setEncrypted(true);
  230. getStorageManager().saveFolder(encFolder, new ArrayList<>(), new ArrayList<>());
  231. useExistingKeys();
  232. rootEncFolder = encFolder.getDecryptedRemotePath();
  233. currentFolder = encFolder;
  234. }
  235. private OCFile createFolder(int i) {
  236. String path = currentFolder.getDecryptedRemotePath() + RandomStringGenerator.make(5) + "/";
  237. Log_OC.d(this, "[" + i + "/" + actionCount + "] " + "Create folder: " + path);
  238. return createFolder(path);
  239. }
  240. private void goIntoFolder(int i) {
  241. ArrayList<OCFile> folders = new ArrayList<>();
  242. for (OCFile file : getStorageManager().getFolderContent(currentFolder, false)) {
  243. if (file.isFolder()) {
  244. folders.add(file);
  245. }
  246. }
  247. if (folders.isEmpty()) {
  248. Log_OC.d(this, "[" + i + "/" + actionCount + "] " + "Go into folder: No folders");
  249. return;
  250. }
  251. currentFolder = folders.get(new Random().nextInt(folders.size()));
  252. Log_OC.d(this,
  253. "[" + i + "/" + actionCount + "] " + "Go into folder: " + currentFolder.getDecryptedRemotePath());
  254. }
  255. private void goUp(int i) {
  256. if (currentFolder.getRemotePath().equals(rootEncFolder)) {
  257. Log_OC.d(this,
  258. "[" + i + "/" + actionCount + "] " + "Go up to folder: " + currentFolder.getDecryptedRemotePath());
  259. return;
  260. }
  261. currentFolder = getStorageManager().getFileById(currentFolder.getParentId());
  262. if (currentFolder == null) {
  263. throw new RuntimeException("Current folder is null");
  264. }
  265. Log_OC.d(this,
  266. "[" + i + "/" + actionCount + "] " + "Go up to folder: " + currentFolder.getDecryptedRemotePath());
  267. }
  268. private void uploadFile(int i) throws IOException {
  269. String fileName = RandomStringGenerator.make(5) + ".txt";
  270. File file;
  271. if (new Random().nextBoolean()) {
  272. file = createFile(fileName, new Random().nextInt(50000));
  273. } else {
  274. file = createFile(fileName, 500000 + new Random().nextInt(50000));
  275. }
  276. String remotePath = currentFolder.getRemotePath() + fileName;
  277. Log_OC.d(this,
  278. "[" + i + "/" + actionCount + "] " +
  279. "Upload file to: " + currentFolder.getDecryptedRemotePath() + fileName);
  280. OCUpload ocUpload = new OCUpload(file.getAbsolutePath(),
  281. remotePath,
  282. account.name);
  283. uploadOCUpload(ocUpload);
  284. shortSleep();
  285. OCFile parentFolder = getStorageManager()
  286. .getFileByEncryptedRemotePath(new File(ocUpload.getRemotePath()).getParent() + "/");
  287. String uploadedFileName = new File(ocUpload.getRemotePath()).getName();
  288. String decryptedPath = parentFolder.getDecryptedRemotePath() + uploadedFileName;
  289. OCFile uploadedFile = getStorageManager().getFileByDecryptedRemotePath(decryptedPath);
  290. verifyStoragePath(uploadedFile);
  291. // verify storage path
  292. refreshFolder(currentFolder.getRemotePath());
  293. uploadedFile = getStorageManager().getFileByDecryptedRemotePath(decryptedPath);
  294. verifyStoragePath(uploadedFile);
  295. // verify that encrypted file is on server
  296. assertTrue(new ReadFileRemoteOperation(currentFolder.getRemotePath() + uploadedFile.getEncryptedFileName())
  297. .execute(client)
  298. .isSuccess());
  299. // verify that unencrypted file is not on server
  300. assertFalse(new ReadFileRemoteOperation(currentFolder.getDecryptedRemotePath() + fileName)
  301. .execute(client)
  302. .isSuccess());
  303. }
  304. private void downloadFile(int i) {
  305. ArrayList<OCFile> files = new ArrayList<>();
  306. for (OCFile file : getStorageManager().getFolderContent(currentFolder, false)) {
  307. if (!file.isFolder()) {
  308. files.add(file);
  309. }
  310. }
  311. if (files.isEmpty()) {
  312. Log_OC.d(this, "[" + i + "/" + actionCount + "] No files in: " + currentFolder.getDecryptedRemotePath());
  313. return;
  314. }
  315. OCFile fileToDownload = files.get(new Random().nextInt(files.size()));
  316. assertNotNull(fileToDownload.getRemoteId());
  317. Log_OC.d(this,
  318. "[" + i + "/" + actionCount + "] " + "Download file: " +
  319. currentFolder.getDecryptedRemotePath() + fileToDownload.getDecryptedFileName());
  320. assertTrue(new DownloadFileOperation(user, fileToDownload, targetContext)
  321. .execute(client)
  322. .isSuccess());
  323. assertTrue(new File(fileToDownload.getStoragePath()).exists());
  324. verifyStoragePath(fileToDownload);
  325. }
  326. @Test
  327. public void testUploadWithCopy() throws Exception {
  328. init();
  329. OCUpload ocUpload = new OCUpload(FileStorageUtils.getTemporalPath(account.name) + "/nonEmpty.txt",
  330. currentFolder.getRemotePath() + "nonEmpty.txt",
  331. account.name);
  332. uploadOCUpload(ocUpload, FileUploader.LOCAL_BEHAVIOUR_COPY);
  333. File originalFile = new File(FileStorageUtils.getTemporalPath(account.name) + "/nonEmpty.txt");
  334. OCFile uploadedFile = fileDataStorageManager.getFileByDecryptedRemotePath(currentFolder.getRemotePath() +
  335. "nonEmpty.txt");
  336. assertTrue(originalFile.exists());
  337. assertTrue(new File(uploadedFile.getStoragePath()).exists());
  338. }
  339. @Test
  340. public void testUploadWithMove() throws Exception {
  341. init();
  342. OCUpload ocUpload = new OCUpload(FileStorageUtils.getTemporalPath(account.name) + "/nonEmpty.txt",
  343. currentFolder.getRemotePath() + "nonEmpty.txt",
  344. account.name);
  345. uploadOCUpload(ocUpload, FileUploader.LOCAL_BEHAVIOUR_MOVE);
  346. File originalFile = new File(FileStorageUtils.getTemporalPath(account.name) + "/nonEmpty.txt");
  347. OCFile uploadedFile = fileDataStorageManager.getFileByDecryptedRemotePath(currentFolder.getRemotePath() +
  348. "nonEmpty.txt");
  349. assertFalse(originalFile.exists());
  350. assertTrue(new File(uploadedFile.getStoragePath()).exists());
  351. }
  352. @Test
  353. public void testUploadWithForget() throws Exception {
  354. init();
  355. OCUpload ocUpload = new OCUpload(FileStorageUtils.getTemporalPath(account.name) + "/nonEmpty.txt",
  356. currentFolder.getRemotePath() + "nonEmpty.txt",
  357. account.name);
  358. uploadOCUpload(ocUpload, FileUploader.LOCAL_BEHAVIOUR_FORGET);
  359. File originalFile = new File(FileStorageUtils.getTemporalPath(account.name) + "/nonEmpty.txt");
  360. OCFile uploadedFile = fileDataStorageManager.getFileByDecryptedRemotePath(currentFolder.getRemotePath() +
  361. "nonEmpty.txt");
  362. assertTrue(originalFile.exists());
  363. assertFalse(new File(uploadedFile.getStoragePath()).exists());
  364. }
  365. @Test
  366. public void testUploadWithDelete() throws Exception {
  367. init();
  368. OCUpload ocUpload = new OCUpload(FileStorageUtils.getTemporalPath(account.name) + "/nonEmpty.txt",
  369. currentFolder.getRemotePath() + "nonEmpty.txt",
  370. account.name);
  371. uploadOCUpload(ocUpload, FileUploader.LOCAL_BEHAVIOUR_DELETE);
  372. File originalFile = new File(FileStorageUtils.getTemporalPath(account.name) + "/nonEmpty.txt");
  373. OCFile uploadedFile = fileDataStorageManager.getFileByDecryptedRemotePath(currentFolder.getRemotePath() +
  374. "nonEmpty.txt");
  375. assertFalse(originalFile.exists());
  376. assertFalse(new File(uploadedFile.getStoragePath()).exists());
  377. }
  378. private void deleteFile(int i) {
  379. ArrayList<OCFile> files = new ArrayList<>();
  380. for (OCFile file : getStorageManager().getFolderContent(currentFolder, false)) {
  381. if (!file.isFolder()) {
  382. files.add(file);
  383. }
  384. }
  385. if (files.isEmpty()) {
  386. Log_OC.d(this, "[" + i + "/" + actionCount + "] No files in: " + currentFolder.getDecryptedRemotePath());
  387. return;
  388. }
  389. OCFile fileToDelete = files.get(new Random().nextInt(files.size()));
  390. assertNotNull(fileToDelete.getRemoteId());
  391. Log_OC.d(this,
  392. "[" + i + "/" + actionCount + "] " +
  393. "Delete file: " + currentFolder.getDecryptedRemotePath() + fileToDelete.getDecryptedFileName());
  394. assertTrue(new RemoveFileOperation(fileToDelete,
  395. false,
  396. user,
  397. false,
  398. targetContext,
  399. getStorageManager())
  400. .execute(client)
  401. .isSuccess());
  402. }
  403. @Test
  404. public void reInit() throws Exception {
  405. // create folder
  406. OCFile encFolder = createFolder(rootEncFolder);
  407. // encrypt it
  408. assertTrue(new ToggleEncryptionRemoteOperation(encFolder.getLocalId(),
  409. encFolder.getRemotePath(),
  410. true)
  411. .execute(client).isSuccess());
  412. encFolder.setEncrypted(true);
  413. getStorageManager().saveFolder(encFolder, new ArrayList<>(), new ArrayList<>());
  414. // delete keys
  415. arbitraryDataProvider.deleteKeyForAccount(account.name, EncryptionUtils.PRIVATE_KEY);
  416. arbitraryDataProvider.deleteKeyForAccount(account.name, EncryptionUtils.PUBLIC_KEY);
  417. arbitraryDataProvider.deleteKeyForAccount(account.name, EncryptionUtils.MNEMONIC);
  418. useExistingKeys();
  419. }
  420. private void useExistingKeys() throws Exception {
  421. // download them from server
  422. GetPublicKeyOperation publicKeyOperation = new GetPublicKeyOperation();
  423. RemoteOperationResult publicKeyResult = publicKeyOperation.execute(account, targetContext);
  424. assertTrue("Result code:" + publicKeyResult.getHttpCode(), publicKeyResult.isSuccess());
  425. String publicKeyFromServer = (String) publicKeyResult.getData().get(0);
  426. arbitraryDataProvider.storeOrUpdateKeyValue(account.name,
  427. EncryptionUtils.PUBLIC_KEY,
  428. publicKeyFromServer);
  429. RemoteOperationResult<PrivateKey> privateKeyResult = new GetPrivateKeyOperation().execute(account,
  430. targetContext);
  431. assertTrue(privateKeyResult.isSuccess());
  432. PrivateKey privateKey = privateKeyResult.getResultData();
  433. String mnemonic = generateMnemonicString();
  434. String decryptedPrivateKey = EncryptionUtils.decryptPrivateKey(privateKey.getKey(), mnemonic);
  435. arbitraryDataProvider.storeOrUpdateKeyValue(account.name,
  436. EncryptionUtils.PRIVATE_KEY, decryptedPrivateKey);
  437. Log_OC.d(this, "Private key successfully decrypted and stored");
  438. arbitraryDataProvider.storeOrUpdateKeyValue(account.name, EncryptionUtils.MNEMONIC, mnemonic);
  439. }
  440. /*
  441. TODO do not c&p code
  442. */
  443. private static void createKeys() throws Exception {
  444. String publicKey;
  445. // Create public/private key pair
  446. KeyPair keyPair = EncryptionUtils.generateKeyPair();
  447. // create CSR
  448. AccountManager accountManager = AccountManager.get(targetContext);
  449. String userId = accountManager.getUserData(account, AccountUtils.Constants.KEY_USER_ID);
  450. String urlEncoded = CsrHelper.generateCsrPemEncodedString(keyPair, userId);
  451. SendCSROperation operation = new SendCSROperation(urlEncoded);
  452. RemoteOperationResult result = operation.execute(account, targetContext);
  453. if (result.isSuccess()) {
  454. publicKey = (String) result.getData().get(0);
  455. } else {
  456. throw new Exception("failed to send CSR", result.getException());
  457. }
  458. java.security.PrivateKey privateKey = keyPair.getPrivate();
  459. String privateKeyString = EncryptionUtils.encodeBytesToBase64String(privateKey.getEncoded());
  460. String privatePemKeyString = EncryptionUtils.privateKeyToPEM(privateKey);
  461. String encryptedPrivateKey = EncryptionUtils.encryptPrivateKey(privatePemKeyString,
  462. generateMnemonicString());
  463. // upload encryptedPrivateKey
  464. StorePrivateKeyOperation storePrivateKeyOperation = new StorePrivateKeyOperation(encryptedPrivateKey);
  465. RemoteOperationResult storePrivateKeyResult = storePrivateKeyOperation.execute(account, targetContext);
  466. if (storePrivateKeyResult.isSuccess()) {
  467. arbitraryDataProvider.storeOrUpdateKeyValue(account.name, EncryptionUtils.PRIVATE_KEY,
  468. privateKeyString);
  469. arbitraryDataProvider.storeOrUpdateKeyValue(account.name, EncryptionUtils.PUBLIC_KEY, publicKey);
  470. arbitraryDataProvider.storeOrUpdateKeyValue(account.name, EncryptionUtils.MNEMONIC,
  471. generateMnemonicString());
  472. } else {
  473. throw new RuntimeException("Error uploading private key!");
  474. }
  475. }
  476. private static String generateMnemonicString() {
  477. return "1 2 3 4 5 6";
  478. }
  479. public void after() {
  480. // remove all encrypted files
  481. OCFile root = fileDataStorageManager.getFileByDecryptedRemotePath("/");
  482. removeFolder(root);
  483. // List<OCFile> files = fileDataStorageManager.getFolderContent(root, false);
  484. //
  485. // for (OCFile child : files) {
  486. // removeFolder(child);
  487. // }
  488. assertEquals(0, fileDataStorageManager.getFolderContent(root, false).size());
  489. super.after();
  490. }
  491. private void removeFolder(OCFile folder) {
  492. Log_OC.d(this, "Start removing content of folder: " + folder.getDecryptedRemotePath());
  493. List<OCFile> children = fileDataStorageManager.getFolderContent(folder, false);
  494. // remove children
  495. for (OCFile child : children) {
  496. if (child.isFolder()) {
  497. removeFolder(child);
  498. // remove folder
  499. Log_OC.d(this, "Remove folder: " + child.getDecryptedRemotePath());
  500. if (!folder.isEncrypted() && child.isEncrypted()) {
  501. assertTrue(new ToggleEncryptionRemoteOperation(child.getLocalId(),
  502. child.getRemotePath(),
  503. false)
  504. .execute(client)
  505. .isSuccess());
  506. OCFile f = getStorageManager().getFileByEncryptedRemotePath(child.getRemotePath());
  507. f.setEncrypted(false);
  508. getStorageManager().saveFile(f);
  509. child.setEncrypted(false);
  510. }
  511. } else {
  512. Log_OC.d(this, "Remove file: " + child.getDecryptedRemotePath());
  513. }
  514. assertTrue(new RemoveFileOperation(child, false, user, false, targetContext, getStorageManager())
  515. .execute(client)
  516. .isSuccess()
  517. );
  518. }
  519. Log_OC.d(this, "Finished removing content of folder: " + folder.getDecryptedRemotePath());
  520. }
  521. private void verifyStoragePath(OCFile file) {
  522. assertEquals(FileStorageUtils.getSavePath(account.name) +
  523. currentFolder.getDecryptedRemotePath() +
  524. file.getDecryptedFileName(),
  525. file.getStoragePath());
  526. }
  527. }