From 898ec65e77084a15c90b5c466ac7c34b5aa961fd Mon Sep 17 00:00:00 2001 From: Callum Brown Date: Wed, 22 Sep 2021 13:18:03 +0100 Subject: [PATCH] client-api: Add registration token UIAA type (from MSC3231) --- crates/ruma-client-api/src/r0/uiaa.rs | 44 +++++++++++++++++++++++++++ crates/ruma-client-api/tests/uiaa.rs | 35 +++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/crates/ruma-client-api/src/r0/uiaa.rs b/crates/ruma-client-api/src/r0/uiaa.rs index 60101b40..defd07e5 100644 --- a/crates/ruma-client-api/src/r0/uiaa.rs +++ b/crates/ruma-client-api/src/r0/uiaa.rs @@ -52,6 +52,11 @@ pub enum AuthData<'a> { /// Dummy authentication (`m.login.dummy`). Dummy(Dummy<'a>), + /// Registration token-based authentication (`org.matrix.msc3231.login.registration_token`) + #[cfg(feature = "unstable-pre-spec")] + #[cfg_attr(docsrs, doc(cfg(feature = "unstable-pre-spec")))] + RegistrationToken(RegistrationToken<'a>), + /// Fallback acknowledgement. FallbackAcknowledgement(FallbackAcknowledgement<'a>), @@ -75,6 +80,8 @@ impl<'a> AuthData<'a> { Self::EmailIdentity(_) => Some("m.login.email.identity"), Self::Msisdn(_) => Some("m.login.msisdn"), Self::Dummy(_) => Some("m.login.dummy"), + #[cfg(feature = "unstable-pre-spec")] + Self::RegistrationToken(_) => Some("org.matrix.msc3231.login.registration_token"), Self::FallbackAcknowledgement(_) => None, Self::_Custom(c) => Some(c.auth_type), } @@ -90,6 +97,8 @@ impl<'a> AuthData<'a> { Self::EmailIdentity(x) => x.session, Self::Msisdn(x) => x.session, Self::Dummy(x) => x.session, + #[cfg(feature = "unstable-pre-spec")] + Self::RegistrationToken(x) => x.session, Self::FallbackAcknowledgement(x) => Some(x.session), Self::_Custom(x) => x.session, } @@ -107,6 +116,8 @@ impl IncomingAuthData { Self::EmailIdentity(_) => Some("m.login.email.identity"), Self::Msisdn(_) => Some("m.login.msisdn"), Self::Dummy(_) => Some("m.login.dummy"), + #[cfg(feature = "unstable-pre-spec")] + Self::RegistrationToken(_) => Some("org.matrix.msc3231.login.registration_token"), Self::FallbackAcknowledgement(_) => None, Self::_Custom(c) => Some(&c.auth_type), } @@ -122,6 +133,8 @@ impl IncomingAuthData { Self::EmailIdentity(x) => x.session.as_deref(), Self::Msisdn(x) => x.session.as_deref(), Self::Dummy(x) => x.session.as_deref(), + #[cfg(feature = "unstable-pre-spec")] + Self::RegistrationToken(x) => x.session.as_deref(), Self::FallbackAcknowledgement(x) => Some(&x.session), Self::_Custom(x) => x.session.as_deref(), } @@ -159,6 +172,10 @@ impl<'de> Deserialize<'de> for IncomingAuthData { Some("m.login.email.identity") => from_raw_json_value(&json).map(Self::EmailIdentity), Some("m.login.msisdn") => from_raw_json_value(&json).map(Self::Msisdn), Some("m.login.dummy") => from_raw_json_value(&json).map(Self::Dummy), + #[cfg(feature = "unstable-pre-spec")] + Some("org.matrix.msc3231.login.registration_token") => { + from_raw_json_value(&json).map(Self::RegistrationToken) + } None => from_raw_json_value(&json).map(Self::FallbackAcknowledgement), Some(_) => from_raw_json_value(&json).map(Self::_Custom), } @@ -317,6 +334,33 @@ impl Dummy<'_> { } } +/// Data for registration token-based UIAA flow. +/// +/// See [MSC3231] for how to use this. +/// +/// [MSC3231]: https://github.com/matrix-org/matrix-doc/pull/3231 +#[derive(Clone, Debug, Outgoing, Serialize)] +#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] +#[cfg(feature = "unstable-pre-spec")] +#[cfg_attr(docsrs, doc(cfg(feature = "unstable-pre-spec")))] +#[serde(tag = "type", rename = "org.matrix.msc3231.login.registration_token")] +pub struct RegistrationToken<'a> { + /// The registration token. + pub token: &'a str, + + /// The value of the session key given by the homeserver, if any. + pub session: Option<&'a str>, +} + +#[cfg(feature = "unstable-pre-spec")] +#[cfg_attr(docsrs, doc(cfg(feature = "unstable-pre-spec")))] +impl<'a> RegistrationToken<'a> { + /// Creates a new `RegistrationToken` with the given token. + pub fn new(token: &'a str) -> Self { + Self { token, session: None } + } +} + /// Data for UIAA fallback acknowledgement. /// /// See [the spec] for how to use this. diff --git a/crates/ruma-client-api/tests/uiaa.rs b/crates/ruma-client-api/tests/uiaa.rs index 2d224b51..147795eb 100644 --- a/crates/ruma-client-api/tests/uiaa.rs +++ b/crates/ruma-client-api/tests/uiaa.rs @@ -63,6 +63,41 @@ fn deserialize_auth_data_direct_request() { ); } +#[test] +#[cfg(feature = "unstable-pre-spec")] +fn serialize_auth_data_registration_token() { + let auth_data = AuthData::RegistrationToken( + assign!(uiaa::RegistrationToken::new("mytoken"), { session: Some("session") }), + ); + + assert_matches!( + to_json_value(auth_data), + Ok(val) if val == json!({ + "type": "org.matrix.msc3231.login.registration_token", + "token": "mytoken", + "session": "session", + }) + ); +} + +#[test] +#[cfg(feature = "unstable-pre-spec")] +fn deserialize_auth_data_registration_token() { + let json = json!({ + "type": "org.matrix.msc3231.login.registration_token", + "token": "mytoken", + "session": "session", + }); + + assert_matches!( + from_json_value(json), + Ok(IncomingAuthData::RegistrationToken( + uiaa::IncomingRegistrationToken { token, session: Some(session), .. }, + )) + if token == "mytoken" && session == "session" + ); +} + #[test] fn serialize_auth_data_fallback() { let auth_data = AuthData::FallbackAcknowledgement(uiaa::FallbackAcknowledgement::new("ZXY000"));