impl Deserialize m.key.verification.start
This commit is contained in:
parent
04cc113473
commit
30c1ef07dc
@ -10,7 +10,7 @@ use super::{
|
|||||||
HashAlgorithm, KeyAgreementProtocol, MessageAuthenticationCode, ShortAuthenticationString,
|
HashAlgorithm, KeyAgreementProtocol, MessageAuthenticationCode, ShortAuthenticationString,
|
||||||
VerificationMethod,
|
VerificationMethod,
|
||||||
};
|
};
|
||||||
use crate::{Event, EventType, InnerInvalidEvent, InvalidEvent, InvalidInput};
|
use crate::{Event, EventResult, EventType, InnerInvalidEvent, InvalidEvent, InvalidInput};
|
||||||
|
|
||||||
/// Begins an SAS key verification process.
|
/// Begins an SAS key verification process.
|
||||||
///
|
///
|
||||||
@ -33,6 +33,36 @@ pub enum StartEventContent {
|
|||||||
__Nonexhaustive,
|
__Nonexhaustive,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for EventResult<StartEvent> {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let json = serde_json::Value::deserialize(deserializer)?;
|
||||||
|
|
||||||
|
let raw: raw::StartEvent = match serde_json::from_value(json.clone()) {
|
||||||
|
Ok(raw) => raw,
|
||||||
|
Err(error) => {
|
||||||
|
return Ok(EventResult::Err(InvalidEvent(
|
||||||
|
InnerInvalidEvent::Validation {
|
||||||
|
json,
|
||||||
|
message: error.to_string(),
|
||||||
|
},
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let content = match raw.content {
|
||||||
|
raw::StartEventContent::MSasV1(content) => StartEventContent::MSasV1(content),
|
||||||
|
raw::StartEventContent::__Nonexhaustive => {
|
||||||
|
panic!("__Nonexhaustive enum variant is not intended for use.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(EventResult::Ok(StartEvent { content }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for StartEvent {
|
impl FromStr for StartEvent {
|
||||||
type Err = InvalidEvent;
|
type Err = InvalidEvent;
|
||||||
|
|
||||||
@ -93,6 +123,76 @@ impl_event!(
|
|||||||
EventType::KeyVerificationStart
|
EventType::KeyVerificationStart
|
||||||
);
|
);
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for EventResult<StartEventContent> {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let json = serde_json::Value::deserialize(deserializer)?;
|
||||||
|
|
||||||
|
let raw: raw::StartEventContent = match serde_json::from_value(json.clone()) {
|
||||||
|
Ok(raw) => raw,
|
||||||
|
Err(error) => {
|
||||||
|
return Ok(EventResult::Err(InvalidEvent(
|
||||||
|
InnerInvalidEvent::Validation {
|
||||||
|
json,
|
||||||
|
message: error.to_string(),
|
||||||
|
},
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match raw {
|
||||||
|
raw::StartEventContent::MSasV1(content) => {
|
||||||
|
if !content
|
||||||
|
.key_agreement_protocols
|
||||||
|
.contains(&KeyAgreementProtocol::Curve25519)
|
||||||
|
{
|
||||||
|
return Ok(EventResult::Err(InvalidEvent(InnerInvalidEvent::Validation {
|
||||||
|
json,
|
||||||
|
message: "`key_agreement_protocols` must contain at least `KeyAgreementProtocol::Curve25519`".to_string(),
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
|
if !content.hashes.contains(&HashAlgorithm::Sha256) {
|
||||||
|
return Ok(EventResult::Err(InvalidEvent(
|
||||||
|
InnerInvalidEvent::Validation {
|
||||||
|
json,
|
||||||
|
message: "`hashes` must contain at least `HashAlgorithm::Sha256`"
|
||||||
|
.to_string(),
|
||||||
|
},
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if !content
|
||||||
|
.message_authentication_codes
|
||||||
|
.contains(&MessageAuthenticationCode::HkdfHmacSha256)
|
||||||
|
{
|
||||||
|
return Ok(EventResult::Err(InvalidEvent(InnerInvalidEvent::Validation {
|
||||||
|
json,
|
||||||
|
message: "`message_authentication_codes` must contain at least `MessageAuthenticationCode::HkdfHmacSha256`".to_string(),
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
|
if !content
|
||||||
|
.short_authentication_string
|
||||||
|
.contains(&ShortAuthenticationString::Decimal)
|
||||||
|
{
|
||||||
|
return Ok(EventResult::Err(InvalidEvent(InnerInvalidEvent::Validation {
|
||||||
|
json,
|
||||||
|
message: "`short_authentication_string` must contain at least `ShortAuthenticationString::Decimal`".to_string(),
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(EventResult::Ok(StartEventContent::MSasV1(content)))
|
||||||
|
}
|
||||||
|
raw::StartEventContent::__Nonexhaustive => {
|
||||||
|
panic!("__Nonexhaustive enum variant is not intended for use.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for StartEventContent {
|
impl FromStr for StartEventContent {
|
||||||
type Err = InvalidEvent;
|
type Err = InvalidEvent;
|
||||||
|
|
||||||
@ -390,7 +490,7 @@ mod tests {
|
|||||||
use serde_json::to_string;
|
use serde_json::to_string;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
HashAlgorithm, KeyAgreementProtocol, MSasV1Content, MSasV1ContentOptions,
|
EventResult, HashAlgorithm, KeyAgreementProtocol, MSasV1Content, MSasV1ContentOptions,
|
||||||
MessageAuthenticationCode, ShortAuthenticationString, StartEvent, StartEventContent,
|
MessageAuthenticationCode, ShortAuthenticationString, StartEvent, StartEventContent,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -498,8 +598,11 @@ mod tests {
|
|||||||
|
|
||||||
// Deserialize the content struct separately to verify `FromStr` is implemented for it.
|
// Deserialize the content struct separately to verify `FromStr` is implemented for it.
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
r#"{"from_device":"123","transaction_id":"456","method":"m.sas.v1","hashes":["sha256"],"key_agreement_protocols":["curve25519"],"message_authentication_codes":["hkdf-hmac-sha256"],"short_authentication_string":["decimal"]}"#
|
serde_json::from_str::<EventResult<StartEventContent>>(
|
||||||
.parse::<StartEventContent>()
|
r#"{"from_device":"123","transaction_id":"456","method":"m.sas.v1","hashes":["sha256"],"key_agreement_protocols":["curve25519"],"message_authentication_codes":["hkdf-hmac-sha256"],"short_authentication_string":["decimal"]}"#
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.into()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
key_verification_start_content
|
key_verification_start_content
|
||||||
);
|
);
|
||||||
@ -509,8 +612,11 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
r#"{"content":{"from_device":"123","transaction_id":"456","method":"m.sas.v1","key_agreement_protocols":["curve25519"],"hashes":["sha256"],"message_authentication_codes":["hkdf-hmac-sha256"],"short_authentication_string":["decimal"]},"type":"m.key.verification.start"}"#
|
serde_json::from_str::<EventResult<StartEvent>>(
|
||||||
.parse::<StartEvent>()
|
r#"{"content":{"from_device":"123","transaction_id":"456","method":"m.sas.v1","key_agreement_protocols":["curve25519"],"hashes":["sha256"],"message_authentication_codes":["hkdf-hmac-sha256"],"short_authentication_string":["decimal"]},"type":"m.key.verification.start"}"#
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.into()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
key_verification_start
|
key_verification_start
|
||||||
)
|
)
|
||||||
@ -518,17 +624,18 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn deserialization_failure() {
|
fn deserialization_failure() {
|
||||||
// Invalid JSON
|
// Ensure that invalid JSON creates a `serde_json::Error` and not `InvalidEvent`
|
||||||
let error = "{".parse::<StartEventContent>().err().unwrap();
|
assert!(serde_json::from_str::<EventResult<StartEventContent>>("{").is_err());
|
||||||
|
|
||||||
// No `serde_json::Value` available if deserialization failed.
|
|
||||||
assert!(error.json().is_none());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn deserialization_structure_mismatch() {
|
fn deserialization_structure_mismatch() {
|
||||||
// Missing several required fields.
|
// Missing several required fields.
|
||||||
let error = r#"{"from_device":"123"}"#.parse::<StartEventContent>().err().unwrap();
|
let error =
|
||||||
|
serde_json::from_str::<EventResult<StartEventContent>>(r#"{"from_device":"123"}"#)
|
||||||
|
.unwrap()
|
||||||
|
.into()
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
assert!(error.message().contains("missing field"));
|
assert!(error.message().contains("missing field"));
|
||||||
assert!(error.json().is_some());
|
assert!(error.json().is_some());
|
||||||
@ -537,10 +644,12 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn deserialization_validation_missing_required_key_agreement_protocols() {
|
fn deserialization_validation_missing_required_key_agreement_protocols() {
|
||||||
let error =
|
let error =
|
||||||
r#"{"from_device":"123","transaction_id":"456","method":"m.sas.v1","key_agreement_protocols":[],"hashes":["sha256"],"message_authentication_codes":["hkdf-hmac-sha256"],"short_authentication_string":["decimal"]}"#
|
serde_json::from_str::<EventResult<StartEventContent>>(
|
||||||
.parse::<StartEventContent>()
|
r#"{"from_device":"123","transaction_id":"456","method":"m.sas.v1","key_agreement_protocols":[],"hashes":["sha256"],"message_authentication_codes":["hkdf-hmac-sha256"],"short_authentication_string":["decimal"]}"#
|
||||||
.err()
|
)
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.into()
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
assert!(error.message().contains("key_agreement_protocols"));
|
assert!(error.message().contains("key_agreement_protocols"));
|
||||||
assert!(error.json().is_some());
|
assert!(error.json().is_some());
|
||||||
@ -549,10 +658,12 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn deserialization_validation_missing_required_hashes() {
|
fn deserialization_validation_missing_required_hashes() {
|
||||||
let error =
|
let error =
|
||||||
r#"{"from_device":"123","transaction_id":"456","method":"m.sas.v1","key_agreement_protocols":["curve25519"],"hashes":[],"message_authentication_codes":["hkdf-hmac-sha256"],"short_authentication_string":["decimal"]}"#
|
serde_json::from_str::<EventResult<StartEventContent>>(
|
||||||
.parse::<StartEventContent>()
|
r#"{"from_device":"123","transaction_id":"456","method":"m.sas.v1","key_agreement_protocols":["curve25519"],"hashes":[],"message_authentication_codes":["hkdf-hmac-sha256"],"short_authentication_string":["decimal"]}"#
|
||||||
.err()
|
)
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.into()
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
assert!(error.message().contains("hashes"));
|
assert!(error.message().contains("hashes"));
|
||||||
assert!(error.json().is_some());
|
assert!(error.json().is_some());
|
||||||
@ -561,10 +672,12 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn deserialization_validation_missing_required_message_authentication_codes() {
|
fn deserialization_validation_missing_required_message_authentication_codes() {
|
||||||
let error =
|
let error =
|
||||||
r#"{"from_device":"123","transaction_id":"456","method":"m.sas.v1","key_agreement_protocols":["curve25519"],"hashes":["sha256"],"message_authentication_codes":[],"short_authentication_string":["decimal"]}"#
|
serde_json::from_str::<EventResult<StartEventContent>>(
|
||||||
.parse::<StartEventContent>()
|
r#"{"from_device":"123","transaction_id":"456","method":"m.sas.v1","key_agreement_protocols":["curve25519"],"hashes":["sha256"],"message_authentication_codes":[],"short_authentication_string":["decimal"]}"#
|
||||||
.err()
|
)
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.into()
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
assert!(error.message().contains("message_authentication_codes"));
|
assert!(error.message().contains("message_authentication_codes"));
|
||||||
assert!(error.json().is_some());
|
assert!(error.json().is_some());
|
||||||
@ -573,10 +686,12 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn deserialization_validation_missing_required_short_authentication_string() {
|
fn deserialization_validation_missing_required_short_authentication_string() {
|
||||||
let error =
|
let error =
|
||||||
r#"{"from_device":"123","transaction_id":"456","method":"m.sas.v1","key_agreement_protocols":["curve25519"],"hashes":["sha256"],"message_authentication_codes":["hkdf-hmac-sha256"],"short_authentication_string":[]}"#
|
serde_json::from_str::<EventResult<StartEventContent>>(
|
||||||
.parse::<StartEventContent>()
|
r#"{"from_device":"123","transaction_id":"456","method":"m.sas.v1","key_agreement_protocols":["curve25519"],"hashes":["sha256"],"message_authentication_codes":["hkdf-hmac-sha256"],"short_authentication_string":[]}"#
|
||||||
.err()
|
)
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.into()
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
assert!(error.message().contains("short_authentication_string"));
|
assert!(error.message().contains("short_authentication_string"));
|
||||||
assert!(error.json().is_some());
|
assert!(error.json().is_some());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user