pub struct OAuth { /* private fields */ }
Expand description
A high-level authentication API to interact with an OAuth 2.0 authorization server.
Implementations§
Source§impl OAuth
impl OAuth
Sourcepub async fn enable_cross_process_refresh_lock(
&self,
lock_value: String,
) -> Result<(), OAuthError>
Available on crate feature e2e-encryption
only.
pub async fn enable_cross_process_refresh_lock( &self, lock_value: String, ) -> Result<(), OAuthError>
e2e-encryption
only.Enable a cross-process store lock on the state store, to coordinate refreshes across different processes.
Sourcepub fn login_with_qr_code<'a>(
&'a self,
data: &'a QrCodeData,
registration_data: Option<&'a ClientRegistrationData>,
) -> LoginWithQrCode<'a>
Available on crate feature e2e-encryption
only.
pub fn login_with_qr_code<'a>( &'a self, data: &'a QrCodeData, registration_data: Option<&'a ClientRegistrationData>, ) -> LoginWithQrCode<'a>
e2e-encryption
only.Log in using a QR code.
This method allows you to log in with a QR code, the existing device needs to display the QR code which this device can scan and call this method to log in.
A successful login using this method will automatically mark the device as verified and transfer all end-to-end encryption related secrets, like the private cross-signing keys and the backup key from the existing device to the new device.
§Arguments
-
data
- The data scanned from a QR code. -
registration_data
- The data to restore or register the client with the server. If this is not provided, an error will occur unlessOAuth::register_client()
orOAuth::restore_registered_client()
was called previously.
§Example
use anyhow::bail;
use futures_util::StreamExt;
use matrix_sdk::{
authentication::oauth::{
registration::ClientMetadata,
qrcode::{LoginProgress, QrCodeData, QrCodeModeData},
},
ruma::serde::Raw,
Client,
};
// 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)?;
// Fetch the homeserver out of the parsed QR code data.
let QrCodeModeData::Reciprocate{ server_name } = qr_code_data.mode_data else {
bail!("The QR code is invalid, we did not receive a homeserver in the QR code.");
};
// Build the client as usual.
let client = Client::builder()
.server_name_or_homeserver_url(server_name)
.handle_refresh_tokens()
.build()
.await?;
let oauth = client.oauth();
let client_metadata: Raw<ClientMetadata> = client_metadata();
let registration_data = client_metadata.into();
// Subscribing to the progress is necessary since we need to input the check
// code on the existing device.
let login = oauth.login_with_qr_code(&qr_code_data, Some(®istration_data));
let mut progress = login.subscribe_to_progress();
// Create a task which will show us the progress and tell us the check
// code to input in the existing device.
let task = tokio::spawn(async move {
while let Some(state) = progress.next().await {
match state {
LoginProgress::Starting => (),
LoginProgress::EstablishingSecureChannel { check_code } => {
let code = check_code.to_digit();
println!("Please enter the following code into the other device {code:02}");
},
LoginProgress::WaitingForToken { user_code } => {
println!("Please use your other device to confirm the log in {user_code}")
},
LoginProgress::Done => break,
}
}
});
// Now run the future to complete the login.
login.await?;
task.abort();
println!("Successfully logged in: {:?} {:?}", client.user_id(), client.device_id());
Sourcepub async fn account_management_actions_supported(
&self,
) -> Result<BTreeSet<AccountManagementAction>, OAuthError>
pub async fn account_management_actions_supported( &self, ) -> Result<BTreeSet<AccountManagementAction>, OAuthError>
The account management actions supported by the authorization server’s account management URL.
Returns an error if the request to get the server metadata fails.
Sourcepub async fn fetch_account_management_url(
&self,
) -> Result<Option<AccountManagementUrlBuilder>, OAuthError>
pub async fn fetch_account_management_url( &self, ) -> Result<Option<AccountManagementUrlBuilder>, OAuthError>
Get the account management URL where the user can manage their identity-related settings.
This will always request the latest server metadata to get the account management URL.
To avoid making a request each time, you can use
OAuth::account_management_url()
.
Returns an AccountManagementUrlBuilder
if the URL was found. An
optional action to perform can be added with .action()
, and the final
URL is obtained with .build()
.
Returns Ok(None)
if the URL was not found.
Returns an error if the request to get the server metadata fails or the URL could not be parsed.
Sourcepub async fn account_management_url(
&self,
) -> Result<Option<AccountManagementUrlBuilder>, OAuthError>
pub async fn account_management_url( &self, ) -> Result<Option<AccountManagementUrlBuilder>, OAuthError>
Get the account management URL where the user can manage their identity-related settings.
This method will cache the URL for a while, if the cache is not
populated it will request the server metadata, like a call to
OAuth::fetch_account_management_url()
, and cache the resulting URL
before returning it.
Returns an AccountManagementUrlBuilder
if the URL was found. An
optional action to perform can be added with .action()
, and the final
URL is obtained with .build()
.
Returns Ok(None)
if the URL was not found.
Returns an error if the request to get the server metadata fails or the URL could not be parsed.
Sourcepub async fn server_metadata(
&self,
) -> Result<AuthorizationServerMetadata, OAuthDiscoveryError>
pub async fn server_metadata( &self, ) -> Result<AuthorizationServerMetadata, OAuthDiscoveryError>
Fetch the OAuth 2.0 authorization server metadata of the homeserver.
Returns an error if a problem occurred when fetching or validating the metadata.
Sourcepub fn client_id(&self) -> Option<&ClientId>
pub fn client_id(&self) -> Option<&ClientId>
The OAuth 2.0 unique identifier of this client obtained after registration.
Returns None
if the client was not registered or if the registration
was not restored with OAuth::restore_registered_client()
or
OAuth::restore_session()
.
Sourcepub fn user_session(&self) -> Option<UserSession>
pub fn user_session(&self) -> Option<UserSession>
The OAuth 2.0 user session of this client.
Returns None
if the client was not logged in.
Sourcepub fn full_session(&self) -> Option<OAuthSession>
pub fn full_session(&self) -> Option<OAuthSession>
The full OAuth 2.0 session of this client.
Returns None
if the client was not logged in with the OAuth 2.0 API.
Sourcepub async fn register_client(
&self,
client_metadata: &Raw<ClientMetadata>,
) -> Result<ClientRegistrationResponse, OAuthError>
pub async fn register_client( &self, client_metadata: &Raw<ClientMetadata>, ) -> Result<ClientRegistrationResponse, OAuthError>
Register a client with the OAuth 2.0 server.
This should be called before any authorization request with an
authorization server that supports dynamic client registration. If the
client registered with the server manually, it should use
OAuth::restore_registered_client()
.
Note that this method only supports public clients, i.e. clients without a secret.
§Arguments
client_metadata
- The serialized client metadata to register.
§Panic
Panics if the authentication data was already set.
§Example
use matrix_sdk::{Client, ServerName};
let server_name = ServerName::parse("myhomeserver.org")?;
let client = Client::builder().server_name(&server_name).build().await?;
let oauth = client.oauth();
if let Err(error) = oauth.server_metadata().await {
if error.is_not_supported() {
println!("OAuth 2.0 is not supported");
}
return Err(error.into());
}
let response = oauth
.register_client(&client_metadata)
.await?;
println!(
"Registered with client_id: {}",
response.client_id.as_str()
);
// The API only supports clients without secrets.
let client_id = response.client_id;
persist_client_registration(client.homeserver(), &client_id);
Sourcepub fn restore_registered_client(&self, client_id: ClientId)
pub fn restore_registered_client(&self, client_id: ClientId)
Set the data of a client that is registered with an OAuth 2.0 authorization server.
This should be called when logging in with a server that is already known by the client.
Note that this method only supports public clients, i.e. clients with no credentials.
§Arguments
client_id
- The unique identifier to authenticate the client with the server, obtained after registration.
§Panic
Panics if authentication data was already set.
Sourcepub async fn restore_session(
&self,
session: OAuthSession,
room_load_settings: RoomLoadSettings,
) -> Result<()>
pub async fn restore_session( &self, session: OAuthSession, room_load_settings: RoomLoadSettings, ) -> Result<()>
Restore a previously logged in session.
This can be used to restore the client to a logged in state, including loading the sync state and the encryption keys from the store, if one was set up.
§Arguments
session
- The session to restore.room_load_settings
— Specify how many rooms must be restored; use::default()
if you don’t know which value to pick.
§Panic
Panics if authentication data was already set.
Sourcepub fn login(
&self,
redirect_uri: Url,
device_id: Option<OwnedDeviceId>,
registration_data: Option<ClientRegistrationData>,
) -> OAuthAuthCodeUrlBuilder
pub fn login( &self, redirect_uri: Url, device_id: Option<OwnedDeviceId>, registration_data: Option<ClientRegistrationData>, ) -> OAuthAuthCodeUrlBuilder
Log in via OAuth 2.0 with the Authorization Code flow.
This method requires to open a URL in the end-user’s browser where they will be able to log into their account in the server’s web UI and grant access to their Matrix account.
The OAuthAuthCodeUrlBuilder
that is returned allows to customize a
few settings before calling .build()
to obtain the URL to open in the
browser of the end-user.
OAuth::finish_login()
must be called once the user has been
redirected to the redirect_uri
. OAuth::abort_login()
should be
called instead if the authorization should be aborted before completion.
§Arguments
-
redirect_uri
- The URI where the end user will be redirected after authorizing the login. It must be one of the redirect URIs sent in the client metadata during registration. -
device_id
- The unique ID that will be associated with the session. If not set, a random one will be generated. It can be an existing device ID from a previous login call. Note that this should be done only if the client also holds the corresponding encryption keys. -
registration_data
- The data to restore or register the client with the server. If this is not provided, an error will occur unlessOAuth::register_client()
orOAuth::restore_registered_client()
was called previously.
§Example
use matrix_sdk::{
authentication::oauth::registration::ClientMetadata,
ruma::serde::Raw,
};
use url::Url;
let oauth = client.oauth();
let client_metadata: Raw<ClientMetadata> = client_metadata();
let registration_data = client_metadata.into();
let auth_data = oauth.login(redirect_uri, None, Some(registration_data))
.build()
.await?;
// Open auth_data.url and wait for response at the redirect URI.
let redirected_to_uri: Url = open_uri_and_wait_for_redirect(auth_data.url).await;
oauth.finish_login(redirected_to_uri.into()).await?;
// The session tokens can be persisted from the
// `OAuth::full_session()` method.
// You can now make requests to the Matrix API.
let _me = client.whoami().await?;
Sourcepub async fn finish_login(&self, url_or_query: UrlOrQuery) -> Result<()>
pub async fn finish_login(&self, url_or_query: UrlOrQuery) -> Result<()>
Finish the login process.
This method should be called after the URL returned by
OAuthAuthCodeUrlBuilder::build()
has been presented and the user has
been redirected to the redirect URI after completing the authorization.
If the authorization needs to be cancelled before its completion,
OAuth::abort_login()
should be used instead to clean up the local
data.
§Arguments
url_or_query
- The URI where the user was redirected, or just its query part.
Returns an error if the authorization failed, if a request fails, or if the client was already logged in with a different session.
Sourcepub async fn abort_login(&self, state: &CsrfToken)
pub async fn abort_login(&self, state: &CsrfToken)
Abort the login process.
This method should be called if a login should be aborted before it is completed.
If the login has been completed, OAuth::finish_login()
should be
used instead.
§Arguments
state
- The state provided inOAuthAuthorizationData
after building the authorization URL.
Sourcepub async fn refresh_access_token(&self) -> Result<(), RefreshTokenError>
pub async fn refresh_access_token(&self) -> Result<(), RefreshTokenError>
Refresh the access token.
This should be called when the access token has expired. It should not
be needed to call this manually if the Client
was constructed with
ClientBuilder::handle_refresh_tokens()
.
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.
Sourcepub async fn logout(&self) -> Result<(), OAuthError>
pub async fn logout(&self) -> Result<(), OAuthError>
Log out from the currently authenticated session.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for OAuth
impl !RefUnwindSafe for OAuth
impl Send for OAuth
impl Sync for OAuth
impl Unpin for OAuth
impl !UnwindSafe for OAuth
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,
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,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§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