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:
boxdot
2023-02-23 08:16:04 +01:00
committed by GitHub
parent 5be00d5950
commit d5154577a0
2 changed files with 66 additions and 4 deletions

View File

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

View File

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