mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-01-05 14:26:48 +01:00
Identity: protect against outdated homeserver
This commit is contained in:
parent
7afc7bdb31
commit
88e8c11ee5
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
||||
|
@ -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<Unit>
|
||||
fun getVersions(): Call<Versions>
|
||||
|
||||
/**
|
||||
* 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<Unit>
|
||||
}
|
||||
|
@ -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<Versions>(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
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ internal class HomeServerPinger @Inject constructor(private val taskExecutor: Ta
|
||||
suspend fun canReachHomeServer(): Boolean {
|
||||
return try {
|
||||
executeRequest<Unit>(null) {
|
||||
apiCall = capabilitiesAPI.getVersions()
|
||||
apiCall = capabilitiesAPI.ping()
|
||||
}
|
||||
true
|
||||
} catch (throwable: Throwable) {
|
||||
|
@ -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<Unit>): 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<Unit>): 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<Unit>): Cancelable {
|
||||
if (homeServerCapabilitiesService.getHomeServerCapabilities().lastVersionIdentityServerSupported.not()) {
|
||||
callback.onFailure(IdentityServiceError.OutdatedHomeServer)
|
||||
return NoOpCancellable
|
||||
}
|
||||
|
||||
return GlobalScope.launchToCallback(coroutineDispatchers.main, callback) {
|
||||
unbindThreePidsTask.execute(UnbindThreePidsTask.Params(threePid))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user