diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/homeserver/HomeServerCapabilities.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/homeserver/HomeServerCapabilities.kt index c8526985e1..5a8770f262 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/homeserver/HomeServerCapabilities.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/homeserver/HomeServerCapabilities.kt @@ -24,7 +24,11 @@ data class HomeServerCapabilities( /** * Max size of file which can be uploaded to the homeserver in bytes. [MAX_UPLOAD_FILE_SIZE_UNKNOWN] if unknown or not retrieved yet */ - val maxUploadFileSize: Long = MAX_UPLOAD_FILE_SIZE_UNKNOWN + val maxUploadFileSize: Long = MAX_UPLOAD_FILE_SIZE_UNKNOWN, + /** + * Last version identity server and binding supported + */ + val lastVersionIdentityServerSupported: Boolean = false ) { companion object { const val MAX_UPLOAD_FILE_SIZE_UNKNOWN = -1L diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityServiceError.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityServiceError.kt index 8dd99d60d1..b4d7a0e0b7 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityServiceError.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityServiceError.kt @@ -18,6 +18,7 @@ package im.vector.matrix.android.api.session.identity sealed class IdentityServiceError(cause: Throwable? = null) : Throwable(cause = cause) { object OutdatedIdentityServer : IdentityServiceError(null) + object OutdatedHomeServer : IdentityServiceError(null) object NoIdentityServerConfigured : IdentityServiceError(null) object TermsNotSignedException : IdentityServiceError(null) object BulkLookupSha256NotSupported : IdentityServiceError(null) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/HomeServerCapabilitiesMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/HomeServerCapabilitiesMapper.kt index a0d3662e03..03086337ae 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/HomeServerCapabilitiesMapper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/HomeServerCapabilitiesMapper.kt @@ -27,14 +27,16 @@ internal object HomeServerCapabilitiesMapper { fun map(entity: HomeServerCapabilitiesEntity): HomeServerCapabilities { return HomeServerCapabilities( canChangePassword = entity.canChangePassword, - maxUploadFileSize = entity.maxUploadFileSize + maxUploadFileSize = entity.maxUploadFileSize, + lastVersionIdentityServerSupported = entity.lastVersionIdentityServerSupported ) } fun map(domain: HomeServerCapabilities): HomeServerCapabilitiesEntity { return HomeServerCapabilitiesEntity( canChangePassword = domain.canChangePassword, - maxUploadFileSize = domain.maxUploadFileSize + maxUploadFileSize = domain.maxUploadFileSize, + lastVersionIdentityServerSupported = domain.lastVersionIdentityServerSupported ) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/HomeServerCapabilitiesEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/HomeServerCapabilitiesEntity.kt index 5743597a61..1fe22e4960 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/HomeServerCapabilitiesEntity.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/HomeServerCapabilitiesEntity.kt @@ -22,6 +22,7 @@ import io.realm.RealmObject internal open class HomeServerCapabilitiesEntity( var canChangePassword: Boolean = true, var maxUploadFileSize: Long = HomeServerCapabilities.MAX_UPLOAD_FILE_SIZE_UNKNOWN, + var lastVersionIdentityServerSupported: Boolean = false, var lastUpdatedTimestamp: Long = 0L ) : RealmObject() { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/CapabilitiesAPI.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/CapabilitiesAPI.kt index f37bbfe798..880a8fbc31 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/CapabilitiesAPI.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/CapabilitiesAPI.kt @@ -16,6 +16,7 @@ package im.vector.matrix.android.internal.session.homeserver +import im.vector.matrix.android.api.auth.data.Versions import im.vector.matrix.android.internal.network.NetworkConstants import retrofit2.Call import retrofit2.http.GET @@ -38,5 +39,11 @@ internal interface CapabilitiesAPI { * Request the versions */ @GET(NetworkConstants.URI_API_PREFIX_PATH_ + "versions") - fun getVersions(): Call + fun getVersions(): Call + + /** + * Ping the homeserver. We do not care about the returned data, so there is no use to parse them + */ + @GET(NetworkConstants.URI_API_PREFIX_PATH_ + "versions") + fun ping(): Call } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTask.kt index 9f068381f0..c625324774 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/DefaultGetHomeServerCapabilitiesTask.kt @@ -17,6 +17,9 @@ package im.vector.matrix.android.internal.session.homeserver import com.zhuinden.monarchy.Monarchy +import im.vector.matrix.android.api.auth.data.Versions +import im.vector.matrix.android.api.auth.data.isLoginAndRegistrationSupportedBySdk +import im.vector.matrix.android.api.extensions.orFalse import im.vector.matrix.android.api.session.homeserver.HomeServerCapabilities import im.vector.matrix.android.internal.database.model.HomeServerCapabilitiesEntity import im.vector.matrix.android.internal.database.query.getOrCreate @@ -57,12 +60,19 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor( } }.getOrNull() - // TODO Add other call here (get version, etc.) + val versions = runCatching { + executeRequest(null) { + apiCall = capabilitiesAPI.getVersions() + } + }.getOrNull() - insertInDb(capabilities, uploadCapabilities) + + insertInDb(capabilities, uploadCapabilities, versions) } - private suspend fun insertInDb(getCapabilitiesResult: GetCapabilitiesResult?, getUploadCapabilitiesResult: GetUploadCapabilitiesResult) { + private suspend fun insertInDb(getCapabilitiesResult: GetCapabilitiesResult?, + getUploadCapabilitiesResult: GetUploadCapabilitiesResult, + getVersionResult: Versions?) { monarchy.awaitTransaction { realm -> val homeServerCapabilitiesEntity = HomeServerCapabilitiesEntity.getOrCreate(realm) @@ -71,6 +81,8 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor( homeServerCapabilitiesEntity.maxUploadFileSize = getUploadCapabilitiesResult.maxUploadSize ?: HomeServerCapabilities.MAX_UPLOAD_FILE_SIZE_UNKNOWN + homeServerCapabilitiesEntity.lastVersionIdentityServerSupported = getVersionResult?.isLoginAndRegistrationSupportedBySdk().orFalse() + homeServerCapabilitiesEntity.lastUpdatedTimestamp = Date().time } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/HomeServerPinger.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/HomeServerPinger.kt index e220c0064d..705deb4e57 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/HomeServerPinger.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/homeserver/HomeServerPinger.kt @@ -35,7 +35,7 @@ internal class HomeServerPinger @Inject constructor(private val taskExecutor: Ta suspend fun canReachHomeServer(): Boolean { return try { executeRequest(null) { - apiCall = capabilitiesAPI.getVersions() + apiCall = capabilitiesAPI.ping() } true } catch (throwable: Throwable) { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt index c6a8b82b42..4794ff1c6b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt @@ -25,6 +25,7 @@ import im.vector.matrix.android.api.extensions.tryThis import im.vector.matrix.android.api.failure.Failure import im.vector.matrix.android.api.failure.MatrixError import im.vector.matrix.android.api.session.events.model.toModel +import im.vector.matrix.android.api.session.homeserver.HomeServerCapabilitiesService import im.vector.matrix.android.api.session.identity.FoundThreePid import im.vector.matrix.android.api.session.identity.IdentityService import im.vector.matrix.android.api.session.identity.IdentityServiceError @@ -75,7 +76,8 @@ internal class DefaultIdentityService @Inject constructor( private val submitTokenForBindingTask: IdentitySubmitTokenForBindingTask, private val unbindThreePidsTask: UnbindThreePidsTask, private val identityApiProvider: IdentityApiProvider, - private val accountDataDataSource: AccountDataDataSource + private val accountDataDataSource: AccountDataDataSource, + private val homeServerCapabilitiesService: HomeServerCapabilitiesService ) : IdentityService { private val lifecycleOwner: LifecycleOwner = LifecycleOwner { lifecycleRegistry } @@ -123,6 +125,11 @@ internal class DefaultIdentityService @Inject constructor( } override fun startBindThreePid(threePid: ThreePid, callback: MatrixCallback): Cancelable { + if (homeServerCapabilitiesService.getHomeServerCapabilities().lastVersionIdentityServerSupported.not()) { + callback.onFailure(IdentityServiceError.OutdatedHomeServer) + return NoOpCancellable + } + return GlobalScope.launchToCallback(coroutineDispatchers.main, callback) { identityRequestTokenForBindingTask.execute(IdentityRequestTokenForBindingTask.Params(threePid, false)) } @@ -141,6 +148,11 @@ internal class DefaultIdentityService @Inject constructor( } override fun finalizeBindThreePid(threePid: ThreePid, callback: MatrixCallback): Cancelable { + if (homeServerCapabilitiesService.getHomeServerCapabilities().lastVersionIdentityServerSupported.not()) { + callback.onFailure(IdentityServiceError.OutdatedHomeServer) + return NoOpCancellable + } + return GlobalScope.launchToCallback(coroutineDispatchers.main, callback) { bindThreePidsTask.execute(BindThreePidsTask.Params(threePid)) } @@ -153,6 +165,11 @@ internal class DefaultIdentityService @Inject constructor( } override fun unbindThreePid(threePid: ThreePid, callback: MatrixCallback): Cancelable { + if (homeServerCapabilitiesService.getHomeServerCapabilities().lastVersionIdentityServerSupported.not()) { + callback.onFailure(IdentityServiceError.OutdatedHomeServer) + return NoOpCancellable + } + return GlobalScope.launchToCallback(coroutineDispatchers.main, callback) { unbindThreePidsTask.execute(UnbindThreePidsTask.Params(threePid)) }