split up alias.rs a bit (alias checks and room alias server name stuff)
Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
parent
e00b65b0e0
commit
f4a2b39d55
1 changed files with 60 additions and 68 deletions
|
@ -8,20 +8,23 @@ use ruma::{
|
||||||
},
|
},
|
||||||
federation,
|
federation,
|
||||||
},
|
},
|
||||||
OwnedRoomAliasId, OwnedServerName,
|
OwnedRoomAliasId, OwnedRoomId, OwnedServerName,
|
||||||
};
|
};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::{debug_info, debug_warn, services, utils::server_name::server_is_ours, Error, Result, Ruma};
|
use crate::{
|
||||||
|
debug_info, debug_warn, service::appservice::RegistrationInfo, services, utils::server_name::server_is_ours, Error,
|
||||||
|
Result, Ruma,
|
||||||
|
};
|
||||||
|
|
||||||
/// # `PUT /_matrix/client/v3/directory/room/{roomAlias}`
|
/// # `PUT /_matrix/client/v3/directory/room/{roomAlias}`
|
||||||
///
|
///
|
||||||
/// Creates a new room alias on this server.
|
/// Creates a new room alias on this server.
|
||||||
pub(crate) async fn create_alias_route(body: Ruma<create_alias::v3::Request>) -> Result<create_alias::v3::Response> {
|
pub(crate) async fn create_alias_route(body: Ruma<create_alias::v3::Request>) -> Result<create_alias::v3::Response> {
|
||||||
if !server_is_ours(body.room_alias.server_name()) {
|
alias_checks(&body.room_alias, &body.appservice_info).await?;
|
||||||
return Err(Error::BadRequest(ErrorKind::InvalidParam, "Alias is from another server."));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// this isn't apart of alias_checks or delete alias route because we should
|
||||||
|
// allow removing forbidden room aliases
|
||||||
if services()
|
if services()
|
||||||
.globals
|
.globals
|
||||||
.forbidden_alias_names()
|
.forbidden_alias_names()
|
||||||
|
@ -30,18 +33,6 @@ pub(crate) async fn create_alias_route(body: Ruma<create_alias::v3::Request>) ->
|
||||||
return Err(Error::BadRequest(ErrorKind::Unknown, "Room alias is forbidden."));
|
return Err(Error::BadRequest(ErrorKind::Unknown, "Room alias is forbidden."));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref info) = body.appservice_info {
|
|
||||||
if !info.aliases.is_match(body.room_alias.as_str()) {
|
|
||||||
return Err(Error::BadRequest(ErrorKind::Exclusive, "Room alias is not in namespace."));
|
|
||||||
}
|
|
||||||
} else if services()
|
|
||||||
.appservice
|
|
||||||
.is_exclusive_alias(&body.room_alias)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
return Err(Error::BadRequest(ErrorKind::Exclusive, "Room alias reserved by appservice."));
|
|
||||||
}
|
|
||||||
|
|
||||||
if services()
|
if services()
|
||||||
.rooms
|
.rooms
|
||||||
.alias
|
.alias
|
||||||
|
@ -73,9 +64,7 @@ pub(crate) async fn create_alias_route(body: Ruma<create_alias::v3::Request>) ->
|
||||||
/// - TODO: additional access control checks
|
/// - TODO: additional access control checks
|
||||||
/// - TODO: Update canonical alias event
|
/// - TODO: Update canonical alias event
|
||||||
pub(crate) async fn delete_alias_route(body: Ruma<delete_alias::v3::Request>) -> Result<delete_alias::v3::Response> {
|
pub(crate) async fn delete_alias_route(body: Ruma<delete_alias::v3::Request>) -> Result<delete_alias::v3::Response> {
|
||||||
if !server_is_ours(body.room_alias.server_name()) {
|
alias_checks(&body.room_alias, &body.appservice_info).await?;
|
||||||
return Err(Error::BadRequest(ErrorKind::InvalidParam, "Alias is from another server."));
|
|
||||||
}
|
|
||||||
|
|
||||||
if services()
|
if services()
|
||||||
.rooms
|
.rooms
|
||||||
|
@ -86,18 +75,6 @@ pub(crate) async fn delete_alias_route(body: Ruma<delete_alias::v3::Request>) ->
|
||||||
return Err(Error::BadRequest(ErrorKind::NotFound, "Alias does not exist."));
|
return Err(Error::BadRequest(ErrorKind::NotFound, "Alias does not exist."));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref info) = body.appservice_info {
|
|
||||||
if !info.aliases.is_match(body.room_alias.as_str()) {
|
|
||||||
return Err(Error::BadRequest(ErrorKind::Exclusive, "Room alias is not in namespace."));
|
|
||||||
}
|
|
||||||
} else if services()
|
|
||||||
.appservice
|
|
||||||
.is_exclusive_alias(&body.room_alias)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
return Err(Error::BadRequest(ErrorKind::Exclusive, "Room alias reserved by appservice."));
|
|
||||||
}
|
|
||||||
|
|
||||||
if services()
|
if services()
|
||||||
.rooms
|
.rooms
|
||||||
.alias
|
.alias
|
||||||
|
@ -180,42 +157,16 @@ pub(crate) async fn get_alias_helper(
|
||||||
if let Ok(response) = response {
|
if let Ok(response) = response {
|
||||||
let room_id = response.room_id;
|
let room_id = response.room_id;
|
||||||
|
|
||||||
let mut servers = response.servers;
|
let mut pre_servers = response.servers;
|
||||||
|
// since the room alis server responded, insert it into the list
|
||||||
|
pre_servers.push(room_alias.server_name().into());
|
||||||
|
|
||||||
// since the room alias server_name responded, insert it into the list
|
let servers = room_available_servers(&room_id, &room_alias, &Some(pre_servers));
|
||||||
servers.push(room_alias.server_name().into());
|
debug_warn!(
|
||||||
|
"room alias servers from federation response for room ID {room_id} and room alias {room_alias}: \
|
||||||
// find active servers in room state cache to suggest
|
{servers:?}"
|
||||||
servers.extend(
|
|
||||||
services()
|
|
||||||
.rooms
|
|
||||||
.state_cache
|
|
||||||
.room_servers(&room_id)
|
|
||||||
.filter_map(Result::ok),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
servers.sort_unstable();
|
|
||||||
servers.dedup();
|
|
||||||
|
|
||||||
// shuffle list of servers randomly after sort and dedupe
|
|
||||||
servers.shuffle(&mut rand::thread_rng());
|
|
||||||
|
|
||||||
// prefer the very first server to be ourselves if available, else prefer the
|
|
||||||
// room alias server first
|
|
||||||
if let Some(server_index) = servers
|
|
||||||
.iter()
|
|
||||||
.position(|server_name| server_is_ours(server_name))
|
|
||||||
{
|
|
||||||
servers.remove(server_index);
|
|
||||||
servers.insert(0, services().globals.server_name().to_owned());
|
|
||||||
} else if let Some(alias_server_index) = servers
|
|
||||||
.iter()
|
|
||||||
.position(|server| server == room_alias.server_name())
|
|
||||||
{
|
|
||||||
servers.remove(alias_server_index);
|
|
||||||
servers.insert(0, room_alias.server_name().into());
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(get_alias::v3::Response::new(room_id, servers));
|
return Ok(get_alias::v3::Response::new(room_id, servers));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,28 +211,69 @@ pub(crate) async fn get_alias_helper(
|
||||||
return Err(Error::BadRequest(ErrorKind::NotFound, "Room with alias not found."));
|
return Err(Error::BadRequest(ErrorKind::NotFound, "Room with alias not found."));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let servers = room_available_servers(&room_id, &room_alias, &None);
|
||||||
|
|
||||||
|
debug_warn!("room alias servers for room ID {room_id} and room alias {room_alias}");
|
||||||
|
|
||||||
|
Ok(get_alias::v3::Response::new(room_id, servers))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn room_available_servers(
|
||||||
|
room_id: &OwnedRoomId, room_alias: &OwnedRoomAliasId, pre_servers: &Option<Vec<OwnedServerName>>,
|
||||||
|
) -> Vec<OwnedServerName> {
|
||||||
// find active servers in room state cache to suggest
|
// find active servers in room state cache to suggest
|
||||||
let mut servers: Vec<OwnedServerName> = services()
|
let mut servers: Vec<OwnedServerName> = services()
|
||||||
.rooms
|
.rooms
|
||||||
.state_cache
|
.state_cache
|
||||||
.room_servers(&room_id)
|
.room_servers(room_id)
|
||||||
.filter_map(Result::ok)
|
.filter_map(Result::ok)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
// push any servers we want in the list already (e.g. responded remote alias
|
||||||
|
// servers, room alias server itself)
|
||||||
|
if let Some(pre_servers) = pre_servers {
|
||||||
|
servers.extend(pre_servers.clone());
|
||||||
|
};
|
||||||
|
|
||||||
servers.sort_unstable();
|
servers.sort_unstable();
|
||||||
servers.dedup();
|
servers.dedup();
|
||||||
|
|
||||||
// shuffle list of servers randomly after sort and dedupe
|
// shuffle list of servers randomly after sort and dedupe
|
||||||
servers.shuffle(&mut rand::thread_rng());
|
servers.shuffle(&mut rand::thread_rng());
|
||||||
|
|
||||||
// insert our server as the very first choice if in list
|
// insert our server as the very first choice if in list, else check if we can
|
||||||
|
// prefer the room alias server first
|
||||||
if let Some(server_index) = servers
|
if let Some(server_index) = servers
|
||||||
.iter()
|
.iter()
|
||||||
.position(|server_name| server_is_ours(server_name))
|
.position(|server_name| server_is_ours(server_name))
|
||||||
{
|
{
|
||||||
servers.remove(server_index);
|
servers.remove(server_index);
|
||||||
servers.insert(0, services().globals.server_name().to_owned());
|
servers.insert(0, services().globals.server_name().to_owned());
|
||||||
|
} else if let Some(alias_server_index) = servers
|
||||||
|
.iter()
|
||||||
|
.position(|server| server == room_alias.server_name())
|
||||||
|
{
|
||||||
|
servers.remove(alias_server_index);
|
||||||
|
servers.insert(0, room_alias.server_name().into());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(get_alias::v3::Response::new(room_id, servers))
|
servers
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn alias_checks(room_alias: &OwnedRoomAliasId, appservice_info: &Option<RegistrationInfo>) -> Result<()> {
|
||||||
|
if !server_is_ours(room_alias.server_name()) {
|
||||||
|
return Err(Error::BadRequest(ErrorKind::InvalidParam, "Alias is from another server."));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(ref info) = appservice_info {
|
||||||
|
if !info.aliases.is_match(room_alias.as_str()) {
|
||||||
|
return Err(Error::BadRequest(ErrorKind::Exclusive, "Room alias is not in namespace."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if services().appservice.is_exclusive_alias(room_alias).await {
|
||||||
|
return Err(Error::BadRequest(ErrorKind::Exclusive, "Room alias reserved by appservice."));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue