Merge pull request #5208 from vector-im/feature/adm/personalisation-capabilities

MSC3283 - Supporting additional homeserver capabilities
This commit is contained in:
Benoit Marty 2022-02-14 14:27:26 +01:00 committed by GitHub
commit 43d6a29ff3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 103 additions and 20 deletions

1
changelog.d/5207.sdk Normal file
View File

@ -0,0 +1 @@
Adds support for MSC3283, additional homeserver capabilities

View File

@ -21,6 +21,18 @@ data class HomeServerCapabilities(
* True if it is possible to change the password of the account.
*/
val canChangePassword: Boolean = true,
/**
* True if it is possible to change the display name of the account.
*/
val canChangeDisplayName: Boolean = true,
/**
* True if it is possible to change the avatar of the account.
*/
val canChangeAvatar: Boolean = true,
/**
* True if it is possible to change the 3pid associations of the account.
*/
val canChange3pid: Boolean = true,
/**
* Max size of file which can be uploaded to the homeserver in bytes. [MAX_UPLOAD_FILE_SIZE_UNKNOWN] if unknown or not retrieved yet
*/
@ -76,6 +88,7 @@ data class HomeServerCapabilities(
}
}
}
fun isFeatureSupported(feature: String, byRoomVersion: String): Boolean {
if (roomVersions?.capabilities == null) return false
val info = roomVersions.capabilities[feature] ?: return false

View File

@ -42,6 +42,7 @@ import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo021
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo022
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo023
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo024
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo025
import org.matrix.android.sdk.internal.util.Normalizer
import timber.log.Timber
import javax.inject.Inject
@ -85,5 +86,6 @@ internal class RealmSessionStoreMigration @Inject constructor(
if (oldVersion < 22) MigrateSessionTo022(realm).perform()
if (oldVersion < 23) MigrateSessionTo023(realm).perform()
if (oldVersion < 24) MigrateSessionTo024(realm).perform()
if (oldVersion < 25) MigrateSessionTo025(realm).perform()
}
}

View File

@ -35,6 +35,9 @@ internal object HomeServerCapabilitiesMapper {
fun map(entity: HomeServerCapabilitiesEntity): HomeServerCapabilities {
return HomeServerCapabilities(
canChangePassword = entity.canChangePassword,
canChangeDisplayName = entity.canChangeDisplayName,
canChangeAvatar = entity.canChangeAvatar,
canChange3pid = entity.canChange3pid,
maxUploadFileSize = entity.maxUploadFileSize,
lastVersionIdentityServerSupported = entity.lastVersionIdentityServerSupported,
defaultIdentityServerUrl = entity.defaultIdentityServerUrl,

View File

@ -17,7 +17,7 @@
package org.matrix.android.sdk.internal.database.migration
import io.realm.DynamicRealm
import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields
import org.matrix.android.sdk.internal.extensions.forceRefreshOfHomeServerCapabilities
import org.matrix.android.sdk.internal.util.database.RealmMigrator
class MigrateSessionTo003(realm: DynamicRealm) : RealmMigrator(realm, 3) {
@ -25,9 +25,6 @@ class MigrateSessionTo003(realm: DynamicRealm) : RealmMigrator(realm, 3) {
override fun doMigrate(realm: DynamicRealm) {
realm.schema.get("HomeServerCapabilitiesEntity")
?.addField("preferredJitsiDomain", String::class.java)
?.transform { obj ->
// Schedule a refresh of the capabilities
obj.setLong(HomeServerCapabilitiesEntityFields.LAST_UPDATED_TIMESTAMP, 0)
}
?.forceRefreshOfHomeServerCapabilities()
}
}

View File

@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.database.migration
import io.realm.DynamicRealm
import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields
import org.matrix.android.sdk.internal.extensions.forceRefreshOfHomeServerCapabilities
import org.matrix.android.sdk.internal.util.database.RealmMigrator
class MigrateSessionTo016(realm: DynamicRealm) : RealmMigrator(realm, 16) {
@ -25,9 +26,6 @@ class MigrateSessionTo016(realm: DynamicRealm) : RealmMigrator(realm, 16) {
override fun doMigrate(realm: DynamicRealm) {
realm.schema.get("HomeServerCapabilitiesEntity")
?.addField(HomeServerCapabilitiesEntityFields.ROOM_VERSIONS_JSON, String::class.java)
?.transform { obj ->
// Schedule a refresh of the capabilities
obj.setLong(HomeServerCapabilitiesEntityFields.LAST_UPDATED_TIMESTAMP, 0)
}
?.forceRefreshOfHomeServerCapabilities()
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2022 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.internal.database.migration
import io.realm.DynamicRealm
import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields
import org.matrix.android.sdk.internal.extensions.forceRefreshOfHomeServerCapabilities
import org.matrix.android.sdk.internal.util.database.RealmMigrator
class MigrateSessionTo025(realm: DynamicRealm) : RealmMigrator(realm, 25) {
override fun doMigrate(realm: DynamicRealm) {
realm.schema.get("HomeServerCapabilitiesEntity")
?.addField(HomeServerCapabilitiesEntityFields.CAN_CHANGE_DISPLAY_NAME, Boolean::class.java)
?.addField(HomeServerCapabilitiesEntityFields.CAN_CHANGE_AVATAR, Boolean::class.java)
?.addField(HomeServerCapabilitiesEntityFields.CAN_CHANGE3PID, Boolean::class.java)
?.forceRefreshOfHomeServerCapabilities()
}
}

View File

@ -21,6 +21,9 @@ import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
internal open class HomeServerCapabilitiesEntity(
var canChangePassword: Boolean = true,
var canChangeDisplayName: Boolean = true,
var canChangeAvatar: Boolean = true,
var canChange3pid: Boolean = true,
var roomVersionsJson: String? = null,
var maxUploadFileSize: Long = HomeServerCapabilities.MAX_UPLOAD_FILE_SIZE_UNKNOWN,
var lastVersionIdentityServerSupported: Boolean = false,

View File

@ -18,6 +18,8 @@ package org.matrix.android.sdk.internal.extensions
import io.realm.RealmList
import io.realm.RealmObject
import io.realm.RealmObjectSchema
import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields
internal fun RealmObject.assertIsManaged() {
check(isManaged) { "${javaClass.simpleName} entity should be managed to use this function" }
@ -31,3 +33,12 @@ internal fun <T> RealmList<T>.clearWith(delete: (T) -> Unit) {
first()?.let { delete.invoke(it) }
}
}
/**
* Schedule a refresh of the HomeServers capabilities
*/
internal fun RealmObjectSchema?.forceRefreshOfHomeServerCapabilities(): RealmObjectSchema? {
return this?.transform { obj ->
obj.setLong(HomeServerCapabilitiesEntityFields.LAST_UPDATED_TIMESTAMP, 0)
}
}

View File

@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.session.homeserver
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.matrix.android.sdk.api.extensions.orTrue
import org.matrix.android.sdk.api.util.JsonDict
/**
@ -37,10 +36,30 @@ internal data class GetCapabilitiesResult(
internal data class Capabilities(
/**
* Capability to indicate if the user can change their password.
* True if the user can change their password, false otherwise.
*/
@Json(name = "m.change_password")
val changePassword: ChangePassword? = null,
val changePassword: BooleanCapability? = null,
/**
* Capability to indicate if the user can change their display name.
* True if the user can change their display name, false otherwise.
*/
@Json(name = "m.set_displayname")
val changeDisplayName: BooleanCapability? = null,
/**
* Capability to indicate if the user can change their avatar.
* True if the user can change their avatar, false otherwise.
*/
@Json(name = "m.set_avatar_url")
val changeAvatar: BooleanCapability? = null,
/**
* Capability to indicate if the user can change add, remove or change 3PID associations.
* True if the user can change their 3PID associations, false otherwise.
*/
@Json(name = "m.3pid_changes")
val change3pid: BooleanCapability? = null,
/**
* This capability describes the default and available room versions a server supports, and at what level of stability.
* Clients should make use of this capability to determine if users need to be encouraged to upgrade their rooms.
@ -50,9 +69,9 @@ internal data class Capabilities(
)
@JsonClass(generateAdapter = true)
internal data class ChangePassword(
internal data class BooleanCapability(
/**
* Required. True if the user can change their password, false otherwise.
* Required.
*/
@Json(name = "enabled")
val enabled: Boolean?
@ -87,8 +106,3 @@ internal data class RoomVersions(
@Json(name = "org.matrix.msc3244.room_capabilities")
val roomCapabilities: JsonDict? = null
)
// The spec says: If not present, the client should assume that password changes are possible via the API
internal fun GetCapabilitiesResult.canChangePassword(): Boolean {
return capabilities?.changePassword?.enabled.orTrue()
}

View File

@ -20,6 +20,7 @@ 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.extensions.orTrue
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
import org.matrix.android.sdk.internal.auth.version.Versions
import org.matrix.android.sdk.internal.auth.version.isLoginAndRegistrationSupportedBySdk
@ -108,9 +109,16 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
val homeServerCapabilitiesEntity = HomeServerCapabilitiesEntity.getOrCreate(realm)
if (getCapabilitiesResult != null) {
homeServerCapabilitiesEntity.canChangePassword = getCapabilitiesResult.canChangePassword()
val capabilities = getCapabilitiesResult.capabilities
homeServerCapabilitiesEntity.roomVersionsJson = getCapabilitiesResult.capabilities?.roomVersions?.let {
// The spec says: If not present, the client should assume that
// password, display name, avatar changes and 3pid changes are possible via the API
homeServerCapabilitiesEntity.canChangePassword = capabilities?.changePassword?.enabled.orTrue()
homeServerCapabilitiesEntity.canChangeDisplayName = capabilities?.changeDisplayName?.enabled.orTrue()
homeServerCapabilitiesEntity.canChangeAvatar = capabilities?.changeAvatar?.enabled.orTrue()
homeServerCapabilitiesEntity.canChange3pid = capabilities?.change3pid?.enabled.orTrue()
homeServerCapabilitiesEntity.roomVersionsJson = capabilities?.roomVersions?.let {
MoshiProvider.providesMoshi().adapter(RoomVersions::class.java).toJson(it)
}
}