mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-23 18:05:59 +03:00
Let the Matrix SDK compute the SSO url
This commit is contained in:
parent
4a5dbde8d3
commit
13938f2ab3
12 changed files with 103 additions and 56 deletions
|
@ -41,6 +41,11 @@ interface AuthenticationService {
|
|||
*/
|
||||
fun getLoginFlowOfSession(sessionId: String, callback: MatrixCallback<LoginFlowResult>): Cancelable
|
||||
|
||||
/**
|
||||
* Get a SSO url
|
||||
*/
|
||||
fun getSsoUrl(redirectUrl: String, deviceId: String?, providerId: String?): String?
|
||||
|
||||
/**
|
||||
* Return a LoginWizard, to login to the homeserver. The login flow has to be retrieved first.
|
||||
*/
|
||||
|
|
|
@ -32,7 +32,7 @@ const val REGISTER_FALLBACK_PATH = "/_matrix/static/client/register/"
|
|||
* Path to use when the client want to connect using SSO
|
||||
* Ref: https://matrix.org/docs/spec/client_server/latest#sso-client-login
|
||||
*/
|
||||
const val SSO_REDIRECT_PATH = "/_matrix/client/r0/login/sso/redirect"
|
||||
const val MSC2858_SSO_REDIRECT_PATH = "/_matrix/client/unstable/org.matrix.msc2858/login/sso/redirect"
|
||||
internal const val SSO_REDIRECT_PATH = "/_matrix/client/r0/login/sso/redirect"
|
||||
internal const val MSC2858_SSO_REDIRECT_PATH = "/_matrix/client/unstable/org.matrix.msc2858/login/sso/redirect"
|
||||
|
||||
const val SSO_REDIRECT_URL_PARAM = "redirectUrl"
|
||||
internal const val SSO_REDIRECT_URL_PARAM = "redirectUrl"
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2020 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.api.util
|
||||
|
||||
import java.net.URLEncoder
|
||||
|
||||
/**
|
||||
* Append param and value to a Url, using "?" or "&". Value parameter will be encoded
|
||||
* Return this for chaining purpose
|
||||
*/
|
||||
fun StringBuilder.appendParamToUrl(param: String, value: String): StringBuilder {
|
||||
if (contains("?")) {
|
||||
append("&")
|
||||
} else {
|
||||
append("?")
|
||||
}
|
||||
|
||||
append(param)
|
||||
append("=")
|
||||
append(URLEncoder.encode(value, "utf-8"))
|
||||
|
||||
return this
|
||||
}
|
|
@ -23,6 +23,9 @@ import kotlinx.coroutines.withContext
|
|||
import okhttp3.OkHttpClient
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import org.matrix.android.sdk.api.auth.AuthenticationService
|
||||
import org.matrix.android.sdk.api.auth.MSC2858_SSO_REDIRECT_PATH
|
||||
import org.matrix.android.sdk.api.auth.SSO_REDIRECT_PATH
|
||||
import org.matrix.android.sdk.api.auth.SSO_REDIRECT_URL_PARAM
|
||||
import org.matrix.android.sdk.api.auth.data.Credentials
|
||||
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
|
||||
import org.matrix.android.sdk.api.auth.data.LoginFlowResult
|
||||
|
@ -34,6 +37,7 @@ import org.matrix.android.sdk.api.failure.Failure
|
|||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.util.Cancelable
|
||||
import org.matrix.android.sdk.api.util.NoOpCancellable
|
||||
import org.matrix.android.sdk.api.util.appendParamToUrl
|
||||
import org.matrix.android.sdk.internal.SessionManager
|
||||
import org.matrix.android.sdk.internal.auth.data.LoginFlowResponse
|
||||
import org.matrix.android.sdk.internal.auth.data.RiotConfig
|
||||
|
@ -99,6 +103,28 @@ internal class DefaultAuthenticationService @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun getSsoUrl(redirectUrl: String, deviceId: String?, providerId: String?): String? {
|
||||
return pendingSessionData?.let { safePendingSessionData ->
|
||||
val homeServerUrl = safePendingSessionData.homeServerConnectionConfig.homeServerUri.toString()
|
||||
|
||||
buildString {
|
||||
append(homeServerUrl.trim { it == '/' })
|
||||
if (providerId != null) {
|
||||
append(MSC2858_SSO_REDIRECT_PATH)
|
||||
append("/$providerId")
|
||||
} else {
|
||||
append(SSO_REDIRECT_PATH)
|
||||
}
|
||||
// Set a redirect url we will intercept later
|
||||
appendParamToUrl(SSO_REDIRECT_URL_PARAM, redirectUrl)
|
||||
deviceId?.takeIf { it.isNotBlank() }?.let {
|
||||
// But https://github.com/matrix-org/synapse/issues/5755
|
||||
appendParamToUrl("device_id", it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig, callback: MatrixCallback<LoginFlowResult>): Cancelable {
|
||||
pendingSessionData = null
|
||||
|
||||
|
|
|
@ -16,26 +16,6 @@
|
|||
|
||||
package im.vector.app.core.extensions
|
||||
|
||||
import java.net.URLEncoder
|
||||
|
||||
/**
|
||||
* Append param and value to a Url, using "?" or "&". Value parameter will be encoded
|
||||
* Return this for chaining purpose
|
||||
*/
|
||||
fun StringBuilder.appendParamToUrl(param: String, value: String): StringBuilder {
|
||||
if (contains("?")) {
|
||||
append("&")
|
||||
} else {
|
||||
append("?")
|
||||
}
|
||||
|
||||
append(param)
|
||||
append("=")
|
||||
append(URLEncoder.encode(value, "utf-8"))
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Ex: "https://matrix.org/" -> "matrix.org"
|
||||
*/
|
||||
|
|
|
@ -87,7 +87,12 @@ abstract class AbstractSSOLoginFragment<VB: ViewBinding> : AbstractLoginFragment
|
|||
withState(loginViewModel) { state ->
|
||||
if (state.loginMode.hasSso() && state.loginMode.ssoIdentityProviders().isNullOrEmpty()) {
|
||||
// in this case we can prefetch (not other cases for privacy concerns)
|
||||
prefetchUrl(state.getSsoUrl(null))
|
||||
loginViewModel.getSsoUrl(
|
||||
redirectUrl = LoginActivity.VECTOR_REDIRECT_URL,
|
||||
deviceId = state.deviceId,
|
||||
providerId = null
|
||||
)
|
||||
?.let { prefetchUrl(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -360,6 +360,9 @@ open class LoginActivity : VectorBaseActivity<ActivityLoginBinding>(), ToolbarCo
|
|||
|
||||
private const val EXTRA_CONFIG = "EXTRA_CONFIG"
|
||||
|
||||
// Note that the domain can be displayed to the user for confirmation that he trusts it. So use a human readable string
|
||||
const val VECTOR_REDIRECT_URL = "element://connect"
|
||||
|
||||
fun newIntent(context: Context, loginConfig: LoginConfig?): Intent {
|
||||
return Intent(context, LoginActivity::class.java).apply {
|
||||
putExtra(EXTRA_CONFIG, loginConfig)
|
||||
|
|
|
@ -193,7 +193,12 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment<FragmentLog
|
|||
views.loginSocialLoginButtons.ssoIdentityProviders = state.loginMode.ssoIdentityProviders
|
||||
views.loginSocialLoginButtons.listener = object : SocialLoginButtonsView.InteractionListener {
|
||||
override fun onProviderSelected(id: String?) {
|
||||
openInCustomTab(state.getSsoUrl(id))
|
||||
loginViewModel.getSsoUrl(
|
||||
redirectUrl = LoginActivity.VECTOR_REDIRECT_URL,
|
||||
deviceId = state.deviceId,
|
||||
providerId = id
|
||||
)
|
||||
?.let { openInCustomTab(it) }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -76,8 +76,12 @@ class LoginSignUpSignInSelectionFragment @Inject constructor() : AbstractSSOLogi
|
|||
views.loginSignupSigninSocialLoginButtons.ssoIdentityProviders = state.loginMode.ssoIdentityProviders()
|
||||
views.loginSignupSigninSocialLoginButtons.listener = object : SocialLoginButtonsView.InteractionListener {
|
||||
override fun onProviderSelected(id: String?) {
|
||||
val url = withState(loginViewModel) { it.getSsoUrl(id) }
|
||||
openInCustomTab(url)
|
||||
loginViewModel.getSsoUrl(
|
||||
redirectUrl = LoginActivity.VECTOR_REDIRECT_URL,
|
||||
deviceId = state.deviceId,
|
||||
providerId = id
|
||||
)
|
||||
?.let { openInCustomTab(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,7 +109,12 @@ class LoginSignUpSignInSelectionFragment @Inject constructor() : AbstractSSOLogi
|
|||
|
||||
private fun submit() = withState(loginViewModel) { state ->
|
||||
if (state.loginMode is LoginMode.Sso) {
|
||||
openInCustomTab(state.getSsoUrl(null))
|
||||
loginViewModel.getSsoUrl(
|
||||
redirectUrl = LoginActivity.VECTOR_REDIRECT_URL,
|
||||
deviceId = state.deviceId,
|
||||
providerId = null
|
||||
)
|
||||
?.let { openInCustomTab(it) }
|
||||
} else {
|
||||
loginViewModel.handle(LoginAction.UpdateSignMode(SignMode.SignUp))
|
||||
}
|
||||
|
|
|
@ -818,4 +818,8 @@ class LoginViewModel @AssistedInject constructor(
|
|||
fun getInitialHomeServerUrl(): String? {
|
||||
return loginConfig?.homeServerUrl
|
||||
}
|
||||
|
||||
fun getSsoUrl(redirectUrl: String, deviceId: String?, providerId: String?): String? {
|
||||
return authenticationService.getSsoUrl(redirectUrl, deviceId, providerId)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,10 +22,6 @@ import com.airbnb.mvrx.MvRxState
|
|||
import com.airbnb.mvrx.PersistState
|
||||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import im.vector.app.core.extensions.appendParamToUrl
|
||||
import org.matrix.android.sdk.api.auth.MSC2858_SSO_REDIRECT_PATH
|
||||
import org.matrix.android.sdk.api.auth.SSO_REDIRECT_PATH
|
||||
import org.matrix.android.sdk.api.auth.SSO_REDIRECT_URL_PARAM
|
||||
|
||||
data class LoginViewState(
|
||||
val asyncLoginAction: Async<Unit> = Uninitialized,
|
||||
|
@ -69,27 +65,4 @@ data class LoginViewState(
|
|||
fun isUserLogged(): Boolean {
|
||||
return asyncLoginAction is Success
|
||||
}
|
||||
|
||||
fun getSsoUrl(providerId: String?): String {
|
||||
return buildString {
|
||||
append(homeServerUrl?.trim { it == '/' })
|
||||
if (providerId != null) {
|
||||
append(MSC2858_SSO_REDIRECT_PATH)
|
||||
append("/$providerId")
|
||||
} else {
|
||||
append(SSO_REDIRECT_PATH)
|
||||
}
|
||||
// Set a redirect url we will intercept later
|
||||
appendParamToUrl(SSO_REDIRECT_URL_PARAM, VECTOR_REDIRECT_URL)
|
||||
deviceId?.takeIf { it.isNotBlank() }?.let {
|
||||
// But https://github.com/matrix-org/synapse/issues/5755
|
||||
appendParamToUrl("device_id", it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
// Note that the domain can be displayed to the user for confirmation that he trusts it. So use a human readable string
|
||||
private const val VECTOR_REDIRECT_URL = "element://connect"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ import android.webkit.WebViewClient
|
|||
import androidx.appcompat.app.AlertDialog
|
||||
import com.airbnb.mvrx.activityViewModel
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.appendParamToUrl
|
||||
import im.vector.app.core.utils.AssetReader
|
||||
import im.vector.app.databinding.FragmentLoginWebBinding
|
||||
import im.vector.app.features.signout.soft.SoftLogoutAction
|
||||
|
@ -42,6 +41,7 @@ import im.vector.app.features.signout.soft.SoftLogoutViewModel
|
|||
import org.matrix.android.sdk.api.auth.LOGIN_FALLBACK_PATH
|
||||
import org.matrix.android.sdk.api.auth.REGISTER_FALLBACK_PATH
|
||||
import org.matrix.android.sdk.api.auth.data.Credentials
|
||||
import org.matrix.android.sdk.api.util.appendParamToUrl
|
||||
import org.matrix.android.sdk.internal.di.MoshiProvider
|
||||
import timber.log.Timber
|
||||
import java.net.URLDecoder
|
||||
|
|
Loading…
Reference in a new issue