|
|
|
@ -1,7 +1,8 @@ |
|
|
|
use super::SESSION_ID_LENGTH; |
|
|
|
use super::SESSION_ID_LENGTH; |
|
|
|
use crate::{database::DatabaseGuard, utils, ConduitResult, Database, Error, Result, Ruma}; |
|
|
|
use crate::{database::DatabaseGuard, utils, ConduitResult, Database, Error, Result, Ruma}; |
|
|
|
use ruma::{ |
|
|
|
use ruma::{ |
|
|
|
api::client::{ |
|
|
|
api::{ |
|
|
|
|
|
|
|
client::{ |
|
|
|
error::ErrorKind, |
|
|
|
error::ErrorKind, |
|
|
|
r0::{ |
|
|
|
r0::{ |
|
|
|
keys::{ |
|
|
|
keys::{ |
|
|
|
@ -11,9 +12,12 @@ use ruma::{ |
|
|
|
uiaa::{AuthFlow, UiaaInfo}, |
|
|
|
uiaa::{AuthFlow, UiaaInfo}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
federation, |
|
|
|
|
|
|
|
}, |
|
|
|
encryption::UnsignedDeviceInfo, |
|
|
|
encryption::UnsignedDeviceInfo, |
|
|
|
DeviceId, DeviceKeyAlgorithm, UserId, |
|
|
|
DeviceId, DeviceKeyAlgorithm, UserId, |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
use serde_json::json; |
|
|
|
use std::collections::{BTreeMap, HashSet}; |
|
|
|
use std::collections::{BTreeMap, HashSet}; |
|
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "conduit_bin")] |
|
|
|
#[cfg(feature = "conduit_bin")] |
|
|
|
@ -84,7 +88,8 @@ pub async fn get_keys_route( |
|
|
|
&body.device_keys, |
|
|
|
&body.device_keys, |
|
|
|
|u| u == sender_user, |
|
|
|
|u| u == sender_user, |
|
|
|
&db, |
|
|
|
&db, |
|
|
|
)?; |
|
|
|
) |
|
|
|
|
|
|
|
.await?; |
|
|
|
|
|
|
|
|
|
|
|
Ok(response.into()) |
|
|
|
Ok(response.into()) |
|
|
|
} |
|
|
|
} |
|
|
|
@ -98,7 +103,7 @@ pub async fn claim_keys_route( |
|
|
|
db: DatabaseGuard, |
|
|
|
db: DatabaseGuard, |
|
|
|
body: Ruma<claim_keys::Request>, |
|
|
|
body: Ruma<claim_keys::Request>, |
|
|
|
) -> ConduitResult<claim_keys::Response> { |
|
|
|
) -> ConduitResult<claim_keys::Response> { |
|
|
|
let response = claim_keys_helper(&body.one_time_keys, &db)?; |
|
|
|
let response = claim_keys_helper(&body.one_time_keys, &db).await?; |
|
|
|
|
|
|
|
|
|
|
|
db.flush().await?; |
|
|
|
db.flush().await?; |
|
|
|
|
|
|
|
|
|
|
|
@ -278,7 +283,7 @@ pub async fn get_key_changes_route( |
|
|
|
.into()) |
|
|
|
.into()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn get_keys_helper<F: Fn(&UserId) -> bool>( |
|
|
|
pub async fn get_keys_helper<F: Fn(&UserId) -> bool>( |
|
|
|
sender_user: Option<&UserId>, |
|
|
|
sender_user: Option<&UserId>, |
|
|
|
device_keys_input: &BTreeMap<UserId, Vec<Box<DeviceId>>>, |
|
|
|
device_keys_input: &BTreeMap<UserId, Vec<Box<DeviceId>>>, |
|
|
|
allowed_signatures: F, |
|
|
|
allowed_signatures: F, |
|
|
|
@ -289,7 +294,16 @@ pub fn get_keys_helper<F: Fn(&UserId) -> bool>( |
|
|
|
let mut user_signing_keys = BTreeMap::new(); |
|
|
|
let mut user_signing_keys = BTreeMap::new(); |
|
|
|
let mut device_keys = BTreeMap::new(); |
|
|
|
let mut device_keys = BTreeMap::new(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut get_over_federation = BTreeMap::new(); |
|
|
|
|
|
|
|
|
|
|
|
for (user_id, device_ids) in device_keys_input { |
|
|
|
for (user_id, device_ids) in device_keys_input { |
|
|
|
|
|
|
|
if user_id.server_name() != db.globals.server_name() { |
|
|
|
|
|
|
|
get_over_federation |
|
|
|
|
|
|
|
.entry(user_id.server_name()) |
|
|
|
|
|
|
|
.or_insert_with(Vec::new) |
|
|
|
|
|
|
|
.push((user_id, device_ids)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if device_ids.is_empty() { |
|
|
|
if device_ids.is_empty() { |
|
|
|
let mut container = BTreeMap::new(); |
|
|
|
let mut container = BTreeMap::new(); |
|
|
|
for device_id in db.users.all_device_ids(user_id) { |
|
|
|
for device_id in db.users.all_device_ids(user_id) { |
|
|
|
@ -347,21 +361,51 @@ pub fn get_keys_helper<F: Fn(&UserId) -> bool>( |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut failures = BTreeMap::new(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (server, vec) in get_over_federation { |
|
|
|
|
|
|
|
let mut device_keys = BTreeMap::new(); |
|
|
|
|
|
|
|
for (user_id, keys) in vec { |
|
|
|
|
|
|
|
device_keys.insert(user_id.clone(), keys.clone()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if let Err(_e) = db |
|
|
|
|
|
|
|
.sending |
|
|
|
|
|
|
|
.send_federation_request( |
|
|
|
|
|
|
|
&db.globals, |
|
|
|
|
|
|
|
server, |
|
|
|
|
|
|
|
federation::keys::get_keys::v1::Request { device_keys }, |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
.await |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
failures.insert(server.to_string(), json!({})); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Ok(get_keys::Response { |
|
|
|
Ok(get_keys::Response { |
|
|
|
master_keys, |
|
|
|
master_keys, |
|
|
|
self_signing_keys, |
|
|
|
self_signing_keys, |
|
|
|
user_signing_keys, |
|
|
|
user_signing_keys, |
|
|
|
device_keys, |
|
|
|
device_keys, |
|
|
|
failures: BTreeMap::new(), |
|
|
|
failures, |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn claim_keys_helper( |
|
|
|
pub async fn claim_keys_helper( |
|
|
|
one_time_keys_input: &BTreeMap<UserId, BTreeMap<Box<DeviceId>, DeviceKeyAlgorithm>>, |
|
|
|
one_time_keys_input: &BTreeMap<UserId, BTreeMap<Box<DeviceId>, DeviceKeyAlgorithm>>, |
|
|
|
db: &Database, |
|
|
|
db: &Database, |
|
|
|
) -> Result<claim_keys::Response> { |
|
|
|
) -> Result<claim_keys::Response> { |
|
|
|
let mut one_time_keys = BTreeMap::new(); |
|
|
|
let mut one_time_keys = BTreeMap::new(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut get_over_federation = BTreeMap::new(); |
|
|
|
|
|
|
|
|
|
|
|
for (user_id, map) in one_time_keys_input { |
|
|
|
for (user_id, map) in one_time_keys_input { |
|
|
|
|
|
|
|
if user_id.server_name() != db.globals.server_name() { |
|
|
|
|
|
|
|
get_over_federation |
|
|
|
|
|
|
|
.entry(user_id.server_name()) |
|
|
|
|
|
|
|
.or_insert_with(Vec::new) |
|
|
|
|
|
|
|
.push((user_id, map)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
let mut container = BTreeMap::new(); |
|
|
|
let mut container = BTreeMap::new(); |
|
|
|
for (device_id, key_algorithm) in map { |
|
|
|
for (device_id, key_algorithm) in map { |
|
|
|
if let Some(one_time_keys) = |
|
|
|
if let Some(one_time_keys) = |
|
|
|
@ -376,6 +420,26 @@ pub fn claim_keys_helper( |
|
|
|
one_time_keys.insert(user_id.clone(), container); |
|
|
|
one_time_keys.insert(user_id.clone(), container); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (server, vec) in get_over_federation { |
|
|
|
|
|
|
|
let mut one_time_keys_input_fed = BTreeMap::new(); |
|
|
|
|
|
|
|
for (user_id, keys) in vec { |
|
|
|
|
|
|
|
one_time_keys_input_fed.insert(user_id.clone(), keys.clone()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Ignore failures
|
|
|
|
|
|
|
|
let keys = db |
|
|
|
|
|
|
|
.sending |
|
|
|
|
|
|
|
.send_federation_request( |
|
|
|
|
|
|
|
&db.globals, |
|
|
|
|
|
|
|
server, |
|
|
|
|
|
|
|
federation::keys::claim_keys::v1::Request { |
|
|
|
|
|
|
|
one_time_keys: one_time_keys_input_fed, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
.await?; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
one_time_keys.extend(keys.one_time_keys); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Ok(claim_keys::Response { |
|
|
|
Ok(claim_keys::Response { |
|
|
|
failures: BTreeMap::new(), |
|
|
|
failures: BTreeMap::new(), |
|
|
|
one_time_keys, |
|
|
|
one_time_keys, |
|
|
|
|