From 6b9075aa42dbd30253468a6c41c84cce2a67d06c Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Sat, 15 Oct 2022 00:49:33 +0200 Subject: [PATCH] refactor(bindings): Use new uniffi::Enum derive macro in crypto-ffi --- bindings/matrix-sdk-crypto-ffi/src/lib.rs | 7 +- bindings/matrix-sdk-crypto-ffi/src/machine.rs | 287 +++++++++--------- bindings/matrix-sdk-crypto-ffi/src/olm.udl | 25 -- .../matrix-sdk-crypto-ffi/src/responses.rs | 1 + .../matrix-sdk-crypto-ffi/src/verification.rs | 5 + 5 files changed, 158 insertions(+), 167 deletions(-) diff --git a/bindings/matrix-sdk-crypto-ffi/src/lib.rs b/bindings/matrix-sdk-crypto-ffi/src/lib.rs index e35c26ae0..caa7c4ddc 100644 --- a/bindings/matrix-sdk-crypto-ffi/src/lib.rs +++ b/bindings/matrix-sdk-crypto-ffi/src/lib.rs @@ -474,7 +474,12 @@ fn parse_user_id(user_id: &str) -> Result { } 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)] diff --git a/bindings/matrix-sdk-crypto-ffi/src/machine.rs b/bindings/matrix-sdk-crypto-ffi/src/machine.rs index bd662a831..7418a571a 100644 --- a/bindings/matrix-sdk-crypto-ffi/src/machine.rs +++ b/bindings/matrix-sdk-crypto-ffi/src/machine.rs @@ -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, + ) -> Option { + 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 { + 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 { + 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 { + 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 { + 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, - ) -> Option { - 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 { - 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 { - 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 { - 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 { - 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. /// diff --git a/bindings/matrix-sdk-crypto-ffi/src/olm.udl b/bindings/matrix-sdk-crypto-ffi/src/olm.udl index 8432e36de..9092fc256 100644 --- a/bindings/matrix-sdk-crypto-ffi/src/olm.udl +++ b/bindings/matrix-sdk-crypto-ffi/src/olm.udl @@ -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 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 methods ); - OutgoingVerificationRequest? accept_verification_request( - [ByRef] string user_id, - [ByRef] string flow_id, - sequence 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? get_emoji_index([ByRef] string user_id, [ByRef] string flow_id); sequence? 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] diff --git a/bindings/matrix-sdk-crypto-ffi/src/responses.rs b/bindings/matrix-sdk-crypto-ffi/src/responses.rs index feb6b89c9..476ef9f70 100644 --- a/bindings/matrix-sdk-crypto-ffi/src/responses.rs +++ b/bindings/matrix-sdk-crypto-ffi/src/responses.rs @@ -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 }, diff --git a/bindings/matrix-sdk-crypto-ffi/src/verification.rs b/bindings/matrix-sdk-crypto-ffi/src/verification.rs index ad4ce52c6..662d99246 100644 --- a/bindings/matrix-sdk-crypto-ffi/src/verification.rs +++ b/bindings/matrix-sdk-crypto-ffi/src/verification.rs @@ -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 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,