Convert to kt

Signed-off-by: alperozturk <alper_ozturk@proton.me>
This commit is contained in:
alperozturk 2024-04-26 15:03:55 +02:00 committed by Alper Öztürk
parent 1ccb686f08
commit d7b30bad46

View file

@ -5,210 +5,199 @@
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH * SPDX-FileCopyrightText: 2017 Nextcloud GmbH
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only * SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
*/ */
package com.owncloud.android.operations
package com.owncloud.android.operations; import android.content.Context
import com.nextcloud.client.account.User
import android.content.Context; import com.owncloud.android.datamodel.ArbitraryDataProvider
import com.owncloud.android.datamodel.ArbitraryDataProviderImpl
import com.nextcloud.client.account.User; import com.owncloud.android.datamodel.FileDataStorageManager
import com.owncloud.android.datamodel.ArbitraryDataProvider; import com.owncloud.android.datamodel.OCFile
import com.owncloud.android.datamodel.ArbitraryDataProviderImpl; import com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedFolderMetadataFileV1
import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedMetadata
import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedFolderMetadataFileV1; import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedMetadata; import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.datamodel.e2e.v2.decrypted.DecryptedFolderMetadataFile; import com.owncloud.android.lib.common.utils.Log_OC
import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.resources.status.E2EVersion
import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.utils.EncryptionUtils
import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.utils.EncryptionUtilsV2
import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.utils.theme.CapabilityUtils
import com.owncloud.android.lib.resources.status.E2EVersion; import org.apache.commons.httpclient.HttpStatus
import com.owncloud.android.utils.EncryptionUtils; import org.apache.commons.httpclient.NameValuePair
import com.owncloud.android.utils.EncryptionUtilsV2; import org.apache.jackrabbit.webdav.client.methods.DeleteMethod
import com.owncloud.android.utils.theme.CapabilityUtils; import java.io.IOException
import java.security.InvalidKeyException
import org.apache.commons.httpclient.HttpStatus; import java.security.NoSuchAlgorithmException
import org.apache.commons.httpclient.NameValuePair; import java.security.cert.CertificateException
import org.apache.jackrabbit.webdav.client.methods.DeleteMethod; import javax.crypto.BadPaddingException
import javax.crypto.IllegalBlockSizeException
import java.io.IOException; import javax.crypto.NoSuchPaddingException
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;
/** /**
* Remote operation performing the removal of a remote encrypted file or folder * Remote operation performing the removal of a remote encrypted file or folder
*/ */
public class RemoveRemoteEncryptedFileOperation extends RemoteOperation<Void> { class RemoveRemoteEncryptedFileOperation
private static final String TAG = RemoveRemoteEncryptedFileOperation.class.getSimpleName(); /**
private static final int REMOVE_READ_TIMEOUT = 30000;
private static final int REMOVE_CONNECTION_TIMEOUT = 5000;
private final String remotePath;
private final OCFile parentFolder;
private final User user;
private final String fileName;
private final Context context;
private final boolean isFolder;
/**
* Constructor * Constructor
* *
* @param remotePath RemotePath of the remote file or folder to remove from the server * @param remotePath RemotePath of the remote file or folder to remove from the server
* @param parentFolder parent folder * @param parentFolder parent folder
*/ */
RemoveRemoteEncryptedFileOperation(String remotePath, internal constructor(
User user, private val remotePath: String,
Context context, private val user: User,
String fileName, private val context: Context,
OCFile parentFolder, private val fileName: String,
boolean isFolder) { private val parentFolder: OCFile,
this.remotePath = remotePath; private val isFolder: Boolean
this.user = user; ) : RemoteOperation<Void>() {
this.fileName = fileName;
this.context = context;
this.parentFolder = parentFolder;
this.isFolder = isFolder;
}
/** /**
* Performs the remove operation. * Performs the remove operation.
*/ */
@Override override fun run(client: OwnCloudClient): RemoteOperationResult<Void> {
protected RemoteOperationResult<Void> run(OwnCloudClient client) { val result: RemoteOperationResult<Void>
RemoteOperationResult<Void> result; var delete: DeleteMethod? = null
DeleteMethod delete = null; var token: String? = null
String token = null; val e2eVersion = CapabilityUtils.getCapability(context).endToEndEncryptionApiVersion
val isE2EVersionAtLeast2 = e2eVersion.compareTo(E2EVersion.V2_0) >= 0
E2EVersion e2eVersion = CapabilityUtils.getCapability(context).getEndToEndEncryptionApiVersion();
boolean isE2EVersionAtLeast2 = e2eVersion.compareTo(E2EVersion.V2_0) >= 0;
try { try {
token = EncryptionUtils.lockFolder(parentFolder, client); token = EncryptionUtils.lockFolder(parentFolder, client)
return if (isE2EVersionAtLeast2) {
if (isE2EVersionAtLeast2) { val (first, second) = deleteForV2(client, token)
Pair<RemoteOperationResult<Void>, DeleteMethod> deleteResult = deleteForV2(client, token); result = first
result = deleteResult.getFirst(); delete = second
delete = deleteResult.getSecond(); result
return result;
} else { } else {
return deleteForV1(client, token); deleteForV1(client, token)
} }
} catch (Exception e) { } catch (e: Exception) {
result = new RemoteOperationResult<>(e); result = RemoteOperationResult(e)
Log_OC.e(TAG, "Remove " + remotePath + ": " + result.getLogMessage(), e); Log_OC.e(TAG, "Remove " + remotePath + ": " + result.logMessage, e)
} finally { } finally {
if (delete != null) { delete?.releaseConnection()
delete.releaseConnection(); token?.let { unlockFile(client, it, isE2EVersionAtLeast2) }
}
return result
} }
if (token != null) { private fun unlockFile(client: OwnCloudClient, token: String, isE2EVersionAtLeast2: Boolean) {
unlockFile(client, token,isE2EVersionAtLeast2); val unlockFileOperationResult = if (isE2EVersionAtLeast2) {
} EncryptionUtils.unlockFolder(parentFolder, client, token)
}
return result;
}
private void unlockFile(OwnCloudClient client, String token, boolean isE2EVersionAtLeast2) {
RemoteOperationResult<Void> unlockFileOperationResult;
if (isE2EVersionAtLeast2) {
unlockFileOperationResult = EncryptionUtils.unlockFolder(parentFolder, client, token);
} else { } else {
unlockFileOperationResult = EncryptionUtils.unlockFolderV1(parentFolder, client, token); EncryptionUtils.unlockFolderV1(parentFolder, client, token)
} }
if (!unlockFileOperationResult.isSuccess()) { if (!unlockFileOperationResult.isSuccess) {
Log_OC.e(TAG, "Failed to unlock " + parentFolder.getLocalId()); Log_OC.e(TAG, "Failed to unlock " + parentFolder.localId)
} }
} }
private Pair<RemoteOperationResult<Void>, DeleteMethod> deleteRemoteFile(OwnCloudClient client, String token) throws IOException { @Throws(IOException::class)
DeleteMethod delete = new DeleteMethod(client.getFilesDavUri(remotePath)); private fun deleteRemoteFile(
delete.setQueryString(new NameValuePair[]{new NameValuePair(E2E_TOKEN, token)}); client: OwnCloudClient,
int status = client.executeMethod(delete, REMOVE_READ_TIMEOUT, REMOVE_CONNECTION_TIMEOUT); token: String?
): Pair<RemoteOperationResult<Void>, DeleteMethod> {
delete.getResponseBodyAsString(); // exhaust the response, although not interesting val delete = DeleteMethod(client.getFilesDavUri(remotePath)).apply {
RemoteOperationResult<Void> result = new RemoteOperationResult<>(delete.succeeded() || status == HttpStatus.SC_NOT_FOUND, delete); setQueryString(arrayOf(NameValuePair(E2E_TOKEN, token)))
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 { val status = client.executeMethod(delete, REMOVE_READ_TIMEOUT, REMOVE_CONNECTION_TIMEOUT)
String publicKey = arbitraryDataProvider.getValue(user.getAccountName(), EncryptionUtils.PUBLIC_KEY); delete.getResponseBodyAsString() // exhaust the response, although not interesting
DecryptedFolderMetadataFileV1 metadata = new DecryptedFolderMetadataFileV1(); val result = RemoteOperationResult<Void>(delete.succeeded() || status == HttpStatus.SC_NOT_FOUND, delete)
metadata.setMetadata(new DecryptedMetadata()); Log_OC.i(TAG, "Remove " + remotePath + ": " + result.logMessage)
metadata.getMetadata().setVersion(1.2);
metadata.getMetadata().setMetadataKeys(new HashMap<>()); return Pair(result, delete)
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 { private fun getMetadataV1(arbitraryDataProvider: ArbitraryDataProvider): DecryptedFolderMetadataFileV1 {
EncryptionUtilsV2 encryptionUtilsV2 = new EncryptionUtilsV2(); val publicKey = arbitraryDataProvider.getValue(user.accountName, EncryptionUtils.PUBLIC_KEY)
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); val metadata = DecryptedFolderMetadataFileV1().apply {
RemoteOperationResult<Void> result = deleteResult.getFirst(); metadata = DecryptedMetadata()
DeleteMethod delete = deleteResult.getSecond(); metadata.version = 1.2
metadata.metadataKeys = HashMap()
}
val metadataKey = EncryptionUtils.encodeBytesToBase64String(EncryptionUtils.generateKey())
val encryptedMetadataKey = EncryptionUtils.encryptStringAsymmetric(metadataKey, publicKey)
metadata.metadata.metadataKey = encryptedMetadataKey
return metadata
}
private fun deleteForV2(client: OwnCloudClient, token: String?): Pair<RemoteOperationResult<Void>, DeleteMethod> {
val encryptionUtilsV2 = EncryptionUtilsV2()
val (metadataExists, metadata) = encryptionUtilsV2.retrieveMetadata(
parentFolder,
client,
user,
context
)
val (result, delete) = deleteRemoteFile(client, token)
if (isFolder) { if (isFolder) {
encryptionUtilsV2.removeFolderFromMetadata(fileName, metadata); encryptionUtilsV2.removeFolderFromMetadata(fileName, metadata)
} else { } else {
encryptionUtilsV2.removeFileFromMetadata(fileName, metadata); encryptionUtilsV2.removeFileFromMetadata(fileName, metadata)
} }
encryptionUtilsV2.serializeAndUploadMetadata(parentFolder, encryptionUtilsV2.serializeAndUploadMetadata(
parentFolder,
metadata, metadata,
token, token!!,
client, client,
metadataExists, metadataExists,
context, context,
user, user,
new FileDataStorageManager(user, context.getContentResolver())); FileDataStorageManager(user, context.contentResolver)
)
return new Pair<>(result, delete); return Pair(result, delete)
} }
private RemoteOperationResult<Void> deleteForV1(OwnCloudClient client, String token) throws NoSuchPaddingException, IllegalBlockSizeException, CertificateException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException, IOException, UploadException { @Throws(
//noinspection deprecation NoSuchPaddingException::class,
ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(context); IllegalBlockSizeException::class,
DecryptedFolderMetadataFileV1 metadata = getMetadataV1(arbitraryDataProvider); CertificateException::class,
Pair<RemoteOperationResult<Void>, DeleteMethod> deleteResult = deleteRemoteFile(client, token); NoSuchAlgorithmException::class,
BadPaddingException::class,
String serializedMetadata; InvalidKeyException::class,
IOException::class,
UploadException::class
)
private fun deleteForV1(client: OwnCloudClient, token: String?): RemoteOperationResult<Void> {
val arbitraryDataProvider: ArbitraryDataProvider = ArbitraryDataProviderImpl(context)
val metadata = getMetadataV1(arbitraryDataProvider)
val (first) = deleteRemoteFile(client, token)
// check if we need metadataKeys // check if we need metadataKeys
if (metadata.getMetadata().getMetadataKey() != null) { val serializedMetadata: String = if (metadata.metadata.getMetadataKey() != null) {
serializedMetadata = EncryptionUtils.serializeJSON(metadata, true); EncryptionUtils.serializeJSON(metadata, true)
} else { } else {
serializedMetadata = EncryptionUtils.serializeJSON(metadata); EncryptionUtils.serializeJSON(metadata)
} }
EncryptionUtils.uploadMetadata(parentFolder, EncryptionUtils.uploadMetadata(
parentFolder,
serializedMetadata, serializedMetadata,
token, token,
client, client,
true, true, E2EVersion.V1_2,
E2EVersion.V1_2,
"", "",
arbitraryDataProvider, arbitraryDataProvider,
user); user
)
return deleteResult.getFirst(); return first
}
companion object {
private val TAG = RemoveRemoteEncryptedFileOperation::class.java.getSimpleName()
private const val REMOVE_READ_TIMEOUT = 30000
private const val REMOVE_CONNECTION_TIMEOUT = 5000
} }
} }