From fb1a686f90bb69defc15c92b5e5a5bca4cc7d31e Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 9 May 2022 16:04:02 +0100 Subject: [PATCH] extracting the login error handling to its own class --- .../im/vector/app/core/di/FragmentModule.kt | 18 +++++ .../ftueauth/FtueAuthCombinedLoginFragment.kt | 25 ++----- .../onboarding/ftueauth/LoginErrorParser.kt | 69 +++++++++++++++++++ .../ftueauth/LoginFieldsValidation.kt | 2 +- 4 files changed, 94 insertions(+), 20 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/onboarding/ftueauth/LoginErrorParser.kt diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index 3dba8b797b..e76f0ad672 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -101,6 +101,9 @@ import im.vector.app.features.onboarding.ftueauth.FtueAuthAccountCreatedFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthCaptchaFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthChooseDisplayNameFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthChooseProfilePictureFragment +import im.vector.app.features.onboarding.ftueauth.FtueAuthCombinedLoginFragment +import im.vector.app.features.onboarding.ftueauth.FtueAuthCombinedRegisterFragment +import im.vector.app.features.onboarding.ftueauth.FtueAuthCombinedServerSelectionFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthEmailEntryFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthGenericTextInputFormFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthLegacyStyleCaptchaFragment @@ -521,6 +524,21 @@ interface FragmentModule { @FragmentKey(FtueAuthPersonalizationCompleteFragment::class) fun bindFtueAuthPersonalizationCompleteFragment(fragment: FtueAuthPersonalizationCompleteFragment): Fragment + @Binds + @IntoMap + @FragmentKey(FtueAuthCombinedLoginFragment::class) + fun bindFtueAuthCombinedLoginFragment(fragment: FtueAuthCombinedLoginFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(FtueAuthCombinedRegisterFragment::class) + fun bindFtueAuthCombinedRegisterFragment(fragment: FtueAuthCombinedRegisterFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(FtueAuthCombinedServerSelectionFragment::class) + fun bindFtueAuthCombinedServerSelectionFragment(fragment: FtueAuthCombinedServerSelectionFragment): Fragment + @Binds @IntoMap @FragmentKey(UserListFragment::class) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt index bcdcae7a7e..2bcaef1125 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt @@ -29,7 +29,6 @@ import im.vector.app.R import im.vector.app.core.extensions.content import im.vector.app.core.extensions.editText import im.vector.app.core.extensions.hasContentFlow -import im.vector.app.core.extensions.hasSurroundingSpaces import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.extensions.hidePassword import im.vector.app.core.extensions.realignPercentagesToParent @@ -45,13 +44,11 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import org.matrix.android.sdk.api.auth.data.SsoIdentityProvider -import org.matrix.android.sdk.api.failure.isInvalidPassword -import org.matrix.android.sdk.api.failure.isInvalidUsername -import org.matrix.android.sdk.api.failure.isLoginEmailUnknown import javax.inject.Inject class FtueAuthCombinedLoginFragment @Inject constructor( - private val loginFieldsValidation: LoginFieldsValidation + private val loginFieldsValidation: LoginFieldsValidation, + private val loginErrorParser: LoginErrorParser ) : AbstractSSOFtueAuthFragment() { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueCombinedLoginBinding { @@ -116,20 +113,10 @@ class FtueAuthCombinedLoginFragment @Inject constructor( override fun onError(throwable: Throwable) { // Trick to display the error without text. views.loginInput.error = " " - when { - throwable.isInvalidUsername() -> { - views.loginInput.error = errorFormatter.toHumanReadable(throwable) - } - throwable.isLoginEmailUnknown() -> { - views.loginInput.error = getString(R.string.login_login_with_email_error) - } - throwable.isInvalidPassword() && views.loginPasswordInput.hasSurroundingSpaces() -> { - views.loginPasswordInput.error = getString(R.string.auth_invalid_login_param_space_in_password) - } - else -> { - super.onError(throwable) - } - } + loginErrorParser.parse(throwable, views.loginPasswordInput.content()) + .onUnknown { super.onError(it) } + .onUsernameOrIdError { views.loginInput.error = it } + .onPasswordError { views.loginPasswordInput.error = it } } override fun updateWithState(state: OnboardingViewState) { diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/LoginErrorParser.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/LoginErrorParser.kt new file mode 100644 index 0000000000..a92fdea04a --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/LoginErrorParser.kt @@ -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.onboarding.ftueauth + +import im.vector.app.R +import im.vector.app.core.error.ErrorFormatter +import im.vector.app.core.resources.StringProvider +import im.vector.app.features.onboarding.ftueauth.LoginErrorParser.LoginErrorResult +import org.matrix.android.sdk.api.failure.isInvalidPassword +import org.matrix.android.sdk.api.failure.isInvalidUsername +import org.matrix.android.sdk.api.failure.isLoginEmailUnknown +import javax.inject.Inject + +class LoginErrorParser @Inject constructor( + private val errorFormatter: ErrorFormatter, + private val stringProvider: StringProvider, +) { + fun parse(throwable: Throwable, password: String): LoginErrorResult { + return when { + throwable.isInvalidUsername() -> { + LoginErrorResult(throwable, usernameOrIdError = errorFormatter.toHumanReadable(throwable)) + } + throwable.isLoginEmailUnknown() -> { + LoginErrorResult(throwable, usernameOrIdError = stringProvider.getString(R.string.login_login_with_email_error)) + } + throwable.isInvalidPassword() && password.hasSurroundingSpaces() -> { + LoginErrorResult(throwable, passwordError = stringProvider.getString(R.string.auth_invalid_login_param_space_in_password)) + } + else -> { + LoginErrorResult(throwable) + } + } + } + + private fun String.hasSurroundingSpaces() = trim() != this + + data class LoginErrorResult(val cause: Throwable, val usernameOrIdError: String? = null, val passwordError: String? = null) +} + +fun LoginErrorResult.onUnknown(action: (Throwable) -> Unit): LoginErrorResult { + when { + usernameOrIdError == null && passwordError == null -> action(cause) + } + return this +} + +fun LoginErrorResult.onUsernameOrIdError(action: (String) -> Unit): LoginErrorResult { + usernameOrIdError?.let(action) + return this +} + +fun LoginErrorResult.onPasswordError(action: (String) -> Unit): LoginErrorResult { + passwordError?.let(action) + return this +} diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/LoginFieldsValidation.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/LoginFieldsValidation.kt index 5a570a4dfe..659a8cd2c1 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/LoginFieldsValidation.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/LoginFieldsValidation.kt @@ -47,7 +47,7 @@ class LoginFieldsValidation @Inject constructor( fun LoginValidationResult.onValid(action: (String, String) -> Unit): LoginValidationResult { when { - usernameOrIdError != null && passwordError != null -> action(usernameOrId, password) + usernameOrIdError == null && passwordError == null -> action(usernameOrId, password) } return this }