mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-14 11:05:32 -04:00
refactor(bindings): Use new uniffi::Enum derive macro in crypto-ffi
This commit is contained in:
committed by
Jonas Platte
parent
01dc166293
commit
6b9075aa42
@@ -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)]
|
||||
|
||||
@@ -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.
|
||||
///
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user