diff --git a/matrix_sdk/Cargo.toml b/matrix_sdk/Cargo.toml index d5338da9..3cb79b13 100644 --- a/matrix_sdk/Cargo.toml +++ b/matrix_sdk/Cargo.toml @@ -15,9 +15,10 @@ features = ["docs"] rustdoc-args = ["--cfg", "feature=\"docs\""] [features] -default = ["encryption", "sled_cryptostore", "sled_state_store", "require_auth_for_profile_requests", "native-tls"] +default = ["encryption", "qrcode", "sled_cryptostore", "sled_state_store", "require_auth_for_profile_requests", "native-tls"] encryption = ["matrix-sdk-base/encryption"] +qrcode = ["encryption", "matrix-sdk-base/qrcode"] sled_state_store = ["matrix-sdk-base/sled_state_store"] sled_cryptostore = ["matrix-sdk-base/sled_cryptostore"] markdown = ["ruma/markdown"] diff --git a/matrix_sdk/README.md b/matrix_sdk/README.md index 6fa378ec..80898baf 100644 --- a/matrix_sdk/README.md +++ b/matrix_sdk/README.md @@ -45,6 +45,8 @@ More examples can be found in the [examples] directory. The following crate feature flags are available: * `encryption`: Enables end-to-end encryption support in the library. +* `qrcode`: Enables qrcode verification support in the library. This will also + enable `encryption`. Enabled by default. * `sled_cryptostore`: Enables a Sled based store for the encryption keys. If this is disabled and `encryption` support is enabled the keys will by default be stored only in memory and thus lost after the client is diff --git a/matrix_sdk/src/client.rs b/matrix_sdk/src/client.rs index 4734ed51..c9addca4 100644 --- a/matrix_sdk/src/client.rs +++ b/matrix_sdk/src/client.rs @@ -138,11 +138,13 @@ use ruma::{ DeviceIdBox, RoomId, RoomIdOrAliasId, ServerName, UInt, UserId, }; +#[cfg(all(feature = "qrcode", feature = "encryption"))] +use crate::verification::QrVerification; #[cfg(feature = "encryption")] use crate::{ error::RoomKeyImportError, identities::{Device, UserDevices}, - verification::{QrVerification, SasVerification, Verification, VerificationRequest}, + verification::{SasVerification, Verification, VerificationRequest}, }; use crate::{ error::{HttpError, HttpResult}, @@ -2561,6 +2563,7 @@ impl Client { matrix_sdk_base::crypto::Verification::SasV1(s) => { SasVerification { inner: s, client: self.clone() }.into() } + #[cfg(feature = "qrcode")] matrix_sdk_base::crypto::Verification::QrV1(qr) => { QrVerification { inner: qr, client: self.clone() }.into() } diff --git a/matrix_sdk/src/identities/devices.rs b/matrix_sdk/src/identities/devices.rs index fb89ee56..1580d5e8 100644 --- a/matrix_sdk/src/identities/devices.rs +++ b/matrix_sdk/src/identities/devices.rs @@ -55,7 +55,8 @@ impl Device { /// The default methods that are supported are `m.sas.v1` and /// `m.qr_code.show.v1`, if this isn't desirable the /// [`request_verification_with_methods()`] method can be used to override - /// this. + /// this. `m.qr_code.show.v1` is only avaliable if the `qrcode` feature is + /// enabled, which it is by default. /// /// # Examples /// diff --git a/matrix_sdk/src/identities/users.rs b/matrix_sdk/src/identities/users.rs index 5cf55332..871eee73 100644 --- a/matrix_sdk/src/identities/users.rs +++ b/matrix_sdk/src/identities/users.rs @@ -82,7 +82,8 @@ impl UserIdentity { /// The default methods that are supported are `m.sas.v1` and /// `m.qr_code.show.v1`, if this isn't desirable the /// [`request_verification_with_methods()`] method can be used to override - /// this. + /// this. `m.qr_code.show.v1` is only avaliable if the `qrcode` feature is + /// enabled, which it is by default. /// /// # Examples /// diff --git a/matrix_sdk/src/verification/mod.rs b/matrix_sdk/src/verification/mod.rs index 247088fc..258d0cfb 100644 --- a/matrix_sdk/src/verification/mod.rs +++ b/matrix_sdk/src/verification/mod.rs @@ -30,11 +30,14 @@ //! string. //! * [`QrVerification`] - Interactive verification using QR codes. +#[cfg(feature = "qrcode")] mod qrcode; mod requests; mod sas; pub use matrix_sdk_base::crypto::{AcceptSettings, CancelInfo}; +#[cfg(feature = "qrcode")] +#[cfg_attr(feature = "docs", doc(cfg(qrcode)))] pub use qrcode::QrVerification; pub use requests::VerificationRequest; pub use sas::SasVerification; @@ -44,6 +47,8 @@ pub use sas::SasVerification; pub enum Verification { /// The `m.sas.v1` verification variant. SasV1(SasVerification), + #[cfg(feature = "qrcode")] + #[cfg_attr(feature = "docs", doc(cfg(qrcode)))] /// The `m.qr_code.*.v1` verification variant. QrV1(QrVerification), } @@ -51,6 +56,7 @@ pub enum Verification { impl Verification { /// Try to deconstruct this verification enum into a SAS verification. pub fn sas(self) -> Option { + #[allow(irrefutable_let_patterns)] if let Verification::SasV1(sas) = self { Some(sas) } else { @@ -58,6 +64,7 @@ impl Verification { } } + #[cfg(feature = "qrcode")] /// Try to deconstruct this verification enum into a QR code verification. pub fn qr(self) -> Option { if let Verification::QrV1(qr) = self { @@ -71,6 +78,7 @@ impl Verification { pub fn is_done(&self) -> bool { match self { Verification::SasV1(s) => s.is_done(), + #[cfg(feature = "qrcode")] Verification::QrV1(qr) => qr.is_done(), } } @@ -79,6 +87,7 @@ impl Verification { pub fn is_cancelled(&self) -> bool { match self { Verification::SasV1(s) => s.is_cancelled(), + #[cfg(feature = "qrcode")] Verification::QrV1(qr) => qr.is_cancelled(), } } @@ -88,6 +97,7 @@ impl Verification { pub fn cancel_info(&self) -> Option { match self { Verification::SasV1(s) => s.cancel_info(), + #[cfg(feature = "qrcode")] Verification::QrV1(q) => q.cancel_info(), } } @@ -96,6 +106,7 @@ impl Verification { pub fn own_user_id(&self) -> &ruma::UserId { match self { Verification::SasV1(v) => v.own_user_id(), + #[cfg(feature = "qrcode")] Verification::QrV1(v) => v.own_user_id(), } } @@ -105,6 +116,7 @@ impl Verification { pub fn other_user_id(&self) -> &ruma::UserId { match self { Verification::SasV1(v) => v.inner.other_user_id(), + #[cfg(feature = "qrcode")] Verification::QrV1(v) => v.inner.other_user_id(), } } @@ -113,6 +125,7 @@ impl Verification { pub fn is_self_verification(&self) -> bool { match self { Verification::SasV1(v) => v.is_self_verification(), + #[cfg(feature = "qrcode")] Verification::QrV1(v) => v.is_self_verification(), } } @@ -121,6 +134,7 @@ impl Verification { pub fn we_started(&self) -> bool { match self { Verification::SasV1(s) => s.we_started(), + #[cfg(feature = "qrcode")] Verification::QrV1(q) => q.we_started(), } } @@ -132,6 +146,7 @@ impl From for Verification { } } +#[cfg(feature = "qrcode")] impl From for Verification { fn from(qr: QrVerification) -> Self { Self::QrV1(qr) diff --git a/matrix_sdk/src/verification/requests.rs b/matrix_sdk/src/verification/requests.rs index b7b39485..3f1b4894 100644 --- a/matrix_sdk/src/verification/requests.rs +++ b/matrix_sdk/src/verification/requests.rs @@ -15,7 +15,9 @@ use matrix_sdk_base::crypto::{CancelInfo, VerificationRequest as BaseVerificationRequest}; use ruma::events::key::verification::VerificationMethod; -use super::{QrVerification, SasVerification}; +#[cfg(feature = "qrcode")] +use super::QrVerification; +use super::SasVerification; use crate::{Client, Result}; /// An object controlling the interactive verification flow. @@ -83,8 +85,10 @@ impl VerificationRequest { /// Accept the verification request. /// - /// This method will accept the request and signal that it supports the - /// `m.sas.v1`, the `m.qr_code.show.v1`, and `m.reciprocate.v1` method. + /// This method will accept the request and signal by default that it + /// supports the `m.sas.v1`, the `m.qr_code.show.v1`, and `m.reciprocate.v1` + /// method. If the `qrcode` feature is disabled it will only signal that it + /// supports the `m.sas.v1` method. /// /// If QR code scanning should be supported or QR code showing shouldn't be /// supported the [`accept_with_methods()`] method should be used instead. @@ -113,6 +117,8 @@ impl VerificationRequest { } /// Generate a QR code + #[cfg(feature = "qrcode")] + #[cfg_attr(feature = "docs", doc(cfg(qrcode)))] pub async fn generate_qr_code(&self) -> Result> { Ok(self .inner diff --git a/matrix_sdk_base/Cargo.toml b/matrix_sdk_base/Cargo.toml index 8fe227b4..5c8066a5 100644 --- a/matrix_sdk_base/Cargo.toml +++ b/matrix_sdk_base/Cargo.toml @@ -17,6 +17,7 @@ rustdoc-args = ["--cfg", "feature=\"docs\""] [features] default = [] encryption = ["matrix-sdk-crypto"] +qrcode = ["matrix-sdk-crypto/qrcode"] sled_state_store = ["sled", "pbkdf2", "hmac", "sha2", "rand", "chacha20poly1305"] sled_cryptostore = ["matrix-sdk-crypto/sled_cryptostore"] diff --git a/matrix_sdk_crypto/Cargo.toml b/matrix_sdk_crypto/Cargo.toml index 5af87f7d..2ae7add5 100644 --- a/matrix_sdk_crypto/Cargo.toml +++ b/matrix_sdk_crypto/Cargo.toml @@ -16,11 +16,12 @@ rustdoc-args = ["--cfg", "feature=\"docs\""] [features] default = [] +qrcode = ["matrix-qrcode"] sled_cryptostore = ["sled"] docs = ["sled_cryptostore"] [dependencies] -matrix-qrcode = { version = "0.1.0", path = "../matrix_qrcode" } +matrix-qrcode = { version = "0.1.0", path = "../matrix_qrcode" , optional = true} matrix-sdk-common = { version = "0.4.0", path = "../matrix_sdk_common" } ruma = { version = "0.4.0", features = ["client-api-c", "unstable-pre-spec"] } diff --git a/matrix_sdk_crypto/src/lib.rs b/matrix_sdk_crypto/src/lib.rs index 8080cb22..cd283ee9 100644 --- a/matrix_sdk_crypto/src/lib.rs +++ b/matrix_sdk_crypto/src/lib.rs @@ -47,6 +47,8 @@ pub use identities::{ ReadOnlyUserIdentities, ReadOnlyUserIdentity, UserDevices, UserIdentities, UserIdentity, }; pub use machine::OlmMachine; +#[cfg(feature = "qrcode")] +#[cfg_attr(feature = "docs", doc(cfg(qrcode)))] pub use matrix_qrcode; pub(crate) use olm::ReadOnlyAccount; pub use olm::{CrossSigningStatus, EncryptionSettings}; @@ -55,6 +57,7 @@ pub use requests::{ OutgoingVerificationRequest, RoomMessageRequest, ToDeviceRequest, UploadSigningKeysRequest, }; pub use store::{CrossSigningKeyExport, CryptoStoreError, SecretImportError}; -pub use verification::{ - AcceptSettings, CancelInfo, QrVerification, Sas, Verification, VerificationRequest, -}; +#[cfg(feature = "qrcode")] +#[cfg_attr(feature = "docs", doc(cfg(qrcode)))] +pub use verification::QrVerification; +pub use verification::{AcceptSettings, CancelInfo, Sas, Verification, VerificationRequest}; diff --git a/matrix_sdk_crypto/src/verification/cache.rs b/matrix_sdk_crypto/src/verification/cache.rs index 24868817..ea9fb771 100644 --- a/matrix_sdk_crypto/src/verification/cache.rs +++ b/matrix_sdk_crypto/src/verification/cache.rs @@ -20,10 +20,9 @@ use ruma::{DeviceId, UserId}; use tracing::trace; use super::{event_enums::OutgoingContent, Sas, Verification}; -use crate::{ - OutgoingRequest, OutgoingVerificationRequest, QrVerification, RoomMessageRequest, - ToDeviceRequest, -}; +#[cfg(feature = "qrcode")] +use crate::QrVerification; +use crate::{OutgoingRequest, OutgoingVerificationRequest, RoomMessageRequest, ToDeviceRequest}; #[derive(Clone, Debug)] pub struct VerificationCache { @@ -55,10 +54,14 @@ impl VerificationCache { self.insert(sas); } + #[cfg(feature = "qrcode")] + #[cfg_attr(feature = "docs", doc(cfg(qrcode)))] pub fn insert_qr(&self, qr: QrVerification) { self.insert(qr) } + #[cfg(feature = "qrcode")] + #[cfg_attr(feature = "docs", doc(cfg(qrcode)))] pub fn get_qr(&self, sender: &UserId, flow_id: &str) -> Option { self.get(sender, flow_id).and_then(|v| { if let Verification::QrV1(qr) = v { @@ -91,6 +94,7 @@ impl VerificationCache { .value() .iter() .filter_map(|s| { + #[allow(irrefutable_let_patterns)] if let Verification::SasV1(s) = s.value() { s.cancel_if_timed_out() } else { @@ -106,6 +110,7 @@ impl VerificationCache { pub fn get_sas(&self, user_id: &UserId, flow_id: &str) -> Option { self.get(user_id, flow_id).and_then(|v| { + #[allow(irrefutable_let_patterns)] if let Verification::SasV1(sas) = v { Some(sas) } else { diff --git a/matrix_sdk_crypto/src/verification/machine.rs b/matrix_sdk_crypto/src/verification/machine.rs index 1624a9e0..2007ea11 100644 --- a/matrix_sdk_crypto/src/verification/machine.rs +++ b/matrix_sdk_crypto/src/verification/machine.rs @@ -387,6 +387,7 @@ impl VerificationMachine { // This won't produce an outgoing content let _ = sas.receive_any_event(event.sender(), &content); } + #[cfg(feature = "qrcode")] Verification::QrV1(qr) => qr.receive_cancel(event.sender(), c), } } @@ -477,6 +478,7 @@ impl VerificationMachine { verification.receive_done(event.sender(), c); } + #[allow(clippy::single_match)] match self.get_verification(event.sender(), flow_id.as_str()) { Some(Verification::SasV1(sas)) => { let content = sas.receive_any_event(event.sender(), &content); @@ -485,6 +487,7 @@ impl VerificationMachine { self.mark_sas_as_done(sas, content).await?; } } + #[cfg(feature = "qrcode")] Some(Verification::QrV1(qr)) => { let (cancellation, request) = qr.receive_done(c).await?; diff --git a/matrix_sdk_crypto/src/verification/mod.rs b/matrix_sdk_crypto/src/verification/mod.rs index 517e6001..1d0eb5ad 100644 --- a/matrix_sdk_crypto/src/verification/mod.rs +++ b/matrix_sdk_crypto/src/verification/mod.rs @@ -15,6 +15,7 @@ mod cache; mod event_enums; mod machine; +#[cfg(feature = "qrcode")] mod qrcode; mod requests; mod sas; @@ -27,6 +28,8 @@ use std::{ use event_enums::OutgoingContent; pub use machine::VerificationMachine; use matrix_sdk_common::locks::Mutex; +#[cfg(feature = "qrcode")] +#[cfg_attr(feature = "docs", doc(cfg(qrcode)))] pub use qrcode::QrVerification; pub use requests::VerificationRequest; use ruma::{ @@ -115,6 +118,8 @@ impl VerificationStore { pub enum Verification { /// The `m.sas.v1` verification variant. SasV1(Sas), + #[cfg(feature = "qrcode")] + #[cfg_attr(feature = "docs", doc(cfg(qrcode)))] /// The `m.qr_code.*.v1` verification variant. QrV1(QrVerification), } @@ -122,6 +127,7 @@ pub enum Verification { impl Verification { /// Try to deconstruct this verification enum into a SAS verification. pub fn sas_v1(self) -> Option { + #[allow(irrefutable_let_patterns)] if let Verification::SasV1(sas) = self { Some(sas) } else { @@ -129,6 +135,8 @@ impl Verification { } } + #[cfg(feature = "qrcode")] + #[cfg_attr(feature = "docs", doc(cfg(qrcode)))] /// Try to deconstruct this verification enum into a QR code verification. pub fn qr_v1(self) -> Option { if let Verification::QrV1(qr) = self { @@ -142,6 +150,7 @@ impl Verification { pub fn is_done(&self) -> bool { match self { Verification::SasV1(s) => s.is_done(), + #[cfg(feature = "qrcode")] Verification::QrV1(qr) => qr.is_done(), } } @@ -150,6 +159,7 @@ impl Verification { pub fn flow_id(&self) -> &str { match self { Verification::SasV1(s) => s.flow_id().as_str(), + #[cfg(feature = "qrcode")] Verification::QrV1(qr) => qr.flow_id().as_str(), } } @@ -158,6 +168,7 @@ impl Verification { pub fn is_cancelled(&self) -> bool { match self { Verification::SasV1(s) => s.is_cancelled(), + #[cfg(feature = "qrcode")] Verification::QrV1(qr) => qr.is_cancelled(), } } @@ -166,6 +177,7 @@ impl Verification { pub fn user_id(&self) -> &UserId { match self { Verification::SasV1(v) => v.user_id(), + #[cfg(feature = "qrcode")] Verification::QrV1(v) => v.user_id(), } } @@ -174,6 +186,7 @@ impl Verification { pub fn other_user(&self) -> &UserId { match self { Verification::SasV1(s) => s.other_user_id(), + #[cfg(feature = "qrcode")] Verification::QrV1(qr) => qr.other_user_id(), } } @@ -182,6 +195,7 @@ impl Verification { pub fn is_self_verification(&self) -> bool { match self { Verification::SasV1(v) => v.is_self_verification(), + #[cfg(feature = "qrcode")] Verification::QrV1(v) => v.is_self_verification(), } } @@ -193,6 +207,8 @@ impl From for Verification { } } +#[cfg(feature = "qrcode")] +#[cfg_attr(feature = "docs", doc(cfg(qrcode)))] impl From for Verification { fn from(qr: QrVerification) -> Self { Self::QrV1(qr) @@ -376,6 +392,7 @@ pub struct IdentitiesBeingVerified { } impl IdentitiesBeingVerified { + #[cfg(feature = "qrcode")] async fn can_sign_devices(&self) -> bool { self.private_identity.can_sign_devices().await } diff --git a/matrix_sdk_crypto/src/verification/requests.rs b/matrix_sdk_crypto/src/verification/requests.rs index 603967ee..b300ea06 100644 --- a/matrix_sdk_crypto/src/verification/requests.rs +++ b/matrix_sdk_crypto/src/verification/requests.rs @@ -17,8 +17,11 @@ use std::{ time::Duration, }; +#[cfg(feature = "qrcode")] use matrix_qrcode::QrVerificationData; use matrix_sdk_common::{instant::Instant, uuid::Uuid}; +#[cfg(feature = "qrcode")] +use ruma::DeviceKeyAlgorithm; use ruma::{ events::{ key::verification::{ @@ -32,7 +35,7 @@ use ruma::{ AnyMessageEventContent, AnyToDeviceEventContent, }, to_device::DeviceIdOrAllDevices, - DeviceId, DeviceIdBox, DeviceKeyAlgorithm, MilliSecondsSinceUnixEpoch, RoomId, UserId, + DeviceId, DeviceIdBox, MilliSecondsSinceUnixEpoch, RoomId, UserId, }; use tracing::{info, trace, warn}; @@ -41,8 +44,12 @@ use super::{ event_enums::{ CancelContent, DoneContent, OutgoingContent, ReadyContent, RequestContent, StartContent, }, + CancelInfo, Cancelled, FlowId, VerificationStore, +}; +#[cfg(feature = "qrcode")] +use super::{ qrcode::{QrVerification, ScanError}, - CancelInfo, Cancelled, FlowId, IdentitiesBeingVerified, VerificationStore, + IdentitiesBeingVerified, }; use crate::{ olm::{PrivateCrossSigningIdentity, ReadOnlyAccount}, @@ -52,6 +59,7 @@ use crate::{ const SUPPORTED_METHODS: &[VerificationMethod] = &[ VerificationMethod::SasV1, + #[cfg(feature = "qrcode")] VerificationMethod::QrCodeShowV1, VerificationMethod::ReciprocateV1, ]; @@ -299,6 +307,8 @@ impl VerificationRequest { matches!(&*self.inner.lock().unwrap(), InnerRequest::Cancelled(_)) } + #[cfg(feature = "qrcode")] + #[cfg_attr(feature = "docs", doc(cfg(qrcode)))] /// Generate a QR code that can be used by another client to start a QR code /// based verification. pub async fn generate_qr_code(&self) -> Result, CryptoStoreError> { @@ -308,7 +318,9 @@ impl VerificationRequest { .generate_qr_code(self.we_started, self.inner.clone().into()) .await } - + /// + #[cfg(feature = "qrcode")] + #[cfg_attr(feature = "docs", doc(cfg(qrcode)))] /// Start a QR code verification by providing a scanned QR code for this /// verification flow. /// @@ -399,8 +411,11 @@ impl VerificationRequest { /// This method will accept the request and signal that it supports the /// `m.sas.v1`, the `m.qr_code.show.v1`, and `m.reciprocate.v1` method. /// - /// If QR code scanning should be supported or QR code showing shouldn't be - /// supported the [`accept_with_methods()`] method should be used instead. + /// `m.qr_code.show.v1` will only be signaled if the `qrcode` feature is + /// enabled. This feature is disabled by default. If it's enabeled and QR + /// code scanning should be supported or QR code showing shouldn't be + /// supported the [`accept_with_methods()`] method should be used + /// instead. /// /// [`accept_with_methods()`]: #method.accept_with_methods pub fn accept(&self) -> Option { @@ -452,6 +467,7 @@ impl VerificationRequest { { match verification { crate::Verification::SasV1(s) => s.cancel_with_code(cancel_code), + #[cfg(feature = "qrcode")] crate::Verification::QrV1(q) => q.cancel_with_code(cancel_code), }; } @@ -720,6 +736,7 @@ impl InnerRequest { }); } + #[cfg(feature = "qrcode")] async fn generate_qr_code( &self, we_started: bool, @@ -938,6 +955,7 @@ impl RequestState { ) } + #[cfg(feature = "qrcode")] async fn generate_qr_code( &self, we_started: bool, @@ -1141,6 +1159,7 @@ impl RequestState { } } } + #[cfg(feature = "qrcode")] StartMethod::ReciprocateV1(_) => { if let Some(qr_verification) = self.verification_cache.get_qr(sender, content.flow_id())