From 6e3283cb3490406d9498a16dc6317559d0ee939a Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 31 May 2022 12:50:26 +0100 Subject: [PATCH] moving homeserver feature for logout all devices to the selected homeserver state via the LoginFlowResult --- .../sdk/api/auth/data/LoginFlowResult.kt | 3 ++- .../android/sdk/api/auth/login/LoginWizard.kt | 4 +-- .../auth/DefaultAuthenticationService.kt | 4 ++- .../internal/auth/login/DefaultLoginWizard.kt | 9 +------ .../internal/auth/login/ResetCapabilities.kt | 27 ------------------- .../onboarding/OnboardingViewModel.kt | 10 +++---- .../onboarding/OnboardingViewState.kt | 1 + .../StartAuthenticationFlowUseCase.kt | 3 ++- .../onboarding/OnboardingViewModelTest.kt | 8 +++--- .../StartAuthenticationFlowUseCaseTest.kt | 3 ++- .../vector/app/test/fakes/FakeLoginWizard.kt | 6 ++--- 11 files changed, 23 insertions(+), 55 deletions(-) delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/ResetCapabilities.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/LoginFlowResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/LoginFlowResult.kt index 7d1407c0d8..5b6c1897bf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/LoginFlowResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/LoginFlowResult.kt @@ -21,5 +21,6 @@ data class LoginFlowResult( val ssoIdentityProviders: List?, val isLoginAndRegistrationSupported: Boolean, val homeServerUrl: String, - val isOutdatedHomeserver: Boolean + val isOutdatedHomeserver: Boolean, + val isLogoutDevicesSupported: Boolean ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt index 638ff079c4..27a4618737 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.api.auth.login import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.auth.login.ResetCapabilities /** * Set of methods to be able to login to an existing account on a homeserver. @@ -66,9 +65,8 @@ interface LoginWizard { * [resetPasswordMailConfirmed] is successfully called. * * @param email an email previously associated to the account the user wants the password to be reset. - * @return a [ResetCapabilities] if the reset is successful. */ - suspend fun resetPassword(email: String): ResetCapabilities + suspend fun resetPassword(email: String) /** * Confirm the new password, once the user has checked their email diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt index 92852e4722..9d6b018a67 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt @@ -40,6 +40,7 @@ import org.matrix.android.sdk.internal.auth.login.DefaultLoginWizard import org.matrix.android.sdk.internal.auth.login.DirectLoginTask import org.matrix.android.sdk.internal.auth.registration.DefaultRegistrationWizard import org.matrix.android.sdk.internal.auth.version.Versions +import org.matrix.android.sdk.internal.auth.version.doesServerSupportLogoutDevices import org.matrix.android.sdk.internal.auth.version.isLoginAndRegistrationSupportedBySdk import org.matrix.android.sdk.internal.auth.version.isSupportedBySdk import org.matrix.android.sdk.internal.di.Unauthenticated @@ -292,7 +293,8 @@ internal class DefaultAuthenticationService @Inject constructor( ssoIdentityProviders = loginFlowResponse.flows.orEmpty().firstOrNull { it.type == LoginFlowTypes.SSO }?.ssoIdentityProvider, isLoginAndRegistrationSupported = versions.isLoginAndRegistrationSupportedBySdk(), homeServerUrl = homeServerUrl, - isOutdatedHomeserver = !versions.isSupportedBySdk() + isOutdatedHomeserver = !versions.isSupportedBySdk(), + isLogoutDevicesSupported = versions.doesServerSupportLogoutDevices() ) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt index 0d73d398fc..656a4f671b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt @@ -31,7 +31,6 @@ import org.matrix.android.sdk.internal.auth.data.TokenLoginParams import org.matrix.android.sdk.internal.auth.db.PendingSessionData import org.matrix.android.sdk.internal.auth.registration.AddThreePidRegistrationParams import org.matrix.android.sdk.internal.auth.registration.RegisterAddThreePidTask -import org.matrix.android.sdk.internal.auth.version.doesServerSupportLogoutDevices import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.content.DefaultContentUrlResolver import org.matrix.android.sdk.internal.session.contentscanner.DisabledContentScannerService @@ -104,7 +103,7 @@ internal class DefaultLoginWizard( return sessionCreator.createSession(credentials, pendingSessionData.homeServerConnectionConfig) } - override suspend fun resetPassword(email: String): ResetCapabilities { + override suspend fun resetPassword(email: String) { val param = RegisterAddThreePidTask.Params( RegisterThreePid.Email(email), pendingSessionData.clientSecret, @@ -120,12 +119,6 @@ internal class DefaultLoginWizard( pendingSessionData = pendingSessionData.copy(resetPasswordData = ResetPasswordData(result)) .also { pendingSessionStore.savePendingSessionData(it) } - - val versions = executeRequest(null) { - authAPI.versions() - } - - return ResetCapabilities(supportsLogoutAllDevices = versions.doesServerSupportLogoutDevices()) } override suspend fun resetPasswordMailConfirmed(newPassword: String, logoutAllDevices: Boolean) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/ResetCapabilities.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/ResetCapabilities.kt deleted file mode 100644 index ed3b473062..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/ResetCapabilities.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 org.matrix.android.sdk.internal.auth.login - -/** - * The reset capabilities of the selected Homeserver - */ -data class ResetCapabilities( - /** - * True if the server supports MSC2457 `logout_devices` parameter when setting a new password. - */ - val supportsLogoutAllDevices: Boolean -) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index 254bca2c7b..38a72441e0 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -60,7 +60,6 @@ import org.matrix.android.sdk.api.auth.login.LoginWizard import org.matrix.android.sdk.api.auth.registration.RegistrationWizard import org.matrix.android.sdk.api.failure.isHomeserverUnavailable import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.internal.auth.login.ResetCapabilities import timber.log.Timber import java.util.UUID import java.util.concurrent.CancellationException @@ -444,11 +443,12 @@ class OnboardingViewModel @AssistedInject constructor( setState { copy(isLoading = true) } currentJob = viewModelScope.launch { runCatching { safeLoginWizard.resetPassword(action.email) }.fold( - onSuccess = { resetCapabilities -> + onSuccess = { + val state = awaitState() setState { copy( isLoading = false, - resetState = createResetState(action, resetCapabilities) + resetState = createResetState(action, state.selectedHomeserver) ) } _viewEvents.post(OnboardingViewEvents.OnResetPasswordSendThreePidDone) @@ -461,10 +461,10 @@ class OnboardingViewModel @AssistedInject constructor( } } - private fun createResetState(action: OnboardingAction.ResetPassword, it: ResetCapabilities) = ResetState( + private fun createResetState(action: OnboardingAction.ResetPassword, selectedHomeserverState: SelectedHomeserverState) = ResetState( email = action.email, newPassword = action.newPassword, - supportsLogoutAllDevices = it.supportsLogoutAllDevices + supportsLogoutAllDevices = selectedHomeserverState.isLogoutDevicesSupported ) private fun handleResetPasswordMailConfirmed() { diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt index 93d5892bf1..c072f13bca 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt @@ -71,6 +71,7 @@ data class SelectedHomeserverState( val upstreamUrl: String? = null, val preferredLoginMode: LoginMode = LoginMode.Unknown, val supportedLoginTypes: List = emptyList(), + val isLogoutDevicesSupported: Boolean = false, ) : Parcelable @Parcelize diff --git a/vector/src/main/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCase.kt b/vector/src/main/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCase.kt index 922258778b..7b6205bfce 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCase.kt @@ -53,7 +53,8 @@ class StartAuthenticationFlowUseCase @Inject constructor( userFacingUrl = config.homeServerUri.toString(), upstreamUrl = authFlow.homeServerUrl, preferredLoginMode = preferredLoginMode, - supportedLoginTypes = authFlow.supportedLoginTypes + supportedLoginTypes = authFlow.supportedLoginTypes, + isLogoutDevicesSupported = authFlow.isLogoutDevicesSupported ) private fun matrixOrgUrl() = stringProvider.getString(R.string.matrix_org_server_url).ensureTrailingSlash() diff --git a/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt b/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt index 3cefeb46be..933e9aa972 100644 --- a/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt +++ b/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt @@ -52,7 +52,6 @@ import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig import org.matrix.android.sdk.api.auth.registration.Stage import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities -import org.matrix.android.sdk.internal.auth.login.ResetCapabilities private const val A_DISPLAY_NAME = "a display name" private const val A_PICTURE_FILENAME = "a-picture.png" @@ -66,9 +65,9 @@ private val A_DIRECT_LOGIN = OnboardingAction.AuthenticateAction.LoginDirect("@a private const val A_HOMESERVER_URL = "https://edited-homeserver.org" private val A_HOMESERVER_CONFIG = HomeServerConnectionConfig(FakeUri().instance) private val SELECTED_HOMESERVER_STATE = SelectedHomeserverState(preferredLoginMode = LoginMode.Password) +private val SELECTED_HOMESERVER_STATE_SUPPORTED_LOGOUT_DEVICES = SelectedHomeserverState(isLogoutDevicesSupported = true) private const val AN_EMAIL = "hello@example.com" private const val A_PASSWORD = "a-password" -private val A_RESET_CAPABILITIES = ResetCapabilities(supportsLogoutAllDevices = true) class OnboardingViewModelTest { @@ -480,8 +479,9 @@ class OnboardingViewModelTest { @Test fun `given can successfully reset password, when resetting password, then emits reset done event`() = runTest { + viewModelWith(initialState.copy(selectedHomeserver = SELECTED_HOMESERVER_STATE_SUPPORTED_LOGOUT_DEVICES)) val test = viewModel.test() - fakeLoginWizard.givenResetPasswordSuccess(AN_EMAIL, A_RESET_CAPABILITIES) + fakeLoginWizard.givenResetPasswordSuccess(AN_EMAIL) fakeAuthenticationService.givenLoginWizard(fakeLoginWizard) viewModel.handle(OnboardingAction.ResetPassword(email = AN_EMAIL, newPassword = A_PASSWORD)) @@ -491,7 +491,7 @@ class OnboardingViewModelTest { initialState, { copy(isLoading = true) }, { - val resetState = ResetState(AN_EMAIL, A_PASSWORD, supportsLogoutAllDevices = A_RESET_CAPABILITIES.supportsLogoutAllDevices) + val resetState = ResetState(AN_EMAIL, A_PASSWORD, supportsLogoutAllDevices = true) copy(isLoading = false, resetState = resetState) } ) diff --git a/vector/src/test/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCaseTest.kt index b75ec231fd..810f2b43c9 100644 --- a/vector/src/test/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCaseTest.kt @@ -128,7 +128,8 @@ class StartAuthenticationFlowUseCaseTest { ssoIdentityProviders = SSO_IDENTITY_PROVIDERS, isLoginAndRegistrationSupported = true, homeServerUrl = A_DECLARED_HOMESERVER_URL, - isOutdatedHomeserver = false + isOutdatedHomeserver = false, + isLogoutDevicesSupported = false ) private fun expectedResult( diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeLoginWizard.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeLoginWizard.kt index c0f9f98f5f..38bb75087c 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeLoginWizard.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeLoginWizard.kt @@ -16,16 +16,14 @@ package im.vector.app.test.fakes -import io.mockk.coEvery import io.mockk.coJustRun import io.mockk.mockk import org.matrix.android.sdk.api.auth.login.LoginWizard -import org.matrix.android.sdk.internal.auth.login.ResetCapabilities class FakeLoginWizard : LoginWizard by mockk() { - fun givenResetPasswordSuccess(email: String, resetCapabilities: ResetCapabilities) { - coEvery { resetPassword(email) } returns resetCapabilities + fun givenResetPasswordSuccess(email: String) { + coJustRun { resetPassword(email) } } fun givenConfirmResetPasswordSuccess(password: String) {