feat: Add MSC3202 types for E2EE appservices

This commit is contained in:
Emelie Graven 2022-09-21 08:31:47 +02:00
parent 3c3c6f388f
commit 27f27d5298
No known key found for this signature in database
GPG Key ID: 1098DC5C94CB1C87
2 changed files with 87 additions and 2 deletions

View File

@ -18,8 +18,10 @@ all-features = true
unstable-exhaustive-types = []
client = []
server = []
unstable-msc3202 = []
[dependencies]
js_int = { version = "0.2.2", features = ["serde"] }
ruma-common = { version = "0.10.5", path = "../ruma-common", features = ["api", "events"] }
serde = { version = "1.0.118", features = ["derive"] }
serde_json = "1.0.61"

View File

@ -11,6 +11,15 @@ pub mod v1 {
api::ruma_api, events::AnyTimelineEvent, serde::Raw, OwnedTransactionId, TransactionId,
};
#[cfg(feature = "unstable-msc3202")]
use js_int::UInt;
#[cfg(feature = "unstable-msc3202")]
use ruma_common::{DeviceKeyAlgorithm, OwnedDeviceId, OwnedUserId};
#[cfg(feature = "unstable-msc3202")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "unstable-msc3202")]
use std::collections::BTreeMap;
ruma_api! {
metadata: {
description: "This API is called by the homeserver when it wants to push an event (or batch of events) to the application service.",
@ -31,6 +40,33 @@ pub mod v1 {
/// A list of events.
pub events: &'a [Raw<AnyTimelineEvent>],
/// Information on E2E device updates.
#[cfg(feature = "unstable-msc3202")]
#[serde(
default,
skip_serializing_if = "DeviceLists::is_empty",
rename = "org.matrix.msc3202.device_lists"
)]
pub device_lists: DeviceLists,
/// The number of unclaimed one-time keys currently held on the server for this device, for each algorithm.
#[cfg(feature = "unstable-msc3202")]
#[serde(
default,
skip_serializing_if = "BTreeMap::is_empty",
rename = "org.matrix.msc3202.device_one_time_keys_count"
)]
pub device_one_time_keys_count: BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, BTreeMap<DeviceKeyAlgorithm, UInt>>>,
/// A list of key algorithms for which the server has an unused fallback key for the device.
#[cfg(feature = "unstable-msc3202")]
#[serde(
default,
skip_serializing_if = "BTreeMap::is_empty",
rename = "org.matrix.msc3202.device_unused_fallback_key_types"
)]
pub device_unused_fallback_key_types: BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, Vec<DeviceKeyAlgorithm>>>,
}
#[derive(Default)]
@ -40,7 +76,16 @@ pub mod v1 {
impl<'a> Request<'a> {
/// Creates a new `Request` with the given transaction ID and list of events.
pub fn new(txn_id: &'a TransactionId, events: &'a [Raw<AnyTimelineEvent>]) -> Self {
Self { txn_id, events }
Self {
txn_id,
events,
#[cfg(feature = "unstable-msc3202")]
device_lists: DeviceLists::new(),
#[cfg(feature = "unstable-msc3202")]
device_one_time_keys_count: BTreeMap::new(),
#[cfg(feature = "unstable-msc3202")]
device_unused_fallback_key_types: BTreeMap::new(),
}
}
}
@ -50,7 +95,16 @@ pub mod v1 {
txn_id: OwnedTransactionId,
events: Vec<Raw<AnyTimelineEvent>>,
) -> IncomingRequest {
IncomingRequest { txn_id, events }
IncomingRequest {
txn_id,
events,
#[cfg(feature = "unstable-msc3202")]
device_lists: DeviceLists::new(),
#[cfg(feature = "unstable-msc3202")]
device_one_time_keys_count: BTreeMap::new(),
#[cfg(feature = "unstable-msc3202")]
device_unused_fallback_key_types: BTreeMap::new(),
}
}
}
@ -61,6 +115,35 @@ pub mod v1 {
}
}
/// Information on E2E device updates.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
#[cfg(feature = "unstable-msc3202")]
pub struct DeviceLists {
/// List of users who have updated their device identity keys or who now
/// share an encrypted room with the client since the previous sync.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub changed: Vec<OwnedUserId>,
/// List of users who no longer share encrypted rooms since the previous sync
/// response.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub left: Vec<OwnedUserId>,
}
#[cfg(feature = "unstable-msc3202")]
impl DeviceLists {
/// Creates an empty `DeviceLists`.
pub fn new() -> Self {
Default::default()
}
/// Returns true if there are no device list updates.
pub fn is_empty(&self) -> bool {
self.changed.is_empty() && self.left.is_empty()
}
}
#[cfg(feature = "server")]
#[cfg(test)]
mod tests {