From 88f5663db7f82fdad647f928ce77d6e15eb32630 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Wed, 9 Sep 2026 14:56:07 +0200 Subject: [PATCH] fix(e2ee): event listen Signed-off-by: alperozturk96 --- .../dialog/SetupEncryptionDialogFragmentIT.kt | 4 +- .../OCFileListFragmentExtensions.kt | 53 +++++++++++-------- .../ui/activity/SetupEncryptionActivity.kt | 2 +- .../SetupEncryptionDialogFragment.kt | 7 ++- .../android/ui/events/EncryptionEvent.kt | 2 +- .../fragment/EncryptedFolderClickHandler.kt | 16 ++++-- .../ui/fragment/OCFileListFragment.java | 2 +- 7 files changed, 55 insertions(+), 31 deletions(-) diff --git a/app/src/androidTest/java/com/owncloud/android/ui/dialog/SetupEncryptionDialogFragmentIT.kt b/app/src/androidTest/java/com/owncloud/android/ui/dialog/SetupEncryptionDialogFragmentIT.kt index 576b11515063..688f805f8eba 100644 --- a/app/src/androidTest/java/com/owncloud/android/ui/dialog/SetupEncryptionDialogFragmentIT.kt +++ b/app/src/androidTest/java/com/owncloud/android/ui/dialog/SetupEncryptionDialogFragmentIT.kt @@ -28,7 +28,7 @@ class SetupEncryptionDialogFragmentIT : AbstractIT() { launchActivity().use { scenario -> var sut: SetupEncryptionDialogFragment? = null scenario.onActivity { activity -> - sut = SetupEncryptionDialogFragment.newInstance(user, null) + sut = SetupEncryptionDialogFragment.newInstance(user, null, null) sut.show(activity.supportFragmentManager, "1") val keyWords = arrayListOf( "ability", @@ -64,7 +64,7 @@ class SetupEncryptionDialogFragmentIT : AbstractIT() { launchActivity().use { scenario -> var sut: SetupEncryptionDialogFragment? = null scenario.onActivity { activity -> - sut = SetupEncryptionDialogFragment.newInstance(user, null) + sut = SetupEncryptionDialogFragment.newInstance(user, null, null) sut.show(activity.supportFragmentManager, "1") sut.errorSavingKeys() } diff --git a/app/src/main/java/com/nextcloud/utils/extensions/OCFileListFragmentExtensions.kt b/app/src/main/java/com/nextcloud/utils/extensions/OCFileListFragmentExtensions.kt index 89519699de9e..0c78af56f303 100644 --- a/app/src/main/java/com/nextcloud/utils/extensions/OCFileListFragmentExtensions.kt +++ b/app/src/main/java/com/nextcloud/utils/extensions/OCFileListFragmentExtensions.kt @@ -9,11 +9,13 @@ package com.nextcloud.utils.extensions import android.os.Bundle import androidx.lifecycle.lifecycleScope +import com.nextcloud.utils.e2ee.model.E2EEAction import com.owncloud.android.R import com.owncloud.android.datamodel.OCFile import com.owncloud.android.lib.common.utils.Log_OC import com.owncloud.android.ui.activity.FileActivity import com.owncloud.android.ui.dialog.setupEncryption.SetupEncryptionDialogFragment +import com.owncloud.android.ui.dialog.setupEncryption.SetupEncryptionDialogFragment.Companion.ARG_ACTION import com.owncloud.android.ui.dialog.setupEncryption.SetupEncryptionDialogFragment.Companion.ARG_FILE_PATH import com.owncloud.android.ui.dialog.setupEncryption.SetupEncryptionDialogFragment.Companion.RESULT_REQUEST_KEY import com.owncloud.android.ui.dialog.setupEncryption.SetupEncryptionDialogFragment.Companion.SUCCESS @@ -23,7 +25,7 @@ import kotlinx.coroutines.launch private const val TAG = "OCFileListFragmentExtensions" -fun OCFileListFragment.showEncryptionDialog(remotePath: String?) { +fun OCFileListFragment.showEncryptionDialog(remotePath: String?, action: E2EEAction) { if (parentFragmentManager.findFragmentByTag(SetupEncryptionDialogFragment.SETUP_ENCRYPTION_DIALOG_TAG) != null) { return } @@ -31,8 +33,8 @@ fun OCFileListFragment.showEncryptionDialog(remotePath: String?) { val user = accountManager.user val connectivityService = typedActivity()?.connectivityService connectivityService?.isNetworkAndServerAvailable { result -> - if (result == true) { - SetupEncryptionDialogFragment.newInstance(user, remotePath) + if (result) { + SetupEncryptionDialogFragment.newInstance(user, remotePath, action) .show(parentFragmentManager, SetupEncryptionDialogFragment.SETUP_ENCRYPTION_DIALOG_TAG) return@isNetworkAndServerAvailable } @@ -55,30 +57,37 @@ fun OCFileListFragment.listenEncryptionDialogResult() { return@setFragmentResultListener } - val fileRemotePath = bundle.getString(ARG_FILE_PATH, null) - if (fileRemotePath == null) { - Log_OC.e(TAG, "file path is null") + val action = bundle.getSerializableArgument(ARG_ACTION, E2EEAction::class.java) + if (action == null) { + Log_OC.e(TAG, "no pending encryption action, nothing to continue with") return@setFragmentResultListener } - val file: OCFile? = mContainerActivity.getStorageManager().getFileByDecryptedRemotePath(fileRemotePath) - if (file == null) { - Log_OC.e(TAG, "file is null, cannot toggle encryption") - return@setFragmentResultListener - } + when (action) { + E2EEAction.NEW_FOLDER -> createFolder(true) - if (file.isRootDirectory) { - Log_OC.d( - TAG, - "result of setup encryption triggered in root directory, this call is for " + - "creating encrypted folder" - ) - createFolder(true) - return@setFragmentResultListener - } + E2EEAction.OPEN -> folderFromResult(bundle)?.let { clickHandler.openAfterKeySetup(it) } - lifecycleScope.launch { - folderEncryption.toggle(file.toEncryptionEvent(true)) + E2EEAction.ENCRYPT -> folderFromResult(bundle)?.let { file -> + lifecycleScope.launch { + folderEncryption.toggle(file.toEncryptionEvent(true)) + } + } } } } + +private fun OCFileListFragment.folderFromResult(bundle: Bundle): OCFile? { + val remotePath = bundle.getString(ARG_FILE_PATH, null) + if (remotePath == null) { + Log_OC.e(TAG, "file path is null") + return null + } + + val file = mContainerActivity.storageManager.getFileByEncryptedRemotePath(remotePath) + if (file == null) { + Log_OC.e(TAG, "file is null, cannot continue encryption action") + } + + return file +} diff --git a/app/src/main/java/com/owncloud/android/ui/activity/SetupEncryptionActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/SetupEncryptionActivity.kt index 9ad74e9edf49..6de75832ce1f 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/SetupEncryptionActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/SetupEncryptionActivity.kt @@ -30,7 +30,7 @@ class SetupEncryptionActivity : AppCompatActivity() { finish() } - val setupEncryptionDialogFragment = SetupEncryptionDialogFragment.newInstance(user, null) + val setupEncryptionDialogFragment = SetupEncryptionDialogFragment.newInstance(user, null, null) supportFragmentManager.setFragmentResultListener( SetupEncryptionDialogFragment.RESULT_REQUEST_KEY, this diff --git a/app/src/main/java/com/owncloud/android/ui/dialog/setupEncryption/SetupEncryptionDialogFragment.kt b/app/src/main/java/com/owncloud/android/ui/dialog/setupEncryption/SetupEncryptionDialogFragment.kt index 1034a7d4fe2a..ec6ec83a13a4 100644 --- a/app/src/main/java/com/owncloud/android/ui/dialog/setupEncryption/SetupEncryptionDialogFragment.kt +++ b/app/src/main/java/com/owncloud/android/ui/dialog/setupEncryption/SetupEncryptionDialogFragment.kt @@ -21,7 +21,9 @@ import com.google.android.material.textfield.TextInputLayout import com.nextcloud.client.account.User import com.nextcloud.client.di.Injectable import com.nextcloud.client.network.ClientFactory +import com.nextcloud.utils.e2ee.model.E2EEAction import com.nextcloud.utils.extensions.getParcelableArgument +import com.nextcloud.utils.extensions.getSerializableArgument import com.owncloud.android.BuildConfig import com.owncloud.android.R import com.owncloud.android.databinding.SetupEncryptionDialogBinding @@ -243,6 +245,7 @@ class SetupEncryptionDialogFragment : return Bundle().apply { putBoolean(SUCCESS, true) putString(ARG_FILE_PATH, requireArguments().getString(ARG_FILE_PATH)) + putSerializable(ARG_ACTION, arguments.getSerializableArgument(ARG_ACTION, E2EEAction::class.java)) } } @@ -526,6 +529,7 @@ class SetupEncryptionDialogFragment : const val SETUP_ENCRYPTION_RESULT_CODE = 101 const val SETUP_ENCRYPTION_DIALOG_TAG = "SETUP_ENCRYPTION_DIALOG_TAG" const val ARG_FILE_PATH = "ARG_FILE_PATH" + const val ARG_ACTION = "ARG_ACTION" const val RESULT_REQUEST_KEY = "RESULT_REQUEST" const val RESULT_KEY_CANCELLED = "IS_CANCELLED" private const val NUMBER_OF_WORDS = 12 @@ -537,11 +541,12 @@ class SetupEncryptionDialogFragment : private const val KEY_GENERATE = "KEY_GENERATE" @JvmStatic - fun newInstance(user: User?, filePath: String?): SetupEncryptionDialogFragment = + fun newInstance(user: User?, filePath: String?, action: E2EEAction?): SetupEncryptionDialogFragment = SetupEncryptionDialogFragment().apply { arguments = Bundle().apply { putParcelable(ARG_USER, user) putString(ARG_FILE_PATH, filePath) + putSerializable(ARG_ACTION, action) } } } diff --git a/app/src/main/java/com/owncloud/android/ui/events/EncryptionEvent.kt b/app/src/main/java/com/owncloud/android/ui/events/EncryptionEvent.kt index 1a7dbc56c9a4..a5763af837d8 100644 --- a/app/src/main/java/com/owncloud/android/ui/events/EncryptionEvent.kt +++ b/app/src/main/java/com/owncloud/android/ui/events/EncryptionEvent.kt @@ -26,7 +26,7 @@ class EncryptionEvent(val localId: Long, val remoteId: String, val remotePath: S } E2EEKeyCheck.ONLY_ON_SERVER, E2EEKeyCheck.MISSING_EVERYWHERE -> { - fragment.showEncryptionDialog(remotePath) + fragment.showEncryptionDialog(remotePath, E2EEAction.ENCRYPT) } E2EEKeyCheck.ONLY_ON_DEVICE, E2EEKeyCheck.DIFFERS_FROM_SERVER -> { diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/EncryptedFolderClickHandler.kt b/app/src/main/java/com/owncloud/android/ui/fragment/EncryptedFolderClickHandler.kt index e182094edc46..3366ce48fbba 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/EncryptedFolderClickHandler.kt +++ b/app/src/main/java/com/owncloud/android/ui/fragment/EncryptedFolderClickHandler.kt @@ -48,7 +48,7 @@ class EncryptedFolderClickHandler(private val fragment: OCFileListFragment) { E2EEKeyCheck.ONLY_ON_SERVER, E2EEKeyCheck.MISSING_EVERYWHERE -> { Log_OC.d(TAG, "keys found on server but missing locally, redirecting to encryption setup") - fragment.showEncryptionDialog(OCFile.ROOT_PATH) + fragment.showEncryptionDialog(OCFile.ROOT_PATH, E2EEAction.NEW_FOLDER) } E2EEKeyCheck.SAME_AS_SERVER -> { @@ -86,7 +86,7 @@ class EncryptedFolderClickHandler(private val fragment: OCFileListFragment) { } E2EEKeyCheck.ONLY_ON_SERVER -> { - fragment.showEncryptionDialog(file.remotePath) + fragment.showEncryptionDialog(file.remotePath, E2EEAction.OPEN) } E2EEKeyCheck.MISSING_EVERYWHERE -> { @@ -114,6 +114,16 @@ class EncryptedFolderClickHandler(private val fragment: OCFileListFragment) { } } + fun openAfterKeySetup(file: OCFile) { + fragment.lifecycleScope.launch { + if (fragment.e2eeActionResolver.checkFolderMetadataKey(file)) { + onEncryptionSetupComplete(file, fragment.adapter.getItemPosition(file)) + } else { + DisplayUtils.showSnackMessage(fragment, R.string.encryption_open_key_mismatch) + } + } + } + private fun dismissCheckingSnackbar() { DisplayUtils.dismissSnackMessage(checkingKeysSnackbar) checkingKeysSnackbar = null @@ -131,7 +141,7 @@ class EncryptedFolderClickHandler(private val fragment: OCFileListFragment) { if (FileOperationsHelper.isEndToEndEncryptionSetup(fragment.context, user)) { onEncryptionSetupComplete(file, position) } else { - fragment.showEncryptionDialog(file.remotePath) + fragment.showEncryptionDialog(file.remotePath, E2EEAction.OPEN) } } diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index b473910fd773..bd729c9393d4 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -201,7 +201,7 @@ public class OCFileListFragment extends ExtendedListFragment implements @Inject ThumbnailGenerator thumbnailGenerator; @Inject public E2EEActionResolver e2eeActionResolver; public E2EEDialogPresenter e2eeDialogPresenter; - private EncryptedFolderClickHandler clickHandler; + public EncryptedFolderClickHandler clickHandler; public FolderEncryption folderEncryption; public FileFragment.ContainerActivity mContainerActivity;