From 664e5354d39890d36bf4416e713dba0f37482076 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 7 Jun 2019 16:01:24 +0200 Subject: [PATCH] Crypto: continue cleaning + fix some issues. --- .../api/session/crypto/CryptoService.kt | 28 +---- .../model/RoomHistoryVisibilityContent.kt | 2 +- .../android/internal/crypto/CryptoManager.kt | 101 +++++++++++------- .../algorithms/megolm/MXMegolmDecryption.kt | 11 +- .../model/event/EncryptedEventContent.kt | 10 +- .../crypto/model/event/RoomKeyContent.kt | 10 +- .../model/rest/ForwardedRoomKeyContent.kt | 14 +-- .../DefaultSasVerificationService.kt | 38 +++---- .../internal/session/DefaultSession.kt | 18 ++-- .../room/timeline/TimelineEventFactory.kt | 42 +++++--- .../session/sync/CryptoSyncHandler.kt | 2 +- .../session/sync/SyncResponseHandler.kt | 2 +- .../riotredesign/features/home/HomeModule.kt | 2 +- .../timeline/factory/EncryptedItemFactory.kt | 18 +--- .../RoomHistoryVisibilityItemFactory.kt | 5 +- .../timeline/factory/TimelineItemFactory.kt | 2 +- 16 files changed, 154 insertions(+), 151 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/CryptoService.kt index 67818c0b..ee2ae132 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/CryptoService.kt @@ -92,34 +92,10 @@ interface CryptoService { roomId: String, callback: MatrixCallback) - /* - fun start(isInitialSync: Boolean, aCallback: MatrixCallback?) - - fun isStarted(): Boolean - - fun isStarting(): Boolean - - fun close() - - - fun getOlmDevice(): MXOlmDevice? - - fun checkUnknownDevices(userIds: List, callback: MatrixCallback) - - fun warnOnUnknownDevices(): Boolean - - @Throws(MXDecryptionException::class) - fun decryptEvent(event: Event, timelineId: String?): MXEventDecryptionResult? - - fun resetReplayAttackCheckInTimeline(timelineId: String) - - - @VisibleForTesting - fun ensureOlmSessionsForUsers(users: List, callback: MatrixCallback>) - */ - fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult? + fun decryptEventAsync(event: Event, timeline: String, callback: MatrixCallback) + fun getEncryptionAlgorithm(roomId: String): String? fun shouldEncryptForInvitedMembers(roomId: String): Boolean diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomHistoryVisibilityContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomHistoryVisibilityContent.kt index 0c9a1f9e..6e843746 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomHistoryVisibilityContent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/RoomHistoryVisibilityContent.kt @@ -23,5 +23,5 @@ import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) data class RoomHistoryVisibilityContent( - @Json(name = "history_visibility") val historyVisibility: RoomHistoryVisibility + @Json(name = "history_visibility") val historyVisibility: RoomHistoryVisibility? = null ) \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt index 5dc11c42..95d6ad24 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt @@ -73,6 +73,7 @@ import org.matrix.olm.OlmManager import timber.log.Timber import java.util.* import java.util.concurrent.atomic.AtomicBoolean +import kotlin.coroutines.EmptyCoroutineContext /** * A `CryptoService` class instance manages the end-to-end crypto for a session. @@ -134,22 +135,8 @@ internal class CryptoManager( // MXEncrypting instance for each room. private val roomEncryptors: MutableMap = HashMap() - - // the encryption is starting - private var isStarting = AtomicBoolean(false) - - // tell if the crypto is started - private var isStarted = AtomicBoolean(false) - - // TODO - //private val mNetworkListener = object : IMXNetworkEventListener { - // override fun onNetworkConnectionUpdate(isConnected: Boolean) { - // if (isConnected && !isStarted()) { - // Timber.v("Start MXCrypto because a network connection has been retrieved ") - // start(false, null) - // } - // } - //} + private val isStarting = AtomicBoolean(false) + private val isStarted = AtomicBoolean(false) fun onStateEvent(roomId: String, event: Event) { when { @@ -262,8 +249,6 @@ internal class CryptoManager( internalStart(isInitialSync) }, { - isStarting.set(false) - isStarted.set(true) outgoingRoomKeyRequestManager.start() keysBackup.checkAndStartKeysBackup() if (isInitialSync) { @@ -273,6 +258,8 @@ internal class CryptoManager( } else { incomingRoomKeyRequestManager.processReceivedRoomKeyRequests() } + isStarting.set(false) + isStarted.set(true) } ) } @@ -589,21 +576,54 @@ internal class CryptoManager( */ @Throws(MXDecryptionException::class) override fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult? { - val eventContent = event.content - if (eventContent == null) { - Timber.e("## decryptEvent : empty event content") - return null - } return runBlocking { - withContext(coroutineDispatchers.crypto) { - val alg = roomDecryptorProvider.getOrCreateRoomDecryptor(event.roomId, eventContent["algorithm"] as String) - if (alg == null) { - val reason = String.format(MXCryptoError.UNABLE_TO_DECRYPT_REASON, event.eventId, eventContent["algorithm"] as String) - Timber.e("## decryptEvent() : $reason") - throw MXDecryptionException(MXCryptoError(MXCryptoError.UNABLE_TO_DECRYPT_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, reason)) - } else { - alg.decryptEvent(event, timeline) - } + internalDecryptEvent(event, timeline).fold( + { throw it }, + { it } + ) + } + } + + /** + * Decrypt an event asynchronously + * + * @param event the raw event. + * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. + * @param callback the callback to return data or null + */ + override fun decryptEventAsync(event: Event, timeline: String, callback: MatrixCallback) { + GlobalScope.launch(EmptyCoroutineContext) { + val result = withContext(coroutineDispatchers.crypto) { + internalDecryptEvent(event, timeline) + } + result.fold( + { callback.onFailure(it) }, + { callback.onSuccess(it) } + ) + } + } + + /** + * Decrypt an event + * + * @param event the raw event. + * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. + * @return the MXEventDecryptionResult data, or null in case of error wrapped into [Try] + */ + private suspend fun internalDecryptEvent(event: Event, timeline: String): Try { + return Try { + val eventContent = event.content + if (eventContent == null) { + Timber.e("## decryptEvent : empty event content") + return@Try null + } + val alg = roomDecryptorProvider.getOrCreateRoomDecryptor(event.roomId, eventContent["algorithm"] as String) + if (alg == null) { + val reason = String.format(MXCryptoError.UNABLE_TO_DECRYPT_REASON, event.eventId, eventContent["algorithm"] as String) + Timber.e("## decryptEvent() : $reason") + throw MXDecryptionException(MXCryptoError(MXCryptoError.UNABLE_TO_DECRYPT_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, reason)) + } else { + alg.decryptEvent(event, timeline) } } } @@ -624,10 +644,16 @@ internal class CryptoManager( */ fun onToDeviceEvent(event: Event) { CoroutineScope(coroutineDispatchers.crypto).launch { - if (event.getClearType() == EventType.ROOM_KEY || event.getClearType() == EventType.FORWARDED_ROOM_KEY) { - onRoomKeyEvent(event) - } else if (event.getClearType() == EventType.ROOM_KEY_REQUEST) { - incomingRoomKeyRequestManager.onRoomKeyRequestEvent(event) + when (event.getClearType()) { + EventType.ROOM_KEY, EventType.FORWARDED_ROOM_KEY -> { + onRoomKeyEvent(event) + } + EventType.ROOM_KEY_REQUEST -> { + incomingRoomKeyRequestManager.onRoomKeyRequestEvent(event) + } + else -> { + //ignore + } } } } @@ -638,7 +664,7 @@ internal class CryptoManager( * @param event the key event. */ private fun onRoomKeyEvent(event: Event) { - val roomKeyContent = event.getClearContent().toModel()!! + val roomKeyContent = event.getClearContent().toModel() ?: return if (TextUtils.isEmpty(roomKeyContent.roomId) || TextUtils.isEmpty(roomKeyContent.algorithm)) { Timber.e("## onRoomKeyEvent() : missing fields") return @@ -722,7 +748,6 @@ internal class CryptoManager( private fun onRoomHistoryVisibilityEvent(roomId: String, event: Event) { val eventContent = event.content.toModel() - eventContent?.historyVisibility?.let { cryptoStore.setShouldEncryptForInvitedMembers(roomId, it != RoomHistoryVisibility.JOINED) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt index e4d1ce93..3365da81 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt @@ -166,7 +166,7 @@ internal class MXMegolmDecryption(private val credentials: Credentials, * @param timelineId the timeline identifier */ private fun addEventToPendingList(event: Event, timelineId: String) { - val encryptedEventContent = event.content.toModel()!! + val encryptedEventContent = event.content.toModel() ?: return val pendingEventsKey = "${encryptedEventContent.senderKey}|${encryptedEventContent.sessionId}" if (!pendingEvents.containsKey(pendingEventsKey)) { @@ -190,7 +190,7 @@ internal class MXMegolmDecryption(private val credentials: Credentials, */ override fun onRoomKeyEvent(event: Event, keysBackup: KeysBackup) { var exportFormat = false - val roomKeyContent = event.getClearContent().toModel()!! + val roomKeyContent = event.getClearContent().toModel() ?: return var senderKey: String? = event.getSenderKey() var keysClaimed: MutableMap = HashMap() @@ -203,11 +203,11 @@ internal class MXMegolmDecryption(private val credentials: Credentials, if (event.getClearType() == EventType.FORWARDED_ROOM_KEY) { Timber.v("## onRoomKeyEvent(), forward adding key : roomId " + roomKeyContent.roomId + " sessionId " + roomKeyContent.sessionId + " sessionKey " + roomKeyContent.sessionKey) // from " + event); - val forwardedRoomKeyContent = event.getClearContent().toModel()!! - forwardingCurve25519KeyChain = if (null == forwardedRoomKeyContent.forwardingCurve25519KeyChain) { + val forwardedRoomKeyContent = event.getClearContent().toModel() ?: return + forwardingCurve25519KeyChain = if (forwardedRoomKeyContent.forwardingCurve25519KeyChain == null) { ArrayList() } else { - ArrayList(forwardedRoomKeyContent.forwardingCurve25519KeyChain!!) + ArrayList(forwardedRoomKeyContent.forwardingCurve25519KeyChain) } forwardingCurve25519KeyChain.add(senderKey!!) @@ -262,6 +262,7 @@ internal class MXMegolmDecryption(private val credentials: Credentials, */ override fun onNewSession(senderKey: String, sessionId: String) { //TODO see how to handle this + Timber.v("ON NEW SESSION $sessionId - $senderKey") /*val k = "$senderKey|$sessionId" val pending = pendingEvents[k] diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/EncryptedEventContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/EncryptedEventContent.kt index fc574eb1..108ce056 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/EncryptedEventContent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/EncryptedEventContent.kt @@ -28,29 +28,29 @@ data class EncryptedEventContent( * the used algorithm */ @Json(name = "algorithm") - var algorithm: String? = null, + val algorithm: String? = null, /** * The encrypted event */ @Json(name = "ciphertext") - var ciphertext: String? = null, + val ciphertext: String? = null, /** * The device id */ @Json(name = "device_id") - var deviceId: String? = null, + val deviceId: String? = null, /** * the sender key */ @Json(name = "sender_key") - var senderKey: String? = null, + val senderKey: String? = null, /** * The session id */ @Json(name = "session_id") - var sessionId: String? = null + val sessionId: String? = null ) \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/RoomKeyContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/RoomKeyContent.kt index cafcb14d..81f45004 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/RoomKeyContent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/event/RoomKeyContent.kt @@ -25,18 +25,18 @@ import com.squareup.moshi.JsonClass data class RoomKeyContent( @Json(name = "algorithm") - var algorithm: String? = null, + val algorithm: String? = null, @Json(name = "room_id") - var roomId: String? = null, + val roomId: String? = null, @Json(name = "session_id") - var sessionId: String? = null, + val sessionId: String? = null, @Json(name = "session_key") - var sessionKey: String? = null, + val sessionKey: String? = null, // should be a Long but it is sometimes a double @Json(name = "chain_index") - var chainIndex: Any? = null + val chainIndex: Any? = null ) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/ForwardedRoomKeyContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/ForwardedRoomKeyContent.kt index a135c2a7..b887989f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/ForwardedRoomKeyContent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/ForwardedRoomKeyContent.kt @@ -25,23 +25,23 @@ import com.squareup.moshi.JsonClass data class ForwardedRoomKeyContent( @Json(name = "algorithm") - var algorithm: String? = null, + val algorithm: String? = null, @Json(name = "room_id") - var roomId: String? = null, + val roomId: String? = null, @Json(name = "sender_key") - var senderKey: String? = null, + val senderKey: String? = null, @Json(name = "session_id") - var sessionId: String? = null, + val sessionId: String? = null, @Json(name = "session_key") - var sessionKey: String? = null, + val sessionKey: String? = null, @Json(name = "forwarding_curve25519_key_chain") - var forwardingCurve25519KeyChain: List? = null, + val forwardingCurve25519KeyChain: List? = null, @Json(name = "sender_claimed_ed25519_key") - var senderClaimedEd25519Key: String? = null + val senderClaimedEd25519Key: String? = null ) \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt index 3789d83c..81556052 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt @@ -54,14 +54,14 @@ import kotlin.collections.HashMap * Short codes interactive verification is a more user friendly way of verifying devices * that is still maintaining a good level of security (alternative to the 43-character strings compare method). */ -internal class DefaultSasVerificationService(private val mCredentials: Credentials, - private val mCryptoStore: IMXCryptoStore, - private val mMyDeviceInfoHolder: MyDeviceInfoHolder, +internal class DefaultSasVerificationService(private val credentials: Credentials, + private val cryptoStore: IMXCryptoStore, + private val myDeviceInfoHolder: MyDeviceInfoHolder, private val deviceListManager: DeviceListManager, private val setDeviceVerificationAction: SetDeviceVerificationAction, - private val mSendToDeviceTask: SendToDeviceTask, + private val sendToDeviceTask: SendToDeviceTask, private val coroutineDispatchers: MatrixCoroutineDispatchers, - private val mTaskExecutor: TaskExecutor) + private val taskExecutor: TaskExecutor) : VerificationTransaction.Listener, SasVerificationService { private val uiHandler = Handler(Looper.getMainLooper()) @@ -194,11 +194,11 @@ internal class DefaultSasVerificationService(private val mCredentials: Credentia val tx = IncomingSASVerificationTransaction( this, setDeviceVerificationAction, - mCredentials, - mCryptoStore, - mSendToDeviceTask, - mTaskExecutor, - mMyDeviceInfoHolder.myDevice.fingerprint()!!, + credentials, + cryptoStore, + sendToDeviceTask, + taskExecutor, + myDeviceInfoHolder.myDevice.fingerprint()!!, startReq.transactionID!!, otherUserId) addTransaction(tx) @@ -363,11 +363,11 @@ internal class DefaultSasVerificationService(private val mCredentials: Credentia val tx = OutgoingSASVerificationRequest( this, setDeviceVerificationAction, - mCredentials, - mCryptoStore, - mSendToDeviceTask, - mTaskExecutor, - mMyDeviceInfoHolder.myDevice.fingerprint()!!, + credentials, + cryptoStore, + sendToDeviceTask, + taskExecutor, + myDeviceInfoHolder.myDevice.fingerprint()!!, txID, userId, deviceID) @@ -387,8 +387,8 @@ internal class DefaultSasVerificationService(private val mCredentials: Credentia private fun createUniqueIDForTransaction(userId: String, deviceID: String): String { val buff = StringBuffer() buff - .append(mCredentials.userId).append("|") - .append(mCredentials.deviceId).append("|") + .append(credentials.userId).append("|") + .append(credentials.deviceId).append("|") .append(userId).append("|") .append(deviceID).append("|") .append(UUID.randomUUID().toString()) @@ -413,7 +413,7 @@ internal class DefaultSasVerificationService(private val mCredentials: Credentia val contentMap = MXUsersDevicesMap() contentMap.setObject(cancelMessage, userId, userDevice) - mSendToDeviceTask.configureWith(SendToDeviceTask.Params(EventType.KEY_VERIFICATION_CANCEL, contentMap, transactionId)) + sendToDeviceTask.configureWith(SendToDeviceTask.Params(EventType.KEY_VERIFICATION_CANCEL, contentMap, transactionId)) .dispatchTo(object : MatrixCallback { override fun onSuccess(data: Unit) { Timber.v("## SAS verification [$transactionId] canceled for reason ${code.value}") @@ -423,6 +423,6 @@ internal class DefaultSasVerificationService(private val mCredentials: Credentia Timber.e(failure, "## SAS verification [$transactionId] failed to cancel.") } }) - .executeBy(mTaskExecutor) + .executeBy(taskExecutor) } } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt index c5feecc3..8ca4c8ea 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt @@ -103,13 +103,13 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi val contentModule = ContentModule().definition val cryptoModule = CryptoModule().definition MatrixKoinHolder.instance.loadModules(listOf(sessionModule, - syncModule, - roomModule, - groupModule, - userModule, - signOutModule, - contentModule, - cryptoModule)) + syncModule, + roomModule, + groupModule, + userModule, + signOutModule, + contentModule, + cryptoModule)) scope = getKoin().getOrCreateScope(SCOPE) if (!monarchy.isMonarchyThreadOpen) { monarchy.openManually() @@ -350,6 +350,10 @@ internal class DefaultSession(override val sessionParams: SessionParams) : Sessi return cryptoService.decryptEvent(event, timeline) } + override fun decryptEventAsync(event: Event, timeline: String, callback: MatrixCallback) { + return cryptoService.decryptEventAsync(event, timeline, callback) + } + override fun getEncryptionAlgorithm(roomId: String): String? { return cryptoService.getEncryptionAlgorithm(roomId) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineEventFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineEventFactory.kt index 5f6425c4..bc0a453a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineEventFactory.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineEventFactory.kt @@ -16,7 +16,9 @@ package im.vector.matrix.android.internal.session.room.timeline +import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.session.crypto.CryptoService +import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.matrix.android.internal.crypto.MXDecryptionException @@ -44,23 +46,7 @@ internal class TimelineEventFactory(private val roomMemberExtractor: SenderRoomM } val event = eventEntity.asDomain() if (event.getClearType() == EventType.ENCRYPTED) { - try { - Timber.v("Encrypted event: try to decrypt ${event.eventId}") - val result = if (decryptionCache.containsKey(eventEntity.localId)) { - Timber.v("Encrypted event ${event.eventId} cached") - decryptionCache[eventEntity.localId] - } else { - cryptoService.decryptEvent(event, timelineId)?.also { - decryptionCache[eventEntity.localId] = it - } - } - event.setClearData(result) - } catch (e: Exception) { - Timber.e(e, "Encrypted event: decryption failed") - if (e is MXDecryptionException) { - event.setCryptoError(e.cryptoError) - } - } + handleEncryptedEvent(event, eventEntity.localId) } return TimelineEvent( event, @@ -72,6 +58,28 @@ internal class TimelineEventFactory(private val roomMemberExtractor: SenderRoomM ) } + private fun handleEncryptedEvent(event: Event, eventId: String) { + Timber.v("Encrypted event: try to decrypt ${event.eventId}") + val cachedDecryption = decryptionCache[eventId] + if (cachedDecryption != null) { + Timber.v("Encrypted event ${event.eventId} cached") + event.setClearData(cachedDecryption) + } else { + try { + val result = cryptoService.decryptEvent(event, timelineId) + if (result != null) { + decryptionCache[eventId] = result + } + event.setClearData(result) + } catch (failure: Throwable) { + Timber.e(failure, "Encrypted event: decryption failed") + if (failure is MXDecryptionException) { + event.setCryptoError(failure.cryptoError) + } + } + } + } + fun clear() { senderCache.clear() } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt index d6877e03..6dd2763f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt @@ -47,7 +47,7 @@ internal class CryptoSyncHandler(private val cryptoManager: CryptoManager, } } - fun onSyncCompleted(syncResponse: SyncResponse, fromToken: String?, catchingUp: Boolean) { + fun onSyncCompleted(syncResponse: SyncResponse) { cryptoManager.onSyncCompleted(syncResponse) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncResponseHandler.kt index 13b91a30..c6305bd9 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncResponseHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncResponseHandler.kt @@ -51,7 +51,7 @@ internal class SyncResponseHandler(private val roomSyncHandler: RoomSyncHandler, userAccountDataSyncHandler.handle(syncResponse.accountData) } Timber.v("On sync completed") - cryptoSyncHandler.onSyncCompleted(syncResponse, fromToken, isCatchingUp) + cryptoSyncHandler.onSyncCompleted(syncResponse) } val isInitialSync = fromToken == null if (!cryptoManager.isStarted()) { diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/HomeModule.kt b/vector/src/main/java/im/vector/riotredesign/features/home/HomeModule.kt index cffd20f1..9962bfe3 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/HomeModule.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/HomeModule.kt @@ -67,7 +67,7 @@ class HomeModule { roomHistoryVisibilityItemFactory = RoomHistoryVisibilityItemFactory(get()), callItemFactory = CallItemFactory(get()), encryptionItemFactory = EncryptionItemFactory(get()), - encryptedItemFactory = EncryptedItemFactory(get(), get(), messageItemFactory), + encryptedItemFactory = EncryptedItemFactory(get()), defaultItemFactory = DefaultItemFactory() ) TimelineEventController(timelineDateFormatter, timelineItemFactory, timelineMediaSizeProvider) diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt index 6010578a..309eb045 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt @@ -20,29 +20,18 @@ import android.graphics.Typeface import android.text.Spannable import android.text.SpannableString import android.text.style.StyleSpan -import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.crypto.MXCryptoError -import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.room.timeline.TimelineEvent -import im.vector.matrix.android.internal.crypto.MXDecryptionException -import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult -import im.vector.matrix.android.internal.di.MoshiProvider import im.vector.riotredesign.R import im.vector.riotredesign.core.epoxy.VectorEpoxyModel import im.vector.riotredesign.core.resources.StringProvider -import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem_ -class EncryptedItemFactory( - private val session: Session, - private val stringProvider: StringProvider, - private val messageItemFactory: MessageItemFactory) { - - fun create(timelineEvent: TimelineEvent, - nextEvent: TimelineEvent?, - callback: TimelineEventController.Callback?): VectorEpoxyModel<*>? { +// This class handles timeline event who haven't been successfully decrypted +class EncryptedItemFactory(private val stringProvider: StringProvider) { + fun create(timelineEvent: TimelineEvent): VectorEpoxyModel<*>? { return when { EventType.ENCRYPTED == timelineEvent.root.getClearType() -> { val cryptoError = timelineEvent.root.mCryptoError @@ -54,7 +43,6 @@ class EncryptedItemFactory( } val message = stringProvider.getString(R.string.notice_crypto_unable_to_decrypt, errorDescription) - val spannableStr = SpannableString(message) spannableStr.setSpan(StyleSpan(Typeface.ITALIC), 0, message.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) // TODO This is not correct format for error, change it diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/RoomHistoryVisibilityItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/RoomHistoryVisibilityItemFactory.kt index 3a3a91f1..c898103e 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/RoomHistoryVisibilityItemFactory.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/RoomHistoryVisibilityItemFactory.kt @@ -39,8 +39,9 @@ class RoomHistoryVisibilityItemFactory(private val stringProvider: StringProvide } private fun buildNoticeText(event: Event, senderName: String?): CharSequence? { - val content = event.content.toModel() ?: return null - val formattedVisibility = when (content.historyVisibility) { + val historyVisibility = event.content.toModel()?.historyVisibility + ?: return null + val formattedVisibility = when (historyVisibility) { RoomHistoryVisibility.SHARED -> stringProvider.getString(R.string.notice_room_visibility_shared) RoomHistoryVisibility.INVITED -> stringProvider.getString(R.string.notice_room_visibility_invited) RoomHistoryVisibility.JOINED -> stringProvider.getString(R.string.notice_room_visibility_joined) diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/TimelineItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/TimelineItemFactory.kt index 905feccc..95e99e29 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/TimelineItemFactory.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/TimelineItemFactory.kt @@ -51,7 +51,7 @@ class TimelineItemFactory(private val messageItemFactory: MessageItemFactory, EventType.ENCRYPTION -> encryptionItemFactory.create(event) - EventType.ENCRYPTED -> encryptedItemFactory.create(event, nextEvent, callback) + EventType.ENCRYPTED -> encryptedItemFactory.create(event) EventType.STATE_ROOM_THIRD_PARTY_INVITE, EventType.STICKER,