Struct matrix_sdk::matrix_auth::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 login_sso<F, Fut>(&self, use_sso_login_url: F) -> SsoLoginBuilder<F>
where F: FnOnce(String) -> Fut + Send, Fut: Future<Output = Result<()>> + Send,

Available on crate feature sso-login only.

Log into the server via Single Sign-On.

This takes care of the whole SSO flow:

  • Spawn a local http server
  • Provide a callback to open the SSO login URL in a web browser
  • Wait for the local http server to get the loginToken
  • Call login_token

If cancellation is needed the method should be wrapped in a cancellable task. Note that users with root access to the system have the ability to snoop in on the data/token that is passed to the local HTTP server that will be spawned.

If you need more control over the SSO login process, you should use get_sso_login_url and login_token directly.

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.

§Arguments
  • use_sso_login_url - A callback that will receive the SSO Login URL. It should usually be used to open the SSO URL in a browser and must return Ok(()) if the URL was successfully opened. If it returns Err, the error will be forwarded.
§Examples
use matrix_sdk::Client;
let client = Client::new(homeserver).await.unwrap();

let response = client
    .matrix_auth()
    .login_sso(|sso_url| async move {
        // Open sso_url
        Ok(())
    })
    .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§

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

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
§

impl<T> CompatExt for T

§

fn compat(self) -> Compat<T>

Applies the [Compat] adapter by value. Read more
§

fn compat_ref(&self) -> Compat<&T>

Applies the [Compat] adapter by shared reference. Read more
§

fn compat_mut(&mut self) -> Compat<&mut T>

Applies the [Compat] adapter by mutable reference. Read more
source§

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

source§

fn __clone_box(&self, _: Private) -> *mut ()

source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

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

source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
source§

impl<T> FutureExt for T

source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
source§

impl<T, UT> HandleAlloc<UT> for T
where T: Send + Sync,

source§

fn new_handle(value: Arc<T>) -> Handle

Create a new handle for an Arc value Read more
source§

fn clone_handle(handle: Handle) -> Handle

Clone a handle Read more
source§

fn consume_handle(handle: Handle) -> Arc<T>

Consume a handle, getting back the initial Arc<>
source§

fn get_arc(handle: Handle) -> Arc<Self>

Get a clone of the Arc<> using a “borrowed” handle. Read more
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,

§

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§

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.
§

impl<T> Instrument for T

§

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

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

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

§

type Output = T

Should always be Self
source§

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

§

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>,

§

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>,

§

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

§

impl<T> WithSubscriber for T

§

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
§

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> SendOutsideWasm for T
where T: Send,

source§

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