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.R
|
||||||
import im.vector.riotx.core.platform.OnBackPressed
|
import im.vector.riotx.core.platform.OnBackPressed
|
||||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import javax.net.ssl.HttpsURLConnection
|
import javax.net.ssl.HttpsURLConnection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,6 +61,7 @@ abstract class AbstractLoginFragment : VectorBaseFragment(), OnBackPressed {
|
|||||||
|
|
||||||
loginViewModel.viewEvents
|
loginViewModel.viewEvents
|
||||||
.observe()
|
.observe()
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe {
|
.subscribe {
|
||||||
handleLoginViewEvents(it)
|
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.LoginTermsFragment
|
||||||
import im.vector.riotx.features.login.terms.LoginTermsFragmentArgument
|
import im.vector.riotx.features.login.terms.LoginTermsFragmentArgument
|
||||||
import im.vector.riotx.features.login.terms.toLocalizedLoginTerms
|
import im.vector.riotx.features.login.terms.toLocalizedLoginTerms
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import kotlinx.android.synthetic.main.activity_login.*
|
import kotlinx.android.synthetic.main.activity_login.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -112,6 +113,7 @@ open class LoginActivity : VectorBaseActivity(), ToolbarConfigurable {
|
|||||||
|
|
||||||
loginViewModel.viewEvents
|
loginViewModel.viewEvents
|
||||||
.observe()
|
.observe()
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe {
|
.subscribe {
|
||||||
handleLoginViewEvents(it)
|
handleLoginViewEvents(it)
|
||||||
}
|
}
|
||||||
|
@ -18,17 +18,21 @@ package im.vector.riotx.features.signout.soft
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.fragment.app.FragmentManager
|
||||||
import com.airbnb.mvrx.Success
|
import com.airbnb.mvrx.Success
|
||||||
import com.airbnb.mvrx.viewModel
|
import com.airbnb.mvrx.viewModel
|
||||||
import im.vector.matrix.android.api.failure.GlobalError
|
import im.vector.matrix.android.api.failure.GlobalError
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.di.ScreenComponent
|
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.core.extensions.replaceFragment
|
||||||
import im.vector.riotx.features.MainActivity
|
import im.vector.riotx.features.MainActivity
|
||||||
import im.vector.riotx.features.MainActivityArgs
|
import im.vector.riotx.features.MainActivityArgs
|
||||||
import im.vector.riotx.features.login.LoginActivity
|
import im.vector.riotx.features.login.LoginActivity
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import kotlinx.android.synthetic.main.activity_login.*
|
import kotlinx.android.synthetic.main.activity_login.*
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -43,6 +47,7 @@ class SoftLogoutActivity : LoginActivity() {
|
|||||||
|
|
||||||
@Inject lateinit var softLogoutViewModelFactory: SoftLogoutViewModel.Factory
|
@Inject lateinit var softLogoutViewModelFactory: SoftLogoutViewModel.Factory
|
||||||
@Inject lateinit var session: Session
|
@Inject lateinit var session: Session
|
||||||
|
@Inject lateinit var errorFormatter: ErrorFormatter
|
||||||
|
|
||||||
override fun injectWith(injector: ScreenComponent) {
|
override fun injectWith(injector: ScreenComponent) {
|
||||||
super.injectWith(injector)
|
super.injectWith(injector)
|
||||||
@ -56,6 +61,40 @@ class SoftLogoutActivity : LoginActivity() {
|
|||||||
.subscribe(this) {
|
.subscribe(this) {
|
||||||
updateWithState(it)
|
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() {
|
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.di.ActiveSessionHolder
|
||||||
import im.vector.riotx.core.extensions.hasUnsavedKeys
|
import im.vector.riotx.core.extensions.hasUnsavedKeys
|
||||||
import im.vector.riotx.core.platform.VectorViewModel
|
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 im.vector.riotx.features.login.LoginMode
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO Test push: disable the pushers?
|
* TODO Test push: disable the pushers?
|
||||||
@ -68,6 +71,9 @@ class SoftLogoutViewModel @AssistedInject constructor(
|
|||||||
|
|
||||||
private var currentTask: Cancelable? = null
|
private var currentTask: Cancelable? = null
|
||||||
|
|
||||||
|
private val _viewEvents = PublishDataSource<SoftLogoutViewEvents>()
|
||||||
|
val viewEvents: DataSource<SoftLogoutViewEvents> = _viewEvents
|
||||||
|
|
||||||
init {
|
init {
|
||||||
// Get the supported login flow
|
// Get the supported login flow
|
||||||
getSupportedLoginFlow()
|
getSupportedLoginFlow()
|
||||||
@ -88,7 +94,6 @@ class SoftLogoutViewModel @AssistedInject constructor(
|
|||||||
|
|
||||||
currentTask = authenticationService.getLoginFlow(homeServerConnectionConfig, object : MatrixCallback<LoginFlowResult> {
|
currentTask = authenticationService.getLoginFlow(homeServerConnectionConfig, object : MatrixCallback<LoginFlowResult> {
|
||||||
override fun onFailure(failure: Throwable) {
|
override fun onFailure(failure: Throwable) {
|
||||||
// TODO _viewEvents.post(LoginViewEvents.Error(failure))
|
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
asyncHomeServerLoginFlowRequest = Fail(failure)
|
asyncHomeServerLoginFlowRequest = Fail(failure)
|
||||||
@ -167,26 +172,38 @@ class SoftLogoutViewModel @AssistedInject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleWebLoginSuccess(action: SoftLogoutAction.WebLoginSuccess) {
|
private fun handleWebLoginSuccess(action: SoftLogoutAction.WebLoginSuccess) {
|
||||||
setState {
|
// User may have been connected with SSO with another userId
|
||||||
copy(
|
// We have to check this
|
||||||
asyncLoginAction = Loading()
|
withState { softLogoutViewState ->
|
||||||
)
|
if (softLogoutViewState.userId != action.credentials.userId) {
|
||||||
}
|
Timber.w("User login again with SSO, but using another account")
|
||||||
currentTask = session.updateCredentials(action.credentials,
|
_viewEvents.post(SoftLogoutViewEvents.ErrorNotSameUser(
|
||||||
object : MatrixCallback<Unit> {
|
softLogoutViewState.userId,
|
||||||
override fun onFailure(failure: Throwable) {
|
action.credentials.userId))
|
||||||
setState {
|
} else {
|
||||||
copy(
|
setState {
|
||||||
asyncLoginAction = Fail(failure)
|
copy(
|
||||||
)
|
asyncLoginAction = Loading()
|
||||||
}
|
)
|
||||||
}
|
|
||||||
|
|
||||||
override fun onSuccess(data: Unit) {
|
|
||||||
onSessionRestored()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
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) {
|
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_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_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_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>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user