diff --git a/bindings/matrix-sdk-ffi/src/qr_code.rs b/bindings/matrix-sdk-ffi/src/qr_code.rs index ced60e372..ccf8eae4d 100644 --- a/bindings/matrix-sdk-ffi/src/qr_code.rs +++ b/bindings/matrix-sdk-ffi/src/qr_code.rs @@ -1,7 +1,9 @@ use std::sync::Arc; use matrix_sdk::{ - authentication::oauth::qrcode::{self, DeviceCodeErrorResponseType, LoginFailureReason}, + authentication::oauth::qrcode::{ + self, DeviceCodeErrorResponseType, LoginFailureReason, QrProgress, + }, crypto::types::qr_login::{LoginQrCodeDecodeError, QrCodeModeData}, }; use matrix_sdk_common::{SendOutsideWasm, SyncOutsideWasm}; @@ -144,13 +146,13 @@ pub trait QrLoginProgressListener: SyncOutsideWasm + SendOutsideWasm { fn on_update(&self, state: QrLoginProgress); } -impl From for QrLoginProgress { - fn from(value: qrcode::LoginProgress) -> Self { +impl From> for QrLoginProgress { + fn from(value: qrcode::LoginProgress) -> Self { use qrcode::LoginProgress; match value { LoginProgress::Starting => Self::Starting, - LoginProgress::EstablishingSecureChannel { check_code } => { + LoginProgress::EstablishingSecureChannel(QrProgress { check_code }) => { let check_code = check_code.to_digit(); Self::EstablishingSecureChannel { diff --git a/crates/matrix-sdk/CHANGELOG.md b/crates/matrix-sdk/CHANGELOG.md index 6a88eaf5e..cbf587518 100644 --- a/crates/matrix-sdk/CHANGELOG.md +++ b/crates/matrix-sdk/CHANGELOG.md @@ -20,6 +20,9 @@ All notable changes to this project will be documented in this file. ([#5733](https://github.com/matrix-org/matrix-rust-sdk/pull/5733)) - The Matrix SDK crate now uses the 2024 edition of Rust. ([#5677](https://github.com/matrix-org/matrix-rust-sdk/pull/5677)) +- [**breaking**] Make `LoginProgress::EstablishingSecureChannel` generic in order to reuse it + for the currently missing QR login flow. + ([#5750](https://github.com/matrix-org/matrix-rust-sdk/pull/5750)) ### Bugfix diff --git a/crates/matrix-sdk/src/authentication/oauth/mod.rs b/crates/matrix-sdk/src/authentication/oauth/mod.rs index 1c00fb3be..c749e0f76 100644 --- a/crates/matrix-sdk/src/authentication/oauth/mod.rs +++ b/crates/matrix-sdk/src/authentication/oauth/mod.rs @@ -431,8 +431,8 @@ impl OAuth { /// while let Some(state) = progress.next().await { /// match state { /// LoginProgress::Starting => (), - /// LoginProgress::EstablishingSecureChannel { check_code } => { - /// let code = check_code.to_digit(); + /// LoginProgress::EstablishingSecureChannel(progress) => { + /// let code = progress.check_code.to_digit(); /// println!("Please enter the following code into the other device {code:02}"); /// }, /// LoginProgress::WaitingForToken { user_code } => { diff --git a/crates/matrix-sdk/src/authentication/oauth/qrcode/login.rs b/crates/matrix-sdk/src/authentication/oauth/qrcode/login.rs index 95df92143..47c466620 100644 --- a/crates/matrix-sdk/src/authentication/oauth/qrcode/login.rs +++ b/crates/matrix-sdk/src/authentication/oauth/qrcode/login.rs @@ -50,11 +50,11 @@ async fn send_unexpected_message_error( .await } -async fn finish_login( +async fn finish_login( client: &Client, mut channel: EstablishedSecureChannel, registration_data: Option<&ClientRegistrationData>, - state: SharedObservable, + state: SharedObservable>, ) -> Result<(), QRCodeLoginError> { let oauth = client.oauth(); @@ -237,17 +237,14 @@ async fn wait_for_tokens( /// Type telling us about the progress of the QR code login. #[derive(Clone, Debug, Default)] -pub enum LoginProgress { +pub enum LoginProgress { /// We're just starting up, this is the default and initial state. #[default] Starting, /// We have established the secure channel, but we need to let the other /// side know about the [`CheckCode`] so they can verify that the secure /// channel is indeed secure. - EstablishingSecureChannel { - /// The check code we need to, out of band, send to the other device. - check_code: CheckCode, - }, + EstablishingSecureChannel(Q), /// We're waiting for the OAuth 2.0 authorization server to give us the /// access token. This will only happen if the other device allows the /// OAuth 2.0 authorization server to do so. @@ -261,13 +258,21 @@ pub enum LoginProgress { Done, } +/// Metadata to be used with [`LoginProgress::EstablishingSecureChannel`] when +/// this device is the one scanning the QR code. +#[derive(Clone, Debug)] +pub struct QrProgress { + /// The check code we need to, out of band, send to the other device. + pub check_code: CheckCode, +} + /// Named future for the [`OAuth::login_with_qr_code()`] method. #[derive(Debug)] pub struct LoginWithQrCode<'a> { client: &'a Client, registration_data: Option<&'a ClientRegistrationData>, qr_code_data: &'a QrCodeData, - state: SharedObservable, + state: SharedObservable>, } impl LoginWithQrCode<'_> { @@ -276,7 +281,7 @@ impl LoginWithQrCode<'_> { /// It's usually necessary to subscribe to this to let the existing device /// know about the [`CheckCode`] which is used to verify that the two /// devices are communicating in a secure manner. - pub fn subscribe_to_progress(&self) -> impl Stream + use<> { + pub fn subscribe_to_progress(&self) -> impl Stream> + use<> { self.state.subscribe() } } @@ -298,7 +303,7 @@ impl<'a> IntoFuture for LoginWithQrCode<'a> { // a check code so they can confirm. let check_code = channel.check_code().to_owned(); - self.state.set(LoginProgress::EstablishingSecureChannel { check_code }); + self.state.set(LoginProgress::EstablishingSecureChannel(QrProgress { check_code })); finish_login(self.client, channel, self.registration_data, self.state).await }) @@ -478,7 +483,7 @@ mod test { while let Some(update) = updates.next().await { match update { - LoginProgress::EstablishingSecureChannel { check_code } => { + LoginProgress::EstablishingSecureChannel(QrProgress { check_code }) => { sender .take() .expect("The establishing secure channel update should be received only once") @@ -566,7 +571,7 @@ mod test { while let Some(update) = updates.next().await { match update { - LoginProgress::EstablishingSecureChannel { check_code } => { + LoginProgress::EstablishingSecureChannel(QrProgress { check_code }) => { sender .take() .expect("The establishing secure channel update should be received only once") @@ -689,7 +694,7 @@ mod test { while let Some(update) = updates.next().await { match update { - LoginProgress::EstablishingSecureChannel { check_code } => { + LoginProgress::EstablishingSecureChannel(QrProgress { check_code }) => { sender .take() .expect("The establishing secure channel update should be received only once") diff --git a/crates/matrix-sdk/src/authentication/oauth/qrcode/mod.rs b/crates/matrix-sdk/src/authentication/oauth/qrcode/mod.rs index bc5675273..c318dc33d 100644 --- a/crates/matrix-sdk/src/authentication/oauth/qrcode/mod.rs +++ b/crates/matrix-sdk/src/authentication/oauth/qrcode/mod.rs @@ -41,7 +41,7 @@ mod rendezvous_channel; mod secure_channel; pub use self::{ - login::{LoginProgress, LoginWithQrCode}, + login::{LoginProgress, LoginWithQrCode, QrProgress}, messages::{LoginFailureReason, LoginProtocolType, QrAuthMessage}, }; use super::CrossProcessRefreshLockError; diff --git a/examples/qr-login/src/main.rs b/examples/qr-login/src/main.rs index bf1e99791..8aac1f5ec 100644 --- a/examples/qr-login/src/main.rs +++ b/examples/qr-login/src/main.rs @@ -6,7 +6,7 @@ use futures_util::StreamExt; use matrix_sdk::{ Client, authentication::oauth::{ - qrcode::{LoginProgress, QrCodeData, QrCodeModeData}, + qrcode::{LoginProgress, QrCodeData, QrCodeModeData, QrProgress}, registration::{ApplicationType, ClientMetadata, Localized, OAuthGrantType}, }, ruma::serde::Raw, @@ -122,7 +122,7 @@ async fn login(proxy: Option) -> Result<()> { while let Some(state) = subscriber.next().await { match state { LoginProgress::Starting => (), - LoginProgress::EstablishingSecureChannel { check_code } => { + LoginProgress::EstablishingSecureChannel(QrProgress { check_code }) => { let code = check_code.to_digit(); println!("Please enter the following code into the other device {code:02}"); }