refactor(bindings): Use new uniffi::Enum derive macro in crypto-ffi

This commit is contained in:
Jonas Platte
2022-10-15 00:49:33 +02:00
committed by Jonas Platte
parent 01dc166293
commit 6b9075aa42
5 changed files with 158 additions and 167 deletions

View File

@@ -474,7 +474,12 @@ fn parse_user_id(user_id: &str) -> Result<OwnedUserId, CryptoStoreError> {
}
mod uniffi_types {
pub use crate::{backup_recovery_key::BackupRecoveryKey, machine::OlmMachine};
pub use crate::{
backup_recovery_key::BackupRecoveryKey,
machine::OlmMachine,
responses::OutgoingVerificationRequest,
verification::{CancelInfo, QrCode, Sas, ScanResult, Verification},
};
}
#[cfg(test)]

View File

@@ -87,6 +87,152 @@ impl OlmMachine {
HashMap::from([("ed25519".to_owned(), ed25519_key), ("curve25519".to_owned(), curve_key)])
}
/// Accept a verification requests that we share with the given user with
/// the given flow id.
///
/// This will move the verification request into the ready state.
///
/// # Arguments
///
/// * `user_id` - The ID of the user for which we would like to accept the
/// verification requests.
///
/// * `flow_id` - The ID that uniquely identifies the verification flow.
///
/// * `methods` - A list of verification methods that we want to advertise
/// as supported.
pub fn accept_verification_request(
&self,
user_id: String,
flow_id: String,
methods: Vec<String>,
) -> Option<OutgoingVerificationRequest> {
let user_id = UserId::parse(user_id).ok()?;
let methods = methods.into_iter().map(VerificationMethod::from).collect();
if let Some(verification) = self.inner.get_verification_request(&user_id, &flow_id) {
verification.accept_with_methods(methods).map(|r| r.into())
} else {
None
}
}
/// Get a verification flow object for the given user with the given flow
/// id.
///
/// # Arguments
///
/// * `user_id` - The ID of the user for which we would like to fetch the
/// verification.
///
/// * `flow_id` - The ID that uniquely identifies the verification flow.
pub fn get_verification(&self, user_id: String, flow_id: String) -> Option<Verification> {
let user_id = UserId::parse(user_id).ok()?;
self.inner.get_verification(&user_id, &flow_id).map(|v| match v {
RustVerification::SasV1(s) => Verification::SasV1 { sas: s.into() },
RustVerification::QrV1(qr) => Verification::QrCodeV1 { qrcode: qr.into() },
_ => unreachable!(),
})
}
/// Cancel a verification for the given user with the given flow id using
/// the given cancel code.
///
/// # Arguments
///
/// * `user_id` - The ID of the user for which we would like to cancel the
/// verification.
///
/// * `flow_id` - The ID that uniquely identifies the verification flow.
///
/// * `cancel_code` - The error code for why the verification was cancelled,
/// manual cancellatio usually happens with `m.user` cancel code. The full
/// list of cancel codes can be found in the [spec]
///
/// [spec]: https://spec.matrix.org/unstable/client-server-api/#mkeyverificationcancel
pub fn cancel_verification(
&self,
user_id: String,
flow_id: String,
cancel_code: String,
) -> Option<OutgoingVerificationRequest> {
let user_id = UserId::parse(user_id).ok()?;
if let Some(request) = self.inner.get_verification_request(&user_id, &flow_id) {
request.cancel().map(|r| r.into())
} else if let Some(verification) = self.inner.get_verification(&user_id, &flow_id) {
match verification {
RustVerification::SasV1(v) => {
v.cancel_with_code(cancel_code.into()).map(|r| r.into())
}
RustVerification::QrV1(v) => {
v.cancel_with_code(cancel_code.into()).map(|r| r.into())
}
_ => unreachable!(),
}
} else {
None
}
}
/// Pass data from a scanned QR code to an active verification request and
/// transition into QR code verification.
///
/// This requires an active `VerificationRequest` to succeed, returns `None`
/// if no `VerificationRequest` is found or if the QR code data is invalid.
///
/// # Arguments
///
/// * `user_id` - The ID of the user for which we would like to start the
/// QR code verification.
///
/// * `flow_id` - The ID of the verification request that initiated the
/// verification flow.
///
/// * `data` - The data that was extracted from the scanned QR code as an
/// base64 encoded string, without padding.
pub fn scan_qr_code(
&self,
user_id: String,
flow_id: String,
data: String,
) -> Option<ScanResult> {
let user_id = UserId::parse(user_id).ok()?;
let data = decode_config(data, STANDARD_NO_PAD).ok()?;
let data = QrVerificationData::from_bytes(data).ok()?;
if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) {
if let Some(qr) = self.runtime.block_on(verification.scan_qr_code(data)).ok()? {
let request = qr.reciprocate()?;
Some(ScanResult { qr: qr.into(), request: request.into() })
} else {
None
}
} else {
None
}
}
/// Accept that we're going forward with the short auth string verification.
///
/// # Arguments
///
/// * `user_id` - The ID of the user for which we would like to accept the
/// SAS verification.
///
/// * `flow_id` - The ID that uniquely identifies the verification flow.
pub fn accept_sas_verification(
&self,
user_id: String,
flow_id: String,
) -> Option<OutgoingVerificationRequest> {
let user_id = UserId::parse(user_id).ok()?;
self.inner.get_verification(&user_id, &flow_id)?.sas_v1()?.accept().map(|r| r.into())
}
}
impl OlmMachine {
@@ -822,36 +968,6 @@ impl OlmMachine {
self.inner.get_verification_request(&user_id, flow_id).map(|v| v.into())
}
/// Accept a verification requests that we share with the given user with
/// the given flow id.
///
/// This will move the verification request into the ready state.
///
/// # Arguments
///
/// * `user_id` - The ID of the user for which we would like to accept the
/// verification requests.
///
/// * `flow_id` - The ID that uniquely identifies the verification flow.
///
/// * `methods` - A list of verification methods that we want to advertise
/// as supported.
pub fn accept_verification_request(
&self,
user_id: &str,
flow_id: &str,
methods: Vec<String>,
) -> Option<OutgoingVerificationRequest> {
let user_id = UserId::parse(user_id).ok()?;
let methods = methods.into_iter().map(VerificationMethod::from).collect();
if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) {
verification.accept_with_methods(methods).map(|r| r.into())
} else {
None
}
}
/// Get an m.key.verification.request content for the given user.
///
/// # Arguments
@@ -994,65 +1110,6 @@ impl OlmMachine {
})
}
/// Get a verification flow object for the given user with the given flow
/// id.
///
/// # Arguments
///
/// * `user_id` - The ID of the user for which we would like to fetch the
/// verification.
///
/// * `flow_id` - The ID that uniquely identifies the verification flow.
pub fn get_verification(&self, user_id: &str, flow_id: &str) -> Option<Verification> {
let user_id = UserId::parse(user_id).ok()?;
self.inner.get_verification(&user_id, flow_id).map(|v| match v {
RustVerification::SasV1(s) => Verification::SasV1 { sas: s.into() },
RustVerification::QrV1(qr) => Verification::QrCodeV1 { qrcode: qr.into() },
_ => unreachable!(),
})
}
/// Cancel a verification for the given user with the given flow id using
/// the given cancel code.
///
/// # Arguments
///
/// * `user_id` - The ID of the user for which we would like to cancel the
/// verification.
///
/// * `flow_id` - The ID that uniquely identifies the verification flow.
///
/// * `cancel_code` - The error code for why the verification was cancelled,
/// manual cancellatio usually happens with `m.user` cancel code. The full
/// list of cancel codes can be found in the [spec]
///
/// [spec]: https://spec.matrix.org/unstable/client-server-api/#mkeyverificationcancel
pub fn cancel_verification(
&self,
user_id: &str,
flow_id: &str,
cancel_code: &str,
) -> Option<OutgoingVerificationRequest> {
let user_id = UserId::parse(user_id).ok()?;
if let Some(request) = self.inner.get_verification_request(&user_id, flow_id) {
request.cancel().map(|r| r.into())
} else if let Some(verification) = self.inner.get_verification(&user_id, flow_id) {
match verification {
RustVerification::SasV1(v) => {
v.cancel_with_code(cancel_code.into()).map(|r| r.into())
}
RustVerification::QrV1(v) => {
v.cancel_with_code(cancel_code.into()).map(|r| r.into())
}
_ => unreachable!(),
}
} else {
None
}
}
/// Confirm a verification was successful.
///
/// This method should be called either if a short auth string should be
@@ -1145,40 +1202,6 @@ impl OlmMachine {
.and_then(|v| v.qr_v1().and_then(|qr| qr.to_bytes().map(encode).ok()))
}
/// Pass data from a scanned QR code to an active verification request and
/// transition into QR code verification.
///
/// This requires an active `VerificationRequest` to succeed, returns `None`
/// if no `VerificationRequest` is found or if the QR code data is invalid.
///
/// # Arguments
///
/// * `user_id` - The ID of the user for which we would like to start the
/// QR code verification.
///
/// * `flow_id` - The ID of the verification request that initiated the
/// verification flow.
///
/// * `data` - The data that was extracted from the scanned QR code as an
/// base64 encoded string, without padding.
pub fn scan_qr_code(&self, user_id: &str, flow_id: &str, data: &str) -> Option<ScanResult> {
let user_id = UserId::parse(user_id).ok()?;
let data = decode_config(data, STANDARD_NO_PAD).ok()?;
let data = QrVerificationData::from_bytes(data).ok()?;
if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) {
if let Some(qr) = self.runtime.block_on(verification.scan_qr_code(data)).ok()? {
let request = qr.reciprocate()?;
Some(ScanResult { qr: qr.into(), request: request.into() })
} else {
None
}
} else {
None
}
}
/// Transition from a verification request into short auth string based
/// verification.
///
@@ -1239,24 +1262,6 @@ impl OlmMachine {
)
}
/// Accept that we're going forward with the short auth string verification.
///
/// # Arguments
///
/// * `user_id` - The ID of the user for which we would like to accept the
/// SAS verification.
///
/// * `flow_id` - The ID that uniquely identifies the verification flow.
pub fn accept_sas_verification(
&self,
user_id: &str,
flow_id: &str,
) -> Option<OutgoingVerificationRequest> {
let user_id = UserId::parse(user_id).ok()?;
self.inner.get_verification(&user_id, flow_id)?.sas_v1()?.accept().map(|r| r.into())
}
/// Get a list of emoji indices of the emoji representation of the short
/// auth string.
///

