events: Add support for the QR verification events and methods
This commit is contained in:
parent
76c9c56471
commit
698d78a6f3
@ -131,6 +131,21 @@ pub enum VerificationMethod {
|
|||||||
#[ruma_enum(rename = "m.sas.v1")]
|
#[ruma_enum(rename = "m.sas.v1")]
|
||||||
MSasV1,
|
MSasV1,
|
||||||
|
|
||||||
|
/// The *m.qr_code.scan.v1* verification method.
|
||||||
|
#[cfg(feature = "unstable-pre-spec")]
|
||||||
|
#[ruma_enum(rename = "m.qr_code.scan.v1")]
|
||||||
|
MQrScanShowV1,
|
||||||
|
|
||||||
|
/// The *m.qr_code.show.v1* verification method.
|
||||||
|
#[cfg(feature = "unstable-pre-spec")]
|
||||||
|
#[ruma_enum(rename = "m.qr_code.show.v1")]
|
||||||
|
MQrCodeShowV1,
|
||||||
|
|
||||||
|
/// The *m.reciprocate.v1* verification method.
|
||||||
|
#[cfg(feature = "unstable-pre-spec")]
|
||||||
|
#[ruma_enum(rename = "m.reciprocate.v1")]
|
||||||
|
MReciprocateV1,
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
_Custom(String),
|
_Custom(String),
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,14 @@ pub enum StartMethod {
|
|||||||
/// The *m.sas.v1* verification method.
|
/// The *m.sas.v1* verification method.
|
||||||
MSasV1(MSasV1Content),
|
MSasV1(MSasV1Content),
|
||||||
|
|
||||||
|
/// The *m.reciprocate.v1* verification method.
|
||||||
|
///
|
||||||
|
/// The spec entry for this method can be found [here][1]
|
||||||
|
///
|
||||||
|
/// [1]: https://spec.matrix.org/unstable/client-server-api/#mkeyverificationstartmreciprocatev1
|
||||||
|
#[cfg(feature = "unstable-pre-spec")]
|
||||||
|
MReciprocateV1(MReciprocateV1Content),
|
||||||
|
|
||||||
/// Any unknown start method.
|
/// Any unknown start method.
|
||||||
Custom(CustomContent),
|
Custom(CustomContent),
|
||||||
}
|
}
|
||||||
@ -82,6 +90,27 @@ pub struct CustomContent {
|
|||||||
pub data: BTreeMap<String, JsonValue>,
|
pub data: BTreeMap<String, JsonValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The payload of an *m.key.verification.start* event using the *m.sas.v1* method.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
#[cfg(feature = "unstable-pre-spec")]
|
||||||
|
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||||
|
#[serde(rename = "m.reciprocate.v1", tag = "method")]
|
||||||
|
pub struct MReciprocateV1Content {
|
||||||
|
/// The shared secret from the QR code, encoded using unpadded base64.
|
||||||
|
pub secret: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable-pre-spec")]
|
||||||
|
impl MReciprocateV1Content {
|
||||||
|
/// Create a new `MReciprocateV1Content` with the given shared secret.
|
||||||
|
///
|
||||||
|
/// The shared secret needs to come from the scanned QR code, encoded using
|
||||||
|
/// unpadded base64.
|
||||||
|
pub fn new(secret: String) -> Self {
|
||||||
|
Self { secret }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The payload of an *m.key.verification.start* event using the *m.sas.v1* method.
|
/// The payload of an *m.key.verification.start* event using the *m.sas.v1* method.
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||||
@ -215,7 +244,7 @@ mod tests {
|
|||||||
StartToDeviceEventContent,
|
StartToDeviceEventContent,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "unstable-pre-spec")]
|
#[cfg(feature = "unstable-pre-spec")]
|
||||||
use super::{Relation, StartEventContent};
|
use super::{MReciprocateV1Content, Relation, StartEventContent};
|
||||||
use crate::ToDeviceEvent;
|
use crate::ToDeviceEvent;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -339,6 +368,26 @@ mod tests {
|
|||||||
ToDeviceEvent { sender, content: key_verification_start_content };
|
ToDeviceEvent { sender, content: key_verification_start_content };
|
||||||
|
|
||||||
assert_eq!(to_json_value(&key_verification_start).unwrap(), json_data);
|
assert_eq!(to_json_value(&key_verification_start).unwrap(), json_data);
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable-pre-spec")]
|
||||||
|
{
|
||||||
|
let secret = "This is a secret to everybody".to_string();
|
||||||
|
|
||||||
|
let key_verification_start_content = StartToDeviceEventContent {
|
||||||
|
from_device: "123".into(),
|
||||||
|
transaction_id: "456".into(),
|
||||||
|
method: StartMethod::MReciprocateV1(MReciprocateV1Content::new(secret.clone())),
|
||||||
|
};
|
||||||
|
|
||||||
|
let json_data = json!({
|
||||||
|
"from_device": "123",
|
||||||
|
"method": "m.reciprocate.v1",
|
||||||
|
"secret": secret,
|
||||||
|
"transaction_id": "456"
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(to_json_value(&key_verification_start_content).unwrap(), json_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -374,6 +423,26 @@ mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(to_json_value(&key_verification_start_content).unwrap(), json_data);
|
assert_eq!(to_json_value(&key_verification_start_content).unwrap(), json_data);
|
||||||
|
|
||||||
|
let secret = "This is a secret to everybody".to_string();
|
||||||
|
|
||||||
|
let key_verification_start_content = StartEventContent {
|
||||||
|
from_device: "123".into(),
|
||||||
|
relation: Relation { event_id: event_id.clone() },
|
||||||
|
method: StartMethod::MReciprocateV1(MReciprocateV1Content::new(secret.clone())),
|
||||||
|
};
|
||||||
|
|
||||||
|
let json_data = json!({
|
||||||
|
"from_device": "123",
|
||||||
|
"method": "m.reciprocate.v1",
|
||||||
|
"secret": secret,
|
||||||
|
"m.relates_to": {
|
||||||
|
"rel_type": "m.reference",
|
||||||
|
"event_id": event_id,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(to_json_value(&key_verification_start_content).unwrap(), json_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -487,6 +556,38 @@ mod tests {
|
|||||||
&& method == "m.sas.custom"
|
&& method == "m.sas.custom"
|
||||||
&& data.get("test").unwrap() == &JsonValue::from("field")
|
&& data.get("test").unwrap() == &JsonValue::from("field")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable-pre-spec")]
|
||||||
|
{
|
||||||
|
let json = json!({
|
||||||
|
"content": {
|
||||||
|
"from_device": "123",
|
||||||
|
"method": "m.reciprocate.v1",
|
||||||
|
"secret": "It's a secret to everybody",
|
||||||
|
"transaction_id": "456",
|
||||||
|
},
|
||||||
|
"type": "m.key.verification.start",
|
||||||
|
"sender": sender,
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
from_json_value::<Raw<ToDeviceEvent<StartToDeviceEventContent>>>(json)
|
||||||
|
.unwrap()
|
||||||
|
.deserialize()
|
||||||
|
.unwrap(),
|
||||||
|
ToDeviceEvent {
|
||||||
|
sender,
|
||||||
|
content: StartToDeviceEventContent {
|
||||||
|
from_device,
|
||||||
|
transaction_id,
|
||||||
|
method: StartMethod::MReciprocateV1(MReciprocateV1Content { secret }),
|
||||||
|
}
|
||||||
|
} if from_device == "123"
|
||||||
|
&& sender == user_id!("@example:localhost")
|
||||||
|
&& transaction_id == "456"
|
||||||
|
&& secret == "It's a secret to everybody"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -531,6 +632,30 @@ mod tests {
|
|||||||
&& message_authentication_codes == vec![MessageAuthenticationCode::HkdfHmacSha256]
|
&& message_authentication_codes == vec![MessageAuthenticationCode::HkdfHmacSha256]
|
||||||
&& short_authentication_string == vec![ShortAuthenticationString::Decimal]
|
&& short_authentication_string == vec![ShortAuthenticationString::Decimal]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let json = json!({
|
||||||
|
"from_device": "123",
|
||||||
|
"method": "m.reciprocate.v1",
|
||||||
|
"secret": "It's a secret to everybody",
|
||||||
|
"m.relates_to": {
|
||||||
|
"rel_type": "m.reference",
|
||||||
|
"event_id": id,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
from_json_value::<Raw<StartEventContent>>(json)
|
||||||
|
.unwrap()
|
||||||
|
.deserialize()
|
||||||
|
.unwrap(),
|
||||||
|
StartEventContent {
|
||||||
|
from_device,
|
||||||
|
relation: Relation { event_id },
|
||||||
|
method: StartMethod::MReciprocateV1(MReciprocateV1Content { secret }),
|
||||||
|
} if from_device == "123"
|
||||||
|
&& event_id == id
|
||||||
|
&& secret == "It's a secret to everybody"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user