mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-22 09:25:49 +03:00
Make self verification work!
This commit is contained in:
parent
87b76d10dd
commit
43358cd86c
9 changed files with 91 additions and 56 deletions
|
@ -129,7 +129,7 @@ internal class IncomingRoomKeyRequestManager @Inject constructor(
|
|||
cryptoStore.deleteIncomingRoomKeyRequest(request)
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
cryptoStore.storeIncomingRoomKeyRequest(request)
|
||||
onRoomKeyRequest(request)
|
||||
}
|
||||
|
|
|
@ -298,6 +298,7 @@ internal class DefaultVerificationService @Inject constructor(
|
|||
otherUserId = senderId, // requestInfo.toUserId,
|
||||
roomId = null,
|
||||
transactionId = requestInfo.transactionID,
|
||||
localID = requestInfo.transactionID!!,
|
||||
requestInfo = requestInfo
|
||||
)
|
||||
requestsForUser.add(pendingVerificationRequest)
|
||||
|
@ -336,6 +337,7 @@ internal class DefaultVerificationService @Inject constructor(
|
|||
otherUserId = senderId, // requestInfo.toUserId,
|
||||
roomId = event.roomId,
|
||||
transactionId = event.eventId,
|
||||
localID = event.eventId!!,
|
||||
requestInfo = requestInfo
|
||||
)
|
||||
requestsForUser.add(pendingVerificationRequest)
|
||||
|
@ -1075,6 +1077,7 @@ internal class DefaultVerificationService @Inject constructor(
|
|||
// We need to update with the syncedID
|
||||
updatePendingRequest(verificationRequest.copy(
|
||||
transactionId = syncedId,
|
||||
// localId stays different
|
||||
requestInfo = info
|
||||
))
|
||||
}
|
||||
|
|
|
@ -143,6 +143,7 @@ internal class VerificationTransportRoomMessage(
|
|||
roomId: String?,
|
||||
toDevices: List<String>?,
|
||||
callback: (String?, VerificationInfoRequest?) -> Unit) {
|
||||
Timber.d("## SAS sending verification request with supported methods: $supportedMethods")
|
||||
// This transport requires a room
|
||||
requireNotNull(roomId)
|
||||
|
||||
|
@ -222,6 +223,7 @@ internal class VerificationTransportRoomMessage(
|
|||
}
|
||||
|
||||
override fun done(transactionId: String) {
|
||||
Timber.d("## SAS sending done for $transactionId")
|
||||
val event = createEventAndLocalEcho(
|
||||
type = EventType.KEY_VERIFICATION_DONE,
|
||||
roomId = roomId,
|
||||
|
@ -337,7 +339,8 @@ internal class VerificationTransportRoomMessage(
|
|||
otherUserId: String,
|
||||
otherDeviceId: String,
|
||||
callback: (() -> Unit)?) {
|
||||
// Not applicable
|
||||
// Not applicable (send event is called directly)
|
||||
Timber.w("## SAS ignored verification ready with methods: ${keyReq.methods}")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ internal class VerificationTransportToDevice(
|
|||
roomId: String?,
|
||||
toDevices: List<String>?,
|
||||
callback: (String?, VerificationInfoRequest?) -> Unit) {
|
||||
Timber.d("## SAS sending verification request with supported methods: $supportedMethods")
|
||||
val contentMap = MXUsersDevicesMap<Any>()
|
||||
val keyReq = KeyVerificationRequest(
|
||||
fromDevice = myDeviceId,
|
||||
|
@ -80,6 +81,7 @@ internal class VerificationTransportToDevice(
|
|||
otherUserId: String,
|
||||
otherDeviceId: String,
|
||||
callback: (() -> Unit)?) {
|
||||
Timber.d("## SAS sending verification ready with methods: ${keyReq.methods}")
|
||||
val contentMap = MXUsersDevicesMap<Any>()
|
||||
|
||||
contentMap.setObject(otherUserId, otherDeviceId, keyReq)
|
||||
|
@ -137,6 +139,7 @@ internal class VerificationTransportToDevice(
|
|||
|
||||
override fun done(transactionId: String) {
|
||||
// To device do not do anything here
|
||||
Timber.d("## SAS done (nothing send in to device transport)")
|
||||
}
|
||||
|
||||
override fun cancelTransaction(transactionId: String, otherUserId: String, otherUserDeviceId: String, code: CancelCode) {
|
||||
|
@ -164,8 +167,7 @@ internal class VerificationTransportToDevice(
|
|||
hash: String,
|
||||
commitment: String,
|
||||
messageAuthenticationCode: String,
|
||||
shortAuthenticationStrings: List<String>)
|
||||
: VerificationInfoAccept = KeyVerificationAccept.create(
|
||||
shortAuthenticationStrings: List<String>): VerificationInfoAccept = KeyVerificationAccept.create(
|
||||
tid,
|
||||
keyAgreementProtocol,
|
||||
hash,
|
||||
|
|
|
@ -105,7 +105,7 @@ internal class DefaultQrCodeVerificationTransaction(
|
|||
|
||||
// Check device key if available
|
||||
if (otherQrCodeData.otherDeviceKey != null
|
||||
&& otherQrCodeData.otherDeviceKey != cryptoStore.getUserDevice(otherQrCodeData.userId, otherDeviceId ?: "")?.fingerprint()) {
|
||||
&& otherQrCodeData.otherDeviceKey != cryptoStore.getUserDevice(userId, deviceId)?.fingerprint()) {
|
||||
Timber.d("## Verification QR: Invalid other device key")
|
||||
cancel(CancelCode.MismatchedKeys)
|
||||
return
|
||||
|
|
|
@ -18,7 +18,13 @@ package im.vector.matrix.android.internal.session.room
|
|||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.session.crypto.CryptoService
|
||||
import im.vector.matrix.android.api.session.crypto.MXCryptoError
|
||||
import im.vector.matrix.android.api.session.events.model.*
|
||||
import im.vector.matrix.android.api.session.events.model.AggregatedAnnotation
|
||||
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.events.model.LocalEcho
|
||||
import im.vector.matrix.android.api.session.events.model.RelationType
|
||||
import im.vector.matrix.android.api.session.events.model.toContent
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.model.ReferencesAggregatedContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageRelationContent
|
||||
|
@ -27,7 +33,13 @@ import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResu
|
|||
import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent
|
||||
import im.vector.matrix.android.internal.database.mapper.ContentMapper
|
||||
import im.vector.matrix.android.internal.database.mapper.EventMapper
|
||||
import im.vector.matrix.android.internal.database.model.*
|
||||
import im.vector.matrix.android.internal.database.model.EditAggregatedSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import im.vector.matrix.android.internal.database.model.ReactionAggregatedSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.model.ReactionAggregatedSummaryEntityFields
|
||||
import im.vector.matrix.android.internal.database.model.ReferencesAggregatedSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
|
||||
import im.vector.matrix.android.internal.database.query.create
|
||||
import im.vector.matrix.android.internal.database.query.getOrCreate
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
|
@ -53,9 +65,10 @@ enum class VerificationState {
|
|||
DONE
|
||||
}
|
||||
|
||||
fun VerificationState.isCanceled() : Boolean {
|
||||
fun VerificationState.isCanceled(): Boolean {
|
||||
return this == VerificationState.CANCELED_BY_ME || this == VerificationState.CANCELED_BY_OTHER
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by EventRelationAggregationUpdater, when new events that can affect relations are inserted in base.
|
||||
*/
|
||||
|
@ -118,6 +131,8 @@ internal class DefaultEventRelationsAggregationTask @Inject constructor(
|
|||
EventType.KEY_VERIFICATION_ACCEPT,
|
||||
EventType.KEY_VERIFICATION_START,
|
||||
EventType.KEY_VERIFICATION_MAC,
|
||||
// TODO Add ?
|
||||
// EventType.KEY_VERIFICATION_READY,
|
||||
EventType.KEY_VERIFICATION_KEY -> {
|
||||
Timber.v("## SAS REF in room $roomId for event ${event.eventId}")
|
||||
event.content.toModel<MessageRelationContent>()?.relatesTo?.let {
|
||||
|
@ -146,6 +161,8 @@ internal class DefaultEventRelationsAggregationTask @Inject constructor(
|
|||
EventType.KEY_VERIFICATION_ACCEPT,
|
||||
EventType.KEY_VERIFICATION_START,
|
||||
EventType.KEY_VERIFICATION_MAC,
|
||||
// TODO Add ?
|
||||
// EventType.KEY_VERIFICATION_READY,
|
||||
EventType.KEY_VERIFICATION_KEY -> {
|
||||
Timber.v("## SAS REF in room $roomId for event ${event.eventId}")
|
||||
encryptedEventContent.relatesTo.eventId?.let {
|
||||
|
@ -473,7 +490,7 @@ internal class DefaultEventRelationsAggregationTask @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun updateVerificationState(oldState: VerificationState?, newState: VerificationState) : VerificationState {
|
||||
private fun updateVerificationState(oldState: VerificationState?, newState: VerificationState): VerificationState {
|
||||
// Cancel is always prioritary ?
|
||||
// Eg id i found that mac or keys mismatch and send a cancel and the other send a done, i have to
|
||||
// consider as canceled
|
||||
|
|
|
@ -35,7 +35,6 @@ import javax.inject.Inject
|
|||
* For reactions will build a EventAnnotationsSummaryEntity, ans for edits a EditAggregatedSummaryEntity.
|
||||
* The summaries can then be extracted and added (as a decoration) to a TimelineEvent for final display.
|
||||
*/
|
||||
|
||||
internal class EventRelationsAggregationUpdater @Inject constructor(
|
||||
@SessionDatabase realmConfiguration: RealmConfiguration,
|
||||
@UserId private val userId: String,
|
||||
|
@ -52,6 +51,8 @@ internal class EventRelationsAggregationUpdater @Inject constructor(
|
|||
EventType.KEY_VERIFICATION_ACCEPT,
|
||||
EventType.KEY_VERIFICATION_START,
|
||||
EventType.KEY_VERIFICATION_MAC,
|
||||
// TODO Add ?
|
||||
// EventType.KEY_VERIFICATION_READY,
|
||||
EventType.KEY_VERIFICATION_KEY,
|
||||
EventType.ENCRYPTED)
|
||||
)
|
||||
|
|
|
@ -42,7 +42,6 @@ import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
|
|||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.matrix.android.internal.crypto.verification.PendingVerificationRequest
|
||||
import im.vector.riotx.core.di.HasScreenInjector
|
||||
import im.vector.riotx.core.extensions.exhaustive
|
||||
import im.vector.riotx.core.platform.EmptyViewEvents
|
||||
import im.vector.riotx.core.platform.VectorViewModel
|
||||
|
@ -56,11 +55,13 @@ data class VerificationBottomSheetViewState(
|
|||
val sasTransactionState: VerificationTxState? = null,
|
||||
val qrTransactionState: VerificationTxState? = null,
|
||||
val transactionId: String? = null,
|
||||
// true when we display the loading and we wait for the other (incoming request)
|
||||
val waitForOtherUserMode: Boolean = false,
|
||||
val isMe: Boolean = false
|
||||
) : MvRxState
|
||||
|
||||
class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted initialState: VerificationBottomSheetViewState,
|
||||
@Assisted args: VerificationBottomSheet.VerificationArgs,
|
||||
private val session: Session)
|
||||
: VectorViewModel<VerificationBottomSheetViewState, VerificationAction, EmptyViewEvents>(initialState),
|
||||
VerificationService.VerificationListener {
|
||||
|
@ -72,6 +73,55 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
|||
|
||||
init {
|
||||
session.getVerificationService().addListener(this)
|
||||
|
||||
val userItem = session.getUser(args.otherUserId)
|
||||
|
||||
val isWaitingForOtherMode = args.waitForIncomingRequest
|
||||
|
||||
var autoReady = false
|
||||
val pr = if (isWaitingForOtherMode) {
|
||||
// See if active tx for this user and take it
|
||||
|
||||
session.getVerificationService().getExistingVerificationRequest(args.otherUserId)
|
||||
?.lastOrNull { !it.isFinished }
|
||||
?.also { verificationRequest ->
|
||||
if (verificationRequest.isIncoming && !verificationRequest.isReady) {
|
||||
// auto ready in this case, as we are waiting
|
||||
autoReady = true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
session.getVerificationService().getExistingVerificationRequest(args.otherUserId, args.verificationId)
|
||||
}
|
||||
|
||||
val sasTx = (pr?.transactionId ?: args.verificationId)?.let {
|
||||
session.getVerificationService().getExistingTransaction(args.otherUserId, it) as? SasVerificationTransaction
|
||||
}
|
||||
|
||||
val qrTx = (pr?.transactionId ?: args.verificationId)?.let {
|
||||
session.getVerificationService().getExistingTransaction(args.otherUserId, it) as? QrCodeVerificationTransaction
|
||||
}
|
||||
|
||||
setState {
|
||||
copy(
|
||||
otherUserMxItem = userItem?.toMatrixItem(),
|
||||
sasTransactionState = sasTx?.state,
|
||||
qrTransactionState = qrTx?.state,
|
||||
transactionId = pr?.transactionId ?: args.verificationId,
|
||||
pendingRequest = if (pr != null) Success(pr) else Uninitialized,
|
||||
waitForOtherUserMode = isWaitingForOtherMode,
|
||||
roomId = args.roomId,
|
||||
isMe = args.otherUserId == session.myUserId
|
||||
)
|
||||
}
|
||||
|
||||
if (autoReady) {
|
||||
// TODO, can I be here in DM mode? in this case should test if roomID is null?
|
||||
session.getVerificationService()
|
||||
.readyPendingVerification(supportedVerificationMethods,
|
||||
pr!!.otherUserId,
|
||||
pr.transactionId ?: "")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
|
@ -81,7 +131,8 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
|||
|
||||
@AssistedInject.Factory
|
||||
interface Factory {
|
||||
fun create(initialState: VerificationBottomSheetViewState): VerificationBottomSheetViewModel
|
||||
fun create(initialState: VerificationBottomSheetViewState,
|
||||
args: VerificationBottomSheet.VerificationArgs): VerificationBottomSheetViewModel
|
||||
}
|
||||
|
||||
companion object : MvRxViewModelFactory<VerificationBottomSheetViewModel, VerificationBottomSheetViewState> {
|
||||
|
@ -90,48 +141,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
|||
val fragment: VerificationBottomSheet = (viewModelContext as FragmentViewModelContext).fragment()
|
||||
val args: VerificationBottomSheet.VerificationArgs = viewModelContext.args()
|
||||
|
||||
val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getActiveSession()
|
||||
|
||||
val userItem = session.getUser(args.otherUserId)
|
||||
|
||||
val isWaitingForOtherMode = args.waitForIncomingRequest
|
||||
|
||||
val pr = if (isWaitingForOtherMode) {
|
||||
// See if active tx for this user and take it
|
||||
session.getVerificationService().getExistingVerificationRequest(args.otherUserId)
|
||||
?.firstOrNull { !it.isFinished }
|
||||
?.also { verificationRequest ->
|
||||
if (verificationRequest.isIncoming && !verificationRequest.isReady) {
|
||||
//auto ready in this case, as we are waiting
|
||||
// TODO, can I be here in DM mode? in this case should test if roomID is null?
|
||||
session.getVerificationService()
|
||||
.readyPendingVerification(supportedVerificationMethods,
|
||||
verificationRequest.otherUserId,
|
||||
verificationRequest.transactionId ?: "")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
session.getVerificationService().getExistingVerificationRequest(args.otherUserId, args.verificationId)
|
||||
}
|
||||
|
||||
val sasTx = (pr?.transactionId ?: args.verificationId)?.let {
|
||||
session.getVerificationService().getExistingTransaction(args.otherUserId, it) as? SasVerificationTransaction
|
||||
}
|
||||
|
||||
val qrTx = (pr?.transactionId ?: args.verificationId)?.let {
|
||||
session.getVerificationService().getExistingTransaction(args.otherUserId, it) as? QrCodeVerificationTransaction
|
||||
}
|
||||
|
||||
return fragment.verificationViewModelFactory.create(VerificationBottomSheetViewState(
|
||||
otherUserMxItem = userItem?.toMatrixItem(),
|
||||
sasTransactionState = sasTx?.state,
|
||||
qrTransactionState = qrTx?.state,
|
||||
transactionId = args.verificationId,
|
||||
pendingRequest = if (pr != null) Success(pr) else Uninitialized,
|
||||
waitForOtherUserMode = isWaitingForOtherMode,
|
||||
roomId = args.roomId,
|
||||
isMe = args.otherUserId == session.myUserId)
|
||||
)
|
||||
return fragment.verificationViewModelFactory.create(state, args)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -309,7 +319,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
|||
// is this an incoming with that user
|
||||
if (pr.isIncoming && pr.otherUserId == state.otherUserMxItem?.id) {
|
||||
if (!pr.isReady) {
|
||||
//auto ready in this case, as we are waiting
|
||||
// auto ready in this case, as we are waiting
|
||||
// TODO, can I be here in DM mode? in this case should test if roomID is null?
|
||||
session.getVerificationService()
|
||||
.readyPendingVerification(supportedVerificationMethods,
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
package im.vector.riotx.features.settings.devices
|
||||
|
||||
import com.airbnb.epoxy.TypedEpoxyController
|
||||
import com.airbnb.mvrx.Fail
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.dividerItem
|
||||
|
|
Loading…
Reference in a new issue