matrix_sdk::matrix_auth

Struct MatrixAuth

Source
pub struct MatrixAuth { /* private fields */ }
Expand description

A high-level API to interact with the native Matrix authentication API.

To access this API, use Client::matrix_auth().

Implementations§

Source§

impl MatrixAuth

Source

pub async fn get_login_types(&self) -> HttpResult<Response>

Gets the homeserver’s supported login types.

This should be the first step when trying to log in so you can call the appropriate method for the next step.

Source

pub async fn get_sso_login_url( &self, redirect_url: &str, idp_id: Option<&str>, ) -> Result<String>

Get the URL to use to log in via Single Sign-On.

Returns a URL that should be opened in a web browser to let the user log in.

After a successful login, the loginToken received at the redirect URL should be used to log in with login_token.

§Arguments
  • redirect_url - The URL that will receive a loginToken after a successful SSO login.

  • idp_id - The optional ID of the identity provider to log in with.

Source

pub fn login_username( &self, id: impl AsRef<str>, password: &str, ) -> LoginBuilder

Log into the server with a username and password.

This can be used for the first login as well as for subsequent logins, note that if the device ID isn’t provided a new device will be created.

If this isn’t the first login, a device ID should be provided through LoginBuilder::device_id to restore the correct stores.

Alternatively the restore_session method can be used to restore a logged-in client without the password.

§Arguments
  • user - The user ID or user ID localpart of the user that should be logged into the homeserver.

  • password - The password of the user.

§Examples
use matrix_sdk::Client;

let client = Client::new(homeserver).await?;
let user = "example";

let response = client
    .matrix_auth()
    .login_username(user, "wordpass")
    .initial_device_display_name("My bot")
    .await?;

println!(
    "Logged in as {user}, got device_id {} and access_token {}",
    response.device_id, response.access_token,
);
Source

pub fn login_identifier( &self, id: UserIdentifier, password: &str, ) -> LoginBuilder

Log into the server with a user identifier and password.

This is a more general form of login_username that also accepts third-party identifiers instead of just the user ID or its localpart.

Source

pub fn login_custom( &self, login_type: &str, data: JsonObject, ) -> Result<LoginBuilder>

Log into the server with a custom login type.

§Arguments
  • login_type - Identifier of the custom login type, e.g. org.matrix.login.jwt

  • data - The additional data which should be attached to the login request.

§Examples
use matrix_sdk::Client;

let client = Client::new(homeserver).await?;
let user = "example";

let response = client
    .matrix_auth()
    .login_custom(
        "org.matrix.login.jwt",
        [("token".to_owned(), "jwt_token_content".into())]
            .into_iter()
            .collect(),
    )?
    .initial_device_display_name("My bot")
    .await?;

println!(
    "Logged in as {user}, got device_id {} and access_token {}",
    response.device_id, response.access_token,
);
Source

pub fn login_token(&self, token: &str) -> LoginBuilder

Log into the server with a token.

This token is usually received in the SSO flow after following the URL provided by get_sso_login_url, note that this is not the access token of a session.

This should only be used for the first login.

The restore_session method should be used to restore a logged-in client after the first login.

A device ID should be provided through LoginBuilder::device_id to restore the correct stores, if the device ID isn’t provided a new device will be created.

§Arguments
  • token - A login token.
§Examples
use matrix_sdk::Client;
let client = Client::new(homeserver).await.unwrap();
let auth = client.matrix_auth();
let sso_url = auth.get_sso_login_url(redirect_url, None);

// Let the user authenticate at the SSO URL.
// Receive the loginToken param at the redirect_url.

let response = auth
    .login_token(login_token)
    .initial_device_display_name("My app")
    .await
    .unwrap();

println!(
    "Logged in as {}, got device_id {} and access_token {}",
    response.user_id, response.device_id, response.access_token,
);
Source

pub fn login_with_sso_callback( &self, callback_url: Url, ) -> Result<LoginBuilder, SsoError>

A higher level wrapper around the methods to complete an SSO login after the user has logged in through a webview. This method should be used in tandem with MatrixAuth::get_sso_login_url.

§Arguments
  • callback_url - The received callback URL carrying the login token.
§Examples
use matrix_sdk::Client;
let client = Client::new(homeserver).await.unwrap();
let auth = client.matrix_auth();
let sso_url = auth.get_sso_login_url(redirect_url, None);

