#1682: try to fetch config.domain.json

This commit is contained in:
Benoit Marty 2020-08-17 19:39:29 +02:00
parent c11c28b406
commit 112f77c4e0
2 changed files with 63 additions and 24 deletions

View file

@ -42,6 +42,11 @@ import retrofit2.http.Url
* The login REST API.
*/
internal interface AuthAPI {
/**
* Get a Riot config file, using the name including the domain
*/
@GET("config.{domain}.json")
fun getRiotConfigDomain(@Path("domain") domain: String): Call<RiotConfig>
/**
* Get a Riot config file

View file

@ -19,6 +19,9 @@ package org.matrix.android.sdk.internal.auth
import android.net.Uri
import dagger.Lazy
import kotlinx.coroutines.launch
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.data.Credentials
@ -50,12 +53,8 @@ import org.matrix.android.sdk.internal.task.TaskExecutor
import org.matrix.android.sdk.internal.task.configureWith
import org.matrix.android.sdk.internal.task.launchToCallback
import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
import org.matrix.android.sdk.internal.util.exhaustive
import org.matrix.android.sdk.internal.util.toCancelable
import org.matrix.android.sdk.internal.wellknown.GetWellknownTask
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import javax.inject.Inject
import javax.net.ssl.HttpsURLConnection
@ -157,7 +156,7 @@ internal class DefaultAuthenticationService @Inject constructor(
if (it is Failure.OtherServerError
&& it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
// It's maybe a Riot url?
getRiotLoginFlowInternal(homeServerConnectionConfig)
getRiotDomainLoginFlowInternal(homeServerConnectionConfig)
} else {
throw it
}
@ -166,6 +165,37 @@ internal class DefaultAuthenticationService @Inject constructor(
}
}
private suspend fun getRiotDomainLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
val authAPI = buildAuthAPI(homeServerConnectionConfig)
val domain = homeServerConnectionConfig.homeServerUri.host
?: return getRiotLoginFlowInternal(homeServerConnectionConfig)
// Ok, try to get the config.domain.json file of a RiotWeb client
return runCatching {
executeRequest<RiotConfig>(null) {
apiCall = authAPI.getRiotConfigDomain(domain)
}
}
.map { riotConfig ->
onRiotConfigRetrieved(homeServerConnectionConfig, riotConfig)
}
.fold(
{
it
},
{
if (it is Failure.OtherServerError
&& it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
// Try with config.json
getRiotLoginFlowInternal(homeServerConnectionConfig)
} else {
throw it
}
}
)
}
private suspend fun getRiotLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
val authAPI = buildAuthAPI(homeServerConnectionConfig)
@ -176,24 +206,7 @@ internal class DefaultAuthenticationService @Inject constructor(
}
}
.map { riotConfig ->
val defaultHomeServerUrl = riotConfig.getPreferredHomeServerUrl()
if (defaultHomeServerUrl?.isNotEmpty() == true) {
// Ok, good sign, we got a default hs url
val newHomeServerConnectionConfig = homeServerConnectionConfig.copy(
homeServerUri = Uri.parse(defaultHomeServerUrl)
)
val newAuthAPI = buildAuthAPI(newHomeServerConnectionConfig)
val versions = executeRequest<Versions>(null) {
apiCall = newAuthAPI.versions()
}
getLoginFlowResult(newAuthAPI, versions, defaultHomeServerUrl)
} else {
// Config exists, but there is no default homeserver url (ex: https://riot.im/app)
throw Failure.OtherServerError("", HttpsURLConnection.HTTP_NOT_FOUND /* 404 */)
}
onRiotConfigRetrieved(homeServerConnectionConfig, riotConfig)
}
.fold(
{
@ -211,6 +224,27 @@ internal class DefaultAuthenticationService @Inject constructor(
)
}
private suspend fun onRiotConfigRetrieved(homeServerConnectionConfig: HomeServerConnectionConfig, riotConfig: RiotConfig): LoginFlowResult {
val defaultHomeServerUrl = riotConfig.getPreferredHomeServerUrl()
if (defaultHomeServerUrl?.isNotEmpty() == true) {
// Ok, good sign, we got a default hs url
val newHomeServerConnectionConfig = homeServerConnectionConfig.copy(
homeServerUri = Uri.parse(defaultHomeServerUrl)
)
val newAuthAPI = buildAuthAPI(newHomeServerConnectionConfig)
val versions = executeRequest<Versions>(null) {
apiCall = newAuthAPI.versions()
}
return getLoginFlowResult(newAuthAPI, versions, defaultHomeServerUrl)
} else {
// Config exists, but there is no default homeserver url (ex: https://riot.im/app)
throw Failure.OtherServerError("", HttpsURLConnection.HTTP_NOT_FOUND /* 404 */)
}
}
private suspend fun getWellknownLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
val domain = homeServerConnectionConfig.homeServerUri.host
?: throw Failure.OtherServerError("", HttpsURLConnection.HTTP_NOT_FOUND /* 404 */)
@ -235,7 +269,7 @@ internal class DefaultAuthenticationService @Inject constructor(
getLoginFlowResult(newAuthAPI, versions, wellknownResult.homeServerUrl)
}
else -> throw Failure.OtherServerError("", HttpsURLConnection.HTTP_NOT_FOUND /* 404 */)
}.exhaustive
}
}
private suspend fun getLoginFlowResult(authAPI: AuthAPI, versions: Versions, homeServerUrl: String): LoginFlowResult {