Merge pull request #7737 from vector-im/bugfix/hughns/qr-server-change

This commit is contained in:
Hugh Nimmo-Smith 2022-12-12 18:21:39 +00:00 committed by GitHub
commit 34ee399f94
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 20 additions and 42 deletions

1
changelog.d/7737.bugfix Normal file
View file

@ -0,0 +1 @@
Fix issue of Scan QR code button sometimes not showing when it should be available

View file

@ -125,12 +125,6 @@ interface AuthenticationService {
deviceId: String? = null deviceId: String? = null
): Session ): Session
/**
* @param homeServerConnectionConfig the information about the homeserver and other configuration
* Return true if qr code login is supported by the server, false otherwise.
*/
suspend fun isQrLoginSupported(homeServerConnectionConfig: HomeServerConnectionConfig): Boolean
/** /**
* Authenticate using m.login.token method during sign in with QR code. * Authenticate using m.login.token method during sign in with QR code.
* @param homeServerConnectionConfig the information about the homeserver and other configuration * @param homeServerConnectionConfig the information about the homeserver and other configuration

View file

@ -22,5 +22,6 @@ data class LoginFlowResult(
val isLoginAndRegistrationSupported: Boolean, val isLoginAndRegistrationSupported: Boolean,
val homeServerUrl: String, val homeServerUrl: String,
val isOutdatedHomeserver: Boolean, val isOutdatedHomeserver: Boolean,
val isLogoutDevicesSupported: Boolean val isLogoutDevicesSupported: Boolean,
val isLoginWithQrSupported: Boolean,
) )

View file

@ -30,7 +30,6 @@ import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
import org.matrix.android.sdk.api.auth.login.LoginWizard import org.matrix.android.sdk.api.auth.login.LoginWizard
import org.matrix.android.sdk.api.auth.registration.RegistrationWizard import org.matrix.android.sdk.api.auth.registration.RegistrationWizard
import org.matrix.android.sdk.api.auth.wellknown.WellknownResult import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.failure.MatrixIdFailure import org.matrix.android.sdk.api.failure.MatrixIdFailure
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
@ -299,7 +298,8 @@ internal class DefaultAuthenticationService @Inject constructor(
isLoginAndRegistrationSupported = versions.isLoginAndRegistrationSupportedBySdk(), isLoginAndRegistrationSupported = versions.isLoginAndRegistrationSupportedBySdk(),
homeServerUrl = homeServerUrl, homeServerUrl = homeServerUrl,
isOutdatedHomeserver = !versions.isSupportedBySdk(), isOutdatedHomeserver = !versions.isSupportedBySdk(),
isLogoutDevicesSupported = versions.doesServerSupportLogoutDevices() isLogoutDevicesSupported = versions.doesServerSupportLogoutDevices(),
isLoginWithQrSupported = versions.doesServerSupportQrCodeLogin(),
) )
} }
@ -408,20 +408,6 @@ internal class DefaultAuthenticationService @Inject constructor(
) )
} }
override suspend fun isQrLoginSupported(homeServerConnectionConfig: HomeServerConnectionConfig): Boolean {
val authAPI = buildAuthAPI(homeServerConnectionConfig)
val versions = runCatching {
executeRequest(null) {
authAPI.versions()
}
}
return if (versions.isSuccess) {
versions.getOrNull()?.doesServerSupportQrCodeLogin().orFalse()
} else {
false
}
}
override suspend fun loginUsingQrLoginToken( override suspend fun loginUsingQrLoginToken(
homeServerConnectionConfig: HomeServerConnectionConfig, homeServerConnectionConfig: HomeServerConnectionConfig,
loginToken: String, loginToken: String,

View file

@ -118,7 +118,7 @@ class OnboardingViewModel @AssistedInject constructor(
} }
} }
private suspend fun checkQrCodeLoginCapability(config: HomeServerConnectionConfig) { private fun checkQrCodeLoginCapability() {
if (!vectorFeatures.isQrCodeLoginEnabled()) { if (!vectorFeatures.isQrCodeLoginEnabled()) {
setState { setState {
copy( copy(
@ -133,11 +133,9 @@ class OnboardingViewModel @AssistedInject constructor(
) )
} }
} else { } else {
// check if selected server supports MSC3882 first
val canLoginWithQrCode = authenticationService.isQrLoginSupported(config)
setState { setState {
copy( copy(
canLoginWithQrCode = canLoginWithQrCode canLoginWithQrCode = selectedHomeserver.isLoginWithQrSupported
) )
} }
} }
@ -705,7 +703,10 @@ class OnboardingViewModel @AssistedInject constructor(
// This is invalid // This is invalid
_viewEvents.post(OnboardingViewEvents.Failure(Throwable("Unable to create a HomeServerConnectionConfig"))) _viewEvents.post(OnboardingViewEvents.Failure(Throwable("Unable to create a HomeServerConnectionConfig")))
} else { } else {
startAuthenticationFlow(action, homeServerConnectionConfig, serverTypeOverride, postAction) startAuthenticationFlow(action, homeServerConnectionConfig, serverTypeOverride, suspend {
checkQrCodeLoginCapability()
postAction()
})
} }
} }
@ -764,8 +765,6 @@ class OnboardingViewModel @AssistedInject constructor(
_viewEvents.post(OnboardingViewEvents.OutdatedHomeserver) _viewEvents.post(OnboardingViewEvents.OutdatedHomeserver)
} }
checkQrCodeLoginCapability(config)
when (trigger) { when (trigger) {
is OnboardingAction.HomeServerChange.SelectHomeServer -> { is OnboardingAction.HomeServerChange.SelectHomeServer -> {
onHomeServerSelected(config, serverTypeOverride, authResult) onHomeServerSelected(config, serverTypeOverride, authResult)

View file

@ -76,6 +76,7 @@ data class SelectedHomeserverState(
val preferredLoginMode: LoginMode = LoginMode.Unknown, val preferredLoginMode: LoginMode = LoginMode.Unknown,
val supportedLoginTypes: List<String> = emptyList(), val supportedLoginTypes: List<String> = emptyList(),
val isLogoutDevicesSupported: Boolean = false, val isLogoutDevicesSupported: Boolean = false,
val isLoginWithQrSupported: Boolean = false,
) : Parcelable ) : Parcelable
@Parcelize @Parcelize

View file

@ -47,7 +47,8 @@ class StartAuthenticationFlowUseCase @Inject constructor(
upstreamUrl = authFlow.homeServerUrl, upstreamUrl = authFlow.homeServerUrl,
preferredLoginMode = preferredLoginMode, preferredLoginMode = preferredLoginMode,
supportedLoginTypes = authFlow.supportedLoginTypes, supportedLoginTypes = authFlow.supportedLoginTypes,
isLogoutDevicesSupported = authFlow.isLogoutDevicesSupported isLogoutDevicesSupported = authFlow.isLogoutDevicesSupported,
isLoginWithQrSupported = authFlow.isLoginWithQrSupported,
) )
private fun LoginFlowResult.findPreferredLoginMode() = when { private fun LoginFlowResult.findPreferredLoginMode() = when {

View file

@ -83,6 +83,7 @@ private val A_HOMESERVER_CONFIG = HomeServerConnectionConfig(FakeUri().instance)
private val SELECTED_HOMESERVER_STATE = SelectedHomeserverState(preferredLoginMode = LoginMode.Password, userFacingUrl = A_HOMESERVER_URL) private val SELECTED_HOMESERVER_STATE = SelectedHomeserverState(preferredLoginMode = LoginMode.Password, userFacingUrl = A_HOMESERVER_URL)
private val SELECTED_HOMESERVER_STATE_SUPPORTED_LOGOUT_DEVICES = SelectedHomeserverState(isLogoutDevicesSupported = true) private val SELECTED_HOMESERVER_STATE_SUPPORTED_LOGOUT_DEVICES = SelectedHomeserverState(isLogoutDevicesSupported = true)
private val DEFAULT_SELECTED_HOMESERVER_STATE = SELECTED_HOMESERVER_STATE.copy(userFacingUrl = A_DEFAULT_HOMESERVER_URL) private val DEFAULT_SELECTED_HOMESERVER_STATE = SELECTED_HOMESERVER_STATE.copy(userFacingUrl = A_DEFAULT_HOMESERVER_URL)
private val DEFAULT_SELECTED_HOMESERVER_STATE_WITH_QR_SUPPORTED = DEFAULT_SELECTED_HOMESERVER_STATE.copy(isLoginWithQrSupported = true)
private const val AN_EMAIL = "hello@example.com" private const val AN_EMAIL = "hello@example.com"
private const val A_PASSWORD = "a-password" private const val A_PASSWORD = "a-password"
private const val A_USERNAME = "hello-world" private const val A_USERNAME = "hello-world"
@ -164,7 +165,7 @@ class OnboardingViewModelTest {
fun `given combined login enabled, when handling sign in splash action, then emits OpenCombinedLogin with default homeserver qrCode supported`() = runTest { fun `given combined login enabled, when handling sign in splash action, then emits OpenCombinedLogin with default homeserver qrCode supported`() = runTest {
val test = viewModel.test() val test = viewModel.test()
fakeVectorFeatures.givenCombinedLoginEnabled() fakeVectorFeatures.givenCombinedLoginEnabled()
givenCanSuccessfullyUpdateHomeserver(A_DEFAULT_HOMESERVER_URL, DEFAULT_SELECTED_HOMESERVER_STATE, canLoginWithQrCode = true) givenCanSuccessfullyUpdateHomeserver(A_DEFAULT_HOMESERVER_URL, DEFAULT_SELECTED_HOMESERVER_STATE_WITH_QR_SUPPORTED)
viewModel.handle(OnboardingAction.SplashAction.OnIAlreadyHaveAnAccount(OnboardingFlow.SignIn)) viewModel.handle(OnboardingAction.SplashAction.OnIAlreadyHaveAnAccount(OnboardingFlow.SignIn))
@ -173,9 +174,9 @@ class OnboardingViewModelTest {
initialState, initialState,
{ copy(onboardingFlow = OnboardingFlow.SignIn) }, { copy(onboardingFlow = OnboardingFlow.SignIn) },
{ copy(isLoading = true) }, { copy(isLoading = true) },
{ copy(canLoginWithQrCode = true) }, { copy(selectedHomeserver = DEFAULT_SELECTED_HOMESERVER_STATE_WITH_QR_SUPPORTED) },
{ copy(selectedHomeserver = DEFAULT_SELECTED_HOMESERVER_STATE) },
{ copy(signMode = SignMode.SignIn) }, { copy(signMode = SignMode.SignIn) },
{ copy(canLoginWithQrCode = true) },
{ copy(isLoading = false) } { copy(isLoading = false) }
) )
.assertEvents(OnboardingViewEvents.OpenCombinedLogin) .assertEvents(OnboardingViewEvents.OpenCombinedLogin)
@ -1174,13 +1175,11 @@ class OnboardingViewModelTest {
resultingState: SelectedHomeserverState, resultingState: SelectedHomeserverState,
config: HomeServerConnectionConfig = A_HOMESERVER_CONFIG, config: HomeServerConnectionConfig = A_HOMESERVER_CONFIG,
fingerprint: Fingerprint? = null, fingerprint: Fingerprint? = null,
canLoginWithQrCode: Boolean = false,
) { ) {
fakeHomeServerConnectionConfigFactory.givenConfigFor(homeserverUrl, fingerprint, config) fakeHomeServerConnectionConfigFactory.givenConfigFor(homeserverUrl, fingerprint, config)
fakeStartAuthenticationFlowUseCase.givenResult(config, StartAuthenticationResult(isHomeserverOutdated = false, resultingState)) fakeStartAuthenticationFlowUseCase.givenResult(config, StartAuthenticationResult(isHomeserverOutdated = false, resultingState))
givenRegistrationResultFor(RegisterAction.StartRegistration, RegistrationActionHandler.Result.StartRegistration) givenRegistrationResultFor(RegisterAction.StartRegistration, RegistrationActionHandler.Result.StartRegistration)
fakeHomeServerHistoryService.expectUrlToBeAdded(config.homeServerUri.toString()) fakeHomeServerHistoryService.expectUrlToBeAdded(config.homeServerUri.toString())
fakeAuthenticationService.givenIsQrLoginSupported(config, canLoginWithQrCode)
} }
private fun givenUpdatingHomeserverErrors(homeserverUrl: String, resultingState: SelectedHomeserverState, error: Throwable) { private fun givenUpdatingHomeserverErrors(homeserverUrl: String, resultingState: SelectedHomeserverState, error: Throwable) {
@ -1188,7 +1187,6 @@ class OnboardingViewModelTest {
fakeStartAuthenticationFlowUseCase.givenResult(A_HOMESERVER_CONFIG, StartAuthenticationResult(isHomeserverOutdated = false, resultingState)) fakeStartAuthenticationFlowUseCase.givenResult(A_HOMESERVER_CONFIG, StartAuthenticationResult(isHomeserverOutdated = false, resultingState))
givenRegistrationResultFor(RegisterAction.StartRegistration, RegistrationActionHandler.Result.Error(error)) givenRegistrationResultFor(RegisterAction.StartRegistration, RegistrationActionHandler.Result.Error(error))
fakeHomeServerHistoryService.expectUrlToBeAdded(A_HOMESERVER_CONFIG.homeServerUri.toString()) fakeHomeServerHistoryService.expectUrlToBeAdded(A_HOMESERVER_CONFIG.homeServerUri.toString())
fakeAuthenticationService.givenIsQrLoginSupported(A_HOMESERVER_CONFIG, false)
} }
private fun givenUserNameIsAvailable(userName: String) { private fun givenUserNameIsAvailable(userName: String) {

View file

@ -140,7 +140,8 @@ class StartAuthenticationFlowUseCaseTest {
isLoginAndRegistrationSupported = true, isLoginAndRegistrationSupported = true,
homeServerUrl = A_DECLARED_HOMESERVER_URL, homeServerUrl = A_DECLARED_HOMESERVER_URL,
isOutdatedHomeserver = false, isOutdatedHomeserver = false,
isLogoutDevicesSupported = false isLogoutDevicesSupported = false,
isLoginWithQrSupported = false
) )
private fun expectedResult( private fun expectedResult(

View file

@ -58,10 +58,6 @@ class FakeAuthenticationService : AuthenticationService by mockk() {
coEvery { getWellKnownData(matrixId, config) } returns result coEvery { getWellKnownData(matrixId, config) } returns result
} }
fun givenIsQrLoginSupported(config: HomeServerConnectionConfig, result: Boolean) {
coEvery { isQrLoginSupported(config) } returns result
}
fun givenWellKnownThrows(matrixId: String, config: HomeServerConnectionConfig?, cause: Throwable) { fun givenWellKnownThrows(matrixId: String, config: HomeServerConnectionConfig?, cause: Throwable) {
coEvery { getWellKnownData(matrixId, config) } throws cause coEvery { getWellKnownData(matrixId, config) } throws cause
} }