Merge branch 'up-ruma' into 'next'

Upgrade Ruma

See merge request famedly/conduit!237
This commit is contained in:
Timo Kösters 2022-01-13 10:24:45 +00:00
commit b32e85ffa8
6 changed files with 182 additions and 119 deletions

56
Cargo.lock generated
View File

@ -938,7 +938,7 @@ checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11"
dependencies = [
"bytes",
"fnv",
"itoa",
"itoa 0.4.8",
]
[[package]]
@ -979,7 +979,7 @@ dependencies = [
"http-body",
"httparse",
"httpdate",
"itoa",
"itoa 0.4.8",
"pin-project-lite",
"socket2 0.4.1",
"tokio",
@ -1114,6 +1114,12 @@ version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]]
name = "itoa"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]]
name = "jobserver"
version = "0.1.24"
@ -1984,7 +1990,7 @@ dependencies = [
[[package]]
name = "ruma"
version = "0.4.0"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"assign",
"js_int",
@ -2005,7 +2011,7 @@ dependencies = [
[[package]]
name = "ruma-api"
version = "0.18.5"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"bytes",
"http",
@ -2021,7 +2027,7 @@ dependencies = [
[[package]]
name = "ruma-api-macros"
version = "0.18.5"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"proc-macro-crate",
"proc-macro2",
@ -2032,7 +2038,7 @@ dependencies = [
[[package]]
name = "ruma-appservice-api"
version = "0.4.0"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"ruma-api",
"ruma-common",
@ -2046,7 +2052,7 @@ dependencies = [
[[package]]
name = "ruma-client-api"
version = "0.12.3"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"assign",
"bytes",
@ -2066,7 +2072,7 @@ dependencies = [
[[package]]
name = "ruma-common"
version = "0.6.0"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"indexmap",
"js_int",
@ -2081,7 +2087,7 @@ dependencies = [
[[package]]
name = "ruma-events"
version = "0.24.6"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"indoc",
"js_int",
@ -2097,7 +2103,7 @@ dependencies = [
[[package]]
name = "ruma-events-macros"
version = "0.24.6"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"proc-macro-crate",
"proc-macro2",
@ -2108,7 +2114,7 @@ dependencies = [
[[package]]
name = "ruma-federation-api"
version = "0.3.1"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"js_int",
"ruma-api",
@ -2123,7 +2129,7 @@ dependencies = [
[[package]]
name = "ruma-identifiers"
version = "0.20.0"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"percent-encoding",
"rand 0.8.4",
@ -2137,7 +2143,7 @@ dependencies = [
[[package]]
name = "ruma-identifiers-macros"
version = "0.20.0"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"quote",
"ruma-identifiers-validation",
@ -2147,7 +2153,7 @@ dependencies = [
[[package]]
name = "ruma-identifiers-validation"
version = "0.5.0"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"thiserror",
]
@ -2155,7 +2161,7 @@ dependencies = [
[[package]]
name = "ruma-identity-service-api"
version = "0.3.0"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"js_int",
"ruma-api",
@ -2168,7 +2174,7 @@ dependencies = [
[[package]]
name = "ruma-push-gateway-api"
version = "0.3.0"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"js_int",
"ruma-api",
@ -2183,11 +2189,11 @@ dependencies = [
[[package]]
name = "ruma-serde"
version = "0.5.0"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"bytes",
"form_urlencoded",
"itoa",
"itoa 0.4.8",
"js_int",
"ruma-serde-macros",
"serde",
@ -2197,7 +2203,7 @@ dependencies = [
[[package]]
name = "ruma-serde-macros"
version = "0.5.0"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"proc-macro-crate",
"proc-macro2",
@ -2208,7 +2214,7 @@ dependencies = [
[[package]]
name = "ruma-signatures"
version = "0.9.0"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"base64 0.13.0",
"ed25519-dalek",
@ -2225,7 +2231,7 @@ dependencies = [
[[package]]
name = "ruma-state-res"
version = "0.4.1"
source = "git+https://github.com/ruma/ruma?rev=16f031fabb7871fcd738b0f25391193ee4ca28a9#16f031fabb7871fcd738b0f25391193ee4ca28a9"
source = "git+https://github.com/ruma/ruma?rev=7cf3abbaf02995b03db74429090ca5af1cd71edc#7cf3abbaf02995b03db74429090ca5af1cd71edc"
dependencies = [
"itertools 0.10.1",
"js_int",
@ -2404,11 +2410,11 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.67"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950"
checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5"
dependencies = [
"itoa",
"itoa 1.0.1",
"ryu",
"serde",
]
@ -2420,7 +2426,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9"
dependencies = [
"form_urlencoded",
"itoa",
"itoa 0.4.8",
"ryu",
"serde",
]

View File

@ -19,7 +19,7 @@ rocket = { version = "0.5.0-rc.1", features = ["tls"] } # Used to handle request
# Used for matrix spec type definitions and helpers
#ruma = { version = "0.4.0", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] }
ruma = { git = "https://github.com/ruma/ruma", rev = "16f031fabb7871fcd738b0f25391193ee4ca28a9", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] }
ruma = { git = "https://github.com/ruma/ruma", rev = "7cf3abbaf02995b03db74429090ca5af1cd71edc", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] }
#ruma = { git = "https://github.com/timokoesters/ruma", rev = "50c1db7e0a3a21fc794b0cce3b64285a4c750c71", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] }
#ruma = { path = "../ruma/crates/ruma", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] }
@ -36,7 +36,7 @@ http = "0.2.4"
# Used to find data directory for default db path
directories = "3.0.2"
# Used for ruma wrapper
serde_json = { version = "1.0.67", features = ["raw_value"] }
serde_json = { version = "1.0.70", features = ["raw_value"] }
# Used for appservice registration files
serde_yaml = "0.8.20"
# Used for pdu definition

View File

@ -15,7 +15,7 @@ use ruma::{
},
federation,
},
encryption::UnsignedDeviceInfo,
serde::Raw,
DeviceId, DeviceKeyAlgorithm, UserId,
};
use serde_json::json;
@ -42,16 +42,9 @@ pub async fn upload_keys_route(
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
let sender_device = body.sender_device.as_ref().expect("user is authenticated");
if let Some(one_time_keys) = &body.one_time_keys {
for (key_key, key_value) in one_time_keys {
db.users.add_one_time_key(
sender_user,
sender_device,
key_key,
key_value,
&db.globals,
)?;
}
for (key_key, key_value) in &body.one_time_keys {
db.users
.add_one_time_key(sender_user, sender_device, key_key, key_value, &db.globals)?;
}
if let Some(device_keys) = &body.device_keys {
@ -350,10 +343,8 @@ pub(crate) async fn get_keys_helper<F: Fn(&UserId) -> bool>(
Error::bad_database("all_device_keys contained nonexistent device.")
})?;
keys.unsigned = UnsignedDeviceInfo {
device_display_name: metadata.display_name,
};
add_unsigned_device_display_name(&mut keys, metadata)
.map_err(|_| Error::bad_database("invalid device keys in database"))?;
container.insert(device_id, keys);
}
}
@ -369,10 +360,8 @@ pub(crate) async fn get_keys_helper<F: Fn(&UserId) -> bool>(
),
)?;
keys.unsigned = UnsignedDeviceInfo {
device_display_name: metadata.display_name,
};
add_unsigned_device_display_name(&mut keys, metadata)
.map_err(|_| Error::bad_database("invalid device keys in database"))?;
container.insert(device_id.to_owned(), keys);
}
device_keys.insert(user_id.to_owned(), container);
@ -441,6 +430,24 @@ pub(crate) async fn get_keys_helper<F: Fn(&UserId) -> bool>(
})
}
fn add_unsigned_device_display_name(
keys: &mut Raw<ruma::encryption::DeviceKeys>,
metadata: ruma::api::client::r0::device::Device,
) -> serde_json::Result<()> {
if let Some(display_name) = metadata.display_name {
let mut object = keys.deserialize_as::<serde_json::Map<String, serde_json::Value>>()?;
let unsigned = object.entry("unsigned").or_insert_with(|| json!({}));
if let serde_json::Value::Object(unsigned_object) = unsigned {
unsigned_object.insert("device_display_name".to_owned(), display_name.into());
}
*keys = Raw::from_json(serde_json::value::to_raw_value(&object)?);
}
Ok(())
}
pub(crate) async fn claim_keys_helper(
one_time_keys_input: &BTreeMap<Box<UserId>, BTreeMap<Box<DeviceId>, DeviceKeyAlgorithm>>,
db: &Database,

View File

@ -762,6 +762,8 @@ async fn sync_helper(
.users
.get_to_device_events(&sender_user, &sender_device)?,
},
// Fallback keys are not yet supported
device_unused_fallback_key_types: None,
};
// TODO: Retry the endpoint instead of returning (waiting for #118)

View File

@ -4,8 +4,10 @@ use ruma::{
error::ErrorKind,
r0::backup::{BackupAlgorithm, KeyBackupData, RoomKeyBackup},
},
serde::Raw,
RoomId, UserId,
};
use serde_json::json;
use std::{collections::BTreeMap, sync::Arc};
use super::abstraction::Tree;
@ -20,7 +22,7 @@ impl KeyBackups {
pub fn create_backup(
&self,
user_id: &UserId,
backup_metadata: &BackupAlgorithm,
backup_metadata: &Raw<BackupAlgorithm>,
globals: &super::globals::Globals,
) -> Result<String> {
let version = globals.next_count()?.to_string();
@ -59,7 +61,7 @@ impl KeyBackups {
&self,
user_id: &UserId,
version: &str,
backup_metadata: &BackupAlgorithm,
backup_metadata: &Raw<BackupAlgorithm>,
globals: &super::globals::Globals,
) -> Result<String> {
let mut key = user_id.as_bytes().to_vec();
@ -73,12 +75,8 @@ impl KeyBackups {
));
}
self.backupid_algorithm.insert(
&key,
serde_json::to_string(backup_metadata)
.expect("BackupAlgorithm::to_string always works")
.as_bytes(),
)?;
self.backupid_algorithm
.insert(&key, backup_metadata.json().get().as_bytes())?;
self.backupid_etag
.insert(&key, &globals.next_count()?.to_be_bytes())?;
Ok(version.to_owned())
@ -105,7 +103,10 @@ impl KeyBackups {
.transpose()
}
pub fn get_latest_backup(&self, user_id: &UserId) -> Result<Option<(String, BackupAlgorithm)>> {
pub fn get_latest_backup(
&self,
user_id: &UserId,
) -> Result<Option<(String, Raw<BackupAlgorithm>)>> {
let mut prefix = user_id.as_bytes().to_vec();
prefix.push(0xff);
let mut last_possible_key = prefix.clone();
@ -133,7 +134,11 @@ impl KeyBackups {
.transpose()
}
pub fn get_backup(&self, user_id: &UserId, version: &str) -> Result<Option<BackupAlgorithm>> {
pub fn get_backup(
&self,
user_id: &UserId,
version: &str,
) -> Result<Option<Raw<BackupAlgorithm>>> {
let mut key = user_id.as_bytes().to_vec();
key.push(0xff);
key.extend_from_slice(version.as_bytes());
@ -152,7 +157,7 @@ impl KeyBackups {
version: &str,
room_id: &RoomId,
session_id: &str,
key_data: &KeyBackupData,
key_data: &Raw<KeyBackupData>,
globals: &super::globals::Globals,
) -> Result<()> {
let mut key = user_id.as_bytes().to_vec();
@ -174,10 +179,8 @@ impl KeyBackups {
key.push(0xff);
key.extend_from_slice(session_id.as_bytes());
self.backupkeyid_backup.insert(
&key,
&serde_json::to_vec(&key_data).expect("KeyBackupData::to_vec always works"),
)?;
self.backupkeyid_backup
.insert(&key, key_data.json().get().as_bytes())?;
Ok(())
}
@ -209,13 +212,13 @@ impl KeyBackups {
&self,
user_id: &UserId,
version: &str,
) -> Result<BTreeMap<Box<RoomId>, RoomKeyBackup>> {
) -> Result<BTreeMap<Box<RoomId>, Raw<RoomKeyBackup>>> {
let mut prefix = user_id.as_bytes().to_vec();
prefix.push(0xff);
prefix.extend_from_slice(version.as_bytes());
prefix.push(0xff);
let mut rooms = BTreeMap::<Box<RoomId>, RoomKeyBackup>::new();
let mut rooms = BTreeMap::<Box<RoomId>, Raw<RoomKeyBackup>>::new();
for result in self
.backupkeyid_backup
@ -241,7 +244,7 @@ impl KeyBackups {
Error::bad_database("backupkeyid_backup room_id is invalid room id.")
})?;
let key_data = serde_json::from_slice(&value).map_err(|_| {
let key_data: serde_json::Value = serde_json::from_slice(&value).map_err(|_| {
Error::bad_database("KeyBackupData in backupkeyid_backup is invalid.")
})?;
@ -249,13 +252,25 @@ impl KeyBackups {
})
{
let (room_id, session_id, key_data) = result?;
rooms
.entry(room_id)
.or_insert_with(|| RoomKeyBackup {
let room_key_backup = rooms.entry(room_id).or_insert_with(|| {
Raw::new(&RoomKeyBackup {
sessions: BTreeMap::new(),
})
.sessions
.insert(session_id, key_data);
.expect("RoomKeyBackup serialization")
});
let mut object = room_key_backup
.deserialize_as::<serde_json::Map<String, serde_json::Value>>()
.map_err(|_| Error::bad_database("RoomKeyBackup is not an object"))?;
let sessions = object.entry("session").or_insert_with(|| json!({}));
if let serde_json::Value::Object(unsigned_object) = sessions {
unsigned_object.insert(session_id, key_data);
}
*room_key_backup = Raw::from_json(
serde_json::value::to_raw_value(&object).expect("Value => RawValue serialization"),
);
}
Ok(rooms)
@ -266,7 +281,7 @@ impl KeyBackups {
user_id: &UserId,
version: &str,
room_id: &RoomId,
) -> Result<BTreeMap<String, KeyBackupData>> {
) -> Result<BTreeMap<String, Raw<KeyBackupData>>> {
let mut prefix = user_id.as_bytes().to_vec();
prefix.push(0xff);
prefix.extend_from_slice(version.as_bytes());
@ -304,7 +319,7 @@ impl KeyBackups {
version: &str,
room_id: &RoomId,
session_id: &str,
) -> Result<Option<KeyBackupData>> {
) -> Result<Option<Raw<KeyBackupData>>> {
let mut key = user_id.as_bytes().to_vec();
key.push(0xff);
key.extend_from_slice(version.as_bytes());

View File

@ -8,7 +8,12 @@ use ruma::{
DeviceId, DeviceKeyAlgorithm, DeviceKeyId, MilliSecondsSinceUnixEpoch, RoomAliasId, UInt,
UserId,
};
use std::{collections::BTreeMap, convert::TryInto, mem, sync::Arc};
use std::{
collections::BTreeMap,
convert::{TryFrom, TryInto},
mem,
sync::Arc,
};
use tracing::warn;
use super::abstraction::Tree;
@ -359,7 +364,7 @@ impl Users {
user_id: &UserId,
device_id: &DeviceId,
one_time_key_key: &DeviceKeyId,
one_time_key_value: &OneTimeKey,
one_time_key_value: &Raw<OneTimeKey>,
globals: &super::globals::Globals,
) -> Result<()> {
let mut key = user_id.as_bytes().to_vec();
@ -409,7 +414,7 @@ impl Users {
device_id: &DeviceId,
key_algorithm: &DeviceKeyAlgorithm,
globals: &super::globals::Globals,
) -> Result<Option<(Box<DeviceKeyId>, OneTimeKey)>> {
) -> Result<Option<(Box<DeviceKeyId>, Raw<OneTimeKey>)>> {
let mut prefix = user_id.as_bytes().to_vec();
prefix.push(0xff);
prefix.extend_from_slice(device_id.as_bytes());
@ -480,7 +485,7 @@ impl Users {
&self,
user_id: &UserId,
device_id: &DeviceId,
device_keys: &DeviceKeys,
device_keys: &Raw<DeviceKeys>,
rooms: &super::rooms::Rooms,
globals: &super::globals::Globals,
) -> Result<()> {
@ -509,9 +514,9 @@ impl Users {
pub fn add_cross_signing_keys(
&self,
user_id: &UserId,
master_key: &CrossSigningKey,
self_signing_key: &Option<CrossSigningKey>,
user_signing_key: &Option<CrossSigningKey>,
master_key: &Raw<CrossSigningKey>,
self_signing_key: &Option<Raw<CrossSigningKey>>,
user_signing_key: &Option<Raw<CrossSigningKey>>,
rooms: &super::rooms::Rooms,
globals: &super::globals::Globals,
) -> Result<()> {
@ -521,7 +526,12 @@ impl Users {
prefix.push(0xff);
// Master key
let mut master_key_ids = master_key.keys.values();
let master_key_map = master_key
.deserialize()
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid master key"))?
.keys;
let mut master_key_ids = master_key_map.values();
let master_key_id = master_key_ids.next().ok_or(Error::BadRequest(
ErrorKind::InvalidParam,
"Master key contained no key.",
@ -537,17 +547,21 @@ impl Users {
let mut master_key_key = prefix.clone();
master_key_key.extend_from_slice(master_key_id.as_bytes());
self.keyid_key.insert(
&master_key_key,
&serde_json::to_vec(&master_key).expect("CrossSigningKey::to_vec always works"),
)?;
self.keyid_key
.insert(&master_key_key, master_key.json().get().as_bytes())?;
self.userid_masterkeyid
.insert(user_id.as_bytes(), &master_key_key)?;
// Self-signing key
if let Some(self_signing_key) = self_signing_key {
let mut self_signing_key_ids = self_signing_key.keys.values();
let self_signing_key_map = self_signing_key
.deserialize()
.map_err(|_| {
Error::BadRequest(ErrorKind::InvalidParam, "Invalid self signing key")
})?
.keys;
let mut self_signing_key_ids = self_signing_key_map.values();
let self_signing_key_id = self_signing_key_ids.next().ok_or(Error::BadRequest(
ErrorKind::InvalidParam,
"Self signing key contained no key.",
@ -565,8 +579,7 @@ impl Users {
self.keyid_key.insert(
&self_signing_key_key,
&serde_json::to_vec(&self_signing_key)
.expect("CrossSigningKey::to_vec always works"),
self_signing_key.json().get().as_bytes(),
)?;
self.userid_selfsigningkeyid
@ -575,7 +588,13 @@ impl Users {
// User-signing key
if let Some(user_signing_key) = user_signing_key {
let mut user_signing_key_ids = user_signing_key.keys.values();
let user_signing_key_map = user_signing_key
.deserialize()
.map_err(|_| {
Error::BadRequest(ErrorKind::InvalidParam, "Invalid user signing key")
})?
.keys;
let mut user_signing_key_ids = user_signing_key_map.values();
let user_signing_key_id = user_signing_key_ids.next().ok_or(Error::BadRequest(
ErrorKind::InvalidParam,
"User signing key contained no key.",
@ -593,8 +612,7 @@ impl Users {
self.keyid_key.insert(
&user_signing_key_key,
&serde_json::to_vec(&user_signing_key)
.expect("CrossSigningKey::to_vec always works"),
user_signing_key.json().get().as_bytes(),
)?;
self.userid_usersigningkeyid
@ -727,7 +745,7 @@ impl Users {
&self,
user_id: &UserId,
device_id: &DeviceId,
) -> Result<Option<DeviceKeys>> {
) -> Result<Option<Raw<DeviceKeys>>> {
let mut key = user_id.as_bytes().to_vec();
key.push(0xff);
key.extend_from_slice(device_id.as_bytes());
@ -744,25 +762,19 @@ impl Users {
&self,
user_id: &UserId,
allowed_signatures: F,
) -> Result<Option<CrossSigningKey>> {
) -> Result<Option<Raw<CrossSigningKey>>> {
self.userid_masterkeyid
.get(user_id.as_bytes())?
.map_or(Ok(None), |key| {
self.keyid_key.get(&key)?.map_or(Ok(None), |bytes| {
let mut cross_signing_key = serde_json::from_slice::<CrossSigningKey>(&bytes)
.map_err(|_| {
Error::bad_database("CrossSigningKey in db is invalid.")
})?;
let mut cross_signing_key = serde_json::from_slice::<serde_json::Value>(&bytes)
.map_err(|_| Error::bad_database("CrossSigningKey in db is invalid."))?;
clean_signatures(&mut cross_signing_key, user_id, allowed_signatures)?;
// A user is not allowed to see signatures from users other than himself and
// the target user
cross_signing_key.signatures = cross_signing_key
.signatures
.into_iter()
.filter(|(user, _)| allowed_signatures(user))
.collect();
Ok(Some(cross_signing_key))
Ok(Some(Raw::from_json(
serde_json::value::to_raw_value(&cross_signing_key)
.expect("Value to RawValue serialization"),
)))
})
})
}
@ -772,31 +784,25 @@ impl Users {
&self,
user_id: &UserId,
allowed_signatures: F,
) -> Result<Option<CrossSigningKey>> {
) -> Result<Option<Raw<CrossSigningKey>>> {
self.userid_selfsigningkeyid
.get(user_id.as_bytes())?
.map_or(Ok(None), |key| {
self.keyid_key.get(&key)?.map_or(Ok(None), |bytes| {
let mut cross_signing_key = serde_json::from_slice::<CrossSigningKey>(&bytes)
.map_err(|_| {
Error::bad_database("CrossSigningKey in db is invalid.")
})?;
let mut cross_signing_key = serde_json::from_slice::<serde_json::Value>(&bytes)
.map_err(|_| Error::bad_database("CrossSigningKey in db is invalid."))?;
clean_signatures(&mut cross_signing_key, user_id, allowed_signatures)?;
// A user is not allowed to see signatures from users other than himself and
// the target user
cross_signing_key.signatures = cross_signing_key
.signatures
.into_iter()
.filter(|(user, _)| user == user_id || allowed_signatures(user))
.collect();
Ok(Some(cross_signing_key))
Ok(Some(Raw::from_json(
serde_json::value::to_raw_value(&cross_signing_key)
.expect("Value to RawValue serialization"),
)))
})
})
}
#[tracing::instrument(skip(self, user_id))]
pub fn get_user_signing_key(&self, user_id: &UserId) -> Result<Option<CrossSigningKey>> {
pub fn get_user_signing_key(&self, user_id: &UserId) -> Result<Option<Raw<CrossSigningKey>>> {
self.userid_usersigningkeyid
.get(user_id.as_bytes())?
.map_or(Ok(None), |key| {
@ -991,3 +997,30 @@ impl Users {
Ok(())
}
}
/// Ensure that a user only sees signatures from themselves and the target user
fn clean_signatures<F: Fn(&UserId) -> bool>(
cross_signing_key: &mut serde_json::Value,
user_id: &UserId,
allowed_signatures: F,
) -> Result<(), Error> {
if let Some(signatures) = cross_signing_key
.get_mut("signatures")
.and_then(|v| v.as_object_mut())
{
// Don't allocate for the full size of the current signatures, but require
// at most one resize if nothing is dropped
let new_capacity = signatures.len() / 2;
for (user, signature) in
mem::replace(signatures, serde_json::Map::with_capacity(new_capacity))
{
let id = <&UserId>::try_from(user.as_str())
.map_err(|_| Error::bad_database("Invalid user ID in database."))?;
if id == user_id || allowed_signatures(id) {
signatures.insert(user, signature);
}
}
}
Ok(())
}