client-api: Add support for using an existing session to log in another

According to MSC3882
This commit is contained in:
Kévin Commaille 2023-05-24 17:57:07 +02:00 committed by Kévin Commaille
parent 5f20a3292c
commit 0b390cc3c9
4 changed files with 84 additions and 3 deletions

View File

@ -9,6 +9,7 @@ Breaking changes:
Improvements:
- Add convenience constructors for enabling lazy-loading in filters
- Add support for using an existing session to log in another (MSC3882 / Matrix 1.7)
# 0.16.2

View File

@ -1,5 +1,6 @@
//! Endpoints for user session management.
pub mod get_login_token;
pub mod get_login_types;
pub mod login;
pub mod login_fallback;

View File

@ -0,0 +1,75 @@
//! `GET /_matrix/client/*/login/get_token`
//!
//! Generate a single-use, time-limited, `m.login.token` token.
pub mod v1 {
//! `/v1/` ([spec])
//!
//! [spec]: https://spec.matrix.org/latest/client-server-api/#post_matrixclientv1loginget_token
use std::time::Duration;
use ruma_common::{
api::{request, response, Metadata},
metadata,
};
use crate::uiaa::{AuthData, UiaaResponse};
const METADATA: Metadata = metadata! {
method: POST,
rate_limited: true,
authentication: AccessToken,
history: {
unstable => "/_matrix/client/unstable/org.matrix.msc3882/login/get_token",
1.7 => "/_matrix/client/v1/login/get_token",
}
};
/// Request type for the `login` endpoint.
#[request(error = UiaaResponse)]
#[derive(Default)]
pub struct Request {
/// Additional authentication information for the user-interactive authentication API.
#[serde(skip_serializing_if = "Option::is_none")]
pub auth: Option<AuthData>,
}
/// Response type for the `login` endpoint.
#[response(error = UiaaResponse)]
pub struct Response {
/// The time remaining in milliseconds until the homeserver will no longer accept the
/// token.
///
/// 2 minutes is recommended as a default.
#[serde(with = "ruma_common::serde::duration::ms", rename = "expires_in_ms")]
pub expires_in: Duration,
/// The login token for the `m.login.token` login flow.
pub login_token: String,
}
impl Request {
/// Creates a new empty `Request`.
pub fn new() -> Self {
Self::default()
}
}
impl Response {
/// Creates a new `Response` with the given expiration duration and login token.
pub fn new(expires_in: Duration, login_token: String) -> Self {
Self { expires_in, login_token }
}
/// Creates a new `Response` with the default expiration duration and the given login token.
pub fn with_default_expiration_duration(login_token: String) -> Self {
Self::new(Self::default_expiration_duration(), login_token)
}
fn default_expiration_duration() -> Duration {
// 2 minutes.
Duration::from_secs(2 * 60)
}
}
}

View File

@ -151,12 +151,16 @@ pub mod v3 {
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[serde(tag = "type", rename = "m.login.token")]
pub struct TokenLoginType {}
pub struct TokenLoginType {
/// Whether the homeserver supports the `POST /login/get_token` endpoint.
#[serde(default, skip_serializing_if = "ruma_common::serde::is_default")]
pub get_login_token: bool,
}
impl TokenLoginType {
/// Creates a new `TokenLoginType`.
pub fn new() -> Self {
Self {}
Self { get_login_token: false }
}
}
@ -409,7 +413,7 @@ pub mod v3 {
fn serialize_sso_login_type() {
let wrapper = to_json_value(Wrapper {
flows: vec![
LoginType::Token(TokenLoginType {}),
LoginType::Token(TokenLoginType::new()),
LoginType::Sso(SsoLoginType {
identity_providers: vec![IdentityProvider {
id: "oidc-github".into(),