Przeglądaj źródła

Add delete v1 method

Signed-off-by: alperozturk <alper_ozturk@proton.me>
alperozturk 1 rok temu
rodzic
commit
a153c5ce52

+ 121 - 39
app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.java

@@ -11,20 +11,36 @@ package com.owncloud.android.operations;
 import android.content.Context;
 
 import com.nextcloud.client.account.User;
+import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedFolderMetadataFileV1;
+import com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedMetadata;
 import com.owncloud.android.datamodel.e2e.v2.decrypted.DecryptedFolderMetadataFile;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.operations.RemoteOperation;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.lib.resources.status.E2EVersion;
 import com.owncloud.android.utils.EncryptionUtils;
 import com.owncloud.android.utils.EncryptionUtilsV2;
+import com.owncloud.android.utils.theme.CapabilityUtils;
 
 import org.apache.commons.httpclient.HttpStatus;
 import org.apache.commons.httpclient.NameValuePair;
 import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
 
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.HashMap;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+
 import kotlin.Pair;
 
 /**
@@ -70,42 +86,20 @@ public class RemoveRemoteEncryptedFileOperation extends RemoteOperation<Void> {
         DeleteMethod delete = null;
         String token = null;
 
+        E2EVersion e2eVersion = CapabilityUtils.getCapability(context).getEndToEndEncryptionApiVersion();
+        boolean isE2EVersionAtLeast2 = e2eVersion.compareTo(E2EVersion.V2_0) >= 0;
+
         try {
-            // Lock folder
             token = EncryptionUtils.lockFolder(parentFolder, client);
 
-            EncryptionUtilsV2 encryptionUtilsV2 = new EncryptionUtilsV2();
-            Pair<Boolean, DecryptedFolderMetadataFile> pair = encryptionUtilsV2.retrieveMetadata(parentFolder, client, user, context);
-            boolean metadataExists = pair.getFirst();
-            DecryptedFolderMetadataFile metadata = pair.getSecond();
-
-            // delete file remote
-            delete = new DeleteMethod(client.getFilesDavUri(remotePath));
-            delete.setQueryString(new NameValuePair[]{new NameValuePair(E2E_TOKEN, token)});
-            int status = client.executeMethod(delete, REMOVE_READ_TIMEOUT, REMOVE_CONNECTION_TIMEOUT);
-
-            delete.getResponseBodyAsString();   // exhaust the response, although not interesting
-            result = new RemoteOperationResult<>(delete.succeeded() || status == HttpStatus.SC_NOT_FOUND, delete);
-            Log_OC.i(TAG, "Remove " + remotePath + ": " + result.getLogMessage());
-
-            if (isFolder) {
-                encryptionUtilsV2.removeFolderFromMetadata(fileName, metadata);
+            if (isE2EVersionAtLeast2) {
+                Pair<RemoteOperationResult<Void>, DeleteMethod> deleteResult = deleteForV2(client, token);
+                result = deleteResult.getFirst();
+                delete = deleteResult.getSecond();
+                return result;
             } else {
-                encryptionUtilsV2.removeFileFromMetadata(fileName, metadata);
+                return deleteForV1(client, token);
             }
-
-            // upload metadata
-            encryptionUtilsV2.serializeAndUploadMetadata(parentFolder,
-                                                         metadata,
-                                                         token,
-                                                         client,
-                                                         metadataExists,
-                                                         context,
-                                                         user,
-                                                         new FileDataStorageManager(user, context.getContentResolver()));
-
-            // return success
-            return result;
         } catch (Exception e) {
             result = new RemoteOperationResult<>(e);
             Log_OC.e(TAG, "Remove " + remotePath + ": " + result.getLogMessage(), e);
@@ -115,18 +109,106 @@ public class RemoveRemoteEncryptedFileOperation extends RemoteOperation<Void> {
                 delete.releaseConnection();
             }
 
-            // unlock file
             if (token != null) {
-                RemoteOperationResult<Void> unlockFileOperationResult = EncryptionUtils.unlockFolder(parentFolder,
-                                                                                                     client,
-                                                                                                     token);
-
-                if (!unlockFileOperationResult.isSuccess()) {
-                    Log_OC.e(TAG, "Failed to unlock " + parentFolder.getLocalId());
-                }
+                unlockFile(client, token,isE2EVersionAtLeast2);
             }
         }
 
         return result;
     }
+
+    private void unlockFile(OwnCloudClient client, String token, boolean isE2EVersionAtLeast2) {
+        RemoteOperationResult<Void> unlockFileOperationResult;
+
+        if (isE2EVersionAtLeast2) {
+            unlockFileOperationResult = EncryptionUtils.unlockFolder(parentFolder, client, token);
+        } else {
+            unlockFileOperationResult = EncryptionUtils.unlockFolderV1(parentFolder, client, token);
+        }
+
+        if (!unlockFileOperationResult.isSuccess()) {
+            Log_OC.e(TAG, "Failed to unlock " + parentFolder.getLocalId());
+        }
+    }
+
+    private Pair<RemoteOperationResult<Void>, DeleteMethod> deleteRemoteFile(OwnCloudClient client, String token) throws IOException {
+        DeleteMethod delete = new DeleteMethod(client.getFilesDavUri(remotePath));
+        delete.setQueryString(new NameValuePair[]{new NameValuePair(E2E_TOKEN, token)});
+        int status = client.executeMethod(delete, REMOVE_READ_TIMEOUT, REMOVE_CONNECTION_TIMEOUT);
+
+        delete.getResponseBodyAsString();   // exhaust the response, although not interesting
+        RemoteOperationResult<Void> result = new RemoteOperationResult<>(delete.succeeded() || status == HttpStatus.SC_NOT_FOUND, delete);
+        Log_OC.i(TAG, "Remove " + remotePath + ": " + result.getLogMessage());
+
+        return new Pair<>(result, delete);
+    }
+
+    private DecryptedFolderMetadataFileV1 getMetadataV1(ArbitraryDataProvider arbitraryDataProvider) throws NoSuchPaddingException, IllegalBlockSizeException, CertificateException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
+        String publicKey = arbitraryDataProvider.getValue(user.getAccountName(), EncryptionUtils.PUBLIC_KEY);
+
+        DecryptedFolderMetadataFileV1 metadata = new DecryptedFolderMetadataFileV1();
+        metadata.setMetadata(new DecryptedMetadata());
+        metadata.getMetadata().setVersion(1.2);
+        metadata.getMetadata().setMetadataKeys(new HashMap<>());
+        String metadataKey = EncryptionUtils.encodeBytesToBase64String(EncryptionUtils.generateKey());
+        String encryptedMetadataKey = EncryptionUtils.encryptStringAsymmetric(metadataKey, publicKey);
+        metadata.getMetadata().setMetadataKey(encryptedMetadataKey);
+        return metadata;
+    }
+
+    private Pair<RemoteOperationResult<Void>, DeleteMethod> deleteForV2(OwnCloudClient client, String token) throws UploadException, IOException {
+        EncryptionUtilsV2 encryptionUtilsV2 = new EncryptionUtilsV2();
+        Pair<Boolean, DecryptedFolderMetadataFile> pair = encryptionUtilsV2.retrieveMetadata(parentFolder, client, user, context);
+        boolean metadataExists = pair.getFirst();
+        DecryptedFolderMetadataFile metadata = pair.getSecond();
+
+        Pair<RemoteOperationResult<Void>, DeleteMethod> deleteResult = deleteRemoteFile(client, token);
+        RemoteOperationResult<Void> result = deleteResult.getFirst();
+        DeleteMethod delete = deleteResult.getSecond();
+
+        if (isFolder) {
+            encryptionUtilsV2.removeFolderFromMetadata(fileName, metadata);
+        } else {
+            encryptionUtilsV2.removeFileFromMetadata(fileName, metadata);
+        }
+
+        encryptionUtilsV2.serializeAndUploadMetadata(parentFolder,
+                                                     metadata,
+                                                     token,
+                                                     client,
+                                                     metadataExists,
+                                                     context,
+                                                     user,
+                                                     new FileDataStorageManager(user, context.getContentResolver()));
+
+        return new Pair<>(result, delete);
+    }
+
+    private RemoteOperationResult<Void> deleteForV1(OwnCloudClient client, String token) throws NoSuchPaddingException, IllegalBlockSizeException, CertificateException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException, IOException, UploadException {
+        //noinspection deprecation
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(context);
+        DecryptedFolderMetadataFileV1 metadata = getMetadataV1(arbitraryDataProvider);
+        Pair<RemoteOperationResult<Void>, DeleteMethod> deleteResult = deleteRemoteFile(client, token);
+
+        String serializedMetadata;
+
+        // check if we need metadataKeys
+        if (metadata.getMetadata().getMetadataKey() != null) {
+            serializedMetadata = EncryptionUtils.serializeJSON(metadata, true);
+        } else {
+            serializedMetadata = EncryptionUtils.serializeJSON(metadata);
+        }
+
+        EncryptionUtils.uploadMetadata(parentFolder,
+                                       serializedMetadata,
+                                       token,
+                                       client,
+                                       true,
+                                       E2EVersion.V1_2,
+                                       "",
+                                       arbitraryDataProvider,
+                                       user);
+
+        return deleteResult.getFirst();
+    }
 }