View File

@@ -160,11 +160,6 @@ dictionary Sas {
CancelInfo? cancel_info;
};
dictionary ScanResult {
QrCode qr;
OutgoingVerificationRequest request;
};
dictionary QrCode {
string other_user_id;
string other_device_id;
@@ -205,12 +200,6 @@ dictionary ConfirmVerificationResult {
SignatureUploadRequest? signature_request;
};
[Enum]
interface Verification {
SasV1(Sas sas);
QrCodeV1(QrCode qrcode);
};
dictionary KeyRequestPair {
Request? cancellation;
Request key_request;
@@ -307,7 +296,6 @@ interface OlmMachine {
void receive_unencrypted_verification_event([ByRef] string event, [ByRef] string room_id);
sequence<VerificationRequest> get_verification_requests([ByRef] string user_id);
VerificationRequest? get_verification_request([ByRef] string user_id, [ByRef] string flow_id);
Verification? get_verification([ByRef] string user_id, [ByRef] string flow_id);
[Throws=CryptoStoreError]
VerificationRequest? request_verification(
@@ -330,31 +318,18 @@ interface OlmMachine {
sequence<string> methods
);
OutgoingVerificationRequest? accept_verification_request(
[ByRef] string user_id,
[ByRef] string flow_id,
sequence<string> methods
);
[Throws=CryptoStoreError]
ConfirmVerificationResult? confirm_verification([ByRef] string user_id, [ByRef] string flow_id);
OutgoingVerificationRequest? cancel_verification(
[ByRef] string user_id,
[ByRef] string flow_id,
[ByRef] string cancel_code
);
[Throws=CryptoStoreError]
StartSasResult? start_sas_with_device([ByRef] string user_id, [ByRef] string device_id);
[Throws=CryptoStoreError]
StartSasResult? start_sas_verification([ByRef] string user_id, [ByRef] string flow_id);
OutgoingVerificationRequest? accept_sas_verification([ByRef] string user_id, [ByRef] string flow_id);
sequence<i32>? get_emoji_index([ByRef] string user_id, [ByRef] string flow_id);
sequence<i32>? get_decimals([ByRef] string user_id, [ByRef] string flow_id);
[Throws=CryptoStoreError]
QrCode? start_qr_verification([ByRef] string user_id, [ByRef] string flow_id);
ScanResult? scan_qr_code([ByRef] string user_id, [ByRef] string flow_id, [ByRef] string data);
string? generate_qr_code([ByRef] string user_id, [ByRef] string flow_id);
[Throws=DecryptionError]

View File

@@ -82,6 +82,7 @@ impl From<(RustUploadSigningKeysRequest, RustSignatureUploadRequest)>
}
}
#[derive(uniffi::Enum)]
pub enum OutgoingVerificationRequest {
ToDevice { request_id: String, event_type: String, body: String },
InRoom { request_id: String, room_id: String, event_type: String, content: String },

View File

@@ -6,6 +6,7 @@ use matrix_sdk_crypto::{
use crate::{OutgoingVerificationRequest, SignatureUploadRequest};
/// Enum representing the different verification flows we support.
#[derive(uniffi::Enum)]
pub enum Verification {
/// The `m.sas.v1` verification flow.
SasV1 {
@@ -21,6 +22,7 @@ pub enum Verification {
}
/// The `m.sas.v1` verification flow.
#[derive(uniffi::Record)]
pub struct Sas {
/// The other user that is participating in the verification flow
pub other_user_id: String,
@@ -53,6 +55,7 @@ pub struct Sas {
/// The `m.qr_code.scan.v1`, `m.qr_code.show.v1`, and `m.reciprocate.v1`
/// verification flow.
#[derive(uniffi::Record)]
pub struct QrCode {
/// The other user that is participating in the verification flow
pub other_user_id: String,
@@ -100,6 +103,7 @@ impl From<InnerQr> for QrCode {
}
/// Information on why a verification flow has been cancelled and by whom.
#[derive(uniffi::Record)]
pub struct CancelInfo {
/// The textual representation of the cancel reason
pub reason: String,
@@ -129,6 +133,7 @@ pub struct StartSasResult {
}
/// A result type for scanning QR codes.
#[derive(uniffi::Record)]
pub struct ScanResult {
/// The QR code verification object that got created.
pub qr: QrCode,