crypto: Add docs to the VerificationRequest class

This commit is contained in:
Damir Jelić 2021-07-21 12:11:11 +02:00
parent b500364322
commit 93615ddba9
1 changed files with 100 additions and 5 deletions

View File

@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.crypto
import android.os.Handler
import android.os.Looper
import com.sun.jna.Native.toByteArray
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.matrix.android.sdk.api.session.crypto.verification.CancelCode
@ -30,10 +29,6 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationServic
import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf
import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding
import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN
import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW
import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE
import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS
import org.matrix.android.sdk.internal.crypto.model.rest.toValue
import org.matrix.android.sdk.internal.crypto.verification.prepareMethods
import timber.log.Timber
import uniffi.olm.OlmMachine
@ -59,37 +54,74 @@ internal class VerificationRequest(
}
}
/** Get the flow ID of this verification request
*
* This is either the transaction ID if the verification is happening
* over to-device events, or the event ID of the m.key.verification.request
* event that initiated the flow.
*/
internal fun flowId(): String {
return this.inner.flowId
}
/** The user ID of the other user that is participating in this verification flow */
internal fun otherUser(): String {
return this.inner.otherUserId
}
/** The device ID of the other user's device that is participating in this verification flow
*
* This will we null if we're initiating the request and the other side
* didn't yet accept the verification flow.
* */
internal fun otherDeviceId(): String? {
refreshData()
return this.inner.otherDeviceId
}
/** Did we initiate this verification flow */
internal fun weStarted(): Boolean {
return this.inner.weStarted
}
/** Get the id of the room where this verification is happening
*
* Will be null if the verification is not happening inside a room.
*/
internal fun roomId(): String? {
return this.inner.roomId
}
/** Did the non-initiating side respond with a m.key.verification.read event
*
* Once the verification request is ready, we're able to transition into a
* concrete verification flow, i.e. we can show/scan a QR code or start emoji
* verification.
*/
internal fun isReady(): Boolean {
refreshData()
return this.inner.isReady
}
/** Did we advertise that we're able to scan QR codes */
internal fun canScanQrCodes(): Boolean {
refreshData()
return this.inner.ourMethods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN) ?: false
}
/** Accept the verification request advertising the given methods as supported
*
* This will send out a m.key.verification.ready event advertising support for
* the given verification methods to the other side. After this method call, the
* verification request will be considered to be ready and will be able to transition
* into concrete verification flows.
*
* The method turns into a noop, if the verification flow has already been accepted
* and is in the ready state, which can be checked with the isRead() method.
*
* @param methods The list of VerificationMethod that we wish to advertise to the other
* side as supported.
*/
suspend fun acceptWithMethods(methods: List<VerificationMethod>) {
val stringMethods = prepareMethods(methods)
@ -105,6 +137,19 @@ internal class VerificationRequest(
}
}
/** Transition from a ready verification request into emoji verification
*
* This method will move the verification forward into emoji verification,
* it will send out a m.key.verification.start event with the method set to
* m.sas.v1.
*
* Note: This method will be a noop and return null if the verification request
* isn't considered to be ready, you can check if the request is ready using the
* isReady() method.
*
* @return A freshly created SasVerification object that represents the newly started
* emoji verification, or null if we can't yet transition into emoji verification.
*/
internal suspend fun startSasVerification(): SasVerification? {
return withContext(Dispatchers.IO) {
val result = machine.startSasVerification(inner.otherUserId, inner.flowId)
@ -118,6 +163,19 @@ internal class VerificationRequest(
}
}
/** Scan a QR code and transition into QR code verification
*
* This method will move the verification forward into QR code verification.
* It will send out a m.key.verification.start event with the method
* set to m.reciprocate.v1.
*
* Note: This method will be a noop and return null if the verification request
* isn't considered to be ready, you can check if the request is ready using the
* isReady() method.
*
* @return A freshly created QrCodeVerification object that represents the newly started
* QR code verification, or null if we can't yet transition into QR code verification.
*/
internal suspend fun scanQrCode(data: String): QrCodeVerification? {
// TODO again, what's the deal with ISO_8859_1?
val byteArray = data.toByteArray(Charsets.ISO_8859_1)
@ -128,6 +186,23 @@ internal class VerificationRequest(
return QrCodeVerification(this.machine, this, result.qr, this.sender, this.listeners)
}
/** Transition into a QR code verification to display a QR code
*
* This method will move the verification forward into QR code verification.
* It will not send out any event out, it should instead be used to display
* a QR code which then can be scanned out of bound by the other side.
*
* A m.key.verification.start event with the method set to m.reciprocate.v1
* incoming from the other side will only be accepted if this method is called
* and the QR code verification is successfully initiated.
*
* Note: This method will be a noop and return null if the verification request
* isn't considered to be ready, you can check if the request is ready using the
* isReady() method.
*
* @return A freshly created QrCodeVerification object that represents the newly started
* QR code verification, or null if we can't yet transition into QR code verification.
*/
internal fun startQrVerification(): QrCodeVerification? {
val qrcode = this.machine.startQrVerification(this.inner.otherUserId, this.inner.flowId)
@ -144,6 +219,16 @@ internal class VerificationRequest(
}
}
/** Cancel the verification flow
*
* This will send out a m.key.verification.cancel event with the cancel
* code set to m.user.
*
* Cancelling the verification request will also cancel any QrcodeVerification and
* SasVerification objects that are related to this verification request.
*
* The method turns into a noop, if the verification flow has already been cancelled.
*/
internal suspend fun cancel() {
val request = this.machine.cancelVerification(
this.inner.otherUserId,
@ -157,6 +242,7 @@ internal class VerificationRequest(
}
}
/** Fetch fresh data from the Rust side for our verification flow */
private fun refreshData() {
val request = this.machine.getVerificationRequest(this.inner.otherUserId, this.inner.flowId)
@ -165,6 +251,15 @@ internal class VerificationRequest(
}
}
/** Convert the VerificationRequest into a PendingVerificationRequest
*
* The public interface of the VerificationService dispatches the data class
* PendingVerificationRequest, this method allows us to easily transform this
* request into the data class. It fetches fresh info from the Rust side before
* it does the transform.
*
* @return The PendingVerificationRequest that matches data from this VerificationRequest.
*/
internal fun toPendingVerificationRequest(): PendingVerificationRequest {
refreshData()
val cancelInfo = this.inner.cancelInfo