Better cleanup of the Crypto database.
This commit is contained in:
parent
5908cd54f0
commit
15c86f3fe3
|
@ -41,15 +41,11 @@ import org.matrix.android.sdk.internal.crypto.store.db.doRealmTransactionAsync
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.doWithRealm
|
import org.matrix.android.sdk.internal.crypto.store.db.doWithRealm
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.mapper.CryptoRoomInfoMapper
|
import org.matrix.android.sdk.internal.crypto.store.db.mapper.CryptoRoomInfoMapper
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.mapper.MyDeviceLastSeenInfoEntityMapper
|
import org.matrix.android.sdk.internal.crypto.store.db.mapper.MyDeviceLastSeenInfoEntityMapper
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.AuditTrailEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.AuditTrailEntityFields
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntity
|
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntity
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntity
|
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntity
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields
|
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntity
|
import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntity
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntityFields
|
import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntityFields
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.OutgoingKeyRequestEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.OutgoingKeyRequestEntityFields
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.query.getById
|
import org.matrix.android.sdk.internal.crypto.store.db.query.getById
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.query.getOrCreate
|
import org.matrix.android.sdk.internal.crypto.store.db.query.getOrCreate
|
||||||
import org.matrix.android.sdk.internal.di.CryptoDatabase
|
import org.matrix.android.sdk.internal.di.CryptoDatabase
|
||||||
|
@ -82,7 +78,6 @@ internal class RustCryptoStore @Inject constructor(
|
||||||
// still needed on rust due to the global crypto settings
|
// still needed on rust due to the global crypto settings
|
||||||
init {
|
init {
|
||||||
// Ensure CryptoMetadataEntity is inserted in DB
|
// Ensure CryptoMetadataEntity is inserted in DB
|
||||||
// TODO BMA
|
|
||||||
doRealmTransaction("init", realmConfiguration) { realm ->
|
doRealmTransaction("init", realmConfiguration) { realm ->
|
||||||
var currentMetadata = realm.where<CryptoMetadataEntity>().findFirst()
|
var currentMetadata = realm.where<CryptoMetadataEntity>().findFirst()
|
||||||
|
|
||||||
|
@ -146,30 +141,7 @@ internal class RustCryptoStore @Inject constructor(
|
||||||
// nop
|
// nop
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tidyUpDataBase() {
|
override fun tidyUpDataBase() = Unit
|
||||||
// These entities are not used in rust actually, but as they are not yet cleaned up, this will do it with time
|
|
||||||
val prevWeekTs = clock.epochMillis() - 7 * 24 * 60 * 60 * 1_000
|
|
||||||
doRealmTransaction("tidyUpDataBase", realmConfiguration) { realm ->
|
|
||||||
|
|
||||||
// Clean the old ones?
|
|
||||||
realm.where<OutgoingKeyRequestEntity>()
|
|
||||||
.lessThan(OutgoingKeyRequestEntityFields.CREATION_TIME_STAMP, prevWeekTs)
|
|
||||||
.findAll()
|
|
||||||
.also { Timber.i("## Crypto Clean up ${it.size} OutgoingKeyRequestEntity") }
|
|
||||||
.deleteAllFromRealm()
|
|
||||||
|
|
||||||
// Only keep one month history
|
|
||||||
|
|
||||||
val prevMonthTs = clock.epochMillis() - 4 * 7 * 24 * 60 * 60 * 1_000L
|
|
||||||
realm.where<AuditTrailEntity>()
|
|
||||||
.lessThan(AuditTrailEntityFields.AGE_LOCAL_TS, prevMonthTs)
|
|
||||||
.findAll()
|
|
||||||
.also { Timber.i("## Crypto Clean up ${it.size} AuditTrailEntity") }
|
|
||||||
.deleteAllFromRealm()
|
|
||||||
|
|
||||||
// Can we do something for WithHeldSessionEntity?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
val tasks = monarchyWriteAsyncExecutor.shutdownNow()
|
val tasks = monarchyWriteAsyncExecutor.shutdownNow()
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2023 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.crypto.store
|
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.UserIdentity
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
|
|
||||||
|
|
||||||
internal data class UserDataToStore(
|
|
||||||
/**
|
|
||||||
* Map of userId -> (Map of deviceId -> [CryptoDeviceInfo]).
|
|
||||||
*/
|
|
||||||
val userDevices: MutableMap<String, Map<String, CryptoDeviceInfo>> = mutableMapOf(),
|
|
||||||
/**
|
|
||||||
* Map of userId -> [UserIdentity].
|
|
||||||
*/
|
|
||||||
val userIdentities: MutableMap<String, UserIdentity> = mutableMapOf(),
|
|
||||||
)
|
|
|
@ -16,15 +16,9 @@
|
||||||
|
|
||||||
package org.matrix.android.sdk.internal.crypto.store.db
|
package org.matrix.android.sdk.internal.crypto.store.db
|
||||||
|
|
||||||
import android.util.Base64
|
|
||||||
import io.realm.Realm
|
import io.realm.Realm
|
||||||
import io.realm.RealmConfiguration
|
import io.realm.RealmConfiguration
|
||||||
import io.realm.RealmObject
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.ByteArrayOutputStream
|
|
||||||
import java.io.ObjectOutputStream
|
|
||||||
import java.util.zip.GZIPInputStream
|
|
||||||
import java.util.zip.GZIPOutputStream
|
|
||||||
import kotlin.system.measureTimeMillis
|
import kotlin.system.measureTimeMillis
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,24 +30,6 @@ internal fun <T> doWithRealm(realmConfiguration: RealmConfiguration, action: (Re
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get realm, do the query, copy from realm, close realm, and return the copied result.
|
|
||||||
*/
|
|
||||||
internal fun <T : RealmObject> doRealmQueryAndCopy(realmConfiguration: RealmConfiguration, action: (Realm) -> T?): T? {
|
|
||||||
return Realm.getInstance(realmConfiguration).use { realm ->
|
|
||||||
action.invoke(realm)?.let { realm.copyFromRealm(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get realm, do the list query, copy from realm, close realm, and return the copied result.
|
|
||||||
*/
|
|
||||||
internal fun <T : RealmObject> doRealmQueryAndCopyList(realmConfiguration: RealmConfiguration, action: (Realm) -> Iterable<T>): Iterable<T> {
|
|
||||||
return Realm.getInstance(realmConfiguration).use { realm ->
|
|
||||||
action.invoke(realm).let { realm.copyFromRealm(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get realm instance, invoke the action in a transaction and close realm.
|
* Get realm instance, invoke the action in a transaction and close realm.
|
||||||
*/
|
*/
|
||||||
|
@ -70,38 +46,3 @@ internal fun doRealmTransactionAsync(realmConfiguration: RealmConfiguration, act
|
||||||
realm.executeTransactionAsync { action.invoke(it) }
|
realm.executeTransactionAsync { action.invoke(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Serialize any Serializable object, zip it and convert to Base64 String.
|
|
||||||
*/
|
|
||||||
internal fun serializeForRealm(o: Any?): String? {
|
|
||||||
if (o == null) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
val baos = ByteArrayOutputStream()
|
|
||||||
val gzis = GZIPOutputStream(baos)
|
|
||||||
val out = ObjectOutputStream(gzis)
|
|
||||||
out.use {
|
|
||||||
it.writeObject(o)
|
|
||||||
}
|
|
||||||
return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do the opposite of serializeForRealm.
|
|
||||||
*/
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
internal fun <T> deserializeFromRealm(string: String?): T? {
|
|
||||||
if (string == null) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
val decodedB64 = Base64.decode(string.toByteArray(), Base64.DEFAULT)
|
|
||||||
|
|
||||||
val bais = decodedB64.inputStream()
|
|
||||||
val gzis = GZIPInputStream(bais)
|
|
||||||
val ois = SafeObjectInputStream(gzis)
|
|
||||||
return ois.use {
|
|
||||||
it.readObject() as T
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package org.matrix.android.sdk.internal.crypto.store.db
|
package org.matrix.android.sdk.internal.crypto.store.db
|
||||||
|
|
||||||
import io.realm.DynamicRealm
|
import io.realm.DynamicRealm
|
||||||
|
import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo024
|
||||||
import org.matrix.android.sdk.internal.util.database.MatrixRealmMigration
|
import org.matrix.android.sdk.internal.util.database.MatrixRealmMigration
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ import javax.inject.Inject
|
||||||
* 0, 1, 2: legacy Riot-Android;
|
* 0, 1, 2: legacy Riot-Android;
|
||||||
* 3: migrate to RiotX schema;
|
* 3: migrate to RiotX schema;
|
||||||
* 4, 5, 6, 7, 8, 9: migrations from RiotX (which was previously 1, 2, 3, 4, 5, 6).
|
* 4, 5, 6, 7, 8, 9: migrations from RiotX (which was previously 1, 2, 3, 4, 5, 6).
|
||||||
|
* 24: Delete nearly all the crypto DB
|
||||||
*/
|
*/
|
||||||
internal class RealmCryptoStoreMigration @Inject constructor(
|
internal class RealmCryptoStoreMigration @Inject constructor(
|
||||||
) : MatrixRealmMigration(
|
) : MatrixRealmMigration(
|
||||||
|
@ -39,8 +41,6 @@ internal class RealmCryptoStoreMigration @Inject constructor(
|
||||||
override fun hashCode() = 5000
|
override fun hashCode() = 5000
|
||||||
|
|
||||||
override fun doMigrate(realm: DynamicRealm, oldVersion: Long) {
|
override fun doMigrate(realm: DynamicRealm, oldVersion: Long) {
|
||||||
// Delete the whole DB
|
if (oldVersion < 24) MigrateCryptoTo024(realm).perform()
|
||||||
// TODO BMA
|
|
||||||
realm.deleteAll()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,23 +17,9 @@
|
||||||
package org.matrix.android.sdk.internal.crypto.store.db
|
package org.matrix.android.sdk.internal.crypto.store.db
|
||||||
|
|
||||||
import io.realm.annotations.RealmModule
|
import io.realm.annotations.RealmModule
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.AuditTrailEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntity
|
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntity
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntity
|
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntity
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.KeyInfoEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.KeyRequestReplyEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntity
|
import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntity
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.OutboundGroupSessionInfoEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.OutgoingKeyRequestEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.TrustLevelEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntity
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Realm module for Crypto store classes.
|
* Realm module for Crypto store classes.
|
||||||
|
@ -43,21 +29,7 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEnti
|
||||||
classes = [
|
classes = [
|
||||||
CryptoMetadataEntity::class,
|
CryptoMetadataEntity::class,
|
||||||
CryptoRoomEntity::class,
|
CryptoRoomEntity::class,
|
||||||
DeviceInfoEntity::class,
|
|
||||||
KeysBackupDataEntity::class,
|
|
||||||
OlmInboundGroupSessionEntity::class,
|
|
||||||
OlmSessionEntity::class,
|
|
||||||
UserEntity::class,
|
|
||||||
KeyInfoEntity::class,
|
|
||||||
CrossSigningInfoEntity::class,
|
|
||||||
TrustLevelEntity::class,
|
|
||||||
AuditTrailEntity::class,
|
|
||||||
OutgoingKeyRequestEntity::class,
|
|
||||||
KeyRequestReplyEntity::class,
|
|
||||||
MyDeviceLastSeenInfoEntity::class,
|
MyDeviceLastSeenInfoEntity::class,
|
||||||
WithHeldSessionEntity::class,
|
|
||||||
SharedSessionEntity::class,
|
|
||||||
OutboundGroupSessionInfoEntity::class
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
internal class RealmCryptoStoreModule
|
internal class RealmCryptoStoreModule
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db
|
|
||||||
|
|
||||||
import java.io.IOException
|
|
||||||
import java.io.InputStream
|
|
||||||
import java.io.ObjectInputStream
|
|
||||||
import java.io.ObjectStreamClass
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Package has been renamed from `im.vector.matrix.android` to `org.matrix.android.sdk`
|
|
||||||
* so ensure deserialization of previously stored objects still works
|
|
||||||
*
|
|
||||||
* Ref: https://stackoverflow.com/questions/3884492/how-can-i-change-package-for-a-bunch-of-java-serializable-classes
|
|
||||||
*/
|
|
||||||
internal class SafeObjectInputStream(inputStream: InputStream) : ObjectInputStream(inputStream) {
|
|
||||||
|
|
||||||
init {
|
|
||||||
enableResolveObject(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(IOException::class, ClassNotFoundException::class)
|
|
||||||
override fun readClassDescriptor(): ObjectStreamClass {
|
|
||||||
val read = super.readClassDescriptor()
|
|
||||||
if (read.name.startsWith("im.vector.matrix.android.")) {
|
|
||||||
return ObjectStreamClass.lookup(Class.forName(read.name.replace("im.vector.matrix.android.", "org.matrix.android.sdk.")))
|
|
||||||
}
|
|
||||||
return read
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 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.crypto.store.db.migration
|
||||||
|
|
||||||
|
import io.realm.DynamicRealm
|
||||||
|
import org.matrix.android.sdk.internal.util.database.RealmMigrator
|
||||||
|
|
||||||
|
internal class MigrateCryptoTo024(realm: DynamicRealm) : RealmMigrator(realm, 24) {
|
||||||
|
/**
|
||||||
|
* Delete the whole DB, except tables that are still used to store data:
|
||||||
|
* - CryptoMetadataEntity
|
||||||
|
* - MyDeviceLastSeenInfoEntity
|
||||||
|
* - CryptoRoomEntity (but remove unused member 'outboundSessionInfo: OutboundGroupSessionInfoEntity')
|
||||||
|
*/
|
||||||
|
override fun doMigrate(realm: DynamicRealm) {
|
||||||
|
with(realm.schema) {
|
||||||
|
get("CryptoRoomEntity")?.removeField("outboundSessionInfo")
|
||||||
|
|
||||||
|
// Warning: order is important, first remove classes that depends on others.
|
||||||
|
remove("UserEntity")
|
||||||
|
remove("DeviceInfoEntity")
|
||||||
|
remove("CrossSigningInfoEntity")
|
||||||
|
remove("KeyInfoEntity")
|
||||||
|
remove("TrustLevelEntity")
|
||||||
|
remove("KeysBackupDataEntity")
|
||||||
|
remove("OlmInboundGroupSessionEntity")
|
||||||
|
remove("OlmSessionEntity")
|
||||||
|
remove("AuditTrailEntity")
|
||||||
|
remove("OutgoingKeyRequestEntity")
|
||||||
|
remove("KeyRequestReplyEntity")
|
||||||
|
remove("WithHeldSessionEntity")
|
||||||
|
remove("SharedSessionEntity")
|
||||||
|
remove("OutboundGroupSessionInfoEntity")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 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.crypto.store.db.model
|
|
||||||
|
|
||||||
import io.realm.RealmObject
|
|
||||||
import io.realm.annotations.Index
|
|
||||||
|
|
||||||
internal open class AuditTrailEntity(
|
|
||||||
var ageLocalTs: Long? = null,
|
|
||||||
@Index var type: String? = null,
|
|
||||||
var contentJson: String? = null
|
|
||||||
) : RealmObject() {
|
|
||||||
companion object
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 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.crypto.store.db.model
|
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.model.AuditTrail
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.model.ForwardInfo
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.model.IncomingKeyRequestInfo
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.model.TrailType
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.model.UnknownInfo
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.model.WithheldInfo
|
|
||||||
import org.matrix.android.sdk.internal.di.MoshiProvider
|
|
||||||
|
|
||||||
internal object AuditTrailMapper {
|
|
||||||
|
|
||||||
fun map(entity: AuditTrailEntity): AuditTrail? {
|
|
||||||
val contentJson = entity.contentJson ?: return null
|
|
||||||
return when (entity.type) {
|
|
||||||
TrailType.OutgoingKeyForward.name -> {
|
|
||||||
val info = tryOrNull {
|
|
||||||
MoshiProvider.providesMoshi().adapter(ForwardInfo::class.java).fromJson(contentJson)
|
|
||||||
} ?: return null
|
|
||||||
AuditTrail(
|
|
||||||
ageLocalTs = entity.ageLocalTs ?: 0,
|
|
||||||
type = TrailType.OutgoingKeyForward,
|
|
||||||
info = info
|
|
||||||
)
|
|
||||||
}
|
|
||||||
TrailType.OutgoingKeyWithheld.name -> {
|
|
||||||
val info = tryOrNull {
|
|
||||||
MoshiProvider.providesMoshi().adapter(WithheldInfo::class.java).fromJson(contentJson)
|
|
||||||
} ?: return null
|
|
||||||
AuditTrail(
|
|
||||||
ageLocalTs = entity.ageLocalTs ?: 0,
|
|
||||||
type = TrailType.OutgoingKeyWithheld,
|
|
||||||
info = info
|
|
||||||
)
|
|
||||||
}
|
|
||||||
TrailType.IncomingKeyRequest.name -> {
|
|
||||||
val info = tryOrNull {
|
|
||||||
MoshiProvider.providesMoshi().adapter(IncomingKeyRequestInfo::class.java).fromJson(contentJson)
|
|
||||||
} ?: return null
|
|
||||||
AuditTrail(
|
|
||||||
ageLocalTs = entity.ageLocalTs ?: 0,
|
|
||||||
type = TrailType.IncomingKeyRequest,
|
|
||||||
info = info
|
|
||||||
)
|
|
||||||
}
|
|
||||||
TrailType.IncomingKeyForward.name -> {
|
|
||||||
val info = tryOrNull {
|
|
||||||
MoshiProvider.providesMoshi().adapter(ForwardInfo::class.java).fromJson(contentJson)
|
|
||||||
} ?: return null
|
|
||||||
AuditTrail(
|
|
||||||
ageLocalTs = entity.ageLocalTs ?: 0,
|
|
||||||
type = TrailType.IncomingKeyForward,
|
|
||||||
info = info
|
|
||||||
)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
AuditTrail(
|
|
||||||
ageLocalTs = entity.ageLocalTs ?: 0,
|
|
||||||
type = TrailType.Unknown,
|
|
||||||
info = UnknownInfo
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db.model
|
|
||||||
|
|
||||||
import io.realm.RealmList
|
|
||||||
import io.realm.RealmObject
|
|
||||||
import io.realm.annotations.PrimaryKey
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.KeyUsage
|
|
||||||
import org.matrix.android.sdk.internal.extensions.clearWith
|
|
||||||
|
|
||||||
internal open class CrossSigningInfoEntity(
|
|
||||||
@PrimaryKey
|
|
||||||
var userId: String? = null,
|
|
||||||
var wasUserVerifiedOnce: Boolean = false,
|
|
||||||
var crossSigningKeys: RealmList<KeyInfoEntity> = RealmList()
|
|
||||||
) : RealmObject() {
|
|
||||||
|
|
||||||
companion object
|
|
||||||
|
|
||||||
fun getMasterKey() = crossSigningKeys.firstOrNull { it.usages.contains(KeyUsage.MASTER.value) }
|
|
||||||
|
|
||||||
fun setMasterKey(info: KeyInfoEntity?) {
|
|
||||||
crossSigningKeys
|
|
||||||
.filter { it.usages.contains(KeyUsage.MASTER.value) }
|
|
||||||
.forEach { crossSigningKeys.remove(it) }
|
|
||||||
info?.let { crossSigningKeys.add(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getSelfSignedKey() = crossSigningKeys.firstOrNull { it.usages.contains(KeyUsage.SELF_SIGNING.value) }
|
|
||||||
|
|
||||||
fun setSelfSignedKey(info: KeyInfoEntity?) {
|
|
||||||
crossSigningKeys
|
|
||||||
.filter { it.usages.contains(KeyUsage.SELF_SIGNING.value) }
|
|
||||||
.forEach { crossSigningKeys.remove(it) }
|
|
||||||
info?.let { crossSigningKeys.add(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getUserSigningKey() = crossSigningKeys.firstOrNull { it.usages.contains(KeyUsage.USER_SIGNING.value) }
|
|
||||||
|
|
||||||
fun setUserSignedKey(info: KeyInfoEntity?) {
|
|
||||||
crossSigningKeys
|
|
||||||
.filter { it.usages.contains(KeyUsage.USER_SIGNING.value) }
|
|
||||||
.forEach { crossSigningKeys.remove(it) }
|
|
||||||
info?.let { crossSigningKeys.add(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun CrossSigningInfoEntity.deleteOnCascade() {
|
|
||||||
crossSigningKeys.clearWith { it.deleteOnCascade() }
|
|
||||||
deleteFromRealm()
|
|
||||||
}
|
|
|
@ -1,123 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db.model
|
|
||||||
|
|
||||||
import com.squareup.moshi.Moshi
|
|
||||||
import com.squareup.moshi.Types
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.model.UnsignedDeviceInfo
|
|
||||||
import org.matrix.android.sdk.api.util.JsonDict
|
|
||||||
import org.matrix.android.sdk.internal.di.SerializeNulls
|
|
||||||
import timber.log.Timber
|
|
||||||
|
|
||||||
internal object CryptoMapper {
|
|
||||||
|
|
||||||
private val moshi = Moshi.Builder().add(SerializeNulls.JSON_ADAPTER_FACTORY).build()
|
|
||||||
private val listMigrationAdapter = moshi.adapter<List<String>>(
|
|
||||||
Types.newParameterizedType(
|
|
||||||
List::class.java,
|
|
||||||
String::class.java,
|
|
||||||
Any::class.java
|
|
||||||
)
|
|
||||||
)
|
|
||||||
private val mapMigrationAdapter = moshi.adapter<JsonDict>(
|
|
||||||
Types.newParameterizedType(
|
|
||||||
Map::class.java,
|
|
||||||
String::class.java,
|
|
||||||
Any::class.java
|
|
||||||
)
|
|
||||||
)
|
|
||||||
private val mapOfStringMigrationAdapter = moshi.adapter<Map<String, Map<String, String>>>(
|
|
||||||
Types.newParameterizedType(
|
|
||||||
Map::class.java,
|
|
||||||
String::class.java,
|
|
||||||
Any::class.java
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
internal fun mapToEntity(deviceInfo: CryptoDeviceInfo): DeviceInfoEntity {
|
|
||||||
return DeviceInfoEntity(primaryKey = DeviceInfoEntity.createPrimaryKey(deviceInfo.userId, deviceInfo.deviceId))
|
|
||||||
.also { updateDeviceInfoEntity(it, deviceInfo) }
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun updateDeviceInfoEntity(entity: DeviceInfoEntity, deviceInfo: CryptoDeviceInfo) {
|
|
||||||
entity.userId = deviceInfo.userId
|
|
||||||
entity.deviceId = deviceInfo.deviceId
|
|
||||||
entity.algorithmListJson = listMigrationAdapter.toJson(deviceInfo.algorithms)
|
|
||||||
entity.keysMapJson = mapMigrationAdapter.toJson(deviceInfo.keys)
|
|
||||||
entity.signatureMapJson = mapMigrationAdapter.toJson(deviceInfo.signatures)
|
|
||||||
entity.isBlocked = deviceInfo.isBlocked
|
|
||||||
val deviceInfoTrustLevel = deviceInfo.trustLevel
|
|
||||||
if (deviceInfoTrustLevel == null) {
|
|
||||||
entity.trustLevelEntity?.deleteFromRealm()
|
|
||||||
entity.trustLevelEntity = null
|
|
||||||
} else {
|
|
||||||
if (entity.trustLevelEntity == null) {
|
|
||||||
// Create a new TrustLevelEntity object
|
|
||||||
entity.trustLevelEntity = TrustLevelEntity()
|
|
||||||
}
|
|
||||||
// Update the existing TrustLevelEntity object
|
|
||||||
entity.trustLevelEntity?.crossSignedVerified = deviceInfoTrustLevel.crossSigningVerified
|
|
||||||
entity.trustLevelEntity?.locallyVerified = deviceInfoTrustLevel.locallyVerified
|
|
||||||
}
|
|
||||||
// We store the device name if present now
|
|
||||||
entity.unsignedMapJson = deviceInfo.unsigned?.deviceDisplayName
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun mapToModel(deviceInfoEntity: DeviceInfoEntity): CryptoDeviceInfo {
|
|
||||||
return CryptoDeviceInfo(
|
|
||||||
userId = deviceInfoEntity.userId ?: "",
|
|
||||||
deviceId = deviceInfoEntity.deviceId ?: "",
|
|
||||||
isBlocked = deviceInfoEntity.isBlocked ?: false,
|
|
||||||
trustLevel = deviceInfoEntity.trustLevelEntity?.let {
|
|
||||||
DeviceTrustLevel(it.crossSignedVerified ?: false, it.locallyVerified)
|
|
||||||
},
|
|
||||||
unsigned = deviceInfoEntity.unsignedMapJson?.let { UnsignedDeviceInfo(deviceDisplayName = it) },
|
|
||||||
signatures = deviceInfoEntity.signatureMapJson?.let {
|
|
||||||
try {
|
|
||||||
mapOfStringMigrationAdapter.fromJson(it)
|
|
||||||
} catch (failure: Throwable) {
|
|
||||||
Timber.e(failure)
|
|
||||||
null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
keys = deviceInfoEntity.keysMapJson?.let {
|
|
||||||
try {
|
|
||||||
moshi.adapter<Map<String, String>>(
|
|
||||||
Types.newParameterizedType(
|
|
||||||
Map::class.java,
|
|
||||||
String::class.java,
|
|
||||||
Any::class.java
|
|
||||||
)
|
|
||||||
).fromJson(it)
|
|
||||||
} catch (failure: Throwable) {
|
|
||||||
Timber.e(failure)
|
|
||||||
null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
algorithms = deviceInfoEntity.algorithmListJson?.let {
|
|
||||||
try {
|
|
||||||
listMigrationAdapter.fromJson(it)
|
|
||||||
} catch (failure: Throwable) {
|
|
||||||
Timber.e(failure)
|
|
||||||
null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
firstTimeSeenLocalTs = deviceInfoEntity.firstTimeSeenLocalTs
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -26,10 +26,6 @@ internal open class CryptoRoomEntity(
|
||||||
var blacklistUnverifiedDevices: Boolean = false,
|
var blacklistUnverifiedDevices: Boolean = false,
|
||||||
// Determines whether or not room history should be shared on new member invites
|
// Determines whether or not room history should be shared on new member invites
|
||||||
var shouldShareHistory: Boolean = false,
|
var shouldShareHistory: Boolean = false,
|
||||||
// Store the current outbound session for this room,
|
|
||||||
// to avoid re-create and re-share at each startup (if rotation not needed..)
|
|
||||||
// This is specific to megolm but not sure how to model it better
|
|
||||||
var outboundSessionInfo: OutboundGroupSessionInfoEntity? = null,
|
|
||||||
// a security to ensure that a room will never revert to not encrypted
|
// a security to ensure that a room will never revert to not encrypted
|
||||||
// even if a new state event with empty encryption, or state is reset somehow
|
// even if a new state event with empty encryption, or state is reset somehow
|
||||||
var wasEncryptedOnce: Boolean? = false,
|
var wasEncryptedOnce: Boolean? = false,
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db.model
|
|
||||||
|
|
||||||
import io.realm.RealmObject
|
|
||||||
import io.realm.RealmResults
|
|
||||||
import io.realm.annotations.LinkingObjects
|
|
||||||
import io.realm.annotations.PrimaryKey
|
|
||||||
|
|
||||||
internal fun DeviceInfoEntity.Companion.createPrimaryKey(userId: String, deviceId: String) = "$userId|$deviceId"
|
|
||||||
|
|
||||||
internal open class DeviceInfoEntity(
|
|
||||||
@PrimaryKey var primaryKey: String = "",
|
|
||||||
var deviceId: String? = null,
|
|
||||||
var identityKey: String? = null,
|
|
||||||
var userId: String? = null,
|
|
||||||
var isBlocked: Boolean? = null,
|
|
||||||
var algorithmListJson: String? = null,
|
|
||||||
var keysMapJson: String? = null,
|
|
||||||
var signatureMapJson: String? = null,
|
|
||||||
// Will contain the device name from unsigned data if present
|
|
||||||
var unsignedMapJson: String? = null,
|
|
||||||
var trustLevelEntity: TrustLevelEntity? = null,
|
|
||||||
/**
|
|
||||||
* We use that to make distinction between old devices (there before mine)
|
|
||||||
* and new ones. Used for example to detect new unverified login
|
|
||||||
*/
|
|
||||||
var firstTimeSeenLocalTs: Long? = null
|
|
||||||
) : RealmObject() {
|
|
||||||
|
|
||||||
@LinkingObjects("devices")
|
|
||||||
val users: RealmResults<UserEntity>? = null
|
|
||||||
|
|
||||||
companion object
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun DeviceInfoEntity.deleteOnCascade() {
|
|
||||||
trustLevelEntity?.deleteFromRealm()
|
|
||||||
deleteFromRealm()
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db.model
|
|
||||||
|
|
||||||
import io.realm.RealmList
|
|
||||||
import io.realm.RealmObject
|
|
||||||
|
|
||||||
internal open class KeyInfoEntity(
|
|
||||||
var publicKeyBase64: String? = null,
|
|
||||||
// var isTrusted: Boolean = false,
|
|
||||||
var usages: RealmList<String> = RealmList(),
|
|
||||||
/**
|
|
||||||
* The signature of this MXDeviceInfo.
|
|
||||||
* A map from "<userId>" to a map from "<key type>:<Publickey>" to "<signature>"
|
|
||||||
*/
|
|
||||||
var signatures: String? = null,
|
|
||||||
var trustLevelEntity: TrustLevelEntity? = null
|
|
||||||
) : RealmObject()
|
|
||||||
|
|
||||||
internal fun KeyInfoEntity.deleteOnCascade() {
|
|
||||||
trustLevelEntity?.deleteFromRealm()
|
|
||||||
deleteFromRealm()
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 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.crypto.store.db.model
|
|
||||||
|
|
||||||
import io.realm.RealmObject
|
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
|
||||||
import org.matrix.android.sdk.internal.di.MoshiProvider
|
|
||||||
|
|
||||||
internal open class KeyRequestReplyEntity(
|
|
||||||
var senderId: String? = null,
|
|
||||||
var fromDevice: String? = null,
|
|
||||||
var eventJson: String? = null
|
|
||||||
) : RealmObject() {
|
|
||||||
companion object
|
|
||||||
|
|
||||||
fun getEvent(): Event? {
|
|
||||||
return eventJson?.let {
|
|
||||||
MoshiProvider.providesMoshi().adapter(Event::class.java).fromJson(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db.model
|
|
||||||
|
|
||||||
import io.realm.RealmObject
|
|
||||||
import io.realm.annotations.PrimaryKey
|
|
||||||
|
|
||||||
internal open class KeysBackupDataEntity(
|
|
||||||
// Primary key to update this object. There is only one object, so it's a constant, please do not set it
|
|
||||||
@PrimaryKey
|
|
||||||
var primaryKey: Int = 0,
|
|
||||||
// The last known hash of the backed up keys on the server
|
|
||||||
var backupLastServerHash: String? = null,
|
|
||||||
// The last known number of backed up keys on the server
|
|
||||||
var backupLastServerNumberOfKeys: Int? = null
|
|
||||||
) : RealmObject()
|
|
|
@ -1,71 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db.model
|
|
||||||
|
|
||||||
import io.realm.RealmObject
|
|
||||||
import io.realm.annotations.PrimaryKey
|
|
||||||
import org.matrix.android.sdk.internal.crypto.model.InboundGroupSessionData
|
|
||||||
import org.matrix.android.sdk.internal.di.MoshiProvider
|
|
||||||
|
|
||||||
internal fun OlmInboundGroupSessionEntity.Companion.createPrimaryKey(sessionId: String?, senderKey: String?) = "$sessionId|$senderKey"
|
|
||||||
|
|
||||||
internal open class OlmInboundGroupSessionEntity(
|
|
||||||
// Combined value to build a primary key
|
|
||||||
@PrimaryKey var primaryKey: String? = null,
|
|
||||||
|
|
||||||
// denormalization for faster querying (these fields are in the inboundGroupSessionDataJson)
|
|
||||||
var sessionId: String? = null,
|
|
||||||
var senderKey: String? = null,
|
|
||||||
var roomId: String? = null,
|
|
||||||
|
|
||||||
// Deprecated, used for migration / olmInboundGroupSessionData contains Json
|
|
||||||
// keep it in case of problem to have a chance to recover
|
|
||||||
var olmInboundGroupSessionData: String? = null,
|
|
||||||
|
|
||||||
// Stores the session data in an extensible format
|
|
||||||
// to allow to store data not yet supported for later use
|
|
||||||
var inboundGroupSessionDataJson: String? = null,
|
|
||||||
|
|
||||||
// The pickled session
|
|
||||||
var serializedOlmInboundGroupSession: String? = null,
|
|
||||||
|
|
||||||
// Flag that indicates whether or not the current inboundSession will be shared to
|
|
||||||
// invited users to decrypt past messages
|
|
||||||
var sharedHistory: Boolean = false,
|
|
||||||
// Indicate if the key has been backed up to the homeserver
|
|
||||||
var backedUp: Boolean = false
|
|
||||||
) :
|
|
||||||
RealmObject() {
|
|
||||||
|
|
||||||
// fun getInboundGroupSession(): OlmInboundGroupSessionWrapper2? {
|
|
||||||
// return try {
|
|
||||||
// deserializeFromRealm<OlmInboundGroupSessionWrapper2?>(olmInboundGroupSessionData)
|
|
||||||
// } catch (failure: Throwable) {
|
|
||||||
// Timber.e(failure, "## Deserialization failure")
|
|
||||||
// return null
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// fun putInboundGroupSession(olmInboundGroupSessionWrapper: OlmInboundGroupSessionWrapper2?) {
|
|
||||||
// olmInboundGroupSessionData = serializeForRealm(olmInboundGroupSessionWrapper)
|
|
||||||
// }
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val adapter = MoshiProvider.providesMoshi()
|
|
||||||
.adapter(InboundGroupSessionData::class.java)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db.model
|
|
||||||
|
|
||||||
import io.realm.RealmObject
|
|
||||||
import io.realm.annotations.PrimaryKey
|
|
||||||
|
|
||||||
internal fun OlmSessionEntity.Companion.createPrimaryKey(sessionId: String, deviceKey: String) = "$sessionId|$deviceKey"
|
|
||||||
|
|
||||||
// olmSessionData is a serialized OlmSession
|
|
||||||
internal open class OlmSessionEntity(
|
|
||||||
@PrimaryKey var primaryKey: String = "",
|
|
||||||
var sessionId: String? = null,
|
|
||||||
var deviceKey: String? = null,
|
|
||||||
var olmSessionData: String? = null,
|
|
||||||
var lastReceivedMessageTs: Long = 0
|
|
||||||
) :
|
|
||||||
RealmObject() {
|
|
||||||
|
|
||||||
companion object
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db.model
|
|
||||||
|
|
||||||
import io.realm.RealmObject
|
|
||||||
|
|
||||||
internal open class OutboundGroupSessionInfoEntity(
|
|
||||||
var serializedOutboundSessionData: String? = null,
|
|
||||||
var creationTime: Long? = null,
|
|
||||||
var shouldShareHistory: Boolean = false
|
|
||||||
) : RealmObject() {
|
|
||||||
|
|
||||||
companion object
|
|
||||||
}
|
|
|
@ -1,136 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.crypto.store.db.model
|
|
||||||
|
|
||||||
import com.squareup.moshi.JsonAdapter
|
|
||||||
import com.squareup.moshi.Types
|
|
||||||
import io.realm.RealmList
|
|
||||||
import io.realm.RealmObject
|
|
||||||
import io.realm.annotations.Index
|
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.OutgoingKeyRequest
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.OutgoingRoomKeyRequestState
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.RequestReply
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.RequestResult
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.model.RoomKeyRequestBody
|
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
|
||||||
import org.matrix.android.sdk.api.session.events.model.content.RoomKeyWithHeldContent
|
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
|
||||||
import org.matrix.android.sdk.internal.di.MoshiProvider
|
|
||||||
|
|
||||||
internal open class OutgoingKeyRequestEntity(
|
|
||||||
@Index var requestId: String? = null,
|
|
||||||
var requestedIndex: Int? = null,
|
|
||||||
var recipientsData: String? = null,
|
|
||||||
var requestedInfoStr: String? = null,
|
|
||||||
var creationTimeStamp: Long? = null,
|
|
||||||
// de-normalization for better query (if not have to query all and parse json)
|
|
||||||
@Index var roomId: String? = null,
|
|
||||||
@Index var megolmSessionId: String? = null,
|
|
||||||
|
|
||||||
var replies: RealmList<KeyRequestReplyEntity> = RealmList()
|
|
||||||
) : RealmObject() {
|
|
||||||
|
|
||||||
@Index private var requestStateStr: String = OutgoingRoomKeyRequestState.UNSENT.name
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
private val recipientsDataMapper: JsonAdapter<Map<String, List<String>>> =
|
|
||||||
MoshiProvider
|
|
||||||
.providesMoshi()
|
|
||||||
.adapter(
|
|
||||||
Types.newParameterizedType(Map::class.java, String::class.java, List::class.java)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getRequestedKeyInfo(): RoomKeyRequestBody? = RoomKeyRequestBody.fromJson(requestedInfoStr)
|
|
||||||
|
|
||||||
fun setRequestBody(body: RoomKeyRequestBody) {
|
|
||||||
requestedInfoStr = body.toJson()
|
|
||||||
roomId = body.roomId
|
|
||||||
megolmSessionId = body.sessionId
|
|
||||||
}
|
|
||||||
|
|
||||||
var requestState: OutgoingRoomKeyRequestState
|
|
||||||
get() {
|
|
||||||
return tryOrNull { OutgoingRoomKeyRequestState.valueOf(requestStateStr) }
|
|
||||||
?: OutgoingRoomKeyRequestState.UNSENT
|
|
||||||
}
|
|
||||||
set(value) {
|
|
||||||
requestStateStr = value.name
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getRecipients(): Map<String, List<String>>? {
|
|
||||||
return this.recipientsData?.let { recipientsDataMapper.fromJson(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setRecipients(recipients: Map<String, List<String>>) {
|
|
||||||
this.recipientsData = recipientsDataMapper.toJson(recipients)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addReply(userId: String, fromDevice: String?, event: Event) {
|
|
||||||
val newReply = KeyRequestReplyEntity(
|
|
||||||
senderId = userId,
|
|
||||||
fromDevice = fromDevice,
|
|
||||||
eventJson = MoshiProvider.providesMoshi().adapter(Event::class.java).toJson(event)
|
|
||||||
)
|
|
||||||
replies.add(newReply)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun toOutgoingKeyRequest(): OutgoingKeyRequest {
|
|
||||||
return OutgoingKeyRequest(
|
|
||||||
requestBody = getRequestedKeyInfo(),
|
|
||||||
recipients = getRecipients().orEmpty(),
|
|
||||||
requestId = requestId ?: "",
|
|
||||||
fromIndex = requestedIndex ?: 0,
|
|
||||||
state = requestState,
|
|
||||||
results = replies.mapNotNull { entity ->
|
|
||||||
val userId = entity.senderId ?: return@mapNotNull null
|
|
||||||
val result = entity.eventJson?.let {
|
|
||||||
MoshiProvider.providesMoshi().adapter(Event::class.java).fromJson(it)
|
|
||||||
}?.let { event ->
|
|
||||||
eventToResult(event)
|
|
||||||
} ?: return@mapNotNull null
|
|
||||||
RequestReply(
|
|
||||||
userId = userId,
|
|
||||||
fromDevice = entity.fromDevice,
|
|
||||||
result = result
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun eventToResult(event: Event): RequestResult? {
|
|
||||||
return when (event.getClearType()) {
|
|
||||||
in EventType.ROOM_KEY_WITHHELD.values -> {
|
|
||||||
event.content.toModel<RoomKeyWithHeldContent>()?.code?.let {
|
|
||||||
RequestResult.Failure(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EventType.FORWARDED_ROOM_KEY -> {
|
|
||||||
RequestResult.Success((event.content?.get("chain_index") as? Number)?.toInt() ?: 0)
|
|
||||||
}
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun OutgoingKeyRequestEntity.deleteOnCascade() {
|
|
||||||
replies.deleteAllFromRealm()
|
|
||||||
deleteFromRealm()
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db.model
|
|
||||||
|
|
||||||
import io.realm.RealmObject
|
|
||||||
import io.realm.annotations.Index
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Keep a record of to whom (user/device) a given session should have been shared.
|
|
||||||
* It will be used to reply to keyshare requests from other users, in order to see if
|
|
||||||
* this session was originaly shared with a given user
|
|
||||||
*/
|
|
||||||
internal open class SharedSessionEntity(
|
|
||||||
var roomId: String? = null,
|
|
||||||
var algorithm: String? = null,
|
|
||||||
@Index var sessionId: String? = null,
|
|
||||||
@Index var userId: String? = null,
|
|
||||||
@Index var deviceId: String? = null,
|
|
||||||
@Index var deviceIdentityKey: String? = null,
|
|
||||||
var chainIndex: Int? = null
|
|
||||||
) : RealmObject() {
|
|
||||||
|
|
||||||
companion object
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db.model
|
|
||||||
|
|
||||||
import io.realm.RealmObject
|
|
||||||
|
|
||||||
internal open class TrustLevelEntity(
|
|
||||||
var crossSignedVerified: Boolean? = null,
|
|
||||||
var locallyVerified: Boolean? = null
|
|
||||||
) : RealmObject() {
|
|
||||||
|
|
||||||
companion object
|
|
||||||
|
|
||||||
fun isVerified(): Boolean = crossSignedVerified == true || locallyVerified == true
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db.model
|
|
||||||
|
|
||||||
import io.realm.RealmList
|
|
||||||
import io.realm.RealmObject
|
|
||||||
import io.realm.annotations.PrimaryKey
|
|
||||||
import org.matrix.android.sdk.internal.extensions.clearWith
|
|
||||||
|
|
||||||
internal open class UserEntity(
|
|
||||||
@PrimaryKey var userId: String? = null,
|
|
||||||
var devices: RealmList<DeviceInfoEntity> = RealmList(),
|
|
||||||
var crossSigningInfoEntity: CrossSigningInfoEntity? = null,
|
|
||||||
var deviceTrackingStatus: Int = 0
|
|
||||||
) : RealmObject() {
|
|
||||||
|
|
||||||
companion object
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun UserEntity.deleteOnCascade() {
|
|
||||||
devices.clearWith { it.deleteOnCascade() }
|
|
||||||
crossSigningInfoEntity?.deleteOnCascade()
|
|
||||||
deleteFromRealm()
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db.model
|
|
||||||
|
|
||||||
import io.realm.RealmObject
|
|
||||||
import io.realm.annotations.Index
|
|
||||||
import org.matrix.android.sdk.api.session.events.model.content.WithHeldCode
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When an encrypted message is sent in a room, the megolm key might not be sent to all devices present in the room.
|
|
||||||
* Sometimes this may be inadvertent (for example, if the sending device is not aware of some devices that have joined),
|
|
||||||
* but some times, this may be purposeful.
|
|
||||||
* For example, the sender may have blacklisted certain devices or users,
|
|
||||||
* or may be choosing to not send the megolm key to devices that they have not verified yet.
|
|
||||||
*/
|
|
||||||
internal open class WithHeldSessionEntity(
|
|
||||||
var roomId: String? = null,
|
|
||||||
var algorithm: String? = null,
|
|
||||||
@Index var sessionId: String? = null,
|
|
||||||
@Index var senderKey: String? = null,
|
|
||||||
var codeString: String? = null,
|
|
||||||
var reason: String? = null
|
|
||||||
) : RealmObject() {
|
|
||||||
|
|
||||||
var code: WithHeldCode?
|
|
||||||
get() {
|
|
||||||
return WithHeldCode.fromCode(codeString)
|
|
||||||
}
|
|
||||||
set(code) {
|
|
||||||
codeString = code?.value
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db.query
|
|
||||||
|
|
||||||
import io.realm.Realm
|
|
||||||
import io.realm.kotlin.createObject
|
|
||||||
import io.realm.kotlin.where
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields
|
|
||||||
|
|
||||||
internal fun CrossSigningInfoEntity.Companion.getOrCreate(realm: Realm, userId: String): CrossSigningInfoEntity {
|
|
||||||
return realm.where<CrossSigningInfoEntity>()
|
|
||||||
.equalTo(UserEntityFields.USER_ID, userId)
|
|
||||||
.findFirst()
|
|
||||||
?: realm.createObject(userId)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun CrossSigningInfoEntity.Companion.get(realm: Realm, userId: String): CrossSigningInfoEntity? {
|
|
||||||
return realm.where<CrossSigningInfoEntity>()
|
|
||||||
.equalTo(UserEntityFields.USER_ID, userId)
|
|
||||||
.findFirst()
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db.query
|
|
||||||
|
|
||||||
import io.realm.Realm
|
|
||||||
import io.realm.kotlin.createObject
|
|
||||||
import io.realm.kotlin.where
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntityFields
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.createPrimaryKey
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get or create a device info.
|
|
||||||
*/
|
|
||||||
internal fun DeviceInfoEntity.Companion.getOrCreate(realm: Realm, userId: String, deviceId: String): DeviceInfoEntity {
|
|
||||||
val key = DeviceInfoEntity.createPrimaryKey(userId, deviceId)
|
|
||||||
|
|
||||||
return realm.where<DeviceInfoEntity>()
|
|
||||||
.equalTo(DeviceInfoEntityFields.PRIMARY_KEY, key)
|
|
||||||
.findFirst()
|
|
||||||
?: realm.createObject<DeviceInfoEntity>(key)
|
|
||||||
.apply {
|
|
||||||
this.deviceId = deviceId
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db.query
|
|
||||||
|
|
||||||
import io.realm.Realm
|
|
||||||
import io.realm.RealmResults
|
|
||||||
import io.realm.kotlin.createObject
|
|
||||||
import io.realm.kotlin.where
|
|
||||||
import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntityFields
|
|
||||||
|
|
||||||
internal fun SharedSessionEntity.Companion.get(
|
|
||||||
realm: Realm,
|
|
||||||
roomId: String?,
|
|
||||||
sessionId: String,
|
|
||||||
userId: String,
|
|
||||||
deviceId: String,
|
|
||||||
deviceIdentityKey: String?
|
|
||||||
): SharedSessionEntity? {
|
|
||||||
return realm.where<SharedSessionEntity>()
|
|
||||||
.equalTo(SharedSessionEntityFields.ROOM_ID, roomId)
|
|
||||||
.equalTo(SharedSessionEntityFields.SESSION_ID, sessionId)
|
|
||||||
.equalTo(SharedSessionEntityFields.ALGORITHM, MXCRYPTO_ALGORITHM_MEGOLM)
|
|
||||||
.equalTo(SharedSessionEntityFields.USER_ID, userId)
|
|
||||||
.equalTo(SharedSessionEntityFields.DEVICE_ID, deviceId)
|
|
||||||
.equalTo(SharedSessionEntityFields.DEVICE_IDENTITY_KEY, deviceIdentityKey)
|
|
||||||
.findFirst()
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun SharedSessionEntity.Companion.get(realm: Realm, roomId: String?, sessionId: String): RealmResults<SharedSessionEntity> {
|
|
||||||
return realm.where<SharedSessionEntity>()
|
|
||||||
.equalTo(SharedSessionEntityFields.ROOM_ID, roomId)
|
|
||||||
.equalTo(SharedSessionEntityFields.SESSION_ID, sessionId)
|
|
||||||
.equalTo(SharedSessionEntityFields.ALGORITHM, MXCRYPTO_ALGORITHM_MEGOLM)
|
|
||||||
.findAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun SharedSessionEntity.Companion.create(
|
|
||||||
realm: Realm,
|
|
||||||
roomId: String?,
|
|
||||||
sessionId: String,
|
|
||||||
userId: String,
|
|
||||||
deviceId: String,
|
|
||||||
deviceIdentityKey: String,
|
|
||||||
chainIndex: Int
|
|
||||||
): SharedSessionEntity {
|
|
||||||
return realm.createObject<SharedSessionEntity>().apply {
|
|
||||||
this.roomId = roomId
|
|
||||||
this.algorithm = MXCRYPTO_ALGORITHM_MEGOLM
|
|
||||||
this.sessionId = sessionId
|
|
||||||
this.userId = userId
|
|
||||||
this.deviceId = deviceId
|
|
||||||
this.deviceIdentityKey = deviceIdentityKey
|
|
||||||
this.chainIndex = chainIndex
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db.query
|
|
||||||
|
|
||||||
import io.realm.Realm
|
|
||||||
import io.realm.kotlin.createObject
|
|
||||||
import io.realm.kotlin.where
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.deleteOnCascade
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get or create a user.
|
|
||||||
*/
|
|
||||||
internal fun UserEntity.Companion.getOrCreate(realm: Realm, userId: String): UserEntity {
|
|
||||||
return realm.where<UserEntity>()
|
|
||||||
.equalTo(UserEntityFields.USER_ID, userId)
|
|
||||||
.findFirst()
|
|
||||||
?: realm.createObject(userId)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a user.
|
|
||||||
*/
|
|
||||||
internal fun UserEntity.Companion.delete(realm: Realm, userId: String) {
|
|
||||||
realm.where<UserEntity>()
|
|
||||||
.equalTo(UserEntityFields.USER_ID, userId)
|
|
||||||
.findFirst()
|
|
||||||
?.deleteOnCascade()
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.crypto.store.db.query
|
|
||||||
|
|
||||||
import io.realm.Realm
|
|
||||||
import io.realm.kotlin.createObject
|
|
||||||
import io.realm.kotlin.where
|
|
||||||
import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntityFields
|
|
||||||
|
|
||||||
internal fun WithHeldSessionEntity.Companion.get(realm: Realm, roomId: String, sessionId: String): WithHeldSessionEntity? {
|
|
||||||
return realm.where<WithHeldSessionEntity>()
|
|
||||||
.equalTo(WithHeldSessionEntityFields.ROOM_ID, roomId)
|
|
||||||
.equalTo(WithHeldSessionEntityFields.SESSION_ID, sessionId)
|
|
||||||
.equalTo(WithHeldSessionEntityFields.ALGORITHM, MXCRYPTO_ALGORITHM_MEGOLM)
|
|
||||||
.findFirst()
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun WithHeldSessionEntity.Companion.getOrCreate(realm: Realm, roomId: String, sessionId: String): WithHeldSessionEntity? {
|
|
||||||
return get(realm, roomId, sessionId)
|
|
||||||
?: realm.createObject<WithHeldSessionEntity>().apply {
|
|
||||||
this.roomId = roomId
|
|
||||||
this.algorithm = MXCRYPTO_ALGORITHM_MEGOLM
|
|
||||||
this.sessionId = sessionId
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue