Fix / support sso_with_password flow when no providers

This commit is contained in:
Valere 2020-12-03 14:58:45 +01:00 committed by Benoit Marty
parent 03428ea9f5
commit 351793d456
3 changed files with 59 additions and 46 deletions

View file

@ -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
}
}
}

View file

@ -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 {

View file

@ -1989,6 +1989,7 @@
<string name="login_social_continue_with">Continue with %s</string>
<string name="login_social_signup_with">Sign up with %s</string>
<string name="login_social_signin_with">Sign in with %s</string>
<string name="login_social_sso">single sign-on</string>
<string name="login_continue">Continue</string>
<!-- Replaced string is the homeserver url -->