Use serde_json::value::RawValue instead of serde_json::Value in most endpoints
This commit is contained in:
parent
b10e5e9ed1
commit
2bb96b5a2b
@ -23,3 +23,7 @@ ruma-serde = "0.1.3"
|
|||||||
serde = { version = "1.0.106", features = ["derive"] }
|
serde = { version = "1.0.106", features = ["derive"] }
|
||||||
serde_json = "1.0.52"
|
serde_json = "1.0.52"
|
||||||
strum = { version = "0.18.0", features = ["derive"] }
|
strum = { version = "0.18.0", features = ["derive"] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
maplit = "1.0.2"
|
||||||
|
matches = "0.1.8"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use ruma_api::ruma_api;
|
use ruma_api::ruma_api;
|
||||||
use ruma_identifiers::UserId;
|
use ruma_identifiers::UserId;
|
||||||
use serde_json::Value as JsonValue;
|
use serde_json::value::RawValue as RawJsonValue;
|
||||||
|
|
||||||
ruma_api! {
|
ruma_api! {
|
||||||
metadata {
|
metadata {
|
||||||
@ -16,8 +16,10 @@ ruma_api! {
|
|||||||
|
|
||||||
request {
|
request {
|
||||||
/// Arbitrary JSON to store as config data.
|
/// Arbitrary JSON to store as config data.
|
||||||
|
///
|
||||||
|
/// To create a `Box<RawJsonValue>`, use `serde_json::value::to_raw_value`.
|
||||||
#[ruma_api(body)]
|
#[ruma_api(body)]
|
||||||
pub data: JsonValue,
|
pub data: Box<RawJsonValue>,
|
||||||
|
|
||||||
/// The event type of the account_data to set.
|
/// The event type of the account_data to set.
|
||||||
///
|
///
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use ruma_api::ruma_api;
|
use ruma_api::ruma_api;
|
||||||
use ruma_identifiers::{RoomId, UserId};
|
use ruma_identifiers::{RoomId, UserId};
|
||||||
use serde_json::Value as JsonValue;
|
use serde_json::value::RawValue as RawJsonValue;
|
||||||
|
|
||||||
ruma_api! {
|
ruma_api! {
|
||||||
metadata {
|
metadata {
|
||||||
@ -16,8 +16,10 @@ ruma_api! {
|
|||||||
|
|
||||||
request {
|
request {
|
||||||
/// Arbitrary JSON to store as config data.
|
/// Arbitrary JSON to store as config data.
|
||||||
|
///
|
||||||
|
/// To create a `Box<RawJsonValue>`, use `serde_json::value::to_raw_value`.
|
||||||
#[ruma_api(body)]
|
#[ruma_api(body)]
|
||||||
pub data: JsonValue,
|
pub data: Box<RawJsonValue>,
|
||||||
|
|
||||||
/// The event type of the account_data to set.
|
/// The event type of the account_data to set.
|
||||||
///
|
///
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
use ruma_api::ruma_api;
|
use ruma_api::ruma_api;
|
||||||
use serde_json::Value as JsonValue;
|
use serde_json::value::RawValue as RawJsonValue;
|
||||||
|
|
||||||
ruma_api! {
|
ruma_api! {
|
||||||
metadata {
|
metadata {
|
||||||
@ -32,8 +32,42 @@ ruma_api! {
|
|||||||
/// Differences from OpenGraph: the image size in bytes is added to the `matrix:image:size`
|
/// Differences from OpenGraph: the image size in bytes is added to the `matrix:image:size`
|
||||||
/// field, and `og:image` returns the MXC URI to the image, if any.
|
/// field, and `og:image` returns the MXC URI to the image, if any.
|
||||||
#[ruma_api(body)]
|
#[ruma_api(body)]
|
||||||
pub data: Option<JsonValue>,
|
pub data: Option<Box<RawJsonValue>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
error: crate::Error
|
error: crate::Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use serde_json::{
|
||||||
|
from_value as from_json_value, json,
|
||||||
|
value::{to_raw_value as to_raw_json_value, RawValue as RawJsonValue},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Since BTreeMap<String, Box<RawJsonValue>> deserialization doesn't seem to
|
||||||
|
// work, test that Option<RawJsonValue> works
|
||||||
|
#[test]
|
||||||
|
fn raw_json_deserialize() {
|
||||||
|
type OptRawJson = Option<Box<RawJsonValue>>;
|
||||||
|
|
||||||
|
assert!(from_json_value::<OptRawJson>(json!(null))
|
||||||
|
.unwrap()
|
||||||
|
.is_none());
|
||||||
|
assert!(from_json_value::<OptRawJson>(json!("test"))
|
||||||
|
.unwrap()
|
||||||
|
.is_some());
|
||||||
|
assert!(from_json_value::<OptRawJson>(json!({ "a": "b" }))
|
||||||
|
.unwrap()
|
||||||
|
.is_some());
|
||||||
|
}
|
||||||
|
|
||||||
|
// For completeness sake, make sure serialization works too
|
||||||
|
#[test]
|
||||||
|
fn raw_json_serialize() {
|
||||||
|
assert!(to_raw_json_value(&json!(null)).is_ok());
|
||||||
|
assert!(to_raw_json_value(&json!("string")).is_ok());
|
||||||
|
assert!(to_raw_json_value(&json!({})).is_ok());
|
||||||
|
assert!(to_raw_json_value(&json!({ "a": "b" })).is_ok());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -4,7 +4,7 @@ use ruma_api::ruma_api;
|
|||||||
use ruma_events::{room::power_levels::PowerLevelsEventContent, EventJson};
|
use ruma_events::{room::power_levels::PowerLevelsEventContent, EventJson};
|
||||||
use ruma_identifiers::{RoomId, UserId};
|
use ruma_identifiers::{RoomId, UserId};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value as JsonValue;
|
use serde_json::value::RawValue as RawJsonValue;
|
||||||
|
|
||||||
use super::Visibility;
|
use super::Visibility;
|
||||||
use crate::r0::membership::Invite3pid;
|
use crate::r0::membership::Invite3pid;
|
||||||
@ -121,5 +121,7 @@ pub struct InitialStateEvent {
|
|||||||
pub state_key: Option<String>,
|
pub state_key: Option<String>,
|
||||||
|
|
||||||
/// JSON content of the state event.
|
/// JSON content of the state event.
|
||||||
pub content: JsonValue,
|
///
|
||||||
|
/// To create a `Box<RawJsonValue>`, use `serde_json::value::to_raw_value`.
|
||||||
|
pub content: Box<RawJsonValue>,
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use ruma_api::ruma_api;
|
use ruma_api::ruma_api;
|
||||||
use ruma_events::EventType;
|
use ruma_events::EventType;
|
||||||
use ruma_identifiers::RoomId;
|
use ruma_identifiers::RoomId;
|
||||||
use serde_json::Value as JsonValue;
|
use serde_json::value::RawValue as RawJsonValue;
|
||||||
|
|
||||||
ruma_api! {
|
ruma_api! {
|
||||||
metadata {
|
metadata {
|
||||||
@ -27,8 +27,10 @@ ruma_api! {
|
|||||||
|
|
||||||
response {
|
response {
|
||||||
/// The content of the state event.
|
/// The content of the state event.
|
||||||
|
///
|
||||||
|
/// To create a `Box<RawJsonValue>`, use `serde_json::value::to_raw_value`.
|
||||||
#[ruma_api(body)]
|
#[ruma_api(body)]
|
||||||
pub content: JsonValue,
|
pub content: Box<RawJsonValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
error: crate::Error
|
error: crate::Error
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use ruma_api::ruma_api;
|
use ruma_api::ruma_api;
|
||||||
use ruma_events::EventType;
|
use ruma_events::EventType;
|
||||||
use ruma_identifiers::RoomId;
|
use ruma_identifiers::RoomId;
|
||||||
use serde_json::Value as JsonValue;
|
use serde_json::value::RawValue as RawJsonValue;
|
||||||
|
|
||||||
ruma_api! {
|
ruma_api! {
|
||||||
metadata {
|
metadata {
|
||||||
@ -32,7 +32,7 @@ ruma_api! {
|
|||||||
response {
|
response {
|
||||||
/// The content of the state event.
|
/// The content of the state event.
|
||||||
#[ruma_api(body)]
|
#[ruma_api(body)]
|
||||||
pub content: JsonValue,
|
pub content: Box<RawJsonValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
error: crate::Error
|
error: crate::Error
|
||||||
|
264
src/r0/uiaa.rs
264
src/r0/uiaa.rs
@ -7,14 +7,16 @@ use std::{
|
|||||||
|
|
||||||
use ruma_api::{error::ResponseDeserializationError, EndpointError};
|
use ruma_api::{error::ResponseDeserializationError, EndpointError};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::{from_slice as from_json_slice, to_vec as to_json_vec, Value as JsonValue};
|
use serde_json::{
|
||||||
|
from_slice as from_json_slice, to_vec as to_json_vec, value::RawValue as RawJsonValue,
|
||||||
|
Value as JsonValue,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::error::{Error as MatrixError, ErrorBody};
|
use crate::error::{Error as MatrixError, ErrorBody};
|
||||||
|
|
||||||
/// Additional authentication information for the user-interactive authentication API.
|
/// Additional authentication information for the user-interactive authentication API.
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
#[cfg_attr(test, derive(PartialEq))]
|
|
||||||
pub enum AuthData {
|
pub enum AuthData {
|
||||||
/// Used for sending UIAA authentication requests to the homeserver directly
|
/// Used for sending UIAA authentication requests to the homeserver directly
|
||||||
/// from the client.
|
/// from the client.
|
||||||
@ -28,6 +30,7 @@ pub enum AuthData {
|
|||||||
session: Option<String>,
|
session: Option<String>,
|
||||||
|
|
||||||
/// Parameters submitted for a particular authentication stage.
|
/// Parameters submitted for a particular authentication stage.
|
||||||
|
// FIXME: RawJsonValue doesn't work here, is that a bug?
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
auth_parameters: BTreeMap<String, JsonValue>,
|
auth_parameters: BTreeMap<String, JsonValue>,
|
||||||
},
|
},
|
||||||
@ -43,7 +46,6 @@ pub enum AuthData {
|
|||||||
/// Information about available authentication flows and status for
|
/// Information about available authentication flows and status for
|
||||||
/// User-Interactive Authenticiation API.
|
/// User-Interactive Authenticiation API.
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
#[cfg_attr(test, derive(PartialEq))]
|
|
||||||
pub struct UiaaInfo {
|
pub struct UiaaInfo {
|
||||||
/// List of authentication flows available for this endpoint.
|
/// List of authentication flows available for this endpoint.
|
||||||
pub flows: Vec<AuthFlow>,
|
pub flows: Vec<AuthFlow>,
|
||||||
@ -52,8 +54,11 @@ pub struct UiaaInfo {
|
|||||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||||
pub completed: Vec<String>,
|
pub completed: Vec<String>,
|
||||||
|
|
||||||
/// Authentication parameters required for the client to complete authentication.
|
/// Authentication parameters required for the client to complete
|
||||||
pub params: JsonValue,
|
/// authentication.
|
||||||
|
///
|
||||||
|
/// To create a `Box<RawJsonValue>`, use `serde_json::value::to_raw_value`.
|
||||||
|
pub params: Box<RawJsonValue>,
|
||||||
|
|
||||||
/// Session key for client to use to complete authentication.
|
/// Session key for client to use to complete authentication.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
@ -129,12 +134,13 @@ impl From<UiaaResponse> for http::Response<Vec<u8>> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::collections::BTreeMap;
|
use maplit::btreemap;
|
||||||
|
use matches::assert_matches;
|
||||||
use ruma_api::EndpointError;
|
use ruma_api::EndpointError;
|
||||||
use serde_json::{
|
use serde_json::{
|
||||||
from_slice as from_json_slice, from_value as from_json_value, json,
|
from_slice as from_json_slice, from_str as from_json_str, from_value as from_json_value,
|
||||||
to_value as to_json_value, Value as JsonValue,
|
json, to_value as to_json_value, value::to_raw_value as to_raw_json_value,
|
||||||
|
Value as JsonValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{AuthData, AuthFlow, UiaaInfo, UiaaResponse};
|
use super::{AuthData, AuthFlow, UiaaInfo, UiaaResponse};
|
||||||
@ -142,40 +148,40 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_serialize_authentication_data_direct_request() {
|
fn test_serialize_authentication_data_direct_request() {
|
||||||
let mut auth_parameters = BTreeMap::new();
|
|
||||||
auth_parameters.insert(
|
|
||||||
"example_credential".into(),
|
|
||||||
JsonValue::String("verypoorsharedsecret".into()),
|
|
||||||
);
|
|
||||||
let authentication_data = AuthData::DirectRequest {
|
let authentication_data = AuthData::DirectRequest {
|
||||||
kind: "example.type.foo".to_string(),
|
kind: "example.type.foo".to_string(),
|
||||||
session: Some("ZXY000".to_string()),
|
session: Some("ZXY000".to_string()),
|
||||||
auth_parameters,
|
auth_parameters: btreemap! {
|
||||||
|
"example_credential".to_owned() => json!("verypoorsharedsecret")
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
json!({ "type": "example.type.foo", "session": "ZXY000", "example_credential": "verypoorsharedsecret" }),
|
json!({
|
||||||
|
"type": "example.type.foo",
|
||||||
|
"session": "ZXY000",
|
||||||
|
"example_credential": "verypoorsharedsecret",
|
||||||
|
}),
|
||||||
to_json_value(authentication_data).unwrap()
|
to_json_value(authentication_data).unwrap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_deserialize_authentication_data_direct_request() {
|
fn test_deserialize_authentication_data_direct_request() {
|
||||||
let mut auth_parameters = BTreeMap::new();
|
let json = json!({
|
||||||
auth_parameters.insert(
|
"type": "example.type.foo",
|
||||||
"example_credential".into(),
|
"session": "opaque_session_id",
|
||||||
JsonValue::String("verypoorsharedsecret".into()),
|
"example_credential": "verypoorsharedsecret",
|
||||||
);
|
});
|
||||||
let authentication_data = AuthData::DirectRequest {
|
|
||||||
kind: "example.type.foo".into(),
|
|
||||||
session: Some("opaque_session_id".to_string()),
|
|
||||||
auth_parameters,
|
|
||||||
};
|
|
||||||
let json = json!({ "type": "example.type.foo", "session": "opaque_session_id", "example_credential": "verypoorsharedsecret", });
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_matches!(
|
||||||
from_json_value::<AuthData>(json).unwrap(),
|
from_json_value::<AuthData>(json).unwrap(),
|
||||||
authentication_data
|
AuthData::DirectRequest { kind, session: Some(session), auth_parameters }
|
||||||
|
if kind == "example.type.foo"
|
||||||
|
&& session == "opaque_session_id"
|
||||||
|
&& auth_parameters == btreemap!{
|
||||||
|
"example_credential".to_owned() => json!("verypoorsharedsecret")
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,31 +199,28 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_deserialize_authentication_data_fallback() {
|
fn test_deserialize_authentication_data_fallback() {
|
||||||
let authentication_data = AuthData::FallbackAcknowledgement {
|
|
||||||
session: "opaque_session_id".to_string(),
|
|
||||||
};
|
|
||||||
let json = json!({ "session": "opaque_session_id" });
|
let json = json!({ "session": "opaque_session_id" });
|
||||||
|
|
||||||
assert_eq!(
|
assert_matches!(
|
||||||
from_json_value::<AuthData>(json).unwrap(),
|
from_json_value::<AuthData>(json).unwrap(),
|
||||||
authentication_data
|
AuthData::FallbackAcknowledgement { session }
|
||||||
|
if session == "opaque_session_id"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_serialize_uiaa_info() {
|
fn test_serialize_uiaa_info() {
|
||||||
let params = json!({
|
|
||||||
"example.type.baz": {
|
|
||||||
"example_key": "foobar"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let uiaa_info = UiaaInfo {
|
let uiaa_info = UiaaInfo {
|
||||||
flows: vec![AuthFlow {
|
flows: vec![AuthFlow {
|
||||||
stages: vec!["m.login.password".to_string(), "m.login.dummy".to_string()],
|
stages: vec!["m.login.password".to_string(), "m.login.dummy".to_string()],
|
||||||
}],
|
}],
|
||||||
completed: vec!["m.login.password".to_string()],
|
completed: vec!["m.login.password".to_string()],
|
||||||
params,
|
params: to_raw_json_value(&json!({
|
||||||
|
"example.type.baz": {
|
||||||
|
"example_key": "foobar"
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.unwrap(),
|
||||||
session: None,
|
session: None,
|
||||||
auth_error: None,
|
auth_error: None,
|
||||||
};
|
};
|
||||||
@ -239,13 +242,13 @@ mod tests {
|
|||||||
let json = json!({
|
let json = json!({
|
||||||
"errcode": "M_FORBIDDEN",
|
"errcode": "M_FORBIDDEN",
|
||||||
"error": "Invalid password",
|
"error": "Invalid password",
|
||||||
"completed": [ "example.type.foo" ],
|
"completed": ["example.type.foo"],
|
||||||
"flows": [
|
"flows": [
|
||||||
{
|
{
|
||||||
"stages": [ "example.type.foo", "example.type.bar" ]
|
"stages": ["example.type.foo", "example.type.bar"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"stages": [ "example.type.foo", "example.type.baz" ]
|
"stages": ["example.type.foo", "example.type.baz"]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"params": {
|
"params": {
|
||||||
@ -256,59 +259,77 @@ mod tests {
|
|||||||
"session": "xxxxxx"
|
"session": "xxxxxx"
|
||||||
});
|
});
|
||||||
|
|
||||||
let uiaa_info = UiaaInfo {
|
assert_matches!(
|
||||||
auth_error: Some(ErrorBody {
|
from_json_value::<UiaaInfo>(json).unwrap(),
|
||||||
kind: ErrorKind::Forbidden,
|
UiaaInfo {
|
||||||
message: "Invalid password".to_string(),
|
auth_error: Some(ErrorBody {
|
||||||
}),
|
kind: ErrorKind::Forbidden,
|
||||||
completed: vec!["example.type.foo".to_string()],
|
message: error_message,
|
||||||
flows: vec![
|
}),
|
||||||
AuthFlow {
|
completed,
|
||||||
stages: vec![
|
flows,
|
||||||
"example.type.foo".to_string(),
|
params,
|
||||||
"example.type.bar".to_string(),
|
session: Some(session),
|
||||||
],
|
} if error_message == "Invalid password"
|
||||||
},
|
&& completed == vec!["example.type.foo".to_string()]
|
||||||
AuthFlow {
|
&& flows == vec![
|
||||||
stages: vec![
|
AuthFlow {
|
||||||
"example.type.foo".to_string(),
|
stages: vec![
|
||||||
"example.type.baz".to_string(),
|
"example.type.foo".to_string(),
|
||||||
],
|
"example.type.bar".to_string(),
|
||||||
},
|
],
|
||||||
],
|
},
|
||||||
params: json!({
|
AuthFlow {
|
||||||
"example.type.baz": {
|
stages: vec![
|
||||||
"example_key": "foobar"
|
"example.type.foo".to_string(),
|
||||||
}
|
"example.type.baz".to_string(),
|
||||||
}),
|
],
|
||||||
session: Some("xxxxxx".to_string()),
|
},
|
||||||
};
|
]
|
||||||
assert_eq!(from_json_value::<UiaaInfo>(json).unwrap(), uiaa_info);
|
&& from_json_str::<JsonValue>(params.get()).unwrap() == json!({
|
||||||
|
"example.type.baz": {
|
||||||
|
"example_key": "foobar"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
&& session == "xxxxxx"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_try_uiaa_response_into_http_response() {
|
fn test_try_uiaa_response_into_http_response() {
|
||||||
let params = json!({
|
|
||||||
"example.type.baz": {
|
|
||||||
"example_key": "foobar"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let uiaa_info = UiaaInfo {
|
let uiaa_info = UiaaInfo {
|
||||||
flows: vec![AuthFlow {
|
flows: vec![AuthFlow {
|
||||||
stages: vec!["m.login.password".to_string(), "m.login.dummy".to_string()],
|
stages: vec!["m.login.password".to_string(), "m.login.dummy".to_string()],
|
||||||
}],
|
}],
|
||||||
completed: vec!["m.login.password".to_string()],
|
completed: vec!["m.login.password".to_string()],
|
||||||
params,
|
params: to_raw_json_value(&json!({
|
||||||
|
"example.type.baz": {
|
||||||
|
"example_key": "foobar"
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.unwrap(),
|
||||||
session: None,
|
session: None,
|
||||||
auth_error: None,
|
auth_error: None,
|
||||||
};
|
};
|
||||||
let uiaa_response: http::Response<Vec<u8>> =
|
let uiaa_response: http::Response<Vec<u8>> = UiaaResponse::AuthResponse(uiaa_info).into();
|
||||||
UiaaResponse::AuthResponse(uiaa_info.clone()).into();
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_matches!(
|
||||||
from_json_slice::<UiaaInfo>(uiaa_response.body()).unwrap(),
|
from_json_slice::<UiaaInfo>(uiaa_response.body()).unwrap(),
|
||||||
uiaa_info,
|
UiaaInfo {
|
||||||
|
flows,
|
||||||
|
completed,
|
||||||
|
params,
|
||||||
|
session: None,
|
||||||
|
auth_error: None,
|
||||||
|
} if flows == vec![AuthFlow {
|
||||||
|
stages: vec!["m.login.password".to_string(), "m.login.dummy".to_string()],
|
||||||
|
}]
|
||||||
|
&& completed == vec!["m.login.password".to_string()]
|
||||||
|
&& from_json_str::<JsonValue>(params.get()).unwrap() == json!({
|
||||||
|
"example.type.baz": {
|
||||||
|
"example_key": "foobar"
|
||||||
|
}
|
||||||
|
})
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
uiaa_response.status(),
|
uiaa_response.status(),
|
||||||
@ -324,10 +345,10 @@ mod tests {
|
|||||||
"completed": [ "example.type.foo" ],
|
"completed": [ "example.type.foo" ],
|
||||||
"flows": [
|
"flows": [
|
||||||
{
|
{
|
||||||
"stages": [ "example.type.foo", "example.type.bar" ]
|
"stages": [ "example.type.foo", "example.type.bar" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"stages": [ "example.type.foo", "example.type.baz" ]
|
"stages": [ "example.type.foo", "example.type.baz" ]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"params": {
|
"params": {
|
||||||
@ -338,47 +359,50 @@ mod tests {
|
|||||||
"session": "xxxxxx"
|
"session": "xxxxxx"
|
||||||
}))
|
}))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let http_response = http::Response::builder()
|
let http_response = http::Response::builder()
|
||||||
.status(http::StatusCode::UNAUTHORIZED)
|
.status(http::StatusCode::UNAUTHORIZED)
|
||||||
.body(json.into())
|
.body(json.into())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let uiaa_info = UiaaInfo {
|
let parsed_uiaa_info = match UiaaResponse::try_from_response(http_response).unwrap() {
|
||||||
auth_error: Some(ErrorBody {
|
UiaaResponse::AuthResponse(uiaa_info) => uiaa_info,
|
||||||
kind: ErrorKind::Forbidden,
|
_ => panic!("Expected UiaaResponse::AuthResponse"),
|
||||||
message: "Invalid password".to_string(),
|
|
||||||
}),
|
|
||||||
completed: vec!["example.type.foo".to_string()],
|
|
||||||
flows: vec![
|
|
||||||
AuthFlow {
|
|
||||||
stages: vec![
|
|
||||||
"example.type.foo".to_string(),
|
|
||||||
"example.type.bar".to_string(),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
AuthFlow {
|
|
||||||
stages: vec![
|
|
||||||
"example.type.foo".to_string(),
|
|
||||||
"example.type.baz".to_string(),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
params: json!({
|
|
||||||
"example.type.baz": {
|
|
||||||
"example_key": "foobar"
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
session: Some("xxxxxx".to_string()),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let parsed_uiaa_info = match UiaaResponse::try_from_response(http_response) {
|
assert_matches!(
|
||||||
Ok(auth_response) => match auth_response {
|
parsed_uiaa_info,
|
||||||
UiaaResponse::AuthResponse(uiaa_info) => Some(uiaa_info),
|
UiaaInfo {
|
||||||
_ => None,
|
auth_error: Some(ErrorBody {
|
||||||
},
|
kind: ErrorKind::Forbidden,
|
||||||
_ => None,
|
message: error_message,
|
||||||
};
|
}),
|
||||||
|
completed,
|
||||||
assert_eq!(parsed_uiaa_info, Some(uiaa_info));
|
flows,
|
||||||
|
params,
|
||||||
|
session: Some(session),
|
||||||
|
} if error_message == "Invalid password"
|
||||||
|
&& completed == vec!["example.type.foo".to_string()]
|
||||||
|
&& flows == vec![
|
||||||
|
AuthFlow {
|
||||||
|
stages: vec![
|
||||||
|
"example.type.foo".to_string(),
|
||||||
|
"example.type.bar".to_string(),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
AuthFlow {
|
||||||
|
stages: vec![
|
||||||
|
"example.type.foo".to_string(),
|
||||||
|
"example.type.baz".to_string(),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
&& from_json_str::<JsonValue>(params.get()).unwrap() == json!({
|
||||||
|
"example.type.baz": {
|
||||||
|
"example_key": "foobar"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
&& session == "xxxxxx"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user