mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-18 04:50:08 +03:00
Mutualize pending auth handling
This commit is contained in:
parent
6c79aae3aa
commit
892fd4445c
6 changed files with 106 additions and 179 deletions
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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 im.vector.app.features.auth
|
||||||
|
|
||||||
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
|
import org.matrix.android.sdk.api.Matrix
|
||||||
|
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
||||||
|
import org.matrix.android.sdk.api.auth.UserPasswordAuth
|
||||||
|
import org.matrix.android.sdk.api.util.fromBase64
|
||||||
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.coroutines.Continuation
|
||||||
|
import kotlin.coroutines.resume
|
||||||
|
import kotlin.coroutines.resumeWithException
|
||||||
|
|
||||||
|
class PendingAuthHandler @Inject constructor(
|
||||||
|
private val matrix: Matrix,
|
||||||
|
private val activeSessionHolder: ActiveSessionHolder,
|
||||||
|
) {
|
||||||
|
|
||||||
|
var uiaContinuation: Continuation<UIABaseAuth>? = null
|
||||||
|
var pendingAuth: UIABaseAuth? = null
|
||||||
|
|
||||||
|
fun ssoAuthDone() {
|
||||||
|
Timber.d("ssoAuthDone $pendingAuth , continuation: $uiaContinuation")
|
||||||
|
pendingAuth?.let {
|
||||||
|
uiaContinuation?.resume(it)
|
||||||
|
} ?: run {
|
||||||
|
uiaContinuation?.resumeWithException(IllegalArgumentException())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun passwordAuthDone(password: String) {
|
||||||
|
Timber.d("passwordAuthDone")
|
||||||
|
val decryptedPass = matrix.secureStorageService()
|
||||||
|
.loadSecureSecret<String>(
|
||||||
|
inputStream = password.fromBase64().inputStream(),
|
||||||
|
keyAlias = ReAuthActivity.DEFAULT_RESULT_KEYSTORE_ALIAS
|
||||||
|
)
|
||||||
|
uiaContinuation?.resume(
|
||||||
|
UserPasswordAuth(
|
||||||
|
session = pendingAuth?.session,
|
||||||
|
password = decryptedPass,
|
||||||
|
user = activeSessionHolder.getActiveSession().myUserId
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reAuthCancelled() {
|
||||||
|
Timber.d("reAuthCancelled")
|
||||||
|
uiaContinuation?.resumeWithException(Exception())
|
||||||
|
uiaContinuation = null
|
||||||
|
pendingAuth = null
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,14 +32,13 @@ import im.vector.app.core.error.ErrorFormatter
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.core.platform.WaitingViewData
|
import im.vector.app.core.platform.WaitingViewData
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.features.auth.ReAuthActivity
|
import im.vector.app.features.auth.PendingAuthHandler
|
||||||
import im.vector.app.features.raw.wellknown.SecureBackupMethod
|
import im.vector.app.features.raw.wellknown.SecureBackupMethod
|
||||||
import im.vector.app.features.raw.wellknown.getElementWellknown
|
import im.vector.app.features.raw.wellknown.getElementWellknown
|
||||||
import im.vector.app.features.raw.wellknown.isSecureBackupRequired
|
import im.vector.app.features.raw.wellknown.isSecureBackupRequired
|
||||||
import im.vector.app.features.raw.wellknown.secureBackupMethod
|
import im.vector.app.features.raw.wellknown.secureBackupMethod
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.Matrix
|
|
||||||
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.auth.UserPasswordAuth
|
import org.matrix.android.sdk.api.auth.UserPasswordAuth
|
||||||
|
@ -57,10 +56,8 @@ import org.matrix.android.sdk.api.session.crypto.keysbackup.toKeysVersionResult
|
||||||
import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec
|
import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec
|
||||||
import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth
|
import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth
|
||||||
import org.matrix.android.sdk.api.util.awaitCallback
|
import org.matrix.android.sdk.api.util.awaitCallback
|
||||||
import org.matrix.android.sdk.api.util.fromBase64
|
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import kotlin.coroutines.Continuation
|
import kotlin.coroutines.Continuation
|
||||||
import kotlin.coroutines.resume
|
|
||||||
import kotlin.coroutines.resumeWithException
|
import kotlin.coroutines.resumeWithException
|
||||||
|
|
||||||
class BootstrapSharedViewModel @AssistedInject constructor(
|
class BootstrapSharedViewModel @AssistedInject constructor(
|
||||||
|
@ -71,7 +68,7 @@ class BootstrapSharedViewModel @AssistedInject constructor(
|
||||||
private val rawService: RawService,
|
private val rawService: RawService,
|
||||||
private val bootstrapTask: BootstrapCrossSigningTask,
|
private val bootstrapTask: BootstrapCrossSigningTask,
|
||||||
private val migrationTask: BackupToQuadSMigrationTask,
|
private val migrationTask: BackupToQuadSMigrationTask,
|
||||||
private val matrix: Matrix,
|
private val pendingAuthHandler: PendingAuthHandler,
|
||||||
) : VectorViewModel<BootstrapViewState, BootstrapActions, BootstrapViewEvents>(initialState) {
|
) : VectorViewModel<BootstrapViewState, BootstrapActions, BootstrapViewEvents>(initialState) {
|
||||||
|
|
||||||
private var doesKeyBackupExist: Boolean = false
|
private var doesKeyBackupExist: Boolean = false
|
||||||
|
@ -85,11 +82,6 @@ class BootstrapSharedViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
companion object : MavericksViewModelFactory<BootstrapSharedViewModel, BootstrapViewState> by hiltMavericksViewModelFactory()
|
companion object : MavericksViewModelFactory<BootstrapSharedViewModel, BootstrapViewState> by hiltMavericksViewModelFactory()
|
||||||
|
|
||||||
// private var _pendingSession: String? = null
|
|
||||||
|
|
||||||
var uiaContinuation: Continuation<UIABaseAuth>? = null
|
|
||||||
var pendingAuth: UIABaseAuth? = null
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
||||||
setState {
|
setState {
|
||||||
|
@ -272,21 +264,10 @@ class BootstrapSharedViewModel @AssistedInject constructor(
|
||||||
is BootstrapActions.DoMigrateWithRecoveryKey -> {
|
is BootstrapActions.DoMigrateWithRecoveryKey -> {
|
||||||
startMigrationFlow(state.step, null, action.recoveryKey)
|
startMigrationFlow(state.step, null, action.recoveryKey)
|
||||||
}
|
}
|
||||||
BootstrapActions.SsoAuthDone -> {
|
BootstrapActions.SsoAuthDone -> pendingAuthHandler.ssoAuthDone()
|
||||||
uiaContinuation?.resume(DefaultBaseAuth(session = pendingAuth?.session ?: ""))
|
is BootstrapActions.PasswordAuthDone -> pendingAuthHandler.passwordAuthDone(action.password)
|
||||||
}
|
|
||||||
is BootstrapActions.PasswordAuthDone -> {
|
|
||||||
val decryptedPass = matrix.secureStorageService()
|
|
||||||
.loadSecureSecret<String>(action.password.fromBase64().inputStream(), ReAuthActivity.DEFAULT_RESULT_KEYSTORE_ALIAS)
|
|
||||||
uiaContinuation?.resume(
|
|
||||||
UserPasswordAuth(
|
|
||||||
session = pendingAuth?.session,
|
|
||||||
password = decryptedPass,
|
|
||||||
user = session.myUserId
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
BootstrapActions.ReAuthCancelled -> {
|
BootstrapActions.ReAuthCancelled -> {
|
||||||
|
pendingAuthHandler.reAuthCancelled()
|
||||||
setState {
|
setState {
|
||||||
copy(step = BootstrapStep.AccountReAuth(stringProvider.getString(R.string.authentication_error)))
|
copy(step = BootstrapStep.AccountReAuth(stringProvider.getString(R.string.authentication_error)))
|
||||||
}
|
}
|
||||||
|
@ -402,13 +383,13 @@ class BootstrapSharedViewModel @AssistedInject constructor(
|
||||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
||||||
when (flowResponse.nextUncompletedStage()) {
|
when (flowResponse.nextUncompletedStage()) {
|
||||||
LoginFlowTypes.PASSWORD -> {
|
LoginFlowTypes.PASSWORD -> {
|
||||||
pendingAuth = UserPasswordAuth(
|
pendingAuthHandler.pendingAuth = UserPasswordAuth(
|
||||||
// Note that _pendingSession may or may not be null, this is OK, it will be managed by the task
|
// Note that _pendingSession may or may not be null, this is OK, it will be managed by the task
|
||||||
session = flowResponse.session,
|
session = flowResponse.session,
|
||||||
user = session.myUserId,
|
user = session.myUserId,
|
||||||
password = null
|
password = null
|
||||||
)
|
)
|
||||||
uiaContinuation = promise
|
pendingAuthHandler.uiaContinuation = promise
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
step = BootstrapStep.AccountReAuth()
|
step = BootstrapStep.AccountReAuth()
|
||||||
|
@ -417,8 +398,8 @@ class BootstrapSharedViewModel @AssistedInject constructor(
|
||||||
_viewEvents.post(BootstrapViewEvents.RequestReAuth(flowResponse, errCode))
|
_viewEvents.post(BootstrapViewEvents.RequestReAuth(flowResponse, errCode))
|
||||||
}
|
}
|
||||||
LoginFlowTypes.SSO -> {
|
LoginFlowTypes.SSO -> {
|
||||||
pendingAuth = DefaultBaseAuth(flowResponse.session)
|
pendingAuthHandler.pendingAuth = DefaultBaseAuth(flowResponse.session)
|
||||||
uiaContinuation = promise
|
pendingAuthHandler.uiaContinuation = promise
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
step = BootstrapStep.AccountReAuth()
|
step = BootstrapStep.AccountReAuth()
|
||||||
|
|
|
@ -23,22 +23,15 @@ import dagger.assisted.AssistedInject
|
||||||
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.features.auth.ReAuthActivity
|
import im.vector.app.features.auth.PendingAuthHandler
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.Matrix
|
|
||||||
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.auth.UserPasswordAuth
|
|
||||||
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
|
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 timber.log.Timber
|
|
||||||
import kotlin.coroutines.Continuation
|
import kotlin.coroutines.Continuation
|
||||||
import kotlin.coroutines.resume
|
|
||||||
import kotlin.coroutines.resumeWithException
|
|
||||||
|
|
||||||
data class DeactivateAccountViewState(
|
data class DeactivateAccountViewState(
|
||||||
val dummy: Boolean = false
|
val dummy: Boolean = false
|
||||||
|
@ -47,7 +40,7 @@ data class DeactivateAccountViewState(
|
||||||
class DeactivateAccountViewModel @AssistedInject constructor(
|
class DeactivateAccountViewModel @AssistedInject constructor(
|
||||||
@Assisted private val initialState: DeactivateAccountViewState,
|
@Assisted private val initialState: DeactivateAccountViewState,
|
||||||
private val session: Session,
|
private val session: Session,
|
||||||
private val matrix: Matrix,
|
private val pendingAuthHandler: PendingAuthHandler,
|
||||||
) :
|
) :
|
||||||
VectorViewModel<DeactivateAccountViewState, DeactivateAccountAction, DeactivateAccountViewEvents>(initialState) {
|
VectorViewModel<DeactivateAccountViewState, DeactivateAccountAction, DeactivateAccountViewEvents>(initialState) {
|
||||||
|
|
||||||
|
@ -56,39 +49,15 @@ class DeactivateAccountViewModel @AssistedInject constructor(
|
||||||
override fun create(initialState: DeactivateAccountViewState): DeactivateAccountViewModel
|
override fun create(initialState: DeactivateAccountViewState): DeactivateAccountViewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
var uiaContinuation: Continuation<UIABaseAuth>? = null
|
|
||||||
var pendingAuth: UIABaseAuth? = null
|
|
||||||
|
|
||||||
override fun handle(action: DeactivateAccountAction) {
|
override fun handle(action: DeactivateAccountAction) {
|
||||||
when (action) {
|
when (action) {
|
||||||
is DeactivateAccountAction.DeactivateAccount -> handleDeactivateAccount(action)
|
is DeactivateAccountAction.DeactivateAccount -> handleDeactivateAccount(action)
|
||||||
DeactivateAccountAction.SsoAuthDone -> {
|
DeactivateAccountAction.SsoAuthDone -> pendingAuthHandler.ssoAuthDone()
|
||||||
Timber.d("## UIA - FallBack success")
|
|
||||||
_viewEvents.post(DeactivateAccountViewEvents.Loading())
|
|
||||||
if (pendingAuth != null) {
|
|
||||||
uiaContinuation?.resume(pendingAuth!!)
|
|
||||||
} else {
|
|
||||||
uiaContinuation?.resumeWithException(IllegalArgumentException())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is DeactivateAccountAction.PasswordAuthDone -> {
|
is DeactivateAccountAction.PasswordAuthDone -> {
|
||||||
_viewEvents.post(DeactivateAccountViewEvents.Loading())
|
_viewEvents.post(DeactivateAccountViewEvents.Loading())
|
||||||
val decryptedPass = matrix.secureStorageService()
|
pendingAuthHandler.passwordAuthDone(action.password)
|
||||||
.loadSecureSecret<String>(action.password.fromBase64().inputStream(), ReAuthActivity.DEFAULT_RESULT_KEYSTORE_ALIAS)
|
|
||||||
uiaContinuation?.resume(
|
|
||||||
UserPasswordAuth(
|
|
||||||
session = pendingAuth?.session,
|
|
||||||
password = decryptedPass,
|
|
||||||
user = session.myUserId
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
DeactivateAccountAction.ReAuthCancelled -> {
|
|
||||||
Timber.d("## UIA - Reauth cancelled")
|
|
||||||
uiaContinuation?.resumeWithException(UiaCancelledException())
|
|
||||||
uiaContinuation = null
|
|
||||||
pendingAuth = null
|
|
||||||
}
|
}
|
||||||
|
DeactivateAccountAction.ReAuthCancelled -> pendingAuthHandler.reAuthCancelled()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,8 +71,8 @@ class DeactivateAccountViewModel @AssistedInject constructor(
|
||||||
object : UserInteractiveAuthInterceptor {
|
object : UserInteractiveAuthInterceptor {
|
||||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
||||||
_viewEvents.post(DeactivateAccountViewEvents.RequestReAuth(flowResponse, errCode))
|
_viewEvents.post(DeactivateAccountViewEvents.RequestReAuth(flowResponse, errCode))
|
||||||
pendingAuth = DefaultBaseAuth(session = flowResponse.session)
|
pendingAuthHandler.pendingAuth = DefaultBaseAuth(session = flowResponse.session)
|
||||||
uiaContinuation = promise
|
pendingAuthHandler.uiaContinuation = promise
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -24,12 +24,11 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.features.auth.ReAuthActivity
|
import im.vector.app.features.auth.PendingAuthHandler
|
||||||
import im.vector.app.features.login.ReAuthHelper
|
import im.vector.app.features.login.ReAuthHelper
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.Matrix
|
|
||||||
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.auth.UserPasswordAuth
|
import org.matrix.android.sdk.api.auth.UserPasswordAuth
|
||||||
|
@ -40,19 +39,17 @@ import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.isVerified
|
import org.matrix.android.sdk.api.session.crypto.crosssigning.isVerified
|
||||||
import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth
|
import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth
|
||||||
import org.matrix.android.sdk.api.util.awaitCallback
|
import org.matrix.android.sdk.api.util.awaitCallback
|
||||||
import org.matrix.android.sdk.api.util.fromBase64
|
|
||||||
import org.matrix.android.sdk.flow.flow
|
import org.matrix.android.sdk.flow.flow
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import kotlin.coroutines.Continuation
|
import kotlin.coroutines.Continuation
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
import kotlin.coroutines.resumeWithException
|
|
||||||
|
|
||||||
class CrossSigningSettingsViewModel @AssistedInject constructor(
|
class CrossSigningSettingsViewModel @AssistedInject constructor(
|
||||||
@Assisted private val initialState: CrossSigningSettingsViewState,
|
@Assisted private val initialState: CrossSigningSettingsViewState,
|
||||||
private val session: Session,
|
private val session: Session,
|
||||||
private val reAuthHelper: ReAuthHelper,
|
private val reAuthHelper: ReAuthHelper,
|
||||||
private val stringProvider: StringProvider,
|
private val stringProvider: StringProvider,
|
||||||
private val matrix: Matrix,
|
private val pendingAuthHandler: PendingAuthHandler,
|
||||||
) : VectorViewModel<CrossSigningSettingsViewState, CrossSigningSettingsAction, CrossSigningSettingsViewEvents>(initialState) {
|
) : VectorViewModel<CrossSigningSettingsViewState, CrossSigningSettingsAction, CrossSigningSettingsViewEvents>(initialState) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -77,9 +74,6 @@ class CrossSigningSettingsViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var uiaContinuation: Continuation<UIABaseAuth>? = null
|
|
||||||
var pendingAuth: UIABaseAuth? = null
|
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory : MavericksAssistedViewModelFactory<CrossSigningSettingsViewModel, CrossSigningSettingsViewState> {
|
interface Factory : MavericksAssistedViewModelFactory<CrossSigningSettingsViewModel, CrossSigningSettingsViewState> {
|
||||||
override fun create(initialState: CrossSigningSettingsViewState): CrossSigningSettingsViewModel
|
override fun create(initialState: CrossSigningSettingsViewState): CrossSigningSettingsViewModel
|
||||||
|
@ -110,8 +104,8 @@ class CrossSigningSettingsViewModel @AssistedInject constructor(
|
||||||
} else {
|
} else {
|
||||||
Timber.d("## UIA : initializeCrossSigning UIA > start reauth activity")
|
Timber.d("## UIA : initializeCrossSigning UIA > start reauth activity")
|
||||||
_viewEvents.post(CrossSigningSettingsViewEvents.RequestReAuth(flowResponse, errCode))
|
_viewEvents.post(CrossSigningSettingsViewEvents.RequestReAuth(flowResponse, errCode))
|
||||||
pendingAuth = DefaultBaseAuth(session = flowResponse.session)
|
pendingAuthHandler.pendingAuth = DefaultBaseAuth(session = flowResponse.session)
|
||||||
uiaContinuation = promise
|
pendingAuthHandler.uiaContinuation = promise
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, it
|
}, it
|
||||||
|
@ -125,31 +119,11 @@ class CrossSigningSettingsViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
Unit
|
Unit
|
||||||
}
|
}
|
||||||
is CrossSigningSettingsAction.SsoAuthDone -> {
|
is CrossSigningSettingsAction.SsoAuthDone -> pendingAuthHandler.ssoAuthDone()
|
||||||
Timber.d("## UIA - FallBack success")
|
is CrossSigningSettingsAction.PasswordAuthDone -> pendingAuthHandler.passwordAuthDone(action.password)
|
||||||
if (pendingAuth != null) {
|
|
||||||
uiaContinuation?.resume(pendingAuth!!)
|
|
||||||
} else {
|
|
||||||
uiaContinuation?.resumeWithException(IllegalArgumentException())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is CrossSigningSettingsAction.PasswordAuthDone -> {
|
|
||||||
val decryptedPass = matrix.secureStorageService()
|
|
||||||
.loadSecureSecret<String>(action.password.fromBase64().inputStream(), ReAuthActivity.DEFAULT_RESULT_KEYSTORE_ALIAS)
|
|
||||||
uiaContinuation?.resume(
|
|
||||||
UserPasswordAuth(
|
|
||||||
session = pendingAuth?.session,
|
|
||||||
password = decryptedPass,
|
|
||||||
user = session.myUserId
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
CrossSigningSettingsAction.ReAuthCancelled -> {
|
CrossSigningSettingsAction.ReAuthCancelled -> {
|
||||||
Timber.d("## UIA - Reauth cancelled")
|
|
||||||
_viewEvents.post(CrossSigningSettingsViewEvents.HideModalWaitingView)
|
_viewEvents.post(CrossSigningSettingsViewEvents.HideModalWaitingView)
|
||||||
uiaContinuation?.resumeWithException(Exception())
|
pendingAuthHandler.reAuthCancelled()
|
||||||
uiaContinuation = null
|
|
||||||
pendingAuth = null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.core.utils.PublishDataSource
|
import im.vector.app.core.utils.PublishDataSource
|
||||||
import im.vector.app.features.auth.ReAuthActivity
|
import im.vector.app.features.auth.PendingAuthHandler
|
||||||
import im.vector.app.features.login.ReAuthHelper
|
import im.vector.app.features.login.ReAuthHelper
|
||||||
import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase
|
import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase
|
||||||
import im.vector.app.features.settings.devices.v2.verification.GetEncryptionTrustLevelForDeviceUseCase
|
import im.vector.app.features.settings.devices.v2.verification.GetEncryptionTrustLevelForDeviceUseCase
|
||||||
|
@ -45,7 +45,6 @@ import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.sample
|
import kotlinx.coroutines.flow.sample
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.Matrix
|
|
||||||
import org.matrix.android.sdk.api.MatrixCallback
|
import org.matrix.android.sdk.api.MatrixCallback
|
||||||
import org.matrix.android.sdk.api.NoOpMatrixCallback
|
import org.matrix.android.sdk.api.NoOpMatrixCallback
|
||||||
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
||||||
|
@ -67,13 +66,11 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransa
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState
|
||||||
import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth
|
import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth
|
||||||
import org.matrix.android.sdk.api.util.awaitCallback
|
import org.matrix.android.sdk.api.util.awaitCallback
|
||||||
import org.matrix.android.sdk.api.util.fromBase64
|
|
||||||
import org.matrix.android.sdk.flow.flow
|
import org.matrix.android.sdk.flow.flow
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.net.ssl.HttpsURLConnection
|
import javax.net.ssl.HttpsURLConnection
|
||||||
import kotlin.coroutines.Continuation
|
import kotlin.coroutines.Continuation
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
import kotlin.coroutines.resumeWithException
|
|
||||||
|
|
||||||
data class DevicesViewState(
|
data class DevicesViewState(
|
||||||
val myDeviceId: String = "",
|
val myDeviceId: String = "",
|
||||||
|
@ -100,15 +97,12 @@ class DevicesViewModel @AssistedInject constructor(
|
||||||
private val session: Session,
|
private val session: Session,
|
||||||
private val reAuthHelper: ReAuthHelper,
|
private val reAuthHelper: ReAuthHelper,
|
||||||
private val stringProvider: StringProvider,
|
private val stringProvider: StringProvider,
|
||||||
private val matrix: Matrix,
|
private val pendingAuthHandler: PendingAuthHandler,
|
||||||
private val checkIfSessionIsInactiveUseCase: CheckIfSessionIsInactiveUseCase,
|
private val checkIfSessionIsInactiveUseCase: CheckIfSessionIsInactiveUseCase,
|
||||||
getCurrentSessionCrossSigningInfoUseCase: GetCurrentSessionCrossSigningInfoUseCase,
|
getCurrentSessionCrossSigningInfoUseCase: GetCurrentSessionCrossSigningInfoUseCase,
|
||||||
private val getEncryptionTrustLevelForDeviceUseCase: GetEncryptionTrustLevelForDeviceUseCase,
|
private val getEncryptionTrustLevelForDeviceUseCase: GetEncryptionTrustLevelForDeviceUseCase,
|
||||||
) : VectorViewModel<DevicesViewState, DevicesAction, DevicesViewEvents>(initialState), VerificationService.Listener {
|
) : VectorViewModel<DevicesViewState, DevicesAction, DevicesViewEvents>(initialState), VerificationService.Listener {
|
||||||
|
|
||||||
var uiaContinuation: Continuation<UIABaseAuth>? = null
|
|
||||||
var pendingAuth: UIABaseAuth? = null
|
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory : MavericksAssistedViewModelFactory<DevicesViewModel, DevicesViewState> {
|
interface Factory : MavericksAssistedViewModelFactory<DevicesViewModel, DevicesViewState> {
|
||||||
override fun create(initialState: DevicesViewState): DevicesViewModel
|
override fun create(initialState: DevicesViewState): DevicesViewModel
|
||||||
|
@ -232,37 +226,9 @@ class DevicesViewModel @AssistedInject constructor(
|
||||||
is DevicesAction.CompleteSecurity -> handleCompleteSecurity()
|
is DevicesAction.CompleteSecurity -> handleCompleteSecurity()
|
||||||
is DevicesAction.MarkAsManuallyVerified -> handleVerifyManually(action)
|
is DevicesAction.MarkAsManuallyVerified -> handleVerifyManually(action)
|
||||||
is DevicesAction.VerifyMyDeviceManually -> handleShowDeviceCryptoInfo(action)
|
is DevicesAction.VerifyMyDeviceManually -> handleShowDeviceCryptoInfo(action)
|
||||||
is DevicesAction.SsoAuthDone -> {
|
is DevicesAction.SsoAuthDone -> pendingAuthHandler.ssoAuthDone()
|
||||||
// we should use token based auth
|
is DevicesAction.PasswordAuthDone -> pendingAuthHandler.passwordAuthDone(action.password)
|
||||||
// _viewEvents.post(CrossSigningSettingsViewEvents.ShowModalWaitingView(null))
|
DevicesAction.ReAuthCancelled -> pendingAuthHandler.reAuthCancelled()
|
||||||
// will release the interactive auth interceptor
|
|
||||||
Timber.d("## UIA - FallBack success $pendingAuth , continuation: $uiaContinuation")
|
|
||||||
if (pendingAuth != null) {
|
|
||||||
uiaContinuation?.resume(pendingAuth!!)
|
|
||||||
} else {
|
|
||||||
uiaContinuation?.resumeWithException(IllegalArgumentException())
|
|
||||||
}
|
|
||||||
Unit
|
|
||||||
}
|
|
||||||
is DevicesAction.PasswordAuthDone -> {
|
|
||||||
val decryptedPass = matrix.secureStorageService()
|
|
||||||
.loadSecureSecret<String>(action.password.fromBase64().inputStream(), ReAuthActivity.DEFAULT_RESULT_KEYSTORE_ALIAS)
|
|
||||||
uiaContinuation?.resume(
|
|
||||||
UserPasswordAuth(
|
|
||||||
session = pendingAuth?.session,
|
|
||||||
password = decryptedPass,
|
|
||||||
user = session.myUserId
|
|
||||||
)
|
|
||||||
)
|
|
||||||
Unit
|
|
||||||
}
|
|
||||||
DevicesAction.ReAuthCancelled -> {
|
|
||||||
Timber.d("## UIA - Reauth cancelled")
|
|
||||||
// _viewEvents.post(DevicesViewEvents.Loading)
|
|
||||||
uiaContinuation?.resumeWithException(Exception())
|
|
||||||
uiaContinuation = null
|
|
||||||
pendingAuth = null
|
|
||||||
}
|
|
||||||
DevicesAction.ResetSecurity -> _viewEvents.post(DevicesViewEvents.PromptResetSecrets)
|
DevicesAction.ResetSecurity -> _viewEvents.post(DevicesViewEvents.PromptResetSecrets)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -371,8 +337,8 @@ class DevicesViewModel @AssistedInject constructor(
|
||||||
} else {
|
} else {
|
||||||
Timber.d("## UIA : deleteDevice UIA > start reauth activity")
|
Timber.d("## UIA : deleteDevice UIA > start reauth activity")
|
||||||
_viewEvents.post(DevicesViewEvents.RequestReAuth(flowResponse, errCode))
|
_viewEvents.post(DevicesViewEvents.RequestReAuth(flowResponse, errCode))
|
||||||
pendingAuth = DefaultBaseAuth(session = flowResponse.session)
|
pendingAuthHandler.pendingAuth = DefaultBaseAuth(session = flowResponse.session)
|
||||||
uiaContinuation = promise
|
pendingAuthHandler.uiaContinuation = promise
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, it)
|
}, it)
|
||||||
|
|
|
@ -28,33 +28,26 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.core.utils.ReadOnceTrue
|
import im.vector.app.core.utils.ReadOnceTrue
|
||||||
import im.vector.app.features.auth.ReAuthActivity
|
import im.vector.app.features.auth.PendingAuthHandler
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.Matrix
|
|
||||||
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.auth.UserPasswordAuth
|
|
||||||
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
|
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
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.DefaultBaseAuth
|
import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth
|
||||||
import org.matrix.android.sdk.api.util.fromBase64
|
|
||||||
import org.matrix.android.sdk.flow.flow
|
import org.matrix.android.sdk.flow.flow
|
||||||
import timber.log.Timber
|
|
||||||
import kotlin.coroutines.Continuation
|
import kotlin.coroutines.Continuation
|
||||||
import kotlin.coroutines.resume
|
|
||||||
import kotlin.coroutines.resumeWithException
|
|
||||||
|
|
||||||
class ThreePidsSettingsViewModel @AssistedInject constructor(
|
class ThreePidsSettingsViewModel @AssistedInject constructor(
|
||||||
@Assisted initialState: ThreePidsSettingsViewState,
|
@Assisted initialState: ThreePidsSettingsViewState,
|
||||||
private val session: Session,
|
private val session: Session,
|
||||||
private val stringProvider: StringProvider,
|
private val stringProvider: StringProvider,
|
||||||
private val matrix: Matrix,
|
private val pendingAuthHandler: PendingAuthHandler,
|
||||||
) : VectorViewModel<ThreePidsSettingsViewState, ThreePidsSettingsAction, ThreePidsSettingsViewEvents>(initialState) {
|
) : VectorViewModel<ThreePidsSettingsViewState, ThreePidsSettingsAction, ThreePidsSettingsViewEvents>(initialState) {
|
||||||
|
|
||||||
// UIA session
|
// UIA session
|
||||||
private var pendingThreePid: ThreePid? = null
|
private var pendingThreePid: ThreePid? = null
|
||||||
// private var pendingSession: String? = null
|
|
||||||
|
|
||||||
private suspend fun loadingSuspendable(block: suspend () -> Unit) {
|
private suspend fun loadingSuspendable(block: suspend () -> Unit) {
|
||||||
runCatching { block() }
|
runCatching { block() }
|
||||||
|
@ -126,42 +119,17 @@ class ThreePidsSettingsViewModel @AssistedInject constructor(
|
||||||
is ThreePidsSettingsAction.CancelThreePid -> handleCancelThreePid(action)
|
is ThreePidsSettingsAction.CancelThreePid -> handleCancelThreePid(action)
|
||||||
is ThreePidsSettingsAction.DeleteThreePid -> handleDeleteThreePid(action)
|
is ThreePidsSettingsAction.DeleteThreePid -> handleDeleteThreePid(action)
|
||||||
is ThreePidsSettingsAction.ChangeUiState -> handleChangeUiState(action)
|
is ThreePidsSettingsAction.ChangeUiState -> handleChangeUiState(action)
|
||||||
ThreePidsSettingsAction.SsoAuthDone -> {
|
ThreePidsSettingsAction.SsoAuthDone -> pendingAuthHandler.ssoAuthDone()
|
||||||
Timber.d("## UIA - FallBack success")
|
is ThreePidsSettingsAction.PasswordAuthDone -> pendingAuthHandler.passwordAuthDone(action.password)
|
||||||
if (pendingAuth != null) {
|
ThreePidsSettingsAction.ReAuthCancelled -> pendingAuthHandler.reAuthCancelled()
|
||||||
uiaContinuation?.resume(pendingAuth!!)
|
|
||||||
} else {
|
|
||||||
uiaContinuation?.resumeWithException(IllegalArgumentException())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is ThreePidsSettingsAction.PasswordAuthDone -> {
|
|
||||||
val decryptedPass = matrix.secureStorageService()
|
|
||||||
.loadSecureSecret<String>(action.password.fromBase64().inputStream(), ReAuthActivity.DEFAULT_RESULT_KEYSTORE_ALIAS)
|
|
||||||
uiaContinuation?.resume(
|
|
||||||
UserPasswordAuth(
|
|
||||||
session = pendingAuth?.session,
|
|
||||||
password = decryptedPass,
|
|
||||||
user = session.myUserId
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
ThreePidsSettingsAction.ReAuthCancelled -> {
|
|
||||||
Timber.d("## UIA - Reauth cancelled")
|
|
||||||
uiaContinuation?.resumeWithException(Exception())
|
|
||||||
uiaContinuation = null
|
|
||||||
pendingAuth = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var uiaContinuation: Continuation<UIABaseAuth>? = null
|
|
||||||
var pendingAuth: UIABaseAuth? = null
|
|
||||||
|
|
||||||
private val uiaInterceptor = object : UserInteractiveAuthInterceptor {
|
private val uiaInterceptor = object : UserInteractiveAuthInterceptor {
|
||||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
||||||
_viewEvents.post(ThreePidsSettingsViewEvents.RequestReAuth(flowResponse, errCode))
|
_viewEvents.post(ThreePidsSettingsViewEvents.RequestReAuth(flowResponse, errCode))
|
||||||
pendingAuth = DefaultBaseAuth(session = flowResponse.session)
|
pendingAuthHandler.pendingAuth = DefaultBaseAuth(session = flowResponse.session)
|
||||||
uiaContinuation = promise
|
pendingAuthHandler.uiaContinuation = promise
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue