From 351793d456be4751b26c86283a5339a461152025 Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 3 Dec 2020 14:58:45 +0100 Subject: [PATCH] Fix / support sso_with_password flow when no providers --- .../LoginSignUpSignInSelectionFragment.kt | 29 +++---- .../features/login/SocialLoginButtonsView.kt | 75 +++++++++++-------- vector/src/main/res/values/strings.xml | 1 + 3 files changed, 59 insertions(+), 46 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/login/LoginSignUpSignInSelectionFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginSignUpSignInSelectionFragment.kt index 00b03835ae..d487ee50de 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginSignUpSignInSelectionFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginSignUpSignInSelectionFragment.kt @@ -28,7 +28,6 @@ import im.vector.app.R import im.vector.app.core.extensions.toReducedUrl import im.vector.app.core.utils.openUrlInChromeCustomTab import kotlinx.android.synthetic.main.fragment_login_signup_signin_selection.* -import org.matrix.android.sdk.api.auth.data.IdentityProvider import javax.inject.Inject /** @@ -53,32 +52,36 @@ class LoginSignUpSignInSelectionFragment @Inject constructor() : AbstractLoginFr loginSignupSigninTitle.text = getString(R.string.login_connect_to, state.homeServerUrl.toReducedUrl()) loginSignupSigninText.text = getString(R.string.login_server_matrix_org_text) } - ServerType.EMS -> { + ServerType.EMS -> { loginSignupSigninServerIcon.setImageResource(R.drawable.ic_logo_element_matrix_services) loginSignupSigninServerIcon.isVisible = true loginSignupSigninTitle.text = getString(R.string.login_connect_to_modular) loginSignupSigninText.text = state.homeServerUrl.toReducedUrl() } - ServerType.Other -> { + ServerType.Other -> { loginSignupSigninServerIcon.isVisible = false loginSignupSigninTitle.text = getString(R.string.login_server_other_title) loginSignupSigninText.text = getString(R.string.login_connect_to, state.homeServerUrl.toReducedUrl()) } - ServerType.Unknown -> Unit /* Should not happen */ + ServerType.Unknown -> Unit /* Should not happen */ } val identityProviders = state.loginMode.ssoProviders() - if (state.loginMode.hasSso() && identityProviders.isNullOrEmpty().not()) { - loginSignupSigninSignInSocialLoginContainer.isVisible = true - loginSignupSigninSocialLoginButtons.identityProviders = identityProviders - loginSignupSigninSocialLoginButtons.listener = object: SocialLoginButtonsView.InteractionListener { - override fun onProviderSelected(id: IdentityProvider) { - ssoUrls[id.id]?.let { openUrlInChromeCustomTab(requireContext(), customTabsSession, it) } + when (state.loginMode) { + is LoginMode.SsoAndPassword -> { + loginSignupSigninSignInSocialLoginContainer.isVisible = true + loginSignupSigninSocialLoginButtons.identityProviders = identityProviders + loginSignupSigninSocialLoginButtons.listener = object : SocialLoginButtonsView.InteractionListener { + override fun onProviderSelected(id: String?) { + ssoUrls[id]?.let { openUrlInChromeCustomTab(requireContext(), customTabsSession, it) } + } } } - } else { - loginSignupSigninSignInSocialLoginContainer.isVisible = false - loginSignupSigninSocialLoginButtons.identityProviders = null + else -> { + // SSO only is managed without container as well as No sso + loginSignupSigninSignInSocialLoginContainer.isVisible = false + loginSignupSigninSocialLoginButtons.identityProviders = null + } } } diff --git a/vector/src/main/java/im/vector/app/features/login/SocialLoginButtonsView.kt b/vector/src/main/java/im/vector/app/features/login/SocialLoginButtonsView.kt index 1d323c0fbc..f6f2678557 100644 --- a/vector/src/main/java/im/vector/app/features/login/SocialLoginButtonsView.kt +++ b/vector/src/main/java/im/vector/app/features/login/SocialLoginButtonsView.kt @@ -32,7 +32,7 @@ class SocialLoginButtonsView @JvmOverloads constructor(context: Context, attrs: : LinearLayout(context, attrs, defStyle) { interface InteractionListener { - fun onProviderSelected(id: IdentityProvider) + fun onProviderSelected(id: String?) } enum class Mode { @@ -66,53 +66,61 @@ class SocialLoginButtonsView @JvmOverloads constructor(context: Context, attrs: } removeAllViews() if (identityProviders.isNullOrEmpty()) { + // Put a default sign in with sso button + MaterialButton(context, null, R.attr.materialButtonOutlinedStyle).apply { + transformationMethod = null + textAlignment = View.TEXT_ALIGNMENT_CENTER + }.let { + it.text = getButtonTitle(context.getString(R.string.login_social_sso)) + it.textAlignment = View.TEXT_ALIGNMENT_CENTER + it.setOnClickListener { + listener?.onProviderSelected(null) + } + addView(it) + } return } identityProviders?.forEach { identityProvider -> // Use some heuristic to render buttons according to branding guidelines - val cached = cachedViews[identityProvider.id] - val button: MaterialButton = if (cached != null) { - cached - } else { - when (identityProvider.id) { - "google" -> { - MaterialButton(context, null, R.attr.vctr_social_login_button_google_style) - } - "github" -> { - MaterialButton(context, null, R.attr.vctr_social_login_button_github_style) - } - "apple" -> { - MaterialButton(context, null, R.attr.vctr_social_login_button_apple_style) - } - "facebook" -> { - MaterialButton(context, null, R.attr.vctr_social_login_button_facebook_style) - } - "twitter" -> { - MaterialButton(context, null, R.attr.vctr_social_login_button_twitter_style) - } - else -> { - MaterialButton(context, null, R.attr.materialButtonStyle).apply { - transformationMethod = null - textAlignment = View.TEXT_ALIGNMENT_CENTER + val button: MaterialButton = cachedViews[identityProvider.id] + ?: when (identityProvider.id) { + "google" -> { + MaterialButton(context, null, R.attr.vctr_social_login_button_google_style) + } + "github" -> { + MaterialButton(context, null, R.attr.vctr_social_login_button_github_style) + } + "apple" -> { + MaterialButton(context, null, R.attr.vctr_social_login_button_apple_style) + } + "facebook" -> { + MaterialButton(context, null, R.attr.vctr_social_login_button_facebook_style) + } + "twitter" -> { + MaterialButton(context, null, R.attr.vctr_social_login_button_twitter_style) + } + else -> { + MaterialButton(context, null, R.attr.materialButtonStyle).apply { + transformationMethod = null + textAlignment = View.TEXT_ALIGNMENT_CENTER + } } } - } - } - button.text = getButtonTitle(identityProvider) + button.text = getButtonTitle(identityProvider.name) button.setTag(R.id.loginSignupSigninSocialLoginButtons, identityProvider.id) button.setOnClickListener { - listener?.onProviderSelected(identityProvider) + listener?.onProviderSelected(identityProvider.id) } addView(button) } } - private fun getButtonTitle(provider: IdentityProvider): String { + private fun getButtonTitle(providerName: String?): String { return when (mode) { - Mode.MODE_SIGN_IN -> context.getString(R.string.login_social_signin_with, provider.name) - Mode.MODE_SIGN_UP -> context.getString(R.string.login_social_signup_with, provider.name) - Mode.MODE_CONTINUE -> context.getString(R.string.login_social_continue_with, provider.name) + Mode.MODE_SIGN_IN -> context.getString(R.string.login_social_signin_with, providerName) + Mode.MODE_SIGN_UP -> context.getString(R.string.login_social_signup_with, providerName) + Mode.MODE_CONTINUE -> context.getString(R.string.login_social_continue_with, providerName) } } @@ -140,6 +148,7 @@ class SocialLoginButtonsView @JvmOverloads constructor(context: Context, attrs: else -> Mode.MODE_CONTINUE } typedArray.recycle() + update() } fun dpToPx(dp: Int): Int { diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index b8d58b809d..5ceee44afa 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1989,6 +1989,7 @@ Continue with %s Sign up with %s Sign in with %s + single sign-on Continue