mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-12-26 19:08:44 +03:00
Suspend API: continue moving verifications
This commit is contained in:
parent
950c7f4a23
commit
9c6fccab1d
9 changed files with 192 additions and 149 deletions
|
@ -26,15 +26,15 @@ interface QrCodeVerificationTransaction : VerificationTransaction {
|
|||
/**
|
||||
* Call when you have scan the other user QR code
|
||||
*/
|
||||
fun userHasScannedOtherQrCode(otherQrCodeText: String)
|
||||
suspend fun userHasScannedOtherQrCode(otherQrCodeText: String)
|
||||
|
||||
/**
|
||||
* Call when you confirm that other user has scanned your QR code
|
||||
*/
|
||||
fun otherUserScannedMyQrCode()
|
||||
suspend fun otherUserScannedMyQrCode()
|
||||
|
||||
/**
|
||||
* Call when you do not confirm that other user has scanned your QR code
|
||||
*/
|
||||
fun otherUserDidNotScannedMyQrCode()
|
||||
suspend fun otherUserDidNotScannedMyQrCode()
|
||||
}
|
||||
|
|
|
@ -30,9 +30,9 @@ interface SasVerificationTransaction : VerificationTransaction {
|
|||
* To be called by the client when the user has verified that
|
||||
* both short codes do match
|
||||
*/
|
||||
fun userHasVerifiedShortCode()
|
||||
suspend fun userHasVerifiedShortCode()
|
||||
|
||||
fun acceptVerification()
|
||||
suspend fun acceptVerification()
|
||||
|
||||
fun shortCodeDoesNotMatch()
|
||||
suspend fun shortCodeDoesNotMatch()
|
||||
}
|
||||
|
|
|
@ -30,9 +30,9 @@ interface VerificationTransaction {
|
|||
/**
|
||||
* User wants to cancel the transaction
|
||||
*/
|
||||
fun cancel()
|
||||
suspend fun cancel()
|
||||
|
||||
fun cancel(code: CancelCode)
|
||||
suspend fun cancel(code: CancelCode)
|
||||
|
||||
fun isToDeviceTransport(): Boolean
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.CancelCode
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.QrCodeVerificationTransaction
|
||||
|
@ -67,20 +66,18 @@ internal class QrCodeVerification(
|
|||
}
|
||||
|
||||
/** Pass the data from a scanned QR code into the QR code verification object */
|
||||
override fun userHasScannedOtherQrCode(otherQrCodeText: String) {
|
||||
runBlocking {
|
||||
override suspend fun userHasScannedOtherQrCode(otherQrCodeText: String) {
|
||||
request.scanQrCode(otherQrCodeText)
|
||||
}
|
||||
dispatchTxUpdated()
|
||||
}
|
||||
|
||||
/** Confirm that the other side has indeed scanned the QR code we presented */
|
||||
override fun otherUserScannedMyQrCode() {
|
||||
runBlocking { confirm() }
|
||||
override suspend fun otherUserScannedMyQrCode() {
|
||||
confirm()
|
||||
}
|
||||
|
||||
/** Cancel the QR code verification, denying that the other side has scanned the QR code */
|
||||
override fun otherUserDidNotScannedMyQrCode() {
|
||||
override suspend fun otherUserDidNotScannedMyQrCode() {
|
||||
// TODO Is this code correct here? The old code seems to do this
|
||||
cancelHelper(CancelCode.MismatchedKeys)
|
||||
}
|
||||
|
@ -140,7 +137,7 @@ internal class QrCodeVerification(
|
|||
*
|
||||
* The method turns into a noop, if the verification flow has already been cancelled.
|
||||
* */
|
||||
override fun cancel() {
|
||||
override suspend fun cancel() {
|
||||
cancelHelper(CancelCode.User)
|
||||
}
|
||||
|
||||
|
@ -155,7 +152,7 @@ internal class QrCodeVerification(
|
|||
*
|
||||
* @param code The cancel code that should be given as the reason for the cancellation.
|
||||
* */
|
||||
override fun cancel(code: CancelCode) {
|
||||
override suspend fun cancel(code: CancelCode) {
|
||||
cancelHelper(code)
|
||||
}
|
||||
|
||||
|
@ -190,11 +187,11 @@ internal class QrCodeVerification(
|
|||
}
|
||||
}
|
||||
|
||||
private fun cancelHelper(code: CancelCode) {
|
||||
private suspend fun cancelHelper(code: CancelCode) {
|
||||
val request = this.machine.cancelVerification(this.request.otherUser(), this.request.flowId(), code.value)
|
||||
|
||||
if (request != null) {
|
||||
runBlocking { sender.sendVerificationRequest(request) }
|
||||
sender.sendVerificationRequest(request)
|
||||
dispatchTxUpdated()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.CancelCode
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentation
|
||||
|
@ -95,7 +94,7 @@ internal class SasVerification(
|
|||
*
|
||||
* The method turns into a noop, if the verification flow has already been cancelled.
|
||||
* */
|
||||
override fun cancel() {
|
||||
override suspend fun cancel() {
|
||||
this.cancelHelper(CancelCode.User)
|
||||
}
|
||||
|
||||
|
@ -110,7 +109,7 @@ internal class SasVerification(
|
|||
*
|
||||
* @param code The cancel code that should be given as the reason for the cancellation.
|
||||
* */
|
||||
override fun cancel(code: CancelCode) {
|
||||
override suspend fun cancel(code: CancelCode) {
|
||||
this.cancelHelper(code)
|
||||
}
|
||||
|
||||
|
@ -123,7 +122,7 @@ internal class SasVerification(
|
|||
*
|
||||
* The method turns into a noop, if the verification flow has already been cancelled.
|
||||
*/
|
||||
override fun shortCodeDoesNotMatch() {
|
||||
override suspend fun shortCodeDoesNotMatch() {
|
||||
this.cancelHelper(CancelCode.MismatchedSas)
|
||||
}
|
||||
|
||||
|
@ -153,8 +152,8 @@ internal class SasVerification(
|
|||
* This method is a noop if we're not yet in a presentable state, i.e. we didn't receive
|
||||
* a m.key.verification.key event from the other side or we're cancelled.
|
||||
*/
|
||||
override fun userHasVerifiedShortCode() {
|
||||
runBlocking { confirm() }
|
||||
override suspend fun userHasVerifiedShortCode() {
|
||||
confirm()
|
||||
}
|
||||
|
||||
/** Accept the verification flow, signaling the other side that we do want to verify
|
||||
|
@ -165,8 +164,8 @@ internal class SasVerification(
|
|||
* This method is a noop if we send the start event out or if the verification has already
|
||||
* been accepted.
|
||||
*/
|
||||
override fun acceptVerification() {
|
||||
runBlocking { accept() }
|
||||
override suspend fun acceptVerification() {
|
||||
accept()
|
||||
}
|
||||
|
||||
/** Get the decimal representation of the short auth string
|
||||
|
@ -220,11 +219,11 @@ internal class SasVerification(
|
|||
}
|
||||
}
|
||||
|
||||
private fun cancelHelper(code: CancelCode) {
|
||||
private suspend fun cancelHelper(code: CancelCode) {
|
||||
val request = this.machine.cancelVerification(this.inner.otherUserId, inner.flowId, code.value)
|
||||
|
||||
if (request != null) {
|
||||
runBlocking { sender.sendVerificationRequest(request) }
|
||||
sender.sendVerificationRequest(request)
|
||||
dispatchTxUpdated()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ sealed class UserIdentities {
|
|||
/**
|
||||
* Convert the identity into a MxCrossSigningInfo class.
|
||||
*/
|
||||
abstract fun toMxCrossSigningInfo(): MXCrossSigningInfo
|
||||
abstract suspend fun toMxCrossSigningInfo(): MXCrossSigningInfo
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,11 +147,11 @@ internal class OwnUserIdentity(
|
|||
/**
|
||||
* Convert the identity into a MxCrossSigningInfo class.
|
||||
*/
|
||||
override fun toMxCrossSigningInfo(): MXCrossSigningInfo {
|
||||
override suspend fun toMxCrossSigningInfo(): MXCrossSigningInfo {
|
||||
val masterKey = this.masterKey
|
||||
val selfSigningKey = this.selfSigningKey
|
||||
val userSigningKey = this.userSigningKey
|
||||
val trustLevel = DeviceTrustLevel(runBlocking { verified() }, false)
|
||||
val trustLevel = DeviceTrustLevel(verified(), false)
|
||||
// TODO remove this, this is silly, we have way too many methods to check if a user is verified
|
||||
masterKey.trustLevel = trustLevel
|
||||
selfSigningKey.trustLevel = trustLevel
|
||||
|
@ -249,9 +249,9 @@ internal class UserIdentity(
|
|||
/**
|
||||
* Convert the identity into a MxCrossSigningInfo class.
|
||||
*/
|
||||
override fun toMxCrossSigningInfo(): MXCrossSigningInfo {
|
||||
override suspend fun toMxCrossSigningInfo(): MXCrossSigningInfo {
|
||||
// val crossSigningKeys = listOf(this.masterKey, this.selfSigningKey)
|
||||
val trustLevel = DeviceTrustLevel(runBlocking { verified() }, false)
|
||||
val trustLevel = DeviceTrustLevel(verified(), false)
|
||||
// TODO remove this, this is silly, we have way too many methods to check if a user is verified
|
||||
masterKey.trustLevel = trustLevel
|
||||
selfSigningKey.trustLevel = trustLevel
|
||||
|
|
|
@ -91,12 +91,14 @@ class IncomingVerificationRequestHandler @Inject constructor(
|
|||
it.navigator.performDeviceVerification(it, tx.otherUserId, tx.transactionId)
|
||||
}
|
||||
}
|
||||
dismissedAction = Runnable {
|
||||
dismissedAction = LaunchCoroutineRunnable(coroutineScope) {
|
||||
tx.cancel()
|
||||
}
|
||||
addButton(
|
||||
context.getString(R.string.action_ignore),
|
||||
{ tx.cancel() }
|
||||
LaunchCoroutineRunnable(coroutineScope) {
|
||||
tx.cancel()
|
||||
}
|
||||
)
|
||||
addButton(
|
||||
context.getString(R.string.action_open),
|
||||
|
@ -163,14 +165,12 @@ class IncomingVerificationRequestHandler @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
dismissedAction = Runnable {
|
||||
coroutineScope.launch {
|
||||
dismissedAction = LaunchCoroutineRunnable(coroutineScope) {
|
||||
session?.cryptoService()?.verificationService()?.declineVerificationRequestInDMs(pr.otherUserId,
|
||||
pr.transactionId ?: "",
|
||||
pr.roomId ?: ""
|
||||
)
|
||||
}
|
||||
}
|
||||
colorAttribute = R.attr.vctr_notice_secondary
|
||||
// 5mn expiration
|
||||
expirationTimestamp = System.currentTimeMillis() + (5 * 60 * 1000L)
|
||||
|
@ -186,6 +186,14 @@ class IncomingVerificationRequestHandler @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private class LaunchCoroutineRunnable(private val coroutineScope: CoroutineScope, private val block: suspend () -> Unit) : Runnable {
|
||||
override fun run() {
|
||||
coroutineScope.launch {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun uniqueIdForVerificationRequest(pr: PendingVerificationRequest) =
|
||||
"verificationRequest_${pr.transactionId}"
|
||||
}
|
||||
|
|
|
@ -239,61 +239,22 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
|||
handleRequestVerificationByDM(roomId, otherUserId)
|
||||
}
|
||||
is VerificationAction.StartSASVerification -> {
|
||||
val request = session.cryptoService().verificationService().getExistingVerificationRequest(otherUserId, action.pendingRequestTransactionId)
|
||||
?: return@withState
|
||||
val otherDevice = if (request.isIncoming) request.requestInfo?.fromDevice else request.readyInfo?.fromDevice
|
||||
viewModelScope.launch {
|
||||
if (roomId == null) {
|
||||
session.cryptoService().verificationService().beginKeyVerification(
|
||||
VerificationMethod.SAS,
|
||||
otherUserId = request.otherUserId,
|
||||
otherDeviceId = otherDevice ?: "",
|
||||
transactionId = action.pendingRequestTransactionId
|
||||
)
|
||||
} else {
|
||||
session.cryptoService().verificationService().beginKeyVerificationInDMs(
|
||||
VerificationMethod.SAS,
|
||||
transactionId = action.pendingRequestTransactionId,
|
||||
roomId = roomId,
|
||||
otherUserId = request.otherUserId,
|
||||
otherDeviceId = otherDevice ?: ""
|
||||
)
|
||||
}
|
||||
}
|
||||
Unit
|
||||
handleStartSASVerification(roomId, otherUserId, action)
|
||||
}
|
||||
is VerificationAction.RemoteQrCodeScanned -> {
|
||||
val existingTransaction = session.cryptoService().verificationService()
|
||||
.getExistingTransaction(action.otherUserId, action.transactionId) as? QrCodeVerificationTransaction
|
||||
existingTransaction
|
||||
?.userHasScannedOtherQrCode(action.scannedData)
|
||||
handleRemoteQrCodeScanned(action)
|
||||
}
|
||||
is VerificationAction.OtherUserScannedSuccessfully -> {
|
||||
val transactionId = state.transactionId ?: return@withState
|
||||
|
||||
val existingTransaction = session.cryptoService().verificationService()
|
||||
.getExistingTransaction(otherUserId, transactionId) as? QrCodeVerificationTransaction
|
||||
existingTransaction
|
||||
?.otherUserScannedMyQrCode()
|
||||
handleOtherUserScannedSuccessfully(state.transactionId, otherUserId)
|
||||
}
|
||||
is VerificationAction.OtherUserDidNotScanned -> {
|
||||
val transactionId = state.transactionId ?: return@withState
|
||||
|
||||
val existingTransaction = session.cryptoService().verificationService()
|
||||
.getExistingTransaction(otherUserId, transactionId) as? QrCodeVerificationTransaction
|
||||
existingTransaction
|
||||
?.otherUserDidNotScannedMyQrCode()
|
||||
handleOtherUserDidNotScanned(state.transactionId, otherUserId)
|
||||
}
|
||||
is VerificationAction.SASMatchAction -> {
|
||||
(session.cryptoService().verificationService()
|
||||
.getExistingTransaction(action.otherUserId, action.sasTransactionId)
|
||||
as? SasVerificationTransaction)?.userHasVerifiedShortCode()
|
||||
handleSASMatchAction(action)
|
||||
}
|
||||
is VerificationAction.SASDoNotMatchAction -> {
|
||||
(session.cryptoService().verificationService()
|
||||
.getExistingTransaction(action.otherUserId, action.sasTransactionId)
|
||||
as? SasVerificationTransaction)
|
||||
?.shortCodeDoesNotMatch()
|
||||
handleSASDoNotMatchAction(action)
|
||||
}
|
||||
is VerificationAction.GotItConclusion -> {
|
||||
_viewEvents.post(VerificationBottomSheetViewEvents.Dismiss)
|
||||
|
@ -324,6 +285,76 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
|||
}.exhaustive
|
||||
}
|
||||
|
||||
private fun handleStartSASVerification(roomId: String?, otherUserId: String, action: VerificationAction.StartSASVerification) {
|
||||
val request = session.cryptoService().verificationService().getExistingVerificationRequest(otherUserId, action.pendingRequestTransactionId)
|
||||
?: return
|
||||
val otherDevice = if (request.isIncoming) request.requestInfo?.fromDevice else request.readyInfo?.fromDevice
|
||||
viewModelScope.launch {
|
||||
if (roomId == null) {
|
||||
session.cryptoService().verificationService().beginKeyVerification(
|
||||
VerificationMethod.SAS,
|
||||
otherUserId = request.otherUserId,
|
||||
otherDeviceId = otherDevice ?: "",
|
||||
transactionId = action.pendingRequestTransactionId
|
||||
)
|
||||
} else {
|
||||
session.cryptoService().verificationService().beginKeyVerificationInDMs(
|
||||
VerificationMethod.SAS,
|
||||
transactionId = action.pendingRequestTransactionId,
|
||||
roomId = roomId,
|
||||
otherUserId = request.otherUserId,
|
||||
otherDeviceId = otherDevice ?: ""
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleSASDoNotMatchAction(action: VerificationAction.SASDoNotMatchAction) {
|
||||
viewModelScope.launch {
|
||||
(session.cryptoService().verificationService()
|
||||
.getExistingTransaction(action.otherUserId, action.sasTransactionId)
|
||||
as? SasVerificationTransaction)
|
||||
?.shortCodeDoesNotMatch()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleSASMatchAction(action: VerificationAction.SASMatchAction) {
|
||||
viewModelScope.launch {
|
||||
(session.cryptoService().verificationService()
|
||||
.getExistingTransaction(action.otherUserId, action.sasTransactionId)
|
||||
as? SasVerificationTransaction)?.userHasVerifiedShortCode()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleOtherUserDidNotScanned(transactionId: String?, otherUserId: String) {
|
||||
transactionId ?: return
|
||||
viewModelScope.launch {
|
||||
val existingTransaction = session.cryptoService().verificationService()
|
||||
.getExistingTransaction(otherUserId, transactionId) as? QrCodeVerificationTransaction
|
||||
existingTransaction
|
||||
?.otherUserDidNotScannedMyQrCode()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleOtherUserScannedSuccessfully(transactionId: String?, otherUserId: String) {
|
||||
transactionId ?: return
|
||||
viewModelScope.launch {
|
||||
val existingTransaction = session.cryptoService().verificationService()
|
||||
.getExistingTransaction(otherUserId, transactionId) as? QrCodeVerificationTransaction
|
||||
existingTransaction
|
||||
?.otherUserScannedMyQrCode()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleRemoteQrCodeScanned(action: VerificationAction.RemoteQrCodeScanned) {
|
||||
viewModelScope.launch {
|
||||
val existingTransaction = session.cryptoService().verificationService()
|
||||
.getExistingTransaction(action.otherUserId, action.transactionId) as? QrCodeVerificationTransaction
|
||||
existingTransaction
|
||||
?.userHasScannedOtherQrCode(action.scannedData)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleRequestVerificationByDM(roomId: String?, otherUserId: String) {
|
||||
viewModelScope.launch {
|
||||
if (roomId == null) {
|
||||
|
@ -449,11 +480,8 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun transactionCreated(tx: VerificationTransaction) {
|
||||
transactionUpdated(tx)
|
||||
}
|
||||
|
||||
override fun transactionUpdated(tx: VerificationTransaction) = withState { state ->
|
||||
private fun handleTransactionUpdate(state: VerificationBottomSheetViewState, tx: VerificationTransaction){
|
||||
viewModelScope.launch {
|
||||
if (state.selfVerificationMode && state.transactionId == null) {
|
||||
// is this an incoming with that user
|
||||
if (tx.isIncoming && tx.otherUserId == state.otherUserMxItem?.id) {
|
||||
|
@ -504,6 +532,15 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun transactionCreated(tx: VerificationTransaction) {
|
||||
transactionUpdated(tx)
|
||||
}
|
||||
|
||||
override fun transactionUpdated(tx: VerificationTransaction) = withState { state ->
|
||||
handleTransactionUpdate(state, tx)
|
||||
}
|
||||
|
||||
override fun verificationRequestCreated(pr: PendingVerificationRequest) {
|
||||
verificationRequestUpdated(pr)
|
||||
|
|
|
@ -196,9 +196,10 @@ class DefaultNavigator @Inject constructor(
|
|||
}
|
||||
|
||||
override fun performDeviceVerification(context: Context, otherUserId: String, sasTransactionId: String) {
|
||||
val session = sessionHolder.getSafeActiveSession() ?: return
|
||||
coroutineScope.launch {
|
||||
val session = sessionHolder.getSafeActiveSession() ?: return@launch
|
||||
val tx = session.cryptoService().verificationService().getExistingTransaction(otherUserId, sasTransactionId)
|
||||
?: return
|
||||
?: return@launch
|
||||
if (tx is SasVerificationTransaction && tx.isIncoming) {
|
||||
tx.acceptVerification()
|
||||
}
|
||||
|
@ -211,6 +212,7 @@ class DefaultNavigator @Inject constructor(
|
|||
).show(context.supportFragmentManager, "REQPOP")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun requestSessionVerification(context: Context, otherSessionId: String) {
|
||||
coroutineScope.launch {
|
||||
|
|
Loading…
Reference in a new issue