client-api: Support custom login types
This commit is contained in:
parent
0c8adbb69e
commit
341869c83c
@ -1,7 +1,7 @@
|
|||||||
//! [GET /_matrix/client/r0/login](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-login)
|
//! [GET /_matrix/client/r0/login](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-login)
|
||||||
|
|
||||||
use ruma_api::ruma_api;
|
use ruma_api::ruma_api;
|
||||||
use serde::{Deserialize, Serialize};
|
use ruma_serde::StringEnum;
|
||||||
|
|
||||||
ruma_api! {
|
ruma_api! {
|
||||||
metadata: {
|
metadata: {
|
||||||
@ -18,7 +18,8 @@ ruma_api! {
|
|||||||
|
|
||||||
response: {
|
response: {
|
||||||
/// The homeserver's supported login types.
|
/// The homeserver's supported login types.
|
||||||
pub flows: Vec<LoginType>
|
#[serde(with = "login_type_list_serde")]
|
||||||
|
pub flows: Vec<LoginType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
error: crate::Error
|
error: crate::Error
|
||||||
@ -39,33 +40,51 @@ impl Response {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An authentication mechanism.
|
/// An authentication mechanism.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, StringEnum)]
|
||||||
#[serde(tag = "type")]
|
|
||||||
pub enum LoginType {
|
pub enum LoginType {
|
||||||
/// A password is supplied to authenticate.
|
/// A password is supplied to authenticate.
|
||||||
#[serde(rename = "m.login.password")]
|
#[ruma_enum(rename = "m.login.password")]
|
||||||
Password,
|
Password,
|
||||||
|
|
||||||
/// Token-based login.
|
/// Token-based login.
|
||||||
#[serde(rename = "m.login.token")]
|
#[ruma_enum(rename = "m.login.token")]
|
||||||
Token,
|
Token,
|
||||||
|
|
||||||
/// SSO-based login.
|
/// SSO-based login.
|
||||||
#[serde(rename = "m.login.sso")]
|
#[ruma_enum(rename = "m.login.sso")]
|
||||||
Sso,
|
Sso,
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
_Custom(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod login_type_list_serde;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use matches::assert_matches;
|
||||||
|
use serde::Deserialize;
|
||||||
use serde_json::{from_value as from_json_value, json};
|
use serde_json::{from_value as from_json_value, json};
|
||||||
|
|
||||||
use super::LoginType;
|
use super::{login_type_list_serde, LoginType};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Foo {
|
||||||
|
#[serde(with = "login_type_list_serde")]
|
||||||
|
pub flows: Vec<LoginType>,
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn deserialize_login_type() {
|
fn deserialize_login_type() {
|
||||||
assert_eq!(
|
assert_matches!(
|
||||||
from_json_value::<LoginType>(json!({ "type": "m.login.password" })).unwrap(),
|
from_json_value::<Foo>(json!({
|
||||||
LoginType::Password,
|
"flows": [
|
||||||
|
{ "type": "m.login.password" }
|
||||||
|
],
|
||||||
|
})),
|
||||||
|
Ok(Foo { flows })
|
||||||
|
if flows.len() == 1
|
||||||
|
&& flows[0] == LoginType::Password
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
|
use super::LoginType;
|
||||||
|
|
||||||
|
pub fn serialize<S>(login_types: &[LoginType], serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct Wrap<'a> {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
inner: &'a LoginType,
|
||||||
|
}
|
||||||
|
|
||||||
|
serializer.collect_seq(login_types.iter().map(|ty| Wrap { inner: ty }))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<LoginType>, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct Wrap {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
inner: LoginType,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Could be optimized by using a visitor, but that's a bunch of extra code
|
||||||
|
let vec = Vec::<Wrap>::deserialize(deserializer)?;
|
||||||
|
Ok(vec.into_iter().map(|w| w.inner).collect())
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user