mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-25 10:55:55 +03:00
Merge pull request #3585 from vector-im/feature/bma/wellknown
Improve wellknown usage
This commit is contained in:
commit
ca45cdd5c7
52 changed files with 330 additions and 200 deletions
|
@ -38,6 +38,7 @@
|
|||
<w>unpublish</w>
|
||||
<w>unwedging</w>
|
||||
<w>vctr</w>
|
||||
<w>wellknown</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
1
changelog.d/2843.bugfix
Normal file
1
changelog.d/2843.bugfix
Normal file
|
@ -0,0 +1 @@
|
|||
Perform .well-known request first, even if the entered URL is a valid homeserver base url
|
1
changelog.d/3572.misc
Normal file
1
changelog.d/3572.misc
Normal file
|
@ -0,0 +1 @@
|
|||
RawService.getWellknown() now takes a domain instead of a matrixId as parameter
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package org.matrix.android.sdk.api
|
||||
|
||||
import org.matrix.android.sdk.BuildConfig
|
||||
|
||||
/**
|
||||
* This class contains pattern to match the different Matrix ids
|
||||
*/
|
||||
|
@ -154,7 +156,7 @@ object MatrixPatterns {
|
|||
* Orders which are not strings, or do not consist solely of ascii characters in the range \x20 (space) to \x7E (~),
|
||||
* or consist of more than 50 characters, are forbidden and the field should be ignored if received.
|
||||
*/
|
||||
fun isValidOrderString(order: String?) : Boolean {
|
||||
fun isValidOrderString(order: String?): Boolean {
|
||||
return order != null && order.length < 50 && order matches ORDER_STRING_REGEX
|
||||
}
|
||||
|
||||
|
@ -163,4 +165,17 @@ object MatrixPatterns {
|
|||
"[^a-z0-9._%#@=+-]".toRegex().replace(it, "")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the domain form a userId
|
||||
* Examples:
|
||||
* - "@alice:domain.org".getDomain() will return "domain.org"
|
||||
* - "@bob:domain.org:3455".getDomain() will return "domain.org:3455"
|
||||
*/
|
||||
fun String.getDomain(): String {
|
||||
if (BuildConfig.DEBUG) {
|
||||
assert(isUserId(this))
|
||||
}
|
||||
return substringAfter(":")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,11 +18,11 @@ package org.matrix.android.sdk.api.auth.data
|
|||
|
||||
import android.net.Uri
|
||||
import com.squareup.moshi.JsonClass
|
||||
import okhttp3.CipherSuite
|
||||
import okhttp3.TlsVersion
|
||||
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig.Builder
|
||||
import org.matrix.android.sdk.internal.network.ssl.Fingerprint
|
||||
import org.matrix.android.sdk.internal.util.ensureTrailingSlash
|
||||
import okhttp3.CipherSuite
|
||||
import okhttp3.TlsVersion
|
||||
|
||||
/**
|
||||
* This data class holds how to connect to a specific Homeserver.
|
||||
|
@ -31,7 +31,12 @@ import okhttp3.TlsVersion
|
|||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class HomeServerConnectionConfig(
|
||||
// This is the homeserver URL entered by the user
|
||||
val homeServerUri: Uri,
|
||||
// This is the homeserver base URL for the client-server API. Default to homeServerUri,
|
||||
// but can be updated with data from .Well-Known before login, and/or with the data
|
||||
// included in the login response
|
||||
val homeServerUriBase: Uri = homeServerUri,
|
||||
val identityServerUri: Uri? = null,
|
||||
val antiVirusServerUri: Uri? = null,
|
||||
val allowedFingerprints: List<Fingerprint> = emptyList(),
|
||||
|
@ -47,7 +52,6 @@ data class HomeServerConnectionConfig(
|
|||
* This builder should be use to create a [HomeServerConnectionConfig] instance.
|
||||
*/
|
||||
class Builder {
|
||||
|
||||
private lateinit var homeServerUri: Uri
|
||||
private var identityServerUri: Uri? = null
|
||||
private var antiVirusServerUri: Uri? = null
|
||||
|
@ -234,16 +238,16 @@ data class HomeServerConnectionConfig(
|
|||
*/
|
||||
fun build(): HomeServerConnectionConfig {
|
||||
return HomeServerConnectionConfig(
|
||||
homeServerUri,
|
||||
identityServerUri,
|
||||
antiVirusServerUri,
|
||||
allowedFingerprints,
|
||||
shouldPin,
|
||||
tlsVersions,
|
||||
tlsCipherSuites,
|
||||
shouldAcceptTlsExtensions,
|
||||
allowHttpExtension,
|
||||
forceUsageTlsVersions
|
||||
homeServerUri = homeServerUri,
|
||||
identityServerUri = identityServerUri,
|
||||
antiVirusServerUri = antiVirusServerUri,
|
||||
allowedFingerprints = allowedFingerprints,
|
||||
shouldPin = shouldPin,
|
||||
tlsVersions = tlsVersions,
|
||||
tlsCipherSuites = tlsCipherSuites,
|
||||
shouldAcceptTlsExtensions = shouldAcceptTlsExtensions,
|
||||
allowHttpExtension = allowHttpExtension,
|
||||
forceUsageTlsVersions = forceUsageTlsVersions
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,13 +51,18 @@ data class SessionParams(
|
|||
val deviceId = credentials.deviceId
|
||||
|
||||
/**
|
||||
* The current homeserver Url. It can be different that the homeserver url entered
|
||||
* during login phase, because a redirection may have occurred
|
||||
* The homeserver Url entered by the user during the login phase.
|
||||
*/
|
||||
val homeServerUrl = homeServerConnectionConfig.homeServerUri.toString()
|
||||
|
||||
/**
|
||||
* The current homeserver host
|
||||
* The current homeserver Url for client-server API. It can be different that the homeserver url entered
|
||||
* during login phase, because a redirection may have occurred
|
||||
*/
|
||||
val homeServerUrlBase = homeServerConnectionConfig.homeServerUriBase.toString()
|
||||
|
||||
/**
|
||||
* The current homeserver host, using what has been entered by the user during login phase
|
||||
*/
|
||||
val homeServerHost = homeServerConnectionConfig.homeServerUri.host
|
||||
|
||||
|
|
|
@ -22,11 +22,6 @@ import org.matrix.android.sdk.api.auth.data.WellKnown
|
|||
* Ref: https://matrix.org/docs/spec/client_server/latest#well-known-uri
|
||||
*/
|
||||
sealed class WellknownResult {
|
||||
/**
|
||||
* The provided matrixId is no valid. Unable to extract a domain name.
|
||||
*/
|
||||
object InvalidMatrixId : WellknownResult()
|
||||
|
||||
/**
|
||||
* Retrieve the specific piece of information from the user in a way which fits within the existing client user experience,
|
||||
* if the client is inclined to do so. Failure can take place instead if no good user experience for this is possible at this point.
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (c) 2021 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* 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.failure
|
||||
|
||||
sealed class MatrixIdFailure : Failure.FeatureFailure() {
|
||||
object InvalidMatrixId : MatrixIdFailure()
|
||||
}
|
|
@ -29,8 +29,10 @@ interface RawService {
|
|||
|
||||
/**
|
||||
* Specific case for the well-known file. Cache validity is 8 hours
|
||||
* @param domain the domain to get the .well-known file, for instance "matrix.org".
|
||||
* The URL will be "https://{domain}/.well-known/matrix/client"
|
||||
*/
|
||||
suspend fun getWellknown(userId: String): String
|
||||
suspend fun getWellknown(domain: String): String
|
||||
|
||||
/**
|
||||
* Clear all the cache data
|
||||
|
|
|
@ -21,8 +21,8 @@ import org.matrix.android.sdk.api.util.JsonDict
|
|||
import org.matrix.android.sdk.internal.auth.data.Availability
|
||||
import org.matrix.android.sdk.internal.auth.data.LoginFlowResponse
|
||||
import org.matrix.android.sdk.internal.auth.data.PasswordLoginParams
|
||||
import org.matrix.android.sdk.internal.auth.data.RiotConfig
|
||||
import org.matrix.android.sdk.internal.auth.data.TokenLoginParams
|
||||
import org.matrix.android.sdk.internal.auth.data.WebClientConfig
|
||||
import org.matrix.android.sdk.internal.auth.login.ResetPasswordMailConfirmed
|
||||
import org.matrix.android.sdk.internal.auth.registration.AddThreePidRegistrationParams
|
||||
import org.matrix.android.sdk.internal.auth.registration.AddThreePidRegistrationResponse
|
||||
|
@ -44,16 +44,16 @@ import retrofit2.http.Url
|
|||
*/
|
||||
internal interface AuthAPI {
|
||||
/**
|
||||
* Get a Riot config file, using the name including the domain
|
||||
* Get a Web client config file, using the name including the domain
|
||||
*/
|
||||
@GET("config.{domain}.json")
|
||||
suspend fun getRiotConfigDomain(@Path("domain") domain: String): RiotConfig
|
||||
suspend fun getWebClientConfigDomain(@Path("domain") domain: String): WebClientConfig
|
||||
|
||||
/**
|
||||
* Get a Riot config file
|
||||
* Get a Web client default config file
|
||||
*/
|
||||
@GET("config.json")
|
||||
suspend fun getRiotConfig(): RiotConfig
|
||||
suspend fun getWebClientConfig(): WebClientConfig
|
||||
|
||||
/**
|
||||
* Get the version information of the homeserver
|
||||
|
|
|
@ -19,6 +19,8 @@ package org.matrix.android.sdk.internal.auth
|
|||
import android.net.Uri
|
||||
import dagger.Lazy
|
||||
import okhttp3.OkHttpClient
|
||||
import org.matrix.android.sdk.api.MatrixPatterns
|
||||
import org.matrix.android.sdk.api.MatrixPatterns.getDomain
|
||||
import org.matrix.android.sdk.api.auth.AuthenticationService
|
||||
import org.matrix.android.sdk.api.auth.data.Credentials
|
||||
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
|
||||
|
@ -28,10 +30,11 @@ import org.matrix.android.sdk.api.auth.login.LoginWizard
|
|||
import org.matrix.android.sdk.api.auth.registration.RegistrationWizard
|
||||
import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
|
||||
import org.matrix.android.sdk.api.failure.Failure
|
||||
import org.matrix.android.sdk.api.failure.MatrixIdFailure
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.util.appendParamToUrl
|
||||
import org.matrix.android.sdk.internal.SessionManager
|
||||
import org.matrix.android.sdk.internal.auth.data.RiotConfig
|
||||
import org.matrix.android.sdk.internal.auth.data.WebClientConfig
|
||||
import org.matrix.android.sdk.internal.auth.db.PendingSessionData
|
||||
import org.matrix.android.sdk.internal.auth.login.DefaultLoginWizard
|
||||
import org.matrix.android.sdk.internal.auth.login.DirectLoginTask
|
||||
|
@ -122,7 +125,7 @@ internal class DefaultAuthenticationService @Inject constructor(
|
|||
private fun getHomeServerUrlBase(): String? {
|
||||
return pendingSessionData
|
||||
?.homeServerConnectionConfig
|
||||
?.homeServerUri
|
||||
?.homeServerUriBase
|
||||
?.toString()
|
||||
?.trim { it == '/' }
|
||||
}
|
||||
|
@ -143,9 +146,9 @@ internal class DefaultAuthenticationService @Inject constructor(
|
|||
return result.fold(
|
||||
{
|
||||
// The homeserver exists and up to date, keep the config
|
||||
// Homeserver url may have been changed, if it was a Riot url
|
||||
// Homeserver url may have been changed, if it was a Web client url
|
||||
val alteredHomeServerConnectionConfig = homeServerConnectionConfig.copy(
|
||||
homeServerUri = Uri.parse(it.homeServerUrl)
|
||||
homeServerUriBase = Uri.parse(it.homeServerUrl)
|
||||
)
|
||||
|
||||
pendingSessionData = PendingSessionData(alteredHomeServerConnectionConfig)
|
||||
|
@ -154,7 +157,7 @@ internal class DefaultAuthenticationService @Inject constructor(
|
|||
},
|
||||
{
|
||||
if (it is UnrecognizedCertificateException) {
|
||||
throw Failure.UnrecognizedCertificateFailure(homeServerConnectionConfig.homeServerUri.toString(), it.fingerprint)
|
||||
throw Failure.UnrecognizedCertificateFailure(homeServerConnectionConfig.homeServerUriBase.toString(), it.fingerprint)
|
||||
} else {
|
||||
throw it
|
||||
}
|
||||
|
@ -165,46 +168,57 @@ internal class DefaultAuthenticationService @Inject constructor(
|
|||
private suspend fun getLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
|
||||
val authAPI = buildAuthAPI(homeServerConnectionConfig)
|
||||
|
||||
// First check the homeserver version
|
||||
return runCatching {
|
||||
executeRequest(null) {
|
||||
authAPI.versions()
|
||||
// First check if there is a well-known file
|
||||
return try {
|
||||
getWellknownLoginFlowInternal(homeServerConnectionConfig)
|
||||
} catch (failure: Throwable) {
|
||||
if (failure is Failure.OtherServerError
|
||||
&& failure.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
|
||||
// 404, no well-known data, try direct access to the API
|
||||
// First check the homeserver version
|
||||
return runCatching {
|
||||
executeRequest(null) {
|
||||
authAPI.versions()
|
||||
}
|
||||
}
|
||||
.map { versions ->
|
||||
// Ok, it seems that the homeserver url is valid
|
||||
getLoginFlowResult(authAPI, versions, homeServerConnectionConfig.homeServerUriBase.toString())
|
||||
}
|
||||
.fold(
|
||||
{
|
||||
it
|
||||
},
|
||||
{
|
||||
if (it is Failure.OtherServerError
|
||||
&& it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
|
||||
// It's maybe a Web client url?
|
||||
getWebClientDomainLoginFlowInternal(homeServerConnectionConfig)
|
||||
} else {
|
||||
throw it
|
||||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
throw failure
|
||||
}
|
||||
}
|
||||
.map { versions ->
|
||||
// Ok, it seems that the homeserver url is valid
|
||||
getLoginFlowResult(authAPI, versions, homeServerConnectionConfig.homeServerUri.toString())
|
||||
}
|
||||
.fold(
|
||||
{
|
||||
it
|
||||
},
|
||||
{
|
||||
if (it is Failure.OtherServerError
|
||||
&& it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
|
||||
// It's maybe a Riot url?
|
||||
getRiotDomainLoginFlowInternal(homeServerConnectionConfig)
|
||||
} else {
|
||||
throw it
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun getRiotDomainLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
|
||||
private suspend fun getWebClientDomainLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
|
||||
val authAPI = buildAuthAPI(homeServerConnectionConfig)
|
||||
|
||||
val domain = homeServerConnectionConfig.homeServerUri.host
|
||||
?: return getRiotLoginFlowInternal(homeServerConnectionConfig)
|
||||
?: return getWebClientLoginFlowInternal(homeServerConnectionConfig)
|
||||
|
||||
// Ok, try to get the config.domain.json file of a RiotWeb client
|
||||
// Ok, try to get the config.domain.json file of a Web client
|
||||
return runCatching {
|
||||
executeRequest(null) {
|
||||
authAPI.getRiotConfigDomain(domain)
|
||||
authAPI.getWebClientConfigDomain(domain)
|
||||
}
|
||||
}
|
||||
.map { riotConfig ->
|
||||
onRiotConfigRetrieved(homeServerConnectionConfig, riotConfig)
|
||||
.map { webClientConfig ->
|
||||
onWebClientConfigRetrieved(homeServerConnectionConfig, webClientConfig)
|
||||
}
|
||||
.fold(
|
||||
{
|
||||
|
@ -214,7 +228,7 @@ internal class DefaultAuthenticationService @Inject constructor(
|
|||
if (it is Failure.OtherServerError
|
||||
&& it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
|
||||
// Try with config.json
|
||||
getRiotLoginFlowInternal(homeServerConnectionConfig)
|
||||
getWebClientLoginFlowInternal(homeServerConnectionConfig)
|
||||
} else {
|
||||
throw it
|
||||
}
|
||||
|
@ -222,40 +236,24 @@ internal class DefaultAuthenticationService @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private suspend fun getRiotLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
|
||||
private suspend fun getWebClientLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
|
||||
val authAPI = buildAuthAPI(homeServerConnectionConfig)
|
||||
|
||||
// Ok, try to get the config.json file of a RiotWeb client
|
||||
return runCatching {
|
||||
executeRequest(null) {
|
||||
authAPI.getRiotConfig()
|
||||
}
|
||||
// Ok, try to get the config.json file of a Web client
|
||||
return executeRequest(null) {
|
||||
authAPI.getWebClientConfig()
|
||||
}
|
||||
.map { riotConfig ->
|
||||
onRiotConfigRetrieved(homeServerConnectionConfig, riotConfig)
|
||||
.let { webClientConfig ->
|
||||
onWebClientConfigRetrieved(homeServerConnectionConfig, webClientConfig)
|
||||
}
|
||||
.fold(
|
||||
{
|
||||
it
|
||||
},
|
||||
{
|
||||
if (it is Failure.OtherServerError
|
||||
&& it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
|
||||
// Try with wellknown
|
||||
getWellknownLoginFlowInternal(homeServerConnectionConfig)
|
||||
} else {
|
||||
throw it
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun onRiotConfigRetrieved(homeServerConnectionConfig: HomeServerConnectionConfig, riotConfig: RiotConfig): LoginFlowResult {
|
||||
val defaultHomeServerUrl = riotConfig.getPreferredHomeServerUrl()
|
||||
private suspend fun onWebClientConfigRetrieved(homeServerConnectionConfig: HomeServerConnectionConfig, webClientConfig: WebClientConfig): LoginFlowResult {
|
||||
val defaultHomeServerUrl = webClientConfig.getPreferredHomeServerUrl()
|
||||
if (defaultHomeServerUrl?.isNotEmpty() == true) {
|
||||
// Ok, good sign, we got a default hs url
|
||||
val newHomeServerConnectionConfig = homeServerConnectionConfig.copy(
|
||||
homeServerUri = Uri.parse(defaultHomeServerUrl)
|
||||
homeServerUriBase = Uri.parse(defaultHomeServerUrl)
|
||||
)
|
||||
|
||||
val newAuthAPI = buildAuthAPI(newHomeServerConnectionConfig)
|
||||
|
@ -275,15 +273,13 @@ internal class DefaultAuthenticationService @Inject constructor(
|
|||
val domain = homeServerConnectionConfig.homeServerUri.host
|
||||
?: throw Failure.OtherServerError("", HttpsURLConnection.HTTP_NOT_FOUND /* 404 */)
|
||||
|
||||
// Create a fake userId, for the getWellknown task
|
||||
val fakeUserId = "@alice:$domain"
|
||||
val wellknownResult = getWellknownTask.execute(GetWellknownTask.Params(fakeUserId, homeServerConnectionConfig))
|
||||
val wellknownResult = getWellknownTask.execute(GetWellknownTask.Params(domain, homeServerConnectionConfig))
|
||||
|
||||
return when (wellknownResult) {
|
||||
is WellknownResult.Prompt -> {
|
||||
val newHomeServerConnectionConfig = homeServerConnectionConfig.copy(
|
||||
homeServerUri = Uri.parse(wellknownResult.homeServerUrl),
|
||||
identityServerUri = wellknownResult.identityServerUrl?.let { Uri.parse(it) }
|
||||
homeServerUriBase = Uri.parse(wellknownResult.homeServerUrl),
|
||||
identityServerUri = wellknownResult.identityServerUrl?.let { Uri.parse(it) } ?: homeServerConnectionConfig.identityServerUri
|
||||
)
|
||||
|
||||
val newAuthAPI = buildAuthAPI(newHomeServerConnectionConfig)
|
||||
|
@ -379,7 +375,14 @@ internal class DefaultAuthenticationService @Inject constructor(
|
|||
|
||||
override suspend fun getWellKnownData(matrixId: String,
|
||||
homeServerConnectionConfig: HomeServerConnectionConfig?): WellknownResult {
|
||||
return getWellknownTask.execute(GetWellknownTask.Params(matrixId, homeServerConnectionConfig))
|
||||
if (!MatrixPatterns.isUserId(matrixId)) {
|
||||
throw MatrixIdFailure.InvalidMatrixId
|
||||
}
|
||||
|
||||
return getWellknownTask.execute(GetWellknownTask.Params(
|
||||
domain = matrixId.getDomain(),
|
||||
homeServerConnectionConfig = homeServerConnectionConfig)
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun directAuthentication(homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||
|
@ -390,7 +393,7 @@ internal class DefaultAuthenticationService @Inject constructor(
|
|||
}
|
||||
|
||||
private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI {
|
||||
val retrofit = retrofitFactory.create(buildClient(homeServerConnectionConfig), homeServerConnectionConfig.homeServerUri.toString())
|
||||
val retrofit = retrofitFactory.create(buildClient(homeServerConnectionConfig), homeServerConnectionConfig.homeServerUriBase.toString())
|
||||
return retrofit.create(AuthAPI::class.java)
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ internal class DefaultIsValidClientServerApiTask @Inject constructor(
|
|||
|
||||
override suspend fun execute(params: IsValidClientServerApiTask.Params): Boolean {
|
||||
val client = buildClient(params.homeServerConnectionConfig)
|
||||
val homeServerUrl = params.homeServerConnectionConfig.homeServerUri.toString()
|
||||
val homeServerUrl = params.homeServerConnectionConfig.homeServerUriBase.toString()
|
||||
|
||||
val authAPI = retrofitFactory.create(client, homeServerUrl)
|
||||
.create(AuthAPI::class.java)
|
||||
|
|
|
@ -56,7 +56,7 @@ internal class DefaultSessionCreator @Inject constructor(
|
|||
tryOrNull {
|
||||
isValidClientServerApiTask.execute(
|
||||
IsValidClientServerApiTask.Params(
|
||||
homeServerConnectionConfig.copy(homeServerUri = it)
|
||||
homeServerConnectionConfig.copy(homeServerUriBase = it)
|
||||
)
|
||||
)
|
||||
.also { Timber.d("Overriding homeserver url: $it") }
|
||||
|
@ -66,7 +66,7 @@ internal class DefaultSessionCreator @Inject constructor(
|
|||
val sessionParams = SessionParams(
|
||||
credentials = credentials,
|
||||
homeServerConnectionConfig = homeServerConnectionConfig.copy(
|
||||
homeServerUri = overriddenUrl ?: homeServerConnectionConfig.homeServerUri,
|
||||
homeServerUriBase = overriddenUrl ?: homeServerConnectionConfig.homeServerUriBase,
|
||||
identityServerUri = credentials.discoveryInformation?.identityServer?.baseURL
|
||||
// remove trailing "/"
|
||||
?.trim { it == '/' }
|
||||
|
|
|
@ -20,7 +20,7 @@ import com.squareup.moshi.Json
|
|||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class RiotConfig(
|
||||
internal data class WebClientConfig(
|
||||
/**
|
||||
* This is now deprecated, but still used first, rather than value from "default_server_config"
|
||||
*/
|
||||
|
@ -28,7 +28,7 @@ internal data class RiotConfig(
|
|||
val defaultHomeServerUrl: String?,
|
||||
|
||||
@Json(name = "default_server_config")
|
||||
val defaultServerConfig: RiotConfigDefaultServerConfig?
|
||||
val defaultServerConfig: WebClientConfigDefaultServerConfig?
|
||||
) {
|
||||
fun getPreferredHomeServerUrl(): String? {
|
||||
return defaultHomeServerUrl
|
||||
|
@ -38,13 +38,13 @@ internal data class RiotConfig(
|
|||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class RiotConfigDefaultServerConfig(
|
||||
internal data class WebClientConfigDefaultServerConfig(
|
||||
@Json(name = "m.homeserver")
|
||||
val homeServer: RiotConfigBaseConfig? = null
|
||||
val homeServer: WebClientConfigBaseConfig? = null
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class RiotConfigBaseConfig(
|
||||
internal data class WebClientConfigBaseConfig(
|
||||
@Json(name = "base_url")
|
||||
val baseURL: String? = null
|
||||
)
|
|
@ -16,17 +16,19 @@
|
|||
|
||||
package org.matrix.android.sdk.internal.auth.db
|
||||
|
||||
import org.matrix.android.sdk.api.auth.data.Credentials
|
||||
import org.matrix.android.sdk.api.auth.data.sessionId
|
||||
import org.matrix.android.sdk.internal.di.MoshiProvider
|
||||
import android.net.Uri
|
||||
import io.realm.DynamicRealm
|
||||
import io.realm.RealmMigration
|
||||
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.sessionId
|
||||
import org.matrix.android.sdk.internal.di.MoshiProvider
|
||||
import timber.log.Timber
|
||||
|
||||
internal object AuthRealmMigration : RealmMigration {
|
||||
|
||||
// Current schema version
|
||||
const val SCHEMA_VERSION = 3L
|
||||
const val SCHEMA_VERSION = 4L
|
||||
|
||||
override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
|
||||
Timber.d("Migrating Auth Realm from $oldVersion to $newVersion")
|
||||
|
@ -34,6 +36,7 @@ internal object AuthRealmMigration : RealmMigration {
|
|||
if (oldVersion <= 0) migrateTo1(realm)
|
||||
if (oldVersion <= 1) migrateTo2(realm)
|
||||
if (oldVersion <= 2) migrateTo3(realm)
|
||||
if (oldVersion <= 3) migrateTo4(realm)
|
||||
}
|
||||
|
||||
private fun migrateTo1(realm: DynamicRealm) {
|
||||
|
@ -81,4 +84,34 @@ internal object AuthRealmMigration : RealmMigration {
|
|||
}
|
||||
?.addPrimaryKey(SessionParamsEntityFields.SESSION_ID)
|
||||
}
|
||||
|
||||
private fun migrateTo4(realm: DynamicRealm) {
|
||||
Timber.d("Step 3 -> 4")
|
||||
Timber.d("Update SessionParamsEntity to add HomeServerConnectionConfig.homeServerUriBase value")
|
||||
|
||||
val adapter = MoshiProvider.providesMoshi()
|
||||
.adapter(HomeServerConnectionConfig::class.java)
|
||||
|
||||
realm.schema.get("SessionParamsEntity")
|
||||
?.transform {
|
||||
val homeserverConnectionConfigJson = it.getString(SessionParamsEntityFields.HOME_SERVER_CONNECTION_CONFIG_JSON)
|
||||
|
||||
val homeserverConnectionConfig = adapter
|
||||
.fromJson(homeserverConnectionConfigJson)
|
||||
|
||||
val homeserverUrl = homeserverConnectionConfig?.homeServerUri?.toString()
|
||||
// Special case for matrix.org. Old session may use "https://matrix.org", newer one may use
|
||||
// "https://matrix-client.matrix.org". So fix that here
|
||||
val alteredHomeserverConnectionConfig =
|
||||
if (homeserverUrl == "https://matrix.org" || homeserverUrl == "https://matrix-client.matrix.org") {
|
||||
homeserverConnectionConfig.copy(
|
||||
homeServerUri = Uri.parse("https://matrix.org"),
|
||||
homeServerUriBase = Uri.parse("https://matrix-client.matrix.org")
|
||||
)
|
||||
} else {
|
||||
homeserverConnectionConfig
|
||||
}
|
||||
it.set(SessionParamsEntityFields.HOME_SERVER_CONNECTION_CONFIG_JSON, adapter.toJson(alteredHomeserverConnectionConfig))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ internal class DefaultDirectLoginTask @Inject constructor(
|
|||
|
||||
override suspend fun execute(params: DirectLoginTask.Params): Session {
|
||||
val client = buildClient(params.homeServerConnectionConfig)
|
||||
val homeServerUrl = params.homeServerConnectionConfig.homeServerUri.toString()
|
||||
val homeServerUrl = params.homeServerConnectionConfig.homeServerUriBase.toString()
|
||||
|
||||
val authAPI = retrofitFactory.create(client, homeServerUrl)
|
||||
.create(AuthAPI::class.java)
|
||||
|
|
|
@ -37,7 +37,8 @@ internal abstract class FederationModule {
|
|||
fun providesFederationAPI(@Unauthenticated okHttpClient: Lazy<OkHttpClient>,
|
||||
sessionParams: SessionParams,
|
||||
retrofitFactory: RetrofitFactory): FederationAPI {
|
||||
return retrofitFactory.create(okHttpClient, sessionParams.homeServerUrl).create(FederationAPI::class.java)
|
||||
return retrofitFactory.create(okHttpClient, sessionParams.homeServerUrlBase)
|
||||
.create(FederationAPI::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -253,7 +253,7 @@ internal object CertUtil {
|
|||
val list = ArrayList<ConnectionSpec>()
|
||||
list.add(builder.build())
|
||||
// TODO: we should display a warning if user enter an http url
|
||||
if (hsConfig.allowHttpExtension || hsConfig.homeServerUri.toString().startsWith("http://")) {
|
||||
if (hsConfig.allowHttpExtension || hsConfig.homeServerUriBase.toString().startsWith("http://")) {
|
||||
list.add(ConnectionSpec.CLEARTEXT)
|
||||
}
|
||||
return list
|
||||
|
|
|
@ -29,10 +29,9 @@ internal class DefaultRawService @Inject constructor(
|
|||
return getUrlTask.execute(GetUrlTask.Params(url, cacheStrategy))
|
||||
}
|
||||
|
||||
override suspend fun getWellknown(userId: String): String {
|
||||
val homeServerDomain = userId.substringAfter(":")
|
||||
override suspend fun getWellknown(domain: String): String {
|
||||
return getUrl(
|
||||
"https://$homeServerDomain/.well-known/matrix/client",
|
||||
"https://$domain/.well-known/matrix/client",
|
||||
CacheStrategy.TtlCache(TimeUnit.HOURS.toMillis(8), false)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -313,7 +313,7 @@ internal class DefaultSession @Inject constructor(
|
|||
|
||||
override fun getUiaSsoFallbackUrl(authenticationSessionId: String): String {
|
||||
val hsBas = sessionParams.homeServerConnectionConfig
|
||||
.homeServerUri
|
||||
.homeServerUriBase
|
||||
.toString()
|
||||
.trim { it == '/' }
|
||||
return buildString {
|
||||
|
|
|
@ -261,7 +261,7 @@ internal abstract class SessionModule {
|
|||
sessionParams: SessionParams,
|
||||
retrofitFactory: RetrofitFactory): Retrofit {
|
||||
return retrofitFactory
|
||||
.create(okHttpClient, sessionParams.homeServerConnectionConfig.homeServerUri.toString())
|
||||
.create(okHttpClient, sessionParams.homeServerConnectionConfig.homeServerUriBase.toString())
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
|
|
@ -26,7 +26,7 @@ private const val MATRIX_CONTENT_URI_SCHEME = "mxc://"
|
|||
|
||||
internal class DefaultContentUrlResolver @Inject constructor(homeServerConnectionConfig: HomeServerConnectionConfig) : ContentUrlResolver {
|
||||
|
||||
private val baseUrl = homeServerConnectionConfig.homeServerUri.toString().ensureTrailingSlash()
|
||||
private val baseUrl = homeServerConnectionConfig.homeServerUriBase.toString().ensureTrailingSlash()
|
||||
|
||||
override val uploadUrl = baseUrl + NetworkConstants.URI_API_MEDIA_PREFIX_PATH_R0 + "upload"
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package org.matrix.android.sdk.internal.session.homeserver
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import org.matrix.android.sdk.api.MatrixPatterns.getDomain
|
||||
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
|
||||
import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
|
||||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
|
||||
|
@ -89,7 +90,10 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
|
|||
}.getOrNull()
|
||||
|
||||
val wellknownResult = runCatching {
|
||||
getWellknownTask.execute(GetWellknownTask.Params(userId, homeServerConnectionConfig))
|
||||
getWellknownTask.execute(GetWellknownTask.Params(
|
||||
domain = userId.getDomain(),
|
||||
homeServerConnectionConfig = homeServerConnectionConfig
|
||||
))
|
||||
}.getOrNull()
|
||||
|
||||
insertInDb(capabilities, mediaConfig, versions, wellknownResult)
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.matrix.android.sdk.internal.session.permalinks
|
||||
|
||||
import org.matrix.android.sdk.api.MatrixPatterns.getDomain
|
||||
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
|
@ -47,9 +48,9 @@ internal class ViaParameterFinder @Inject constructor(
|
|||
}
|
||||
|
||||
fun computeViaParams(userId: String, roomId: String, max: Int): List<String> {
|
||||
val userHomeserver = userId.substringAfter(":")
|
||||
val userHomeserver = userId.getDomain()
|
||||
return getUserIdsOfJoinedMembers(roomId)
|
||||
.map { it.substringAfter(":") }
|
||||
.map { it.getDomain() }
|
||||
.groupBy { it }
|
||||
.mapValues { it.value.size }
|
||||
.toMutableMap()
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.matrix.android.sdk.internal.session.room.alias
|
||||
|
||||
import org.matrix.android.sdk.api.MatrixPatterns.getDomain
|
||||
import org.matrix.android.sdk.api.failure.Failure
|
||||
import org.matrix.android.sdk.api.session.room.alias.RoomAliasError
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
|
@ -64,6 +65,6 @@ internal class RoomAliasAvailabilityChecker @Inject constructor(
|
|||
}
|
||||
|
||||
companion object {
|
||||
internal fun String.toFullLocalAlias(userId: String) = "#" + this + ":" + userId.substringAfter(":")
|
||||
internal fun String.toFullLocalAlias(userId: String) = "#" + this + ":" + userId.getDomain()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,8 @@ import java.net.Socket
|
|||
internal class HomeServerAvailabilityChecker(val sessionParams: SessionParams) {
|
||||
|
||||
fun check(): Boolean {
|
||||
val host = sessionParams.homeServerConnectionConfig.homeServerUri.host ?: return false
|
||||
val port = sessionParams.homeServerConnectionConfig.homeServerUri.port.takeIf { it != -1 } ?: 80
|
||||
val host = sessionParams.homeServerConnectionConfig.homeServerUriBase.host ?: return false
|
||||
val port = sessionParams.homeServerConnectionConfig.homeServerUriBase.port.takeIf { it != -1 } ?: 80
|
||||
val timeout = 30_000
|
||||
try {
|
||||
Socket().use { socket ->
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.wellknown
|
|||
|
||||
import android.util.MalformedJsonException
|
||||
import dagger.Lazy
|
||||
import org.matrix.android.sdk.api.MatrixPatterns
|
||||
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
|
||||
import org.matrix.android.sdk.api.auth.data.WellKnown
|
||||
import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
|
||||
|
@ -39,7 +38,11 @@ import javax.net.ssl.HttpsURLConnection
|
|||
|
||||
internal interface GetWellknownTask : Task<GetWellknownTask.Params, WellknownResult> {
|
||||
data class Params(
|
||||
val matrixId: String,
|
||||
/**
|
||||
* domain, for instance "matrix.org"
|
||||
* the URL will be https://{domain}/.well-known/matrix/client
|
||||
*/
|
||||
val domain: String,
|
||||
val homeServerConnectionConfig: HomeServerConnectionConfig?
|
||||
)
|
||||
}
|
||||
|
@ -54,14 +57,8 @@ internal class DefaultGetWellknownTask @Inject constructor(
|
|||
) : GetWellknownTask {
|
||||
|
||||
override suspend fun execute(params: GetWellknownTask.Params): WellknownResult {
|
||||
if (!MatrixPatterns.isUserId(params.matrixId)) {
|
||||
return WellknownResult.InvalidMatrixId
|
||||
}
|
||||
|
||||
val homeServerDomain = params.matrixId.substringAfter(":")
|
||||
|
||||
val client = buildClient(params.homeServerConnectionConfig)
|
||||
return findClientConfig(homeServerDomain, client)
|
||||
return findClientConfig(params.domain, client)
|
||||
}
|
||||
|
||||
private fun buildClient(homeServerConnectionConfig: HomeServerConnectionConfig?): OkHttpClient {
|
||||
|
|
|
@ -50,7 +50,15 @@ class UnrecognizedCertificateDialog @Inject constructor(
|
|||
val userId = activeSessionHolder.getSafeActiveSession()?.myUserId
|
||||
val hsConfig = activeSessionHolder.getSafeActiveSession()?.sessionParams?.homeServerConnectionConfig ?: return
|
||||
|
||||
internalShow(activity, unrecognizedFingerprint, true, callback, userId, hsConfig.homeServerUri.toString(), hsConfig.allowedFingerprints.isNotEmpty())
|
||||
internalShow(
|
||||
activity = activity,
|
||||
unrecognizedFingerprint = unrecognizedFingerprint,
|
||||
existing = true,
|
||||
callback = callback,
|
||||
userId = userId,
|
||||
homeServerUrl = hsConfig.homeServerUriBase.toString(),
|
||||
homeServerConnectionConfigHasFingerprints = hsConfig.allowedFingerprints.isNotEmpty()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,7 +68,15 @@ class UnrecognizedCertificateDialog @Inject constructor(
|
|||
unrecognizedFingerprint: Fingerprint,
|
||||
homeServerUrl: String,
|
||||
callback: Callback) {
|
||||
internalShow(activity, unrecognizedFingerprint, false, callback, null, homeServerUrl, false)
|
||||
internalShow(
|
||||
activity = activity,
|
||||
unrecognizedFingerprint = unrecognizedFingerprint,
|
||||
existing = false,
|
||||
callback = callback,
|
||||
userId = null,
|
||||
homeServerUrl = homeServerUrl,
|
||||
homeServerConnectionConfigHasFingerprints = false
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,6 +21,7 @@ import im.vector.app.core.resources.StringProvider
|
|||
import im.vector.app.features.call.dialpad.DialPadLookup
|
||||
import org.matrix.android.sdk.api.failure.Failure
|
||||
import org.matrix.android.sdk.api.failure.MatrixError
|
||||
import org.matrix.android.sdk.api.failure.MatrixIdFailure
|
||||
import org.matrix.android.sdk.api.failure.isInvalidPassword
|
||||
import org.matrix.android.sdk.api.session.identity.IdentityServiceError
|
||||
import java.net.HttpURLConnection
|
||||
|
@ -39,9 +40,9 @@ class DefaultErrorFormatter @Inject constructor(
|
|||
|
||||
override fun toHumanReadable(throwable: Throwable?): String {
|
||||
return when (throwable) {
|
||||
null -> null
|
||||
is IdentityServiceError -> identityServerError(throwable)
|
||||
is Failure.NetworkConnection -> {
|
||||
null -> null
|
||||
is IdentityServiceError -> identityServerError(throwable)
|
||||
is Failure.NetworkConnection -> {
|
||||
when (throwable.ioException) {
|
||||
is SocketTimeoutException ->
|
||||
stringProvider.getString(R.string.error_network_timeout)
|
||||
|
@ -54,7 +55,7 @@ class DefaultErrorFormatter @Inject constructor(
|
|||
stringProvider.getString(R.string.error_no_network)
|
||||
}
|
||||
}
|
||||
is Failure.ServerError -> {
|
||||
is Failure.ServerError -> {
|
||||
when {
|
||||
throwable.error.code == MatrixError.M_CONSENT_NOT_GIVEN -> {
|
||||
// Special case for terms and conditions
|
||||
|
@ -104,23 +105,25 @@ class DefaultErrorFormatter @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
is Failure.OtherServerError -> {
|
||||
is Failure.OtherServerError -> {
|
||||
when (throwable.httpCode) {
|
||||
HttpURLConnection.HTTP_NOT_FOUND ->
|
||||
HttpURLConnection.HTTP_NOT_FOUND ->
|
||||
// homeserver not found
|
||||
stringProvider.getString(R.string.login_error_no_homeserver_found)
|
||||
HttpURLConnection.HTTP_UNAUTHORIZED ->
|
||||
// uia errors?
|
||||
stringProvider.getString(R.string.error_unauthorized)
|
||||
else ->
|
||||
else ->
|
||||
throwable.localizedMessage
|
||||
}
|
||||
}
|
||||
is DialPadLookup.Failure.NumberIsYours ->
|
||||
is DialPadLookup.Failure.NumberIsYours ->
|
||||
stringProvider.getString(R.string.cannot_call_yourself)
|
||||
is DialPadLookup.Failure.NoResult ->
|
||||
is DialPadLookup.Failure.NoResult ->
|
||||
stringProvider.getString(R.string.call_dial_pad_lookup_error)
|
||||
else -> throwable.localizedMessage
|
||||
is MatrixIdFailure.InvalidMatrixId ->
|
||||
stringProvider.getString(R.string.login_signin_matrix_id_error_invalid_matrix_id)
|
||||
else -> throwable.localizedMessage
|
||||
}
|
||||
?: stringProvider.getString(R.string.unknown_error)
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ class JitsiService @Inject constructor(
|
|||
// Build data for a jitsi widget
|
||||
val widgetId: String = WidgetType.Jitsi.preferred + "_" + session.myUserId + "_" + System.currentTimeMillis()
|
||||
val preferredJitsiDomain = tryOrNull {
|
||||
rawService.getElementWellknown(session.myUserId)
|
||||
rawService.getElementWellknown(session.sessionParams)
|
||||
?.jitsiServer
|
||||
?.preferredDomain
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted
|
|||
setState { copy(createAndInviteState = Loading()) }
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val adminE2EByDefault = rawService.getElementWellknown(session.myUserId)
|
||||
val adminE2EByDefault = rawService.getElementWellknown(session.sessionParams)
|
||||
?.isE2EByDefault()
|
||||
?: true
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ class DirectRoomHelper @Inject constructor(
|
|||
if (existingRoomId != null) {
|
||||
roomId = existingRoomId
|
||||
} else {
|
||||
val adminE2EByDefault = rawService.getElementWellknown(session.myUserId)
|
||||
val adminE2EByDefault = rawService.getElementWellknown(session.sessionParams)
|
||||
?.isE2EByDefault()
|
||||
?: true
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ class HomeServerCapabilitiesViewModel @AssistedInject constructor(
|
|||
private fun initAdminE2eByDefault() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val adminE2EByDefault = tryOrNull {
|
||||
rawService.getElementWellknown(session.myUserId)
|
||||
rawService.getElementWellknown(session.sessionParams)
|
||||
?.isE2EByDefault()
|
||||
?: true
|
||||
} ?: true
|
||||
|
|
|
@ -174,7 +174,7 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment<FragmentLog
|
|||
ServerType.MatrixOrg -> {
|
||||
views.loginServerIcon.isVisible = true
|
||||
views.loginServerIcon.setImageResource(R.drawable.ic_logo_matrix_org)
|
||||
views.loginTitle.text = getString(resId, state.homeServerUrl.toReducedUrl())
|
||||
views.loginTitle.text = getString(resId, state.homeServerUrlFromUser.toReducedUrl())
|
||||
views.loginNotice.text = getString(R.string.login_server_matrix_org_text)
|
||||
}
|
||||
ServerType.EMS -> {
|
||||
|
@ -185,7 +185,7 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment<FragmentLog
|
|||
}
|
||||
ServerType.Other -> {
|
||||
views.loginServerIcon.isVisible = false
|
||||
views.loginTitle.text = getString(resId, state.homeServerUrl.toReducedUrl())
|
||||
views.loginTitle.text = getString(resId, state.homeServerUrlFromUser.toReducedUrl())
|
||||
views.loginNotice.text = getString(R.string.login_server_other_text)
|
||||
}
|
||||
ServerType.Unknown -> Unit /* Should not happen */
|
||||
|
|
|
@ -55,7 +55,7 @@ class LoginResetPasswordFragment @Inject constructor() : AbstractLoginFragment<F
|
|||
}
|
||||
|
||||
private fun setupUi(state: LoginViewState) {
|
||||
views.resetPasswordTitle.text = getString(R.string.login_reset_password_on, state.homeServerUrl.toReducedUrl())
|
||||
views.resetPasswordTitle.text = getString(R.string.login_reset_password_on, state.homeServerUrlFromUser.toReducedUrl())
|
||||
}
|
||||
|
||||
private fun setupSubmitButton() {
|
||||
|
|
|
@ -53,19 +53,19 @@ class LoginSignUpSignInSelectionFragment @Inject constructor() : AbstractSSOLogi
|
|||
ServerType.MatrixOrg -> {
|
||||
views.loginSignupSigninServerIcon.setImageResource(R.drawable.ic_logo_matrix_org)
|
||||
views.loginSignupSigninServerIcon.isVisible = true
|
||||
views.loginSignupSigninTitle.text = getString(R.string.login_connect_to, state.homeServerUrl.toReducedUrl())
|
||||
views.loginSignupSigninTitle.text = getString(R.string.login_connect_to, state.homeServerUrlFromUser.toReducedUrl())
|
||||
views.loginSignupSigninText.text = getString(R.string.login_server_matrix_org_text)
|
||||
}
|
||||
ServerType.EMS -> {
|
||||
views.loginSignupSigninServerIcon.setImageResource(R.drawable.ic_logo_element_matrix_services)
|
||||
views.loginSignupSigninServerIcon.isVisible = true
|
||||
views.loginSignupSigninTitle.text = getString(R.string.login_connect_to_modular)
|
||||
views.loginSignupSigninText.text = state.homeServerUrl.toReducedUrl()
|
||||
views.loginSignupSigninText.text = state.homeServerUrlFromUser.toReducedUrl()
|
||||
}
|
||||
ServerType.Other -> {
|
||||
views.loginSignupSigninServerIcon.isVisible = false
|
||||
views.loginSignupSigninTitle.text = getString(R.string.login_server_other_title)
|
||||
views.loginSignupSigninText.text = getString(R.string.login_connect_to, state.homeServerUrl.toReducedUrl())
|
||||
views.loginSignupSigninText.text = getString(R.string.login_connect_to, state.homeServerUrlFromUser.toReducedUrl())
|
||||
}
|
||||
ServerType.Unknown -> Unit /* Should not happen */
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ import im.vector.app.core.utils.ensureTrailingSlash
|
|||
import im.vector.app.features.signout.soft.SoftLogoutActivity
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.MatrixPatterns.getDomain
|
||||
import org.matrix.android.sdk.api.auth.AuthenticationService
|
||||
import org.matrix.android.sdk.api.auth.HomeServerHistoryService
|
||||
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
|
||||
|
@ -51,6 +52,7 @@ import org.matrix.android.sdk.api.auth.registration.RegistrationWizard
|
|||
import org.matrix.android.sdk.api.auth.registration.Stage
|
||||
import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
|
||||
import org.matrix.android.sdk.api.failure.Failure
|
||||
import org.matrix.android.sdk.api.failure.MatrixIdFailure
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.CancellationException
|
||||
|
@ -213,6 +215,7 @@ class LoginViewModel @AssistedInject constructor(
|
|||
copy(
|
||||
signMode = SignMode.SignIn,
|
||||
loginMode = LoginMode.Sso(action.ssoIdentityProviders),
|
||||
homeServerUrlFromUser = action.homeServerUrl,
|
||||
homeServerUrl = action.homeServerUrl,
|
||||
deviceId = action.deviceId
|
||||
)
|
||||
|
@ -364,6 +367,7 @@ class LoginViewModel @AssistedInject constructor(
|
|||
setState {
|
||||
copy(
|
||||
asyncHomeServerLoginFlowRequest = Uninitialized,
|
||||
homeServerUrlFromUser = null,
|
||||
homeServerUrl = null,
|
||||
loginMode = LoginMode.Unknown,
|
||||
serverType = ServerType.Unknown,
|
||||
|
@ -560,24 +564,16 @@ class LoginViewModel @AssistedInject constructor(
|
|||
return@launch
|
||||
}
|
||||
when (data) {
|
||||
is WellknownResult.Prompt ->
|
||||
is WellknownResult.Prompt ->
|
||||
onWellknownSuccess(action, data, homeServerConnectionConfig)
|
||||
is WellknownResult.FailPrompt ->
|
||||
is WellknownResult.FailPrompt ->
|
||||
// Relax on IS discovery if home server is valid
|
||||
if (data.homeServerUrl != null && data.wellKnown != null) {
|
||||
onWellknownSuccess(action, WellknownResult.Prompt(data.homeServerUrl!!, null, data.wellKnown!!), homeServerConnectionConfig)
|
||||
} else {
|
||||
onWellKnownError()
|
||||
}
|
||||
is WellknownResult.InvalidMatrixId -> {
|
||||
setState {
|
||||
copy(
|
||||
asyncLoginAction = Uninitialized
|
||||
)
|
||||
}
|
||||
_viewEvents.post(LoginViewEvents.Failure(Exception(stringProvider.getString(R.string.login_signin_matrix_id_error_invalid_matrix_id))))
|
||||
}
|
||||
else -> {
|
||||
else -> {
|
||||
onWellKnownError()
|
||||
}
|
||||
}.exhaustive
|
||||
|
@ -598,11 +594,12 @@ class LoginViewModel @AssistedInject constructor(
|
|||
homeServerConnectionConfig: HomeServerConnectionConfig?) {
|
||||
val alteredHomeServerConnectionConfig = homeServerConnectionConfig
|
||||
?.copy(
|
||||
homeServerUri = Uri.parse(wellKnownPrompt.homeServerUrl),
|
||||
homeServerUriBase = Uri.parse(wellKnownPrompt.homeServerUrl),
|
||||
identityServerUri = wellKnownPrompt.identityServerUrl?.let { Uri.parse(it) }
|
||||
)
|
||||
?: HomeServerConnectionConfig(
|
||||
homeServerUri = Uri.parse(wellKnownPrompt.homeServerUrl),
|
||||
homeServerUri = Uri.parse("https://${action.username.getDomain()}"),
|
||||
homeServerUriBase = Uri.parse(wellKnownPrompt.homeServerUrl),
|
||||
identityServerUri = wellKnownPrompt.identityServerUrl?.let { Uri.parse(it) }
|
||||
)
|
||||
|
||||
|
@ -620,19 +617,23 @@ class LoginViewModel @AssistedInject constructor(
|
|||
}
|
||||
|
||||
private fun onDirectLoginError(failure: Throwable) {
|
||||
if (failure is Failure.UnrecognizedCertificateFailure) {
|
||||
// Display this error in a dialog
|
||||
_viewEvents.post(LoginViewEvents.Failure(failure))
|
||||
setState {
|
||||
copy(
|
||||
asyncLoginAction = Uninitialized
|
||||
)
|
||||
when (failure) {
|
||||
is MatrixIdFailure.InvalidMatrixId,
|
||||
is Failure.UnrecognizedCertificateFailure -> {
|
||||
// Display this error in a dialog
|
||||
_viewEvents.post(LoginViewEvents.Failure(failure))
|
||||
setState {
|
||||
copy(
|
||||
asyncLoginAction = Uninitialized
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setState {
|
||||
copy(
|
||||
asyncLoginAction = Fail(failure)
|
||||
)
|
||||
else -> {
|
||||
setState {
|
||||
copy(
|
||||
asyncLoginAction = Fail(failure)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -775,7 +776,7 @@ class LoginViewModel @AssistedInject constructor(
|
|||
data ?: return@launch
|
||||
|
||||
// Valid Homeserver, add it to the history.
|
||||
// Note: we add what the user has input, data.homeServerUrl can be different
|
||||
// Note: we add what the user has input, data.homeServerUrlBase can be different
|
||||
rememberHomeServer(homeServerConnectionConfig.homeServerUri.toString())
|
||||
|
||||
val loginMode = when {
|
||||
|
@ -791,6 +792,7 @@ class LoginViewModel @AssistedInject constructor(
|
|||
setState {
|
||||
copy(
|
||||
asyncHomeServerLoginFlowRequest = Uninitialized,
|
||||
homeServerUrlFromUser = homeServerConnectionConfig.homeServerUri.toString(),
|
||||
homeServerUrl = data.homeServerUrl,
|
||||
loginMode = loginMode,
|
||||
loginModeSupportedTypes = data.supportedLoginTypes.toList()
|
||||
|
|
|
@ -38,7 +38,12 @@ data class LoginViewState(
|
|||
@PersistState
|
||||
val resetPasswordEmail: String? = null,
|
||||
@PersistState
|
||||
val homeServerUrlFromUser: String? = null,
|
||||
|
||||
// Can be modified after a Wellknown request
|
||||
@PersistState
|
||||
val homeServerUrl: String? = null,
|
||||
|
||||
// For SSO session recovery
|
||||
@PersistState
|
||||
val deviceId: String? = null,
|
||||
|
|
|
@ -112,7 +112,7 @@ class LoginTermsFragment @Inject constructor(
|
|||
}
|
||||
|
||||
override fun updateWithState(state: LoginViewState) {
|
||||
policyController.homeServer = state.homeServerUrl.toReducedUrl()
|
||||
policyController.homeServer = state.homeServerUrlFromUser.toReducedUrl()
|
||||
renderState()
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ import im.vector.app.features.login.LoginMode
|
|||
import im.vector.app.features.login.ReAuthHelper
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.MatrixPatterns.getDomain
|
||||
import org.matrix.android.sdk.api.auth.AuthenticationService
|
||||
import org.matrix.android.sdk.api.auth.HomeServerHistoryService
|
||||
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
|
||||
|
@ -595,10 +596,6 @@ class LoginViewModel2 @AssistedInject constructor(
|
|||
} else {
|
||||
onWellKnownError()
|
||||
}
|
||||
is WellknownResult.InvalidMatrixId -> {
|
||||
setState { copy(isLoading = false) }
|
||||
_viewEvents.post(LoginViewEvents2.Failure(Exception(stringProvider.getString(R.string.login_signin_matrix_id_error_invalid_matrix_id))))
|
||||
}
|
||||
else -> {
|
||||
onWellKnownError()
|
||||
}
|
||||
|
@ -616,7 +613,7 @@ class LoginViewModel2 @AssistedInject constructor(
|
|||
homeServerConnectionConfig: HomeServerConnectionConfig?) {
|
||||
val alteredHomeServerConnectionConfig = homeServerConnectionConfig
|
||||
?.copy(
|
||||
homeServerUri = Uri.parse(wellKnownPrompt.homeServerUrl),
|
||||
homeServerUriBase = Uri.parse(wellKnownPrompt.homeServerUrl),
|
||||
identityServerUri = wellKnownPrompt.identityServerUrl?.let { Uri.parse(it) }
|
||||
)
|
||||
?: HomeServerConnectionConfig(
|
||||
|
@ -655,7 +652,7 @@ class LoginViewModel2 @AssistedInject constructor(
|
|||
}
|
||||
viewEvent?.let { _viewEvents.post(it) }
|
||||
|
||||
val urlFromUser = action.username.substringAfter(":")
|
||||
val urlFromUser = action.username.getDomain()
|
||||
setState {
|
||||
copy(
|
||||
isLoading = false,
|
||||
|
@ -756,7 +753,7 @@ class LoginViewModel2 @AssistedInject constructor(
|
|||
} ?: return@launch
|
||||
|
||||
// Valid Homeserver, add it to the history.
|
||||
// Note: we add what the user has input, data.homeServerUrl can be different
|
||||
// Note: we add what the user has input, data.homeServerUrlBase can be different
|
||||
rememberHomeServer(homeServerConnectionConfig.homeServerUri.toString())
|
||||
|
||||
val loginMode = when {
|
||||
|
|
|
@ -16,11 +16,15 @@
|
|||
|
||||
package im.vector.app.features.raw.wellknown
|
||||
|
||||
import org.matrix.android.sdk.api.MatrixPatterns.getDomain
|
||||
import org.matrix.android.sdk.api.auth.data.SessionParams
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
import org.matrix.android.sdk.api.raw.RawService
|
||||
|
||||
suspend fun RawService.getElementWellknown(userId: String): ElementWellKnown? {
|
||||
return tryOrNull { getWellknown(userId) }
|
||||
suspend fun RawService.getElementWellknown(sessionParams: SessionParams): ElementWellKnown? {
|
||||
// By default we use the domain of the userId to retrieve the .well-known data
|
||||
val domain = sessionParams.userId.getDomain()
|
||||
return tryOrNull { getWellknown(domain) }
|
||||
?.let { ElementWellKnownMapper.from(it) }
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ import im.vector.app.features.raw.wellknown.getElementWellknown
|
|||
import im.vector.app.features.raw.wellknown.isE2EByDefault
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.MatrixPatterns.getDomain
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
import org.matrix.android.sdk.api.raw.RawService
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
|
@ -62,7 +63,7 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted private val init
|
|||
private fun initHomeServerName() {
|
||||
setState {
|
||||
copy(
|
||||
homeServerName = session.myUserId.substringAfter(":")
|
||||
homeServerName = session.myUserId.getDomain()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +73,7 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted private val init
|
|||
private fun initAdminE2eByDefault() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
adminE2EByDefault = tryOrNull {
|
||||
rawService.getElementWellknown(session.myUserId)
|
||||
rawService.getElementWellknown(session.sessionParams)
|
||||
?.isE2EByDefault()
|
||||
?: true
|
||||
} ?: true
|
||||
|
|
|
@ -20,6 +20,7 @@ import im.vector.app.R
|
|||
import im.vector.app.core.resources.StringArrayProvider
|
||||
import im.vector.app.features.roomdirectory.RoomDirectoryData
|
||||
import im.vector.app.features.roomdirectory.RoomDirectoryServer
|
||||
import org.matrix.android.sdk.api.MatrixPatterns.getDomain
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
|
||||
import javax.inject.Inject
|
||||
|
@ -36,7 +37,7 @@ class RoomDirectoryListCreator @Inject constructor(
|
|||
val protocols = ArrayList<RoomDirectoryData>()
|
||||
|
||||
// Add user homeserver name
|
||||
val userHsName = session.myUserId.substringAfter(":")
|
||||
val userHsName = session.myUserId.getDomain()
|
||||
|
||||
// Add default protocol
|
||||
protocols.add(
|
||||
|
|
|
@ -31,6 +31,7 @@ import im.vector.app.core.extensions.exhaustive
|
|||
import im.vector.app.core.platform.VectorViewModel
|
||||
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.MatrixPatterns.getDomain
|
||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
|
@ -101,7 +102,7 @@ class RoomAliasViewModel @AssistedInject constructor(@Assisted initialState: Roo
|
|||
private fun initHomeServerName() {
|
||||
setState {
|
||||
copy(
|
||||
homeServerName = session.myUserId.substringAfter(":")
|
||||
homeServerName = session.myUserId.getDomain()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -157,7 +157,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
|
|||
findPreference<VectorPreference>(VectorPreferences.SETTINGS_CRYPTOGRAPHY_HS_ADMIN_DISABLED_E2E_DEFAULT)?.isVisible =
|
||||
vectorActivity.getVectorComponent()
|
||||
.rawService()
|
||||
.getElementWellknown(session.myUserId)
|
||||
.getElementWellknown(session.sessionParams)
|
||||
?.isE2EByDefault() == false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,8 @@ import org.matrix.android.sdk.api.federation.FederationVersion
|
|||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
|
||||
|
||||
data class HomeServerSettingsViewState(
|
||||
val baseUrl: String = "",
|
||||
val homeserverUrl: String = "",
|
||||
val homeserverClientServerApiUrl: String = "",
|
||||
val homeServerCapabilities: HomeServerCapabilities = HomeServerCapabilities(),
|
||||
val federationVersion: Async<FederationVersion> = Uninitialized
|
||||
) : MvRxState
|
||||
|
|
|
@ -29,13 +29,15 @@ import im.vector.app.core.resources.StringProvider
|
|||
import im.vector.app.features.discovery.settingsCenteredImageItem
|
||||
import im.vector.app.features.discovery.settingsInfoItem
|
||||
import im.vector.app.features.discovery.settingsSectionTitleItem
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import org.matrix.android.sdk.api.federation.FederationVersion
|
||||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
|
||||
import javax.inject.Inject
|
||||
|
||||
class HomeserverSettingsController @Inject constructor(
|
||||
private val stringProvider: StringProvider,
|
||||
private val errorFormatter: ErrorFormatter
|
||||
private val errorFormatter: ErrorFormatter,
|
||||
private val vectorPreferences: VectorPreferences
|
||||
) : TypedEpoxyController<HomeServerSettingsViewState>() {
|
||||
|
||||
var callback: Callback? = null
|
||||
|
@ -78,7 +80,17 @@ class HomeserverSettingsController @Inject constructor(
|
|||
}
|
||||
settingsInfoItem {
|
||||
id("urlValue")
|
||||
helperText(state.baseUrl)
|
||||
helperText(state.homeserverUrl)
|
||||
}
|
||||
if (vectorPreferences.developerMode()) {
|
||||
settingsSectionTitleItem {
|
||||
id("urlApiTitle")
|
||||
titleResId(R.string.hs_client_url)
|
||||
}
|
||||
settingsInfoItem {
|
||||
id("urlApiValue")
|
||||
helperText(state.homeserverClientServerApiUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,8 @@ class HomeserverSettingsViewModel @AssistedInject constructor(
|
|||
init {
|
||||
setState {
|
||||
copy(
|
||||
baseUrl = session.sessionParams.homeServerUrl,
|
||||
homeserverUrl = session.sessionParams.homeServerUrl,
|
||||
homeserverClientServerApiUrl = session.sessionParams.homeServerUrlBase,
|
||||
homeServerCapabilities = session.getHomeServerCapabilities()
|
||||
)
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import im.vector.app.core.resources.StringProvider
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.MatrixPatterns
|
||||
import org.matrix.android.sdk.api.MatrixPatterns.getDomain
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.room.AliasAvailabilityResult
|
||||
import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure
|
||||
|
@ -51,7 +52,7 @@ class CreateSpaceViewModel @AssistedInject constructor(
|
|||
init {
|
||||
setState {
|
||||
copy(
|
||||
homeServerName = session.myUserId.substringAfter(":")
|
||||
homeServerName = session.myUserId.getDomain()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ class CreateSpaceViewModelTask @Inject constructor(
|
|||
val childIds = mutableListOf<String>()
|
||||
|
||||
val e2eByDefault = tryOrNull {
|
||||
rawService.getElementWellknown(session.myUserId)
|
||||
rawService.getElementWellknown(session.sessionParams)
|
||||
?.isE2EByDefault()
|
||||
?: true
|
||||
} ?: true
|
||||
|
|
|
@ -81,7 +81,7 @@ class SpacePeopleViewModel @AssistedInject constructor(
|
|||
setState { copy(createAndInviteState = Loading()) }
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val adminE2EByDefault = rawService.getElementWellknown(session.myUserId)
|
||||
val adminE2EByDefault = rawService.getElementWellknown(session.sessionParams)
|
||||
?.isE2EByDefault()
|
||||
?: true
|
||||
|
||||
|
|
|
@ -538,6 +538,7 @@
|
|||
<string name="login">Log in</string>
|
||||
<string name="logout">Sign out</string>
|
||||
<string name="hs_url">Homeserver URL</string>
|
||||
<string name="hs_client_url">Homeserver API URL</string>
|
||||
<string name="identity_url">Identity Server URL</string>
|
||||
<string name="search">Search</string>
|
||||
|
||||
|
|
Loading…
Reference in a new issue