mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 02:05:06 +08:00
Merge pull request #1945 from vector-im/feature/update_element_config_file_parsing
Feature/update element config file parsing
This commit is contained in:
commit
72f5f8b64b
@ -9,6 +9,7 @@ Improvements 🙌:
|
||||
- Give user the possibility to prevent accidental call (#1869)
|
||||
- Display device information (name, id and key) in Cryptography setting screen (#1784)
|
||||
- Ensure users do not accidentally ignore other users (#1890)
|
||||
- Support new config.json format and config.domain.json files (#1682)
|
||||
- Increase Font size on Calling screen (#1643)
|
||||
|
||||
Bugfix 🐛:
|
||||
|
@ -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
|
||||
|
@ -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,23 +206,7 @@ internal class DefaultAuthenticationService @Inject constructor(
|
||||
}
|
||||
}
|
||||
.map { riotConfig ->
|
||||
if (riotConfig.defaultHomeServerUrl?.isNotBlank() == true) {
|
||||
// Ok, good sign, we got a default hs url
|
||||
val newHomeServerConnectionConfig = homeServerConnectionConfig.copy(
|
||||
homeServerUri = Uri.parse(riotConfig.defaultHomeServerUrl)
|
||||
)
|
||||
|
||||
val newAuthAPI = buildAuthAPI(newHomeServerConnectionConfig)
|
||||
|
||||
val versions = executeRequest<Versions>(null) {
|
||||
apiCall = newAuthAPI.versions()
|
||||
}
|
||||
|
||||
getLoginFlowResult(newAuthAPI, versions, riotConfig.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(
|
||||
{
|
||||
@ -210,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 */)
|
||||
@ -234,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 {
|
||||
|
@ -21,9 +21,31 @@ import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class RiotConfig(
|
||||
// There are plenty of other elements in the file config.json of a RiotWeb client, but for the moment only one is interesting
|
||||
// Ex: "brand", "branding", etc.
|
||||
internal data class RiotConfig(
|
||||
/**
|
||||
* This is now deprecated, but still used first, rather than value from "default_server_config"
|
||||
*/
|
||||
@Json(name = "default_hs_url")
|
||||
val defaultHomeServerUrl: String?
|
||||
val defaultHomeServerUrl: String?,
|
||||
|
||||
@Json(name = "default_server_config")
|
||||
val defaultServerConfig: RiotConfigDefaultServerConfig?
|
||||
) {
|
||||
fun getPreferredHomeServerUrl(): String? {
|
||||
return defaultHomeServerUrl
|
||||
?.takeIf { it.isNotEmpty() }
|
||||
?: defaultServerConfig?.homeServer?.baseURL
|
||||
}
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class RiotConfigDefaultServerConfig(
|
||||
@Json(name = "m.homeserver")
|
||||
val homeServer: RiotConfigBaseConfig? = null
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class RiotConfigBaseConfig(
|
||||
@Json(name = "base_url")
|
||||
val baseURL: String? = null
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user