// Let the user authenticate at the SSO URL.
// Receive the callback_url.

let response = auth
    .login_with_sso_callback(callback_url)
    .unwrap()
    .initial_device_display_name("My app")
    .await
    .unwrap();

println!(
    "Logged in as {}, got device_id {} and access_token {}",
    response.user_id, response.device_id, response.access_token,
);
Source

pub fn logged_in(&self) -> bool

Is the client logged in using the native Matrix authentication API.

Source

pub async fn refresh_access_token(&self) -> Result<(), RefreshTokenError>

Refresh the access token.

When support for refreshing access tokens is activated on both the homeserver and the client, access tokens have an expiration date and need to be refreshed periodically. To activate support for refresh tokens in the Client, it needs to be done at login with the LoginBuilder::request_refresh_token() method, or during account registration.

This method doesn’t need to be called if ClientBuilder::handle_refresh_tokens() is called during construction of the Client. Otherwise, it should be called once when a refresh token is available and an UnknownToken error is received. If this call fails with another UnknownToken error, it means that the session needs to be logged in again.

It can also be called at any time when a refresh token is available, it will invalidate the previous access token.

The new tokens in the response will be used by the Client and should be persisted to be able to restore the session. The response will always contain an access token that replaces the previous one. It can also contain a refresh token, in which case it will also replace the previous one.

This method is protected behind a lock, so calling this method several times at once will only call the endpoint once and all subsequent calls will wait for the result of the first call. The first call will return Ok(Some(response)) or the HttpError returned by the endpoint, while the others will return Ok(None) if the token was refreshed by the first call or a RefreshTokenError error, if it failed.

§Examples
use matrix_sdk::{Client, Error};
use url::Url;

let homeserver = Url::parse("http://example.com")?;
let client = Client::new(homeserver).await?;

let (user, password) = get_credentials();
let response = client
    .matrix_auth()
    .login_username(user, password)
    .initial_device_display_name("My App")
    .request_refresh_token()
    .send()
    .await?;

persist_session(client.session());

// Handle when an `M_UNKNOWN_TOKEN` error is encountered.
async fn on_unknown_token_err(client: &Client) -> Result<(), Error> {
    let auth = client.matrix_auth();

    if auth.refresh_token().is_some()
        && auth.refresh_access_token().await.is_ok()
    {
        persist_session(client.session());
        return Ok(());
    }

    let (user, password) = get_credentials();
    auth.login_username(user, password)
        .request_refresh_token()
        .send()
        .await?;

    persist_session(client.session());

    Ok(())
}
Source

pub async fn register(&self, request: Request) -> Result<Response>

Register a user to the server.

If registration was successful and a session token was returned by the server, the client session is set (the client is logged in).

§Arguments
§Examples
use matrix_sdk::{
    ruma::api::client::{
        account::register::v3::Request as RegistrationRequest, uiaa,
    },
    Client,
};

let mut request = RegistrationRequest::new();
request.username = Some("user".to_owned());
request.password = Some("password".to_owned());
request.auth = Some(uiaa::AuthData::FallbackAcknowledgement(
    uiaa::FallbackAcknowledgement::new("foobar".to_owned()),
));

let client = Client::new(homeserver).await.unwrap();
client.matrix_auth().register(request).await;
Source

pub async fn logout(&self) -> HttpResult<Response>

Log out the current user.

Source

pub fn session_tokens(&self) -> Option<MatrixSessionTokens>

Get the current access token and optional refresh token for this session.

Will be None if the client has not been logged in with the native Matrix Authentication API.

After login, the tokens should only change if support for refreshing access tokens has been enabled.

Source

pub fn access_token(&self) -> Option<String>

Get the current access token for this session.

Will be None if the client has not been logged in with the native Matrix Authentication API.

After login, this token should only change if support for refreshing access tokens has been enabled.

Source

pub fn refresh_token(&self) -> Option<String>

Get the current refresh token for this session.

Will be None if the client has not been logged in with the native Matrix Authentication API, or if the access token doesn’t expire.

After login, this token should only change if support for refreshing access tokens has been enabled.

Source

pub fn session_tokens_changed_stream(&self) -> Option<impl Stream<Item = ()>>

Stream to get notified when the current access token and optional refresh token for this session change.

