pub mod claim_key;
pub use claim_key::*;
use std::collections::{BTreeMap, btree_map};
use std::ops::Deref;
use std::time::Duration;
use salvo::oapi::{ToParameters, ToSchema};
use serde::{Deserialize, Serialize};
use crate::{
DeviceKeyAlgorithm, JsonValue, OwnedDeviceId, OwnedDeviceKeyId, OwnedUserId, PrivOwnedStr, RawJsonValue,
client::uiaa::AuthData,
encryption::{CrossSigningKey, DeviceKeys, OneTimeKey},
serde::{RawJson, StringEnum},
};
#[derive(Debug)]
pub struct SignedKeysIter<'a>(pub(super) btree_map::Iter<'a, Box<str>, Box<RawJsonValue>>);
impl<'a> Iterator for SignedKeysIter<'a> {
type Item = (&'a str, &'a RawJsonValue);
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(id, val)| (&**id, &**val))
}
}
#[derive(ToSchema, Deserialize, Debug)]
pub struct KeysReqBody {
#[serde(
with = "crate::serde::duration::opt_ms",
default,
skip_serializing_if = "Option::is_none"
)]
pub timeout: Option<Duration>,
pub device_keys: BTreeMap<OwnedUserId, Vec<OwnedDeviceId>>,
}
#[derive(ToSchema, Serialize, Debug)]
pub struct KeysResBody {
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
#[salvo(schema(value_type = Object, additional_properties = true))]
pub failures: BTreeMap<String, JsonValue>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub device_keys: BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, DeviceKeys>>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub master_keys: BTreeMap<OwnedUserId, CrossSigningKey>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub self_signing_keys: BTreeMap<OwnedUserId, CrossSigningKey>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub user_signing_keys: BTreeMap<OwnedUserId, CrossSigningKey>,
}
#[derive(ToSchema, Deserialize, Debug)]
pub struct UploadKeysReqBody {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub device_keys: Option<DeviceKeys>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub one_time_keys: BTreeMap<OwnedDeviceKeyId, OneTimeKey>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub fallback_keys: BTreeMap<OwnedDeviceKeyId, OneTimeKey>,
}
#[derive(ToSchema, Serialize, Debug)]
pub struct UploadKeysResBody {
pub one_time_key_counts: BTreeMap<DeviceKeyAlgorithm, u64>,
}
impl UploadKeysResBody {
pub fn new(one_time_key_counts: BTreeMap<DeviceKeyAlgorithm, u64>) -> Self {
Self { one_time_key_counts }
}
}
#[derive(ToParameters, Deserialize, Debug)]
pub struct KeyChangesReqArgs {
#[salvo(parameter(parameter_in = Query))]
pub from: String,
#[salvo(parameter(parameter_in = Query))]
pub to: String,
}
#[derive(ToSchema, Serialize, Debug)]
pub struct KeyChangesResBody {
pub changed: Vec<OwnedUserId>,
pub left: Vec<OwnedUserId>,
}
impl KeyChangesResBody {
pub fn new(changed: Vec<OwnedUserId>, left: Vec<OwnedUserId>) -> Self {
Self { changed, left }
}
}
#[derive(ToSchema, Deserialize, Clone, Debug)]
pub struct UploadSigningKeysReqBody {
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "crate::serde::empty_as_none"
)]
pub auth: Option<AuthData>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub master_key: Option<CrossSigningKey>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub self_signing_key: Option<CrossSigningKey>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub user_signing_key: Option<CrossSigningKey>,
}
#[derive(ToSchema, Deserialize, Debug)]
pub struct UploadSignaturesReqBody(pub BTreeMap<OwnedUserId, SignedKeys>);
impl Deref for UploadSignaturesReqBody {
type Target = BTreeMap<OwnedUserId, SignedKeys>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(ToSchema, Serialize, Debug)]
pub struct UploadSignaturesResBody {
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub failures: BTreeMap<OwnedUserId, BTreeMap<String, Failure>>,
}
impl UploadSignaturesResBody {
pub fn new(failures: BTreeMap<OwnedUserId, BTreeMap<String, Failure>>) -> Self {
Self { failures }
}
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[serde(transparent)]
pub struct SignedKeys(BTreeMap<Box<str>, Box<RawJsonValue>>);
impl SignedKeys {
pub fn new() -> Self {
Self::default()
}
pub fn add_device_keys(&mut self, device_id: OwnedDeviceId, device_keys: RawJson<DeviceKeys>) {
self.0.insert(device_id.as_str().into(), device_keys.into_inner());
}
pub fn add_cross_signing_keys(
&mut self,
cross_signing_key_id: Box<str>,
cross_signing_keys: RawJson<CrossSigningKey>,
) {
self.0.insert(cross_signing_key_id, cross_signing_keys.into_inner());
}
pub fn iter(&self) -> SignedKeysIter<'_> {
SignedKeysIter(self.0.iter())
}
}
#[derive(ToSchema, Deserialize, Serialize, Clone, Debug)]
pub struct Failure {
errcode: FailureErrorCode,
error: String,
}
#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
#[derive(ToSchema, Clone, PartialEq, Eq, StringEnum)]
#[non_exhaustive]
#[palpo_enum(rename_all = "M_MATRIX_ERROR_CASE")]
pub enum FailureErrorCode {
InvalidSignature,
#[doc(hidden)]
#[salvo(schema(skip))]
_Custom(PrivOwnedStr),
}