Crypto store : avoid copying before mapping to other data

This commit is contained in:
ganfra 2020-04-28 16:26:04 +02:00
parent 4e8177f738
commit 43055964ba

View file

@ -201,9 +201,9 @@ internal class RealmCryptoStore @Inject constructor(
} }
override fun getDeviceId(): String { override fun getDeviceId(): String {
return doRealmQueryAndCopy(realmConfiguration) { return doWithRealm(realmConfiguration) {
it.where<CryptoMetadataEntity>().findFirst() it.where<CryptoMetadataEntity>().findFirst()?.deviceId
}?.deviceId ?: "" } ?: ""
} }
override fun saveOlmAccount() { override fun saveOlmAccount() {
@ -257,24 +257,25 @@ internal class RealmCryptoStore @Inject constructor(
} }
override fun getUserDevice(userId: String, deviceId: String): CryptoDeviceInfo? { override fun getUserDevice(userId: String, deviceId: String): CryptoDeviceInfo? {
return doRealmQueryAndCopy(realmConfiguration) { return doWithRealm(realmConfiguration) {
it.where<DeviceInfoEntity>() it.where<DeviceInfoEntity>()
.equalTo(DeviceInfoEntityFields.PRIMARY_KEY, DeviceInfoEntity.createPrimaryKey(userId, deviceId)) .equalTo(DeviceInfoEntityFields.PRIMARY_KEY, DeviceInfoEntity.createPrimaryKey(userId, deviceId))
.findFirst() .findFirst()
}?.let { ?.let { deviceInfo ->
CryptoMapper.mapToModel(it) CryptoMapper.mapToModel(deviceInfo)
}
} }
} }
override fun deviceWithIdentityKey(identityKey: String): CryptoDeviceInfo? { override fun deviceWithIdentityKey(identityKey: String): CryptoDeviceInfo? {
return doRealmQueryAndCopy(realmConfiguration) { return doWithRealm(realmConfiguration) {
it.where<DeviceInfoEntity>() it.where<DeviceInfoEntity>()
.equalTo(DeviceInfoEntityFields.IDENTITY_KEY, identityKey) .equalTo(DeviceInfoEntityFields.IDENTITY_KEY, identityKey)
.findFirst() .findFirst()
?.let { deviceInfo ->
CryptoMapper.mapToModel(deviceInfo)
}
} }
?.let {
CryptoMapper.mapToModel(it)
}
} }
override fun storeUserDevices(userId: String, devices: Map<String, CryptoDeviceInfo>?) { override fun storeUserDevices(userId: String, devices: Map<String, CryptoDeviceInfo>?) {
@ -344,14 +345,16 @@ internal class RealmCryptoStore @Inject constructor(
} }
override fun getCrossSigningPrivateKeys(): PrivateKeysInfo? { override fun getCrossSigningPrivateKeys(): PrivateKeysInfo? {
return doRealmQueryAndCopy(realmConfiguration) { realm -> return doWithRealm(realmConfiguration) { realm ->
realm.where<CryptoMetadataEntity>().findFirst() realm.where<CryptoMetadataEntity>()
}?.let { .findFirst()
PrivateKeysInfo( ?.let {
master = it.xSignMasterPrivateKey, PrivateKeysInfo(
selfSigned = it.xSignSelfSignedPrivateKey, master = it.xSignMasterPrivateKey,
user = it.xSignUserPrivateKey selfSigned = it.xSignSelfSignedPrivateKey,
) user = it.xSignUserPrivateKey
)
}
} }
} }
@ -375,16 +378,18 @@ internal class RealmCryptoStore @Inject constructor(
} }
override fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo? { override fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo? {
return doRealmQueryAndCopy(realmConfiguration) { realm -> return doWithRealm(realmConfiguration) { realm ->
realm.where<CryptoMetadataEntity>().findFirst() realm.where<CryptoMetadataEntity>()
}?.let { .findFirst()
val key = it.keyBackupRecoveryKey ?.let {
val version = it.keyBackupRecoveryKeyVersion val key = it.keyBackupRecoveryKey
if (!key.isNullOrBlank() && !version.isNullOrBlank()) { val version = it.keyBackupRecoveryKeyVersion
SavedKeyBackupKeyInfo(recoveryKey = key, version = version) if (!key.isNullOrBlank() && !version.isNullOrBlank()) {
} else { SavedKeyBackupKeyInfo(recoveryKey = key, version = version)
null } else {
} null
}
}
} }
} }
@ -405,24 +410,30 @@ internal class RealmCryptoStore @Inject constructor(
} }
override fun getUserDevices(userId: String): Map<String, CryptoDeviceInfo>? { override fun getUserDevices(userId: String): Map<String, CryptoDeviceInfo>? {
return doRealmQueryAndCopy(realmConfiguration) { return doWithRealm(realmConfiguration) {
it.where<UserEntity>() it.where<UserEntity>()
.equalTo(UserEntityFields.USER_ID, userId) .equalTo(UserEntityFields.USER_ID, userId)
.findFirst() .findFirst()
?.devices
?.map { deviceInfo ->
CryptoMapper.mapToModel(deviceInfo)
}
?.associateBy { cryptoDevice ->
cryptoDevice.deviceId
}
} }
?.devices
?.map { CryptoMapper.mapToModel(it) }
?.associateBy { it.deviceId }
} }
override fun getUserDeviceList(userId: String): List<CryptoDeviceInfo>? { override fun getUserDeviceList(userId: String): List<CryptoDeviceInfo>? {
return doRealmQueryAndCopy(realmConfiguration) { return doWithRealm(realmConfiguration) {
it.where<UserEntity>() it.where<UserEntity>()
.equalTo(UserEntityFields.USER_ID, userId) .equalTo(UserEntityFields.USER_ID, userId)
.findFirst() .findFirst()
?.devices
?.map { deviceInfo ->
CryptoMapper.mapToModel(deviceInfo)
}
} }
?.devices
?.map { CryptoMapper.mapToModel(it) }
} }
override fun getLiveDeviceList(userId: String): LiveData<List<CryptoDeviceInfo>> { override fun getLiveDeviceList(userId: String): LiveData<List<CryptoDeviceInfo>> {
@ -478,17 +489,16 @@ internal class RealmCryptoStore @Inject constructor(
} }
override fun getRoomAlgorithm(roomId: String): String? { override fun getRoomAlgorithm(roomId: String): String? {
return doRealmQueryAndCopy(realmConfiguration) { return doWithRealm(realmConfiguration) {
CryptoRoomEntity.getById(it, roomId) CryptoRoomEntity.getById(it, roomId)?.algorithm
} }
?.algorithm
} }
override fun shouldEncryptForInvitedMembers(roomId: String): Boolean { override fun shouldEncryptForInvitedMembers(roomId: String): Boolean {
return doRealmQueryAndCopy(realmConfiguration) { return doWithRealm(realmConfiguration) {
CryptoRoomEntity.getById(it, roomId) CryptoRoomEntity.getById(it, roomId)?.shouldEncryptForInvitedMembers
} }
?.shouldEncryptForInvitedMembers ?: false ?: false
} }
override fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean) { override fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean) {
@ -552,24 +562,24 @@ internal class RealmCryptoStore @Inject constructor(
} }
override fun getLastUsedSessionId(deviceKey: String): String? { override fun getLastUsedSessionId(deviceKey: String): String? {
return doRealmQueryAndCopy(realmConfiguration) { return doWithRealm(realmConfiguration) {
it.where<OlmSessionEntity>() it.where<OlmSessionEntity>()
.equalTo(OlmSessionEntityFields.DEVICE_KEY, deviceKey) .equalTo(OlmSessionEntityFields.DEVICE_KEY, deviceKey)
.sort(OlmSessionEntityFields.LAST_RECEIVED_MESSAGE_TS, Sort.DESCENDING) .sort(OlmSessionEntityFields.LAST_RECEIVED_MESSAGE_TS, Sort.DESCENDING)
.findFirst() .findFirst()
?.sessionId
} }
?.sessionId
} }
override fun getDeviceSessionIds(deviceKey: String): MutableSet<String> { override fun getDeviceSessionIds(deviceKey: String): MutableSet<String> {
return doRealmQueryAndCopyList(realmConfiguration) { return doWithRealm(realmConfiguration) {
it.where<OlmSessionEntity>() it.where<OlmSessionEntity>()
.equalTo(OlmSessionEntityFields.DEVICE_KEY, deviceKey) .equalTo(OlmSessionEntityFields.DEVICE_KEY, deviceKey)
.findAll() .findAll()
.mapNotNull { sessionEntity ->
sessionEntity.sessionId
}
} }
.mapNotNull {
it.sessionId
}
.toMutableSet() .toMutableSet()
} }
@ -616,12 +626,12 @@ internal class RealmCryptoStore @Inject constructor(
// If not in cache (or not found), try to read it from realm // If not in cache (or not found), try to read it from realm
if (inboundGroupSessionToRelease[key] == null) { if (inboundGroupSessionToRelease[key] == null) {
doRealmQueryAndCopy(realmConfiguration) { doWithRealm(realmConfiguration) {
it.where<OlmInboundGroupSessionEntity>() it.where<OlmInboundGroupSessionEntity>()
.equalTo(OlmInboundGroupSessionEntityFields.PRIMARY_KEY, key) .equalTo(OlmInboundGroupSessionEntityFields.PRIMARY_KEY, key)
.findFirst() .findFirst()
?.getInboundGroupSession()
} }
?.getInboundGroupSession()
?.let { ?.let {
inboundGroupSessionToRelease[key] = it inboundGroupSessionToRelease[key] = it
} }
@ -635,13 +645,13 @@ internal class RealmCryptoStore @Inject constructor(
* so there is no need to use or update `inboundGroupSessionToRelease` for native memory management * so there is no need to use or update `inboundGroupSessionToRelease` for native memory management
*/ */
override fun getInboundGroupSessions(): MutableList<OlmInboundGroupSessionWrapper> { override fun getInboundGroupSessions(): MutableList<OlmInboundGroupSessionWrapper> {
return doRealmQueryAndCopyList(realmConfiguration) { return doWithRealm(realmConfiguration) {
it.where<OlmInboundGroupSessionEntity>() it.where<OlmInboundGroupSessionEntity>()
.findAll() .findAll()
.mapNotNull { inboundGroupSessionEntity ->
inboundGroupSessionEntity.getInboundGroupSession()
}
} }
.mapNotNull {
it.getInboundGroupSession()
}
.toMutableList() .toMutableList()
} }
@ -730,13 +740,14 @@ internal class RealmCryptoStore @Inject constructor(
} }
override fun inboundGroupSessionsToBackup(limit: Int): List<OlmInboundGroupSessionWrapper> { override fun inboundGroupSessionsToBackup(limit: Int): List<OlmInboundGroupSessionWrapper> {
return doRealmQueryAndCopyList(realmConfiguration) { return doWithRealm(realmConfiguration) {
it.where<OlmInboundGroupSessionEntity>() it.where<OlmInboundGroupSessionEntity>()
.equalTo(OlmInboundGroupSessionEntityFields.BACKED_UP, false) .equalTo(OlmInboundGroupSessionEntityFields.BACKED_UP, false)
.limit(limit.toLong()) .limit(limit.toLong())
.findAll() .findAll()
}.mapNotNull { inboundGroupSession -> .mapNotNull { inboundGroupSession ->
inboundGroupSession.getInboundGroupSession() inboundGroupSession.getInboundGroupSession()
}
} }
} }
@ -760,10 +771,9 @@ internal class RealmCryptoStore @Inject constructor(
} }
override fun getGlobalBlacklistUnverifiedDevices(): Boolean { override fun getGlobalBlacklistUnverifiedDevices(): Boolean {
return doRealmQueryAndCopy(realmConfiguration) { return doWithRealm(realmConfiguration) {
it.where<CryptoMetadataEntity>().findFirst() it.where<CryptoMetadataEntity>().findFirst()?.globalBlacklistUnverifiedDevices
}?.globalBlacklistUnverifiedDevices } ?: false
?: false
} }
override fun setRoomsListBlacklistUnverifiedDevices(roomIds: List<String>) { override fun setRoomsListBlacklistUnverifiedDevices(roomIds: List<String>) {
@ -786,28 +796,28 @@ internal class RealmCryptoStore @Inject constructor(
} }
override fun getRoomsListBlacklistUnverifiedDevices(): MutableList<String> { override fun getRoomsListBlacklistUnverifiedDevices(): MutableList<String> {
return doRealmQueryAndCopyList(realmConfiguration) { return doWithRealm(realmConfiguration) {
it.where<CryptoRoomEntity>() it.where<CryptoRoomEntity>()
.equalTo(CryptoRoomEntityFields.BLACKLIST_UNVERIFIED_DEVICES, true) .equalTo(CryptoRoomEntityFields.BLACKLIST_UNVERIFIED_DEVICES, true)
.findAll() .findAll()
.mapNotNull { cryptoRoom ->
cryptoRoom.roomId
}
} }
.mapNotNull {
it.roomId
}
.toMutableList() .toMutableList()
} }
override fun getDeviceTrackingStatuses(): MutableMap<String, Int> { override fun getDeviceTrackingStatuses(): MutableMap<String, Int> {
return doRealmQueryAndCopyList(realmConfiguration) { return doWithRealm(realmConfiguration) {
it.where<UserEntity>() it.where<UserEntity>()
.findAll() .findAll()
.associateBy { user ->
user.userId!!
}
.mapValues { entry ->
entry.value.deviceTrackingStatus
}
} }
.associateBy {
it.userId!!
}
.mapValues {
it.value.deviceTrackingStatus
}
.toMutableMap() .toMutableMap()
} }
@ -822,12 +832,12 @@ internal class RealmCryptoStore @Inject constructor(
} }
override fun getDeviceTrackingStatus(userId: String, defaultValue: Int): Int { override fun getDeviceTrackingStatus(userId: String, defaultValue: Int): Int {
return doRealmQueryAndCopy(realmConfiguration) { return doWithRealm(realmConfiguration) {
it.where<UserEntity>() it.where<UserEntity>()
.equalTo(UserEntityFields.USER_ID, userId) .equalTo(UserEntityFields.USER_ID, userId)
.findFirst() .findFirst()
?.deviceTrackingStatus
} }
?.deviceTrackingStatus
?: defaultValue ?: defaultValue
} }
@ -1064,63 +1074,65 @@ internal class RealmCryptoStore @Inject constructor(
} }
override fun getIncomingRoomKeyRequest(userId: String, deviceId: String, requestId: String): IncomingRoomKeyRequest? { override fun getIncomingRoomKeyRequest(userId: String, deviceId: String, requestId: String): IncomingRoomKeyRequest? {
return doRealmQueryAndCopyList(realmConfiguration) { realm -> return doWithRealm(realmConfiguration) { realm ->
realm.where<IncomingGossipingRequestEntity>() realm.where<IncomingGossipingRequestEntity>()
.equalTo(IncomingGossipingRequestEntityFields.TYPE_STR, GossipRequestType.KEY.name) .equalTo(IncomingGossipingRequestEntityFields.TYPE_STR, GossipRequestType.KEY.name)
.equalTo(IncomingGossipingRequestEntityFields.OTHER_DEVICE_ID, deviceId) .equalTo(IncomingGossipingRequestEntityFields.OTHER_DEVICE_ID, deviceId)
.equalTo(IncomingGossipingRequestEntityFields.OTHER_USER_ID, userId) .equalTo(IncomingGossipingRequestEntityFields.OTHER_USER_ID, userId)
.findAll() .findAll()
}.mapNotNull { entity -> .mapNotNull { entity ->
entity.toIncomingGossipingRequest() as? IncomingRoomKeyRequest entity.toIncomingGossipingRequest() as? IncomingRoomKeyRequest
}.firstOrNull() }
.firstOrNull()
}
} }
override fun getPendingIncomingRoomKeyRequests(): List<IncomingRoomKeyRequest> { override fun getPendingIncomingRoomKeyRequests(): List<IncomingRoomKeyRequest> {
return doRealmQueryAndCopyList(realmConfiguration) { return doWithRealm(realmConfiguration) {
it.where<IncomingGossipingRequestEntity>() it.where<IncomingGossipingRequestEntity>()
.equalTo(IncomingGossipingRequestEntityFields.TYPE_STR, GossipRequestType.KEY.name) .equalTo(IncomingGossipingRequestEntityFields.TYPE_STR, GossipRequestType.KEY.name)
.equalTo(IncomingGossipingRequestEntityFields.REQUEST_STATE_STR, GossipingRequestState.PENDING.name) .equalTo(IncomingGossipingRequestEntityFields.REQUEST_STATE_STR, GossipingRequestState.PENDING.name)
.findAll() .findAll()
.map { entity ->
IncomingRoomKeyRequest(
userId = entity.otherUserId,
deviceId = entity.otherDeviceId,
requestId = entity.requestId,
requestBody = entity.getRequestedKeyInfo(),
localCreationTimestamp = entity.localCreationTimestamp
)
}
} }
.map { entity ->
IncomingRoomKeyRequest(
userId = entity.otherUserId,
deviceId = entity.otherDeviceId,
requestId = entity.requestId,
requestBody = entity.getRequestedKeyInfo(),
localCreationTimestamp = entity.localCreationTimestamp
)
}
} }
override fun getPendingIncomingGossipingRequests(): List<IncomingShareRequestCommon> { override fun getPendingIncomingGossipingRequests(): List<IncomingShareRequestCommon> {
return doRealmQueryAndCopyList(realmConfiguration) { return doWithRealm(realmConfiguration) {
it.where<IncomingGossipingRequestEntity>() it.where<IncomingGossipingRequestEntity>()
.equalTo(IncomingGossipingRequestEntityFields.REQUEST_STATE_STR, GossipingRequestState.PENDING.name) .equalTo(IncomingGossipingRequestEntityFields.REQUEST_STATE_STR, GossipingRequestState.PENDING.name)
.findAll() .findAll()
} .mapNotNull { entity ->
.mapNotNull { entity -> when (entity.type) {
when (entity.type) { GossipRequestType.KEY -> {
GossipRequestType.KEY -> { IncomingRoomKeyRequest(
IncomingRoomKeyRequest( userId = entity.otherUserId,
userId = entity.otherUserId, deviceId = entity.otherDeviceId,
deviceId = entity.otherDeviceId, requestId = entity.requestId,
requestId = entity.requestId, requestBody = entity.getRequestedKeyInfo(),
requestBody = entity.getRequestedKeyInfo(), localCreationTimestamp = entity.localCreationTimestamp
localCreationTimestamp = entity.localCreationTimestamp )
) }
} GossipRequestType.SECRET -> {
GossipRequestType.SECRET -> { IncomingSecretShareRequest(
IncomingSecretShareRequest( userId = entity.otherUserId,
userId = entity.otherUserId, deviceId = entity.otherDeviceId,
deviceId = entity.otherDeviceId, requestId = entity.requestId,
requestId = entity.requestId, secretName = entity.getRequestedSecretName(),
secretName = entity.getRequestedSecretName(), localCreationTimestamp = entity.localCreationTimestamp
localCreationTimestamp = entity.localCreationTimestamp )
) }
} }
} }
} }
} }
override fun storeIncomingGossipingRequest(request: IncomingShareRequestCommon, ageLocalTS: Long?) { override fun storeIncomingGossipingRequest(request: IncomingShareRequestCommon, ageLocalTS: Long?) {