allow adding canonical aliases from remote servers

Like is mentioned in the comment, this isn't explicitly required by the
spec, but it's reasonable and what synapse does.
This commit is contained in:
Olivia Lee 2025-01-20 16:53:08 -08:00
parent 29d8fbaefa
commit 472f51c350
No known key found for this signature in database
GPG key ID: 54D568A15B9CD1F9
4 changed files with 57 additions and 12 deletions

View file

@ -1,6 +1,7 @@
use http::StatusCode;
use ruma::{
api::client::error::ErrorKind, OwnedRoomAliasId, OwnedRoomId, RoomAliasId,
RoomId, UserId,
api::{client::error::ErrorKind, federation},
OwnedRoomAliasId, OwnedRoomId, RoomAliasId, RoomId, UserId,
};
use crate::{services, Error, Result};
@ -60,7 +61,7 @@ impl Service {
self.db.remove_alias(alias)
}
/// Looks up the roomid for the given alias.
/// Looks up the roomid for the given local alias.
pub(crate) fn resolve_local_alias(
&self,
alias: &RoomAliasId,
@ -75,4 +76,46 @@ impl Service {
) -> Box<dyn Iterator<Item = Result<OwnedRoomAliasId>> + 'a> {
self.db.local_aliases_for_room(room_id)
}
/// Looks up the roomid for the given alias, fetching over federation if
/// remote.
pub(crate) async fn resolve_alias(
&self,
alias: &RoomAliasId,
) -> Result<Option<OwnedRoomId>> {
if alias.server_name() == services().globals.server_name() {
self.resolve_local_alias(alias)
} else {
self.resolve_remote_alias(alias).await
}
}
/// Look up an alias on a remote server over federation.
async fn resolve_remote_alias(
&self,
alias: &RoomAliasId,
) -> Result<Option<OwnedRoomId>> {
let result = services()
.sending
.send_federation_request(
alias.server_name(),
federation::query::get_room_information::v1::Request {
room_alias: alias.to_owned(),
},
)
.await;
match result {
Ok(response) => Ok(Some(response.room_id)),
// The spec only names the 404 status code explicitly, but matching
// on M_NOT_FOUND as well seems reasonable.
Err(Error::Federation(_, error))
if error.status_code == StatusCode::NOT_FOUND
|| error.error_kind() == Some(&ErrorKind::NotFound) =>
{
Ok(None)
}
Err(error) => Err(error),
}
}
}