improvement: use invite state as hints to what servers to ask for joining

This commit is contained in:
Timo Kösters 2021-04-14 14:41:39 +02:00
parent d6b59cd20c
commit bc98425dfe
No known key found for this signature in database
GPG Key ID: 24DA7517711A2BA4
2 changed files with 48 additions and 6 deletions

View File

@ -22,7 +22,11 @@ use ruma::{
serde::{to_canonical_value, CanonicalJsonObject, Raw},
EventId, RoomId, RoomVersionId, ServerName, UserId,
};
use std::{collections::BTreeMap, convert::TryFrom, sync::RwLock};
use std::{
collections::{BTreeMap, HashSet},
convert::TryFrom,
sync::RwLock,
};
#[cfg(feature = "conduit_bin")]
use rocket::{get, post};
@ -36,11 +40,29 @@ pub async fn join_room_by_id_route(
db: State<'_, Database>,
body: Ruma<join_room_by_id::Request<'_>>,
) -> ConduitResult<join_room_by_id::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
let mut servers = db
.rooms
.invite_state(&sender_user, &body.room_id)?
.unwrap_or_default()
.iter()
.filter_map(|event| {
serde_json::from_str::<serde_json::Value>(&event.json().to_string()).ok()
})
.filter_map(|event| event.get("sender").cloned())
.filter_map(|sender| sender.as_str().map(|s| s.to_owned()))
.filter_map(|sender| UserId::try_from(sender).ok())
.map(|user| user.server_name().to_owned())
.collect::<HashSet<_>>();
servers.insert(body.room_id.server_name().to_owned());
join_room_by_id_helper(
&db,
body.sender_user.as_ref(),
&body.room_id,
&[body.room_id.server_name().to_owned()],
&servers,
body.third_party_signed.as_ref(),
)
.await
@ -55,12 +77,31 @@ pub async fn join_room_by_id_or_alias_route(
db: State<'_, Database>,
body: Ruma<join_room_by_id_or_alias::Request<'_>>,
) -> ConduitResult<join_room_by_id_or_alias::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
let (servers, room_id) = match RoomId::try_from(body.room_id_or_alias.clone()) {
Ok(room_id) => (vec![room_id.server_name().to_owned()], room_id),
Ok(room_id) => {
let mut servers = db
.rooms
.invite_state(&sender_user, &room_id)?
.unwrap_or_default()
.iter()
.filter_map(|event| {
serde_json::from_str::<serde_json::Value>(&event.json().to_string()).ok()
})
.filter_map(|event| event.get("sender").cloned())
.filter_map(|sender| sender.as_str().map(|s| s.to_owned()))
.filter_map(|sender| UserId::try_from(sender).ok())
.map(|user| user.server_name().to_owned())
.collect::<HashSet<_>>();
servers.insert(room_id.server_name().to_owned());
(servers, room_id)
}
Err(room_alias) => {
let response = client_server::get_alias_helper(&db, &room_alias).await?;
(response.0.servers, response.0.room_id)
(response.0.servers.into_iter().collect(), response.0.room_id)
}
};
@ -406,7 +447,7 @@ async fn join_room_by_id_helper(
db: &Database,
sender_user: Option<&UserId>,
room_id: &RoomId,
servers: &[Box<ServerName>],
servers: &HashSet<Box<ServerName>>,
_third_party_signed: Option<&IncomingThirdPartySigned>,
) -> ConduitResult<join_room_by_id::Response> {
let sender_user = sender_user.expect("user is authenticated");

View File

@ -1795,7 +1795,8 @@ impl Rooms {
.filter_map(|event| event.get("sender").cloned())
.filter_map(|sender| sender.as_str().map(|s| s.to_owned()))
.filter_map(|sender| UserId::try_from(sender).ok())
.map(|user| user.server_name().to_owned());
.map(|user| user.server_name().to_owned())
.collect::<HashSet<_>>();
for remote_server in servers {
let make_leave_response = db