GrantLoginWithQrCodeBuilder

Struct GrantLoginWithQrCodeBuilder 

Source
pub struct GrantLoginWithQrCodeBuilder<'a> { /* private fields */ }
Available on crate feature e2e-encryption only.
Expand description

Builder for QR login grant handlers.

Implementations§

Source§

impl<'a> GrantLoginWithQrCodeBuilder<'a>

Source

pub fn device_creation_timeout(self, device_creation_timeout: Duration) -> Self

Set the device creation timeout.

§Arguments
  • device_creation_timeout - The duration to wait for the homeserver to create the new device after consenting the login before giving up.
Source

pub fn scan(self, data: &'a QrCodeData) -> GrantLoginWithScannedQrCode<'a>

This method allows you to grant login to a new device by scanning a QR code generated by the new device.

The new device needs to display the QR code which this device can scan and call this method to grant the login.

A successful login grant using this method will automatically mark the new device as verified and transfer all end-to-end encryption related secrets, like the private cross-signing keys and the backup key from this device device to the new device.

For the reverse flow where this device generates the QR code for the new device to scan, use GrantLoginWithQrCodeBuilder::generate.

§Arguments
  • data - The data scanned from a QR code.
§Example
use anyhow::bail;
use futures_util::StreamExt;
use matrix_sdk::{
    Client, authentication::oauth::{
        qrcode::{GrantLoginProgress, QrCodeData, QrCodeModeData, QrProgress},
    }
};
use std::{error::Error, io::stdin};
// You'll need to use a different library to scan and extract the raw bytes from the QR
// code.
let qr_code_data = QrCodeData::from_bytes(bytes)?;

// Build the client as usual.
let client = Client::builder()
    .server_name_or_homeserver_url("matrix.org")
    .handle_refresh_tokens()
    .build()
    .await?;

let oauth = client.oauth();

// Subscribing to the progress is necessary to capture
// the checkcode in order to display it to the other device and to obtain the verification URL to
// open it in a browser so the user can consent to the new login.
let mut grant = oauth.grant_login_with_qr_code().scan(&qr_code_data);
let mut progress = grant.subscribe_to_progress();

// Create a task which will show us the progress and allows us to receive
// and feed back data.
let task = tokio::spawn(async move {
    while let Some(state) = progress.next().await {
        match state {
            GrantLoginProgress::Starting | GrantLoginProgress::SyncingSecrets => (),
            GrantLoginProgress::EstablishingSecureChannel(QrProgress { check_code }) => {
                println!("Please enter the checkcode on your other device: {:?}", check_code);
            }
            GrantLoginProgress::WaitingForAuth { verification_uri } => {
                println!("Please open {verification_uri} to confirm the new login")
            },
            GrantLoginProgress::Done => break,
        }
    }
    Ok::<(), Box<dyn Error + Send + Sync>>(())
});

// Now run the future to grant the login.
grant.await?;
task.abort();

println!("Successfully granted login");
Source

pub fn generate(self) -> GrantLoginWithGeneratedQrCode<'a>

This method allows you to grant login to a new device by generating a QR code on this device to be scanned by the new device.

This device needs to call this method to generate and display the QR code which the new device can scan to initiate the grant process.

A successful login grant using this method will automatically mark the new device as verified and transfer all end-to-end encryption related secrets, like the private cross-signing keys and the backup key from this device device to the new device.

For the reverse flow where the new device generates the QR code for this device to scan, use GrantLoginWithQrCodeBuilder::scan.

§Example
use anyhow::bail;
use futures_util::StreamExt;
use matrix_sdk::{
    Client, authentication::oauth::{
        qrcode::{GeneratedQrProgress, GrantLoginProgress}
    }
};
use std::{error::Error, io::stdin};
// Build the client as usual.
let client = Client::builder()
    .server_name_or_homeserver_url("matrix.org")
    .handle_refresh_tokens()
    .build()
    .await?;

let oauth = client.oauth();

// Subscribing to the progress is necessary since we need to capture the
// QR code, feed the checkcode back in and obtain the verification URL to
// open it in a browser so the user can consent to the new login.
let mut grant = oauth.grant_login_with_qr_code().generate();
let mut progress = grant.subscribe_to_progress();

// Create a task which will show us the progress and allows us to receive
// and feed back data.
let task = tokio::spawn(async move {
    while let Some(state) = progress.next().await {
        match state {
            GrantLoginProgress::Starting | GrantLoginProgress::SyncingSecrets => (),
            GrantLoginProgress::EstablishingSecureChannel(GeneratedQrProgress::QrReady(qr_code_data)) => {
                println!("Please scan the QR code on your other device: {:?}", qr_code_data);
            }
            GrantLoginProgress::EstablishingSecureChannel(GeneratedQrProgress::QrScanned(checkcode_sender)) => {
                println!("Please enter the code displayed on your other device");
                let mut s = String::new();
                stdin().read_line(&mut s)?;
                let check_code = s.trim().parse::<u8>()?;
                checkcode_sender.send(check_code).await?;
            }
            GrantLoginProgress::WaitingForAuth { verification_uri } => {
                println!("Please open {verification_uri} to confirm the new login")
            },
            GrantLoginProgress::Done => break,
        }
    }
    Ok::<(), Box<dyn Error + Send + Sync>>(())
});

// Now run the future to grant the login.
grant.await?;
task.abort();

println!("Successfully granted login");

Trait Implementations§

Source§

impl<'a> Debug for GrantLoginWithQrCodeBuilder<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, W> HasTypeWitness<W> for T
where W: MakeTypeWitness<Arg = T>, T: ?Sized,

Source§

const WITNESS: W = W::MAKE

A constant of the type witness
Source§

impl<T> Identity for T
where T: ?Sized,

Source§

const TYPE_EQ: TypeEq<T, <T as Identity>::Type> = TypeEq::NEW

Proof that Self is the same type as Self::Type, provides methods for casting between Self and Self::Type.
Source§

type Type = T

The same type as Self, used to emulate type equality bounds (T == U) with associated type equality constraints (T: Identity<Type = U>).
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> Any for T
where T: Any,

Source§

impl<T> AsyncTraitDeps for T

Source§

impl<T> JsonCastable<CanonicalJsonValue> for T

Source§

impl<T> JsonCastable<Value> for T

Source§

impl<T> SendOutsideWasm for T
where T: Send,

Source§

impl<T> SyncOutsideWasm for T
where T: Sync,