diff --git a/app/src/androidTest/java/com/owncloud/android/utils/EncryptionUtilsV2IT.kt b/app/src/androidTest/java/com/owncloud/android/utils/EncryptionUtilsV2IT.kt index 8e09ee62dbcb..ba6ba727f327 100644 --- a/app/src/androidTest/java/com/owncloud/android/utils/EncryptionUtilsV2IT.kt +++ b/app/src/androidTest/java/com/owncloud/android/utils/EncryptionUtilsV2IT.kt @@ -1,6 +1,7 @@ /* * Nextcloud - Android Client * + * SPDX-FileCopyrightText: 2026 Alper Ozturk * SPDX-FileCopyrightText: 2023 Tobias Kaminsky * SPDX-FileCopyrightText: 2023 Nextcloud GmbH * SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only @@ -300,8 +301,7 @@ class EncryptionUtilsV2IT : EncryptionIT() { // random string, not real tag EncryptionUtils.generateUid(), EncryptionUtils.generateKey(), - metadataFile, - storageManager + metadataFile ) assertEquals(3, updatedMetadata.metadata.files.size) @@ -341,7 +341,6 @@ class EncryptionUtilsV2IT : EncryptionIT() { @Test fun addFolder() { - val folder = OCFile("/e/") val enc1 = MockUser("enc1", "Nextcloud") val metadataFile = generateDecryptedFolderMetadataFile(enc1, enc1Cert) assertEquals(2, metadataFile.metadata.files.size) @@ -350,9 +349,7 @@ class EncryptionUtilsV2IT : EncryptionIT() { val updatedMetadata = encryptionUtilsV2.addFolderToMetadata( EncryptionUtils.generateUid(), "new subfolder", - metadataFile, - folder, - storageManager + metadataFile ) assertEquals(2, updatedMetadata.metadata.files.size) @@ -361,7 +358,6 @@ class EncryptionUtilsV2IT : EncryptionIT() { @Test fun removeFolder() { - val folder = OCFile("/e/") val enc1 = MockUser("enc1", "Nextcloud") val metadataFile = generateDecryptedFolderMetadataFile(enc1, enc1Cert) assertEquals(2, metadataFile.metadata.files.size) @@ -371,9 +367,7 @@ class EncryptionUtilsV2IT : EncryptionIT() { var updatedMetadata = encryptionUtilsV2.addFolderToMetadata( encryptedFileName, "new subfolder", - metadataFile, - folder, - storageManager + metadataFile ) assertEquals(2, updatedMetadata.metadata.files.size) diff --git a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java index 1df445d5d3e6..b1bbe319d3b8 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -21,9 +21,9 @@ import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; -import android.media.MediaScannerConnection; import android.content.OperationApplicationException; import android.database.Cursor; +import android.media.MediaScannerConnection; import android.net.Uri; import android.os.RemoteException; import android.provider.MediaStore; @@ -50,8 +50,8 @@ import com.nextcloud.utils.e2ee.E2EVersionHelper; import com.nextcloud.utils.extensions.DateExtensionsKt; import com.nextcloud.utils.extensions.FileExtensionsKt; -import com.nextcloud.utils.extensions.StringExtensionsKt; import com.owncloud.android.MainApp; +import com.owncloud.android.datamodel.e2e.v2.decrypted.DecryptedFolderMetadataFile; import com.owncloud.android.db.ProviderMeta.ProviderTableMeta; import com.owncloud.android.lib.common.network.WebdavEntry; import com.owncloud.android.lib.common.utils.Log_OC; @@ -2919,4 +2919,13 @@ public FileEntity getFileEntity(OCFile file) { public void updateFileEntity(@NonNull FileEntity entity) { fileDao.update(entity); } + + public void updateE2EECounter(OCFile file, DecryptedFolderMetadataFile metadata) { + updateE2EECounter(file, metadata.getMetadata().getCounter()); + } + + public void updateE2EECounter(OCFile file, long counter) { + file.setE2eCounter(counter); + saveFile(file); + } } diff --git a/app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java b/app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java index 3edc2ae2a2ec..d5f05a18677b 100644 --- a/app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java +++ b/app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java @@ -1,6 +1,7 @@ /* * Nextcloud - Android Client * + * SPDX-FileCopyrightText: 2026 Alper Ozturk * SPDX-FileCopyrightText: 2020-2023 Tobias Kaminsky * SPDX-FileCopyrightText: 2020 Chris Narkiewicz * SPDX-FileCopyrightText: 2020 Andy Scherzinger @@ -336,9 +337,7 @@ private RemoteOperationResult encryptedCreateV2(OCFile parent, OwnCloudClient cl // update metadata DecryptedFolderMetadataFile updatedMetadataFile = encryptionUtilsV2.addFolderToMetadata(encryptedFileName, filename, - metadata, - parent, - getStorageManager()); + metadata); // upload metadata encryptionUtilsV2.serializeAndUploadMetadata(parent, @@ -350,6 +349,8 @@ private RemoteOperationResult encryptedCreateV2(OCFile parent, OwnCloudClient cl user, getStorageManager()); + getStorageManager().updateE2EECounter(parent, metadata); + // unlock folder RemoteOperationResult unlockFolderResult = EncryptionUtils.unlockFolder(parent, client, token); diff --git a/app/src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java b/app/src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java index e47fd552c88e..1e76a4d8bc17 100644 --- a/app/src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java +++ b/app/src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java @@ -554,10 +554,8 @@ private void synchronizeData(List folderAndFiles) { localFilesMap = prefillLocalFilesMap(metadataFileV1, fileDataStorageManager.getFolderContent(mLocalFolder, false)); } else { localFilesMap = prefillLocalFilesMap(object, fileDataStorageManager.getFolderContent(mLocalFolder, false)); - - // update counter - if (object != null) { - mLocalFolder.setE2eCounter(((DecryptedFolderMetadataFile) object).getMetadata().getCounter()); + if (object instanceof DecryptedFolderMetadataFile metadataFile) { + mLocalFolder.setE2eCounter(metadataFile.getMetadata().getCounter()); } } @@ -599,14 +597,10 @@ private void synchronizeData(List folderAndFiles) { FileStorageUtils.searchForLocalFileInDefaultPath(updatedFile, user.getAccountName()); // update file name for encrypted files - if (E2EVersionHelper.INSTANCE.isV1(e2EVersion)) { - updateFileNameForEncryptedFileV1(fileDataStorageManager, - (DecryptedFolderMetadataFileV1) object, - updatedFile); - } else if (object != null) { - updateFileNameForEncryptedFile(fileDataStorageManager, - (DecryptedFolderMetadataFile) object, - updatedFile); + if (E2EVersionHelper.INSTANCE.isV1(e2EVersion) && object instanceof DecryptedFolderMetadataFileV1 metadata) { + updateFileNameForEncryptedFileV1(fileDataStorageManager, metadata, updatedFile); + } else if (object instanceof DecryptedFolderMetadataFile metadata) { + updateFileNameForEncryptedFile(fileDataStorageManager, metadata, updatedFile); if (localFile != null) { updatedFile.setE2eCounter(localFile.getE2eCounter()); } @@ -622,15 +616,12 @@ private void synchronizeData(List folderAndFiles) { // save updated contents in local database // update file name for encrypted files - if (E2EVersionHelper.INSTANCE.isV1(e2EVersion)) { - updateFileNameForEncryptedFileV1(fileDataStorageManager, - (DecryptedFolderMetadataFileV1) object, - mLocalFolder); - } else { - updateFileNameForEncryptedFile(fileDataStorageManager, - (DecryptedFolderMetadataFile) object, - mLocalFolder); + if (E2EVersionHelper.INSTANCE.isV1(e2EVersion) && object instanceof DecryptedFolderMetadataFileV1 metadata) { + updateFileNameForEncryptedFileV1(fileDataStorageManager, metadata, mLocalFolder); + } else if (object instanceof DecryptedFolderMetadataFile metadata) { + updateFileNameForEncryptedFile(fileDataStorageManager, metadata, mLocalFolder); } + fileDataStorageManager.saveFolder(remoteFolder, updatedFiles, localFilesMap.values()); mChildren = updatedFiles; diff --git a/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt b/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt index a94178a10bc2..65020e6eee08 100644 --- a/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt +++ b/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt @@ -183,9 +183,7 @@ class RemoveRemoteEncryptedFileOperation internal constructor( encryptionUtilsV2.removeFileFromMetadata(fileName, metadata) } - parentFolder.setE2eCounter(metadata.metadata.counter) val storageManager = FileDataStorageManager(user, context.contentResolver) - storageManager.saveFile(parentFolder) encryptionUtilsV2.serializeAndUploadMetadata( parentFolder, @@ -198,6 +196,8 @@ class RemoveRemoteEncryptedFileOperation internal constructor( storageManager ) + storageManager.updateE2EECounter(parentFolder, metadata) + return Pair(result, delete) } diff --git a/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java b/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java index d00aa6b4d56e..39b7395516cf 100644 --- a/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java +++ b/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java @@ -1,6 +1,7 @@ /* * Nextcloud - Android Client * + * SPDX-FileCopyrightText: 2026 Alper Ozturk * SPDX-FileCopyrightText: 2020-2023 Tobias Kaminsky * SPDX-FileCopyrightText: 2021 Chris Narkiewicz * SPDX-FileCopyrightText: 2017-2018 Andy Scherzinger @@ -892,11 +893,7 @@ private void updateMetadataForV2(DecryptedFolderMetadataFile metadata, Encryptio e2eData.getIv(), e2eData.getEncryptedFile().getAuthenticationTag(), e2eData.getKey(), - metadata, - getStorageManager()); - - parentFile.setE2eCounter(metadata.getMetadata().getCounter()); - getStorageManager().saveFile(parentFile); + metadata); // upload metadata encryptionUtilsV2.serializeAndUploadMetadata(parentFile, @@ -907,6 +904,8 @@ private void updateMetadataForV2(DecryptedFolderMetadataFile metadata, Encryptio mContext, user, getStorageManager()); + + getStorageManager().updateE2EECounter(parentFile, metadata); } private void completeE2EUpload(RemoteOperationResult result, E2EFiles e2eFiles, OwnCloudClient client) { diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java index 32950fb06ebe..352bc6472b8d 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java +++ b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java @@ -305,8 +305,8 @@ public void updateFileEncryptionById(String fileId, boolean encrypted) { e2eCounter = EncryptionUtils.E2E_V2_INITIAL_COUNTER; } - file.setE2eCounter(e2eCounter); - mStorageManager.saveFile(file); + mStorageManager.updateE2EECounter(file, e2eCounter); + int position = getItemPosition(file); if (position != -1) { notifyItemChanged(position); diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.kt b/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.kt index 928beeee83d5..cdacde73a97f 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.kt +++ b/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.kt @@ -423,8 +423,7 @@ class FileDetailSharingFragment : val client = clientFactory.create(user) val metadata = RefreshFolderOperation.getDecryptedFolderMetadata(true, file, client, user, context) if (metadata is DecryptedFolderMetadataFile) { - file?.setE2eCounter(metadata.metadata.counter) - fileDataStorageManager?.saveFile(file) + fileDataStorageManager?.updateE2EECounter(file, metadata) } true } catch (e: Exception) { diff --git a/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt b/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt index 991d45247465..42c5052cb6d0 100644 --- a/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt +++ b/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt @@ -1,6 +1,7 @@ /* * Nextcloud - Android Client * + * SPDX-FileCopyrightText: 2026 Alper Ozturk * SPDX-FileCopyrightText: 2023 Tobias Kaminsky * SPDX-FileCopyrightText: 2023 Nextcloud GmbH * SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only @@ -12,7 +13,6 @@ import android.content.Context import androidx.annotation.VisibleForTesting import com.google.gson.reflect.TypeToken import com.nextcloud.client.account.User -import com.nextcloud.client.account.UserAccountManagerImpl import com.nextcloud.utils.CmsSignatureVerifier import com.nextcloud.utils.autoRename.AutoRename import com.nextcloud.utils.e2ee.E2EVersionHelper @@ -474,8 +474,7 @@ class EncryptionUtilsV2 { initializationVector: ByteArray, authenticationTag: String, key: ByteArray, - metadataFile: DecryptedFolderMetadataFile, - fileDataStorageManager: FileDataStorageManager + metadataFile: DecryptedFolderMetadataFile ): DecryptedFolderMetadataFile { val decryptedFile = DecryptedFile( ocFile.decryptedFileName, @@ -487,8 +486,6 @@ class EncryptionUtilsV2 { metadataFile.metadata.files[encryptedFileName] = decryptedFile metadataFile.metadata.counter++ - ocFile.setE2eCounter(metadataFile.metadata.counter) - fileDataStorageManager.saveFile(ocFile) return metadataFile } @@ -496,14 +493,10 @@ class EncryptionUtilsV2 { fun addFolderToMetadata( encryptedFileName: String, fileName: String, - metadataFile: DecryptedFolderMetadataFile, - ocFile: OCFile, - fileDataStorageManager: FileDataStorageManager + metadataFile: DecryptedFolderMetadataFile ): DecryptedFolderMetadataFile { metadataFile.metadata.folders[encryptedFileName] = fileName metadataFile.metadata.counter++ - ocFile.setE2eCounter(metadataFile.metadata.counter) - fileDataStorageManager.saveFile(ocFile) return metadataFile } @@ -861,7 +854,9 @@ class EncryptionUtilsV2 { oldCounter: Long, signature: String ): Boolean { - if (decryptedFolderMetadataFile.metadata.counter < oldCounter) { + val metadataCounter = decryptedFolderMetadataFile.metadata.counter + if (metadataCounter < oldCounter) { + Log_OC.e(TAG, "old counter: $oldCounter, metadata counter $metadataCounter") MainApp.showMessage(R.string.e2e_counter_too_old) return false }