Merge pull request #5721 from vector-im/feature/aris/fix_account_deactivation_issue
Fix Account deactivation issues
This commit is contained in:
commit
942bc13ccc
1
changelog.d/5721.bugfix
Normal file
1
changelog.d/5721.bugfix
Normal file
@ -0,0 +1 @@
|
|||||||
|
Improving deactivation experience along with a crash fix
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.api.session.uia
|
||||||
|
|
||||||
|
enum class UiaResult {
|
||||||
|
SUCCESS,
|
||||||
|
FAILURE,
|
||||||
|
CANCELLED
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.api.session.uia.exceptions
|
||||||
|
|
||||||
|
class UiaCancelledException(message: String? = null) : Exception(message)
|
@ -20,6 +20,8 @@ import org.matrix.android.sdk.api.auth.UIABaseAuth
|
|||||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
||||||
import org.matrix.android.sdk.api.failure.Failure
|
import org.matrix.android.sdk.api.failure.Failure
|
||||||
import org.matrix.android.sdk.api.failure.toRegistrationFlowResponse
|
import org.matrix.android.sdk.api.failure.toRegistrationFlowResponse
|
||||||
|
import org.matrix.android.sdk.api.session.uia.UiaResult
|
||||||
|
import org.matrix.android.sdk.api.session.uia.exceptions.UiaCancelledException
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import kotlin.coroutines.suspendCoroutine
|
import kotlin.coroutines.suspendCoroutine
|
||||||
|
|
||||||
@ -30,14 +32,15 @@ import kotlin.coroutines.suspendCoroutine
|
|||||||
* @param interceptor see doc in [UserInteractiveAuthInterceptor]
|
* @param interceptor see doc in [UserInteractiveAuthInterceptor]
|
||||||
* @param retryBlock called at the end of the process, in this block generally retry executing the task, with
|
* @param retryBlock called at the end of the process, in this block generally retry executing the task, with
|
||||||
* provided authUpdate
|
* provided authUpdate
|
||||||
* @return true if UIA is handled without error
|
* @return UiaResult if UIA handled, failed or cancelled
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
internal suspend fun handleUIA(failure: Throwable,
|
internal suspend fun handleUIA(failure: Throwable,
|
||||||
interceptor: UserInteractiveAuthInterceptor,
|
interceptor: UserInteractiveAuthInterceptor,
|
||||||
retryBlock: suspend (UIABaseAuth) -> Unit): Boolean {
|
retryBlock: suspend (UIABaseAuth) -> Unit): UiaResult {
|
||||||
Timber.d("## UIA: check error ${failure.message}")
|
Timber.d("## UIA: check error ${failure.message}")
|
||||||
val flowResponse = failure.toRegistrationFlowResponse()
|
val flowResponse = failure.toRegistrationFlowResponse()
|
||||||
?: return false.also {
|
?: return UiaResult.FAILURE.also {
|
||||||
Timber.d("## UIA: not a UIA error")
|
Timber.d("## UIA: not a UIA error")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,14 +53,19 @@ internal suspend fun handleUIA(failure: Throwable,
|
|||||||
interceptor.performStage(flowResponse, (failure as? Failure.ServerError)?.error?.code, continuation)
|
interceptor.performStage(flowResponse, (failure as? Failure.ServerError)?.error?.code, continuation)
|
||||||
}
|
}
|
||||||
} catch (failure2: Throwable) {
|
} catch (failure2: Throwable) {
|
||||||
Timber.w(failure2, "## UIA: failed to participate")
|
return if (failure2 is UiaCancelledException) {
|
||||||
return false
|
Timber.w(failure2, "## UIA: cancelled")
|
||||||
|
UiaResult.CANCELLED
|
||||||
|
} else {
|
||||||
|
Timber.w(failure2, "## UIA: failed to participate")
|
||||||
|
UiaResult.FAILURE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Timber.d("## UIA: updated auth")
|
Timber.d("## UIA: updated auth")
|
||||||
return try {
|
return try {
|
||||||
retryBlock(authUpdate)
|
retryBlock(authUpdate)
|
||||||
true
|
UiaResult.SUCCESS
|
||||||
} catch (failure3: Throwable) {
|
} catch (failure3: Throwable) {
|
||||||
handleUIA(failure3, interceptor, retryBlock)
|
handleUIA(failure3, interceptor, retryBlock)
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.crypto.tasks
|
|||||||
|
|
||||||
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
||||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
||||||
|
import org.matrix.android.sdk.api.session.uia.UiaResult
|
||||||
import org.matrix.android.sdk.internal.auth.registration.handleUIA
|
import org.matrix.android.sdk.internal.auth.registration.handleUIA
|
||||||
import org.matrix.android.sdk.internal.crypto.api.CryptoApi
|
import org.matrix.android.sdk.internal.crypto.api.CryptoApi
|
||||||
import org.matrix.android.sdk.internal.crypto.model.rest.DeleteDeviceParams
|
import org.matrix.android.sdk.internal.crypto.model.rest.DeleteDeviceParams
|
||||||
@ -47,13 +48,13 @@ internal class DefaultDeleteDeviceTask @Inject constructor(
|
|||||||
}
|
}
|
||||||
} catch (throwable: Throwable) {
|
} catch (throwable: Throwable) {
|
||||||
if (params.userInteractiveAuthInterceptor == null ||
|
if (params.userInteractiveAuthInterceptor == null ||
|
||||||
!handleUIA(
|
handleUIA(
|
||||||
failure = throwable,
|
failure = throwable,
|
||||||
interceptor = params.userInteractiveAuthInterceptor,
|
interceptor = params.userInteractiveAuthInterceptor,
|
||||||
retryBlock = { authUpdate ->
|
retryBlock = { authUpdate ->
|
||||||
execute(params.copy(userAuthParam = authUpdate))
|
execute(params.copy(userAuthParam = authUpdate))
|
||||||
}
|
}
|
||||||
)
|
) != UiaResult.SUCCESS
|
||||||
) {
|
) {
|
||||||
Timber.d("## UIA: propagate failure")
|
Timber.d("## UIA: propagate failure")
|
||||||
throw throwable
|
throw throwable
|
||||||
|
@ -20,6 +20,7 @@ import dagger.Lazy
|
|||||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
||||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey
|
import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey
|
||||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.KeyUsage
|
import org.matrix.android.sdk.api.session.crypto.crosssigning.KeyUsage
|
||||||
|
import org.matrix.android.sdk.api.session.uia.UiaResult
|
||||||
import org.matrix.android.sdk.api.util.toBase64NoPadding
|
import org.matrix.android.sdk.api.util.toBase64NoPadding
|
||||||
import org.matrix.android.sdk.internal.auth.registration.handleUIA
|
import org.matrix.android.sdk.internal.auth.registration.handleUIA
|
||||||
import org.matrix.android.sdk.internal.crypto.MXOlmDevice
|
import org.matrix.android.sdk.internal.crypto.MXOlmDevice
|
||||||
@ -126,13 +127,13 @@ internal class DefaultInitializeCrossSigningTask @Inject constructor(
|
|||||||
uploadSigningKeysTask.execute(uploadSigningKeysParams)
|
uploadSigningKeysTask.execute(uploadSigningKeysParams)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
if (params.interactiveAuthInterceptor == null ||
|
if (params.interactiveAuthInterceptor == null ||
|
||||||
!handleUIA(
|
handleUIA(
|
||||||
failure = failure,
|
failure = failure,
|
||||||
interceptor = params.interactiveAuthInterceptor,
|
interceptor = params.interactiveAuthInterceptor,
|
||||||
retryBlock = { authUpdate ->
|
retryBlock = { authUpdate ->
|
||||||
uploadSigningKeysTask.execute(uploadSigningKeysParams.copy(userAuthParam = authUpdate))
|
uploadSigningKeysTask.execute(uploadSigningKeysParams.copy(userAuthParam = authUpdate))
|
||||||
}
|
}
|
||||||
)
|
) != UiaResult.SUCCESS
|
||||||
) {
|
) {
|
||||||
Timber.d("## UIA: propagate failure")
|
Timber.d("## UIA: propagate failure")
|
||||||
throw failure
|
throw failure
|
||||||
|
@ -18,6 +18,8 @@ package org.matrix.android.sdk.internal.session.account
|
|||||||
|
|
||||||
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
||||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
||||||
|
import org.matrix.android.sdk.api.session.uia.UiaResult
|
||||||
|
import org.matrix.android.sdk.api.session.uia.exceptions.UiaCancelledException
|
||||||
import org.matrix.android.sdk.internal.auth.registration.handleUIA
|
import org.matrix.android.sdk.internal.auth.registration.handleUIA
|
||||||
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
|
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
|
||||||
import org.matrix.android.sdk.internal.network.executeRequest
|
import org.matrix.android.sdk.internal.network.executeRequest
|
||||||
@ -51,18 +53,24 @@ internal class DefaultDeactivateAccountTask @Inject constructor(
|
|||||||
}
|
}
|
||||||
true
|
true
|
||||||
} catch (throwable: Throwable) {
|
} catch (throwable: Throwable) {
|
||||||
if (!handleUIA(
|
when (handleUIA(
|
||||||
failure = throwable,
|
failure = throwable,
|
||||||
interceptor = params.userInteractiveAuthInterceptor,
|
interceptor = params.userInteractiveAuthInterceptor,
|
||||||
retryBlock = { authUpdate ->
|
retryBlock = { authUpdate ->
|
||||||
execute(params.copy(userAuthParam = authUpdate))
|
execute(params.copy(userAuthParam = authUpdate))
|
||||||
}
|
}
|
||||||
)
|
)) {
|
||||||
) {
|
UiaResult.SUCCESS -> {
|
||||||
Timber.d("## UIA: propagate failure")
|
false
|
||||||
throw throwable
|
}
|
||||||
} else {
|
UiaResult.FAILURE -> {
|
||||||
false
|
Timber.d("## UIA: propagate failure")
|
||||||
|
throw throwable
|
||||||
|
}
|
||||||
|
UiaResult.CANCELLED -> {
|
||||||
|
Timber.d("## UIA: cancelled")
|
||||||
|
throw UiaCancelledException()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
|||||||
import org.matrix.android.sdk.api.failure.Failure
|
import org.matrix.android.sdk.api.failure.Failure
|
||||||
import org.matrix.android.sdk.api.failure.toRegistrationFlowResponse
|
import org.matrix.android.sdk.api.failure.toRegistrationFlowResponse
|
||||||
import org.matrix.android.sdk.api.session.identity.ThreePid
|
import org.matrix.android.sdk.api.session.identity.ThreePid
|
||||||
|
import org.matrix.android.sdk.api.session.uia.UiaResult
|
||||||
import org.matrix.android.sdk.internal.auth.registration.handleUIA
|
import org.matrix.android.sdk.internal.auth.registration.handleUIA
|
||||||
import org.matrix.android.sdk.internal.database.model.PendingThreePidEntity
|
import org.matrix.android.sdk.internal.database.model.PendingThreePidEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.PendingThreePidEntityFields
|
import org.matrix.android.sdk.internal.database.model.PendingThreePidEntityFields
|
||||||
@ -72,13 +73,13 @@ internal class DefaultFinalizeAddingThreePidTask @Inject constructor(
|
|||||||
true
|
true
|
||||||
} catch (throwable: Throwable) {
|
} catch (throwable: Throwable) {
|
||||||
if (params.userInteractiveAuthInterceptor == null ||
|
if (params.userInteractiveAuthInterceptor == null ||
|
||||||
!handleUIA(
|
handleUIA(
|
||||||
failure = throwable,
|
failure = throwable,
|
||||||
interceptor = params.userInteractiveAuthInterceptor,
|
interceptor = params.userInteractiveAuthInterceptor,
|
||||||
retryBlock = { authUpdate ->
|
retryBlock = { authUpdate ->
|
||||||
execute(params.copy(userAuthParam = authUpdate))
|
execute(params.copy(userAuthParam = authUpdate))
|
||||||
}
|
}
|
||||||
)
|
) != UiaResult.SUCCESS
|
||||||
) {
|
) {
|
||||||
Timber.d("## UIA: propagate failure")
|
Timber.d("## UIA: propagate failure")
|
||||||
throw throwable.toRegistrationFlowResponse()
|
throw throwable.toRegistrationFlowResponse()
|
||||||
|
@ -34,6 +34,7 @@ import im.vector.app.features.analytics.plan.MobileScreen
|
|||||||
import im.vector.app.features.auth.ReAuthActivity
|
import im.vector.app.features.auth.ReAuthActivity
|
||||||
import im.vector.app.features.settings.VectorSettingsActivity
|
import im.vector.app.features.settings.VectorSettingsActivity
|
||||||
import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
|
import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
|
||||||
|
import org.matrix.android.sdk.api.session.uia.exceptions.UiaCancelledException
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class DeactivateAccountFragment @Inject constructor() : VectorBaseFragment<FragmentDeactivateAccountBinding>() {
|
class DeactivateAccountFragment @Inject constructor() : VectorBaseFragment<FragmentDeactivateAccountBinding>() {
|
||||||
@ -114,7 +115,9 @@ class DeactivateAccountFragment @Inject constructor() : VectorBaseFragment<Fragm
|
|||||||
is DeactivateAccountViewEvents.OtherFailure -> {
|
is DeactivateAccountViewEvents.OtherFailure -> {
|
||||||
settingsActivity?.ignoreInvalidTokenError = false
|
settingsActivity?.ignoreInvalidTokenError = false
|
||||||
dismissLoadingDialog()
|
dismissLoadingDialog()
|
||||||
displayErrorDialog(it.throwable)
|
if (it.throwable !is UiaCancelledException) {
|
||||||
|
displayErrorDialog(it.throwable)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DeactivateAccountViewEvents.Done -> {
|
DeactivateAccountViewEvents.Done -> {
|
||||||
MainActivity.restartApp(requireActivity(), MainActivityArgs(clearCredentials = true, isAccountDeactivated = true))
|
MainActivity.restartApp(requireActivity(), MainActivityArgs(clearCredentials = true, isAccountDeactivated = true))
|
||||||
@ -123,7 +126,8 @@ class DeactivateAccountFragment @Inject constructor() : VectorBaseFragment<Fragm
|
|||||||
ReAuthActivity.newIntent(requireContext(),
|
ReAuthActivity.newIntent(requireContext(),
|
||||||
it.registrationFlowResponse,
|
it.registrationFlowResponse,
|
||||||
it.lastErrorCode,
|
it.lastErrorCode,
|
||||||
getString(R.string.deactivate_account_title)).let { intent ->
|
getString(R.string.deactivate_account_title)
|
||||||
|
).let { intent ->
|
||||||
reAuthActivityResultLauncher.launch(intent)
|
reAuthActivityResultLauncher.launch(intent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
|
|||||||
import org.matrix.android.sdk.api.failure.isInvalidUIAAuth
|
import org.matrix.android.sdk.api.failure.isInvalidUIAAuth
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth
|
import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth
|
||||||
|
import org.matrix.android.sdk.api.session.uia.exceptions.UiaCancelledException
|
||||||
import org.matrix.android.sdk.api.util.fromBase64
|
import org.matrix.android.sdk.api.util.fromBase64
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import kotlin.coroutines.Continuation
|
import kotlin.coroutines.Continuation
|
||||||
@ -59,6 +60,7 @@ class DeactivateAccountViewModel @AssistedInject constructor(@Assisted private v
|
|||||||
is DeactivateAccountAction.DeactivateAccount -> handleDeactivateAccount(action)
|
is DeactivateAccountAction.DeactivateAccount -> handleDeactivateAccount(action)
|
||||||
DeactivateAccountAction.SsoAuthDone -> {
|
DeactivateAccountAction.SsoAuthDone -> {
|
||||||
Timber.d("## UIA - FallBack success")
|
Timber.d("## UIA - FallBack success")
|
||||||
|
_viewEvents.post(DeactivateAccountViewEvents.Loading())
|
||||||
if (pendingAuth != null) {
|
if (pendingAuth != null) {
|
||||||
uiaContinuation?.resume(pendingAuth!!)
|
uiaContinuation?.resume(pendingAuth!!)
|
||||||
} else {
|
} else {
|
||||||
@ -66,6 +68,7 @@ class DeactivateAccountViewModel @AssistedInject constructor(@Assisted private v
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
is DeactivateAccountAction.PasswordAuthDone -> {
|
is DeactivateAccountAction.PasswordAuthDone -> {
|
||||||
|
_viewEvents.post(DeactivateAccountViewEvents.Loading())
|
||||||
val decryptedPass = session.secureStorageService()
|
val decryptedPass = session.secureStorageService()
|
||||||
.loadSecureSecret<String>(action.password.fromBase64().inputStream(), ReAuthActivity.DEFAULT_RESULT_KEYSTORE_ALIAS)
|
.loadSecureSecret<String>(action.password.fromBase64().inputStream(), ReAuthActivity.DEFAULT_RESULT_KEYSTORE_ALIAS)
|
||||||
uiaContinuation?.resume(
|
uiaContinuation?.resume(
|
||||||
@ -78,7 +81,7 @@ class DeactivateAccountViewModel @AssistedInject constructor(@Assisted private v
|
|||||||
}
|
}
|
||||||
DeactivateAccountAction.ReAuthCancelled -> {
|
DeactivateAccountAction.ReAuthCancelled -> {
|
||||||
Timber.d("## UIA - Reauth cancelled")
|
Timber.d("## UIA - Reauth cancelled")
|
||||||
uiaContinuation?.resumeWithException(Exception())
|
uiaContinuation?.resumeWithException(UiaCancelledException())
|
||||||
uiaContinuation = null
|
uiaContinuation = null
|
||||||
pendingAuth = null
|
pendingAuth = null
|
||||||
}
|
}
|
||||||
@ -101,7 +104,7 @@ class DeactivateAccountViewModel @AssistedInject constructor(@Assisted private v
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
DeactivateAccountViewEvents.Done
|
DeactivateAccountViewEvents.Done
|
||||||
} catch (failure: Exception) {
|
} catch (failure: Throwable) {
|
||||||
if (failure.isInvalidUIAAuth()) {
|
if (failure.isInvalidUIAAuth()) {
|
||||||
DeactivateAccountViewEvents.InvalidAuth
|
DeactivateAccountViewEvents.InvalidAuth
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user