SoftLogout: handle the case where user sign in with SSO on another account
This commit is contained in:
parent
050519e998
commit
1de85daad9
|
@ -29,6 +29,7 @@ import im.vector.matrix.android.api.failure.MatrixError
|
|||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.platform.OnBackPressed
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
|
||||
/**
|
||||
|
@ -60,6 +61,7 @@ abstract class AbstractLoginFragment : VectorBaseFragment(), OnBackPressed {
|
|||
|
||||
loginViewModel.viewEvents
|
||||
.observe()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe {
|
||||
handleLoginViewEvents(it)
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ import im.vector.riotx.features.home.HomeActivity
|
|||
import im.vector.riotx.features.login.terms.LoginTermsFragment
|
||||
import im.vector.riotx.features.login.terms.LoginTermsFragmentArgument
|
||||
import im.vector.riotx.features.login.terms.toLocalizedLoginTerms
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.android.synthetic.main.activity_login.*
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -112,6 +113,7 @@ open class LoginActivity : VectorBaseActivity(), ToolbarConfigurable {
|
|||
|
||||
loginViewModel.viewEvents
|
||||
.observe()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe {
|
||||
handleLoginViewEvents(it)
|
||||
}
|
||||
|
|
|
@ -18,17 +18,21 @@ package im.vector.riotx.features.signout.soft
|
|||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.viewModel
|
||||
import im.vector.matrix.android.api.failure.GlobalError
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.error.ErrorFormatter
|
||||
import im.vector.riotx.core.extensions.replaceFragment
|
||||
import im.vector.riotx.features.MainActivity
|
||||
import im.vector.riotx.features.MainActivityArgs
|
||||
import im.vector.riotx.features.login.LoginActivity
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.android.synthetic.main.activity_login.*
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
@ -43,6 +47,7 @@ class SoftLogoutActivity : LoginActivity() {
|
|||
|
||||
@Inject lateinit var softLogoutViewModelFactory: SoftLogoutViewModel.Factory
|
||||
@Inject lateinit var session: Session
|
||||
@Inject lateinit var errorFormatter: ErrorFormatter
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
super.injectWith(injector)
|
||||
|
@ -56,6 +61,40 @@ class SoftLogoutActivity : LoginActivity() {
|
|||
.subscribe(this) {
|
||||
updateWithState(it)
|
||||
}
|
||||
|
||||
softLogoutViewModel.viewEvents
|
||||
.observe()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe {
|
||||
handleSoftLogoutViewEvents(it)
|
||||
}
|
||||
.disposeOnDestroy()
|
||||
}
|
||||
|
||||
private fun handleSoftLogoutViewEvents(softLogoutViewEvents: SoftLogoutViewEvents) {
|
||||
when (softLogoutViewEvents) {
|
||||
is SoftLogoutViewEvents.Error ->
|
||||
showError(errorFormatter.toHumanReadable(softLogoutViewEvents.throwable))
|
||||
is SoftLogoutViewEvents.ErrorNotSameUser -> {
|
||||
// Pop the backstack
|
||||
supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
|
||||
|
||||
// And inform the user
|
||||
showError(getString(
|
||||
R.string.soft_logout_sso_not_same_user_error,
|
||||
softLogoutViewEvents.currentUserId,
|
||||
softLogoutViewEvents.newUserId)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showError(message: String) {
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle(R.string.dialog_title_error)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun addFirstFragment() {
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright 2019 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.riotx.features.signout.soft
|
||||
|
||||
/**
|
||||
* Transient events for SoftLogout
|
||||
*/
|
||||
sealed class SoftLogoutViewEvents {
|
||||
data class ErrorNotSameUser(val currentUserId: String, val newUserId: String) : SoftLogoutViewEvents()
|
||||
data class Error(val throwable: Throwable) : SoftLogoutViewEvents()
|
||||
}
|
|
@ -28,7 +28,10 @@ import im.vector.matrix.android.internal.auth.data.LoginFlowTypes
|
|||
import im.vector.riotx.core.di.ActiveSessionHolder
|
||||
import im.vector.riotx.core.extensions.hasUnsavedKeys
|
||||
import im.vector.riotx.core.platform.VectorViewModel
|
||||
import im.vector.riotx.core.utils.DataSource
|
||||
import im.vector.riotx.core.utils.PublishDataSource
|
||||
import im.vector.riotx.features.login.LoginMode
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* TODO Test push: disable the pushers?
|
||||
|
@ -68,6 +71,9 @@ class SoftLogoutViewModel @AssistedInject constructor(
|
|||
|
||||
private var currentTask: Cancelable? = null
|
||||
|
||||
private val _viewEvents = PublishDataSource<SoftLogoutViewEvents>()
|
||||
val viewEvents: DataSource<SoftLogoutViewEvents> = _viewEvents
|
||||
|
||||
init {
|
||||
// Get the supported login flow
|
||||
getSupportedLoginFlow()
|
||||
|
@ -88,7 +94,6 @@ class SoftLogoutViewModel @AssistedInject constructor(
|
|||
|
||||
currentTask = authenticationService.getLoginFlow(homeServerConnectionConfig, object : MatrixCallback<LoginFlowResult> {
|
||||
override fun onFailure(failure: Throwable) {
|
||||
// TODO _viewEvents.post(LoginViewEvents.Error(failure))
|
||||
setState {
|
||||
copy(
|
||||
asyncHomeServerLoginFlowRequest = Fail(failure)
|
||||
|
@ -167,26 +172,38 @@ class SoftLogoutViewModel @AssistedInject constructor(
|
|||
}
|
||||
|
||||
private fun handleWebLoginSuccess(action: SoftLogoutAction.WebLoginSuccess) {
|
||||
setState {
|
||||
copy(
|
||||
asyncLoginAction = Loading()
|
||||
)
|
||||
}
|
||||
currentTask = session.updateCredentials(action.credentials,
|
||||
object : MatrixCallback<Unit> {
|
||||
override fun onFailure(failure: Throwable) {
|
||||
setState {
|
||||
copy(
|
||||
asyncLoginAction = Fail(failure)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSuccess(data: Unit) {
|
||||
onSessionRestored()
|
||||
}
|
||||
// User may have been connected with SSO with another userId
|
||||
// We have to check this
|
||||
withState { softLogoutViewState ->
|
||||
if (softLogoutViewState.userId != action.credentials.userId) {
|
||||
Timber.w("User login again with SSO, but using another account")
|
||||
_viewEvents.post(SoftLogoutViewEvents.ErrorNotSameUser(
|
||||
softLogoutViewState.userId,
|
||||
action.credentials.userId))
|
||||
} else {
|
||||
setState {
|
||||
copy(
|
||||
asyncLoginAction = Loading()
|
||||
)
|
||||
}
|
||||
)
|
||||
currentTask = session.updateCredentials(action.credentials,
|
||||
object : MatrixCallback<Unit> {
|
||||
override fun onFailure(failure: Throwable) {
|
||||
_viewEvents.post(SoftLogoutViewEvents.Error(failure))
|
||||
setState {
|
||||
copy(
|
||||
asyncLoginAction = Uninitialized
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSuccess(data: Unit) {
|
||||
onSessionRestored()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleSignInAgain(action: SoftLogoutAction.SignInAgain) {
|
||||
|
|
|
@ -159,5 +159,6 @@
|
|||
<string name="soft_logout_clear_data_dialog_content">Clear all data currently stored on this device?\nSign in again to access your account data and messages.</string>
|
||||
<string name="soft_logout_clear_data_dialog_e2e_warning_content">You’ll lose access to secure messages unless you sign in to recover your encryption keys.</string>
|
||||
<string name="soft_logout_clear_data_dialog_submit">Clear data</string>
|
||||
<string name="soft_logout_sso_not_same_user_error">The current session is for user %1$s and you provide credentials for user %2$s. This is not supported by RiotX.\nPlease first clear data, then sign in again on another account.</string>
|
||||
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue