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
impl MatrixAuth
Sourcepub async fn get_login_types(&self) -> HttpResult<Response>
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.
Sourcepub async fn get_sso_login_url(
&self,
redirect_url: &str,
idp_id: Option<&str>,
) -> Result<String>
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 aloginToken
after a successful SSO login. -
idp_id
- The optional ID of the identity provider to log in with.
Sourcepub fn login_username(
&self,
id: impl AsRef<str>,
password: &str,
) -> LoginBuilder
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,
);
Sourcepub fn login_identifier(
&self,
id: UserIdentifier,
password: &str,
) -> LoginBuilder
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.
Sourcepub fn login_custom(
&self,
login_type: &str,
data: JsonObject,
) -> Result<LoginBuilder>
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,
);
Sourcepub fn login_token(&self, token: &str) -> LoginBuilder
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,
);
Sourcepub fn login_with_sso_callback(
&self,
callback_url: Url,
) -> Result<LoginBuilder, SsoError>
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,
);
Sourcepub fn login_sso<F, Fut>(&self, use_sso_login_url: F) -> SsoLoginBuilder<F>
Available on crate feature sso-login
only.
pub fn login_sso<F, Fut>(&self, use_sso_login_url: F) -> SsoLoginBuilder<F>
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 returnOk(())
if the URL was successfully opened. If it returnsErr
, 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
);
Sourcepub fn logged_in(&self) -> bool
pub fn logged_in(&self) -> bool
Is the client logged in using the native Matrix authentication API.
Sourcepub async fn refresh_access_token(&self) -> Result<(), RefreshTokenError>
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(())
}
Sourcepub async fn register(&self, request: Request) -> Result<Response>
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
registration
- The easiest way to create this request is using theregister::v3::Request
itself.
§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;
Sourcepub async fn logout(&self) -> HttpResult<Response>
pub async fn logout(&self) -> HttpResult<Response>
Log out the current user.
Sourcepub fn session_tokens(&self) -> Option<MatrixSessionTokens>
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.
Sourcepub fn access_token(&self) -> Option<String>
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.
Sourcepub fn refresh_token(&self) -> Option<String>
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.
Sourcepub fn session_tokens_changed_stream(&self) -> Option<impl Stream<Item = ()>>
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);
Sourcepub fn session_tokens_stream(
&self,
) -> Option<impl Stream<Item = MatrixSessionTokens>>
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);
}
}
Sourcepub fn session(&self) -> Option<MatrixSession>
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.
Sourcepub async fn restore_session(&self, session: MatrixSession) -> Result<()>
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
impl Clone for MatrixAuth
Source§fn clone(&self) -> MatrixAuth
fn clone(&self) -> MatrixAuth
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreAuto Trait Implementations§
impl Freeze for MatrixAuth
impl !RefUnwindSafe for MatrixAuth
impl Send for MatrixAuth
impl Sync for MatrixAuth
impl Unpin for MatrixAuth
impl !UnwindSafe for MatrixAuth
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> CompatExt for T
impl<T> CompatExt for T
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
Source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
Source§impl<T, UT> HandleAlloc<UT> for T
impl<T, UT> HandleAlloc<UT> for T
Source§fn consume_handle(handle: Handle) -> Arc<T>
fn consume_handle(handle: Handle) -> Arc<T>
Arc<>
Source§impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
Source§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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