mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-15 11:36:07 -04:00
feat(sdk): Add custom login method
The `Client::login_custom` allows to login by using a custom login method. In particular, it is possible to login to Synapse which supports JWT authentication. Signed-off-by: boxdot <d@zerovolt.org>
This commit is contained in:
@@ -22,6 +22,7 @@ use std::{
|
||||
use ruma::{
|
||||
api::client::{session::login, uiaa::UserIdentifier},
|
||||
assign,
|
||||
serde::JsonObject,
|
||||
};
|
||||
use tracing::{info, instrument};
|
||||
|
||||
@@ -35,16 +36,20 @@ use crate::{config::RequestConfig, Result};
|
||||
/// [the spec]: https://spec.matrix.org/v1.3/client-server-api/#post_matrixclientv3login
|
||||
enum LoginMethod {
|
||||
/// Login type `m.login.password`
|
||||
UserPassword { id: UserIdentifier, password: String },
|
||||
UserPassword {
|
||||
id: UserIdentifier,
|
||||
password: String,
|
||||
},
|
||||
/// Login type `m.token`
|
||||
Token(String),
|
||||
Custom(login::v3::LoginInfo),
|
||||
}
|
||||
|
||||
impl LoginMethod {
|
||||
fn id(&self) -> Option<&UserIdentifier> {
|
||||
match self {
|
||||
LoginMethod::UserPassword { id, .. } => Some(id),
|
||||
LoginMethod::Token(_) => None,
|
||||
LoginMethod::Token(_) | LoginMethod::Custom(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +57,7 @@ impl LoginMethod {
|
||||
match self {
|
||||
LoginMethod::UserPassword { .. } => "identifier and password",
|
||||
LoginMethod::Token(_) => "token",
|
||||
LoginMethod::Custom(_) => "custom",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +67,7 @@ impl LoginMethod {
|
||||
login::v3::LoginInfo::Password(login::v3::Password::new(id, password))
|
||||
}
|
||||
LoginMethod::Token(token) => login::v3::LoginInfo::Token(login::v3::Token::new(token)),
|
||||
LoginMethod::Custom(login_info) => login_info,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,6 +105,15 @@ impl LoginBuilder {
|
||||
Self::new(client, LoginMethod::Token(token))
|
||||
}
|
||||
|
||||
pub(super) fn new_custom(
|
||||
client: Client,
|
||||
login_type: &str,
|
||||
data: JsonObject,
|
||||
) -> serde_json::Result<Self> {
|
||||
let login_info = login::v3::LoginInfo::new(login_type, data)?;
|
||||
Ok(Self::new(client, LoginMethod::Custom(login_info)))
|
||||
}
|
||||
|
||||
/// Set the device ID.
|
||||
///
|
||||
/// The device ID is a unique ID that will be associated with this session.
|
||||
|
||||
@@ -61,8 +61,10 @@ use ruma::{
|
||||
error::FromHttpResponseError,
|
||||
MatrixVersion, OutgoingRequest, SendAccessToken,
|
||||
},
|
||||
assign, DeviceId, OwnedDeviceId, OwnedRoomId, OwnedServerName, RoomAliasId, RoomId,
|
||||
RoomOrAliasId, ServerName, UInt, UserId,
|
||||
assign,
|
||||
serde::JsonObject,
|
||||
DeviceId, OwnedDeviceId, OwnedRoomId, OwnedServerName, RoomAliasId, RoomId, RoomOrAliasId,
|
||||
ServerName, UInt, UserId,
|
||||
};
|
||||
use serde::de::DeserializeOwned;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
@@ -1017,6 +1019,50 @@ impl Client {
|
||||
LoginBuilder::new_password(self.clone(), id, password.to_owned())
|
||||
}
|
||||
|
||||
/// Login to 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.
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use futures::executor::block_on;
|
||||
/// # use url::Url;
|
||||
/// # let homeserver = Url::parse("http://example.com").unwrap();
|
||||
/// # block_on(async {
|
||||
/// use matrix_sdk::Client;
|
||||
///
|
||||
/// let client = Client::new(homeserver).await?;
|
||||
/// let user = "example";
|
||||
///
|
||||
/// let response = client
|
||||
/// .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,
|
||||
/// );
|
||||
/// # anyhow::Ok(()) });
|
||||
/// ```
|
||||
pub fn login_custom(
|
||||
&self,
|
||||
login_type: &str,
|
||||
data: JsonObject,
|
||||
) -> serde_json::Result<LoginBuilder> {
|
||||
LoginBuilder::new_custom(self.clone(), login_type, data)
|
||||
}
|
||||
|
||||
/// Login to the server with a token.
|
||||
///
|
||||
/// This token is usually received in the SSO flow after following the URL
|
||||
|
||||
Reference in New Issue
Block a user