This can be used with MatrixAuth::session() to persist the MatrixSession when the tokens change.

After login, the tokens should only change if support for refreshing access tokens has been enabled.

§Examples
use futures_util::StreamExt;
use matrix_sdk::Client;

let homeserver = "http://example.com";
let client = Client::builder()
    .homeserver_url(homeserver)
    .handle_refresh_tokens()
    .build()
    .await?;
let auth = client.matrix_auth();

let response = auth
    .login_username("user", "wordpass")
    .initial_device_display_name("My App")
    .request_refresh_token()
    .send()
    .await?;

persist_session(client.session());

// Handle when at least one of the tokens changed.
let future = auth
    .session_tokens_changed_stream()
    .expect("Client should be logged in")
    .for_each(move |_| {
        let client = client.clone();
        async move {
            persist_session(client.session());
        }
    });

tokio::spawn(future);
Source

pub fn session_tokens_stream( &self, ) -> Option<impl Stream<Item = MatrixSessionTokens>>

Get changes to the access token and optional refresh token for this session as a Stream.

Will be None if the client has not been logged in.

After login, the tokens should only change if support for refreshing access tokens has been enabled.

§Examples
use futures_util::StreamExt;
use matrix_sdk::Client;
let homeserver = "http://example.com";
let client = Client::builder()
    .homeserver_url(homeserver)
    .handle_refresh_tokens()
    .build()
    .await?;
let auth = client.matrix_auth();

auth.login_username("user", "wordpass")
    .initial_device_display_name("My App")
    .request_refresh_token()
    .send()
    .await?;

let mut session = auth.session().expect("Client should be logged in");
persist_session(&session);

// Handle when at least one of the tokens changed.
let mut tokens_stream =
    auth.session_tokens_stream().expect("Client should be logged in");
loop {
    if let Some(tokens) = tokens_stream.next().await {
        session.tokens.access_token = tokens.access_token;

        if let Some(refresh_token) = tokens.refresh_token {
            session.tokens.refresh_token = Some(refresh_token);
        }

        persist_session(&session);
    }
}
Source

pub fn session(&self) -> Option<MatrixSession>

Get the whole native Matrix authentication session info of this client.

Will be None if the client has not been logged in with the native Matrix Authentication API.

Can be used with MatrixAuth::restore_session to restore a previously logged-in session.

Source

pub async fn restore_session(&self, session: MatrixSession) -> Result<()>

Restore a previously logged in session.

This can be used to restore the client to a logged in state, loading all the stored state and encryption keys.

Alternatively, if the whole session isn’t stored the login method can be used with a device ID.

§Arguments
  • session - A session that the user already has from a previous login call.
§Panics

Panics if a session was already restored or logged in.

§Examples
use matrix_sdk::{
    matrix_auth::{MatrixSession, MatrixSessionTokens},
    ruma::{device_id, user_id},
    Client, SessionMeta,
};

let homeserver = Url::parse("http://example.com")?;
let client = Client::new(homeserver).await?;

let session = MatrixSession {
    meta: SessionMeta {
        user_id: user_id!("@example:localhost").to_owned(),
        device_id: device_id!("MYDEVICEID").to_owned(),
    },
    tokens: MatrixSessionTokens {
        access_token: "My-Token".to_owned(),
        refresh_token: None,
    },
};

client.restore_session(session).await?;

The MatrixSession object can also be created from the response the LoginBuilder::send() method returns:

use matrix_sdk::Client;
use url::Url;

let homeserver = Url::parse("http://example.com")?;
let client = Client::new(homeserver).await?;
let auth = client.matrix_auth();

let response = auth.login_username("example", "my-password").send().await?;

// Persist the `MatrixSession` so it can later be used to restore the login.

auth.restore_session((&response).into()).await?;

Trait Implementations§

Source§

impl Clone for MatrixAuth

Source§

fn clone(&self) -> MatrixAuth

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for MatrixAuth

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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> CloneAny for T
where T: Any + Clone,

Source§

impl<T> CloneAnySend for T
where T: Any + Send + Clone,

Source§

impl<T> CloneAnySendSync for T
where T: Any + Send + Sync + Clone,

Source§

impl<T> CloneAnySync for T
where T: Any + Sync + Clone,

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> MaybeSendSync for T

Source§

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

Source§

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