QR code: handle the case where other user can scan QR codes
This commit is contained in:
parent
df49ab8362
commit
adc2d570eb
|
@ -55,11 +55,15 @@ import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationCancel
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationKey
|
import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationKey
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationMac
|
import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationMac
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationStart
|
import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationStart
|
||||||
|
import im.vector.matrix.android.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE
|
import im.vector.matrix.android.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.VERIFICATION_METHOD_SAS
|
import im.vector.matrix.android.internal.crypto.model.rest.VERIFICATION_METHOD_SAS
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.supportedVerificationMethods
|
import im.vector.matrix.android.internal.crypto.model.rest.supportedVerificationMethods
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.toValue
|
import im.vector.matrix.android.internal.crypto.model.rest.toValue
|
||||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||||
|
import im.vector.matrix.android.internal.crypto.verification.qrcode.QrCodeData
|
||||||
|
import im.vector.matrix.android.internal.crypto.verification.qrcode.generateSharedSecret
|
||||||
|
import im.vector.matrix.android.internal.crypto.verification.qrcode.toUrl
|
||||||
import im.vector.matrix.android.internal.session.SessionScope
|
import im.vector.matrix.android.internal.session.SessionScope
|
||||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
@ -72,6 +76,9 @@ import kotlin.collections.set
|
||||||
|
|
||||||
@SessionScope
|
@SessionScope
|
||||||
internal class DefaultVerificationService @Inject constructor(
|
internal class DefaultVerificationService @Inject constructor(
|
||||||
|
// TODO @UserId private val userId: String,
|
||||||
|
// TODO @DeviceId private val deviceId: String,
|
||||||
|
// TODO Do not use credential (do it in a dedicated commit)
|
||||||
private val credentials: Credentials,
|
private val credentials: Credentials,
|
||||||
private val cryptoStore: IMXCryptoStore,
|
private val cryptoStore: IMXCryptoStore,
|
||||||
private val myDeviceInfoHolder: Lazy<MyDeviceInfoHolder>,
|
private val myDeviceInfoHolder: Lazy<MyDeviceInfoHolder>,
|
||||||
|
@ -650,7 +657,63 @@ internal class DefaultVerificationService @Inject constructor(
|
||||||
Timber.e("## SAS Received Ready for unknown request txId:${readyReq.transactionID} fromDevice ${readyReq.fromDevice}")
|
Timber.e("## SAS Received Ready for unknown request txId:${readyReq.transactionID} fromDevice ${readyReq.fromDevice}")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
updatePendingRequest(existingRequest.copy(readyInfo = readyReq))
|
|
||||||
|
var myGeneratedSharedSecret: String? = null
|
||||||
|
val qrCodeText = readyReq.methods
|
||||||
|
// Check if other user is able to scan QR code
|
||||||
|
?.takeIf { it.contains(VERIFICATION_METHOD_QR_CODE_SCAN) }
|
||||||
|
?.let {
|
||||||
|
// Build the QR code URL
|
||||||
|
val requestEventId = existingRequest.transactionId ?: run {
|
||||||
|
Timber.w("Unknown requestEventId")
|
||||||
|
return@let null
|
||||||
|
}
|
||||||
|
|
||||||
|
val myMasterKey = crossSigningService.getMyCrossSigningKeys()
|
||||||
|
?.masterKey()
|
||||||
|
?.unpaddedBase64PublicKey
|
||||||
|
?: run {
|
||||||
|
Timber.w("Unable to get my master key")
|
||||||
|
return@let null
|
||||||
|
}
|
||||||
|
|
||||||
|
val otherUserMasterKey = crossSigningService.getUserCrossSigningKeys(existingRequest.otherUserId)
|
||||||
|
?.masterKey()
|
||||||
|
?.unpaddedBase64PublicKey
|
||||||
|
?: run {
|
||||||
|
Timber.w("Unable to get other user master key")
|
||||||
|
return@let null
|
||||||
|
}
|
||||||
|
|
||||||
|
val myDeviceId = credentials.deviceId
|
||||||
|
?: run {
|
||||||
|
Timber.w("Unable to get my deviceId")
|
||||||
|
return@let null
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO I'm pretty sure it's the correct key to put here
|
||||||
|
val myDeviceKey = myDeviceInfoHolder.get().myDevice.fingerprint()!!
|
||||||
|
|
||||||
|
val generatedSharedSecret = generateSharedSecret()
|
||||||
|
.also { myGeneratedSharedSecret = it }
|
||||||
|
QrCodeData(
|
||||||
|
userId = credentials.userId,
|
||||||
|
requestEventId = requestEventId,
|
||||||
|
action = QrCodeData.ACTION_VERIFY,
|
||||||
|
keys = hashMapOf(
|
||||||
|
myMasterKey to myMasterKey,
|
||||||
|
myDeviceId to myDeviceKey
|
||||||
|
),
|
||||||
|
sharedSecret = generatedSharedSecret,
|
||||||
|
otherUserKey = otherUserMasterKey
|
||||||
|
).toUrl()
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePendingRequest(existingRequest.copy(
|
||||||
|
readyInfo = readyReq,
|
||||||
|
myGeneratedSecret = myGeneratedSharedSecret,
|
||||||
|
qrCodeText = qrCodeText
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleDoneReceived(senderId: String, doneInfo: VerificationInfo) {
|
private fun handleDoneReceived(senderId: String, doneInfo: VerificationInfo) {
|
||||||
|
|
|
@ -37,7 +37,9 @@ data class PendingVerificationRequest(
|
||||||
val readyInfo: VerificationInfoReady? = null,
|
val readyInfo: VerificationInfoReady? = null,
|
||||||
val cancelConclusion: CancelCode? = null,
|
val cancelConclusion: CancelCode? = null,
|
||||||
val isSuccessful: Boolean = false,
|
val isSuccessful: Boolean = false,
|
||||||
val handledByOtherSession: Boolean = false
|
val handledByOtherSession: Boolean = false,
|
||||||
|
val myGeneratedSecret: String? = null,
|
||||||
|
val qrCodeText: String? = null
|
||||||
|
|
||||||
) {
|
) {
|
||||||
val isReady: Boolean = readyInfo != null
|
val isReady: Boolean = readyInfo != null
|
||||||
|
|
|
@ -49,10 +49,10 @@ class VerificationChooseMethodController @Inject constructor(
|
||||||
notice(stringProvider.getString(R.string.verification_scan_notice))
|
notice(stringProvider.getString(R.string.verification_scan_notice))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.otherCanScanQrCode && !state.QRtext.isNullOrBlank()) {
|
if (state.otherCanScanQrCode && !state.qrCodeText.isNullOrBlank()) {
|
||||||
bottomSheetVerificationQrCodeItem {
|
bottomSheetVerificationQrCodeItem {
|
||||||
id("qr")
|
id("qr")
|
||||||
data(state.QRtext)
|
data(state.qrCodeText)
|
||||||
animate(false)
|
animate(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ data class VerificationChooseMethodViewState(
|
||||||
val transactionId: String = "",
|
val transactionId: String = "",
|
||||||
val otherCanShowQrCode: Boolean = false,
|
val otherCanShowQrCode: Boolean = false,
|
||||||
val otherCanScanQrCode: Boolean = false,
|
val otherCanScanQrCode: Boolean = false,
|
||||||
val QRtext: String? = null,
|
val qrCodeText: String? = null,
|
||||||
val SASModeAvailable: Boolean = false
|
val SASModeAvailable: Boolean = false
|
||||||
) : MvRxState
|
) : MvRxState
|
||||||
|
|
||||||
|
@ -57,8 +57,7 @@ class VerificationChooseMethodViewModel @AssistedInject constructor(
|
||||||
copy(
|
copy(
|
||||||
otherCanShowQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SHOW) ?: false,
|
otherCanShowQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SHOW) ?: false,
|
||||||
otherCanScanQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SCAN) ?: false,
|
otherCanScanQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SCAN) ?: false,
|
||||||
// TODO
|
qrCodeText = pvr?.qrCodeText,
|
||||||
QRtext = "https://www.example.org",
|
|
||||||
SASModeAvailable = pvr?.hasMethod(VerificationMethod.SAS) ?: false
|
SASModeAvailable = pvr?.hasMethod(VerificationMethod.SAS) ?: false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -93,8 +92,7 @@ class VerificationChooseMethodViewModel @AssistedInject constructor(
|
||||||
transactionId = args.verificationId ?: "",
|
transactionId = args.verificationId ?: "",
|
||||||
otherCanShowQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SHOW) ?: false,
|
otherCanShowQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SHOW) ?: false,
|
||||||
otherCanScanQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SCAN) ?: false,
|
otherCanScanQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SCAN) ?: false,
|
||||||
// TODO
|
qrCodeText = pvr?.qrCodeText,
|
||||||
QRtext = "https://www.example.org",
|
|
||||||
SASModeAvailable = pvr?.hasMethod(VerificationMethod.SAS) ?: false
|
SASModeAvailable = pvr?.hasMethod(VerificationMethod.SAS) ?: false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue