fix spec violation and slight alias resolution refactor

This commit is contained in:
dasha_uwu
2025-09-20 06:56:21 +05:00
committed by Jason Volk
parent 9c4d376bec
commit 1c0b4e94ac
12 changed files with 74 additions and 118 deletions

View File

@@ -304,7 +304,7 @@ pub(super) async fn get_remote_pdu(
#[admin_command]
pub(super) async fn get_room_state(&self, room: OwnedRoomOrAliasId) -> Result {
let room_id = self.services.alias.resolve(&room).await?;
let room_id = self.services.alias.maybe_resolve(&room).await?;
let room_state: Vec<Raw<AnyStateEvent>> = self
.services
.state_accessor

View File

@@ -25,7 +25,11 @@ pub(crate) enum RoomTimelineCommand {
#[admin_command]
pub(super) async fn last(&self, room_id: OwnedRoomOrAliasId) -> Result {
let room_id = self.services.alias.resolve(&room_id).await?;
let room_id = self
.services
.alias
.maybe_resolve(&room_id)
.await?;
let result = self
.services
@@ -43,7 +47,11 @@ pub(super) async fn pdus(
from: Option<String>,
limit: Option<usize>,
) -> Result {
let room_id = self.services.alias.resolve(&room_id).await?;
let room_id = self
.services
.alias
.maybe_resolve(&room_id)
.await?;
let from: Option<PduCount> = from.as_deref().map(str::parse).transpose()?;

View File

@@ -30,7 +30,11 @@ pub(super) async fn short_event_id(&self, event_id: OwnedEventId) -> Result {
#[admin_command]
pub(super) async fn short_room_id(&self, room_id: OwnedRoomOrAliasId) -> Result {
let room_id = self.services.alias.resolve(&room_id).await?;
let room_id = self
.services
.alias
.maybe_resolve(&room_id)
.await?;
let shortid = self
.services

View File

@@ -105,7 +105,7 @@ async fn ban_room(&self, room: OwnedRoomOrAliasId) -> Result {
match self
.services
.alias
.resolve_alias(room_alias, None)
.resolve_alias(room_alias)
.await
{
| Ok((room_id, servers)) => {
@@ -260,7 +260,7 @@ async fn ban_list_of_rooms(&self) -> Result {
match self
.services
.alias
.resolve_alias(room_alias, None)
.resolve_alias(room_alias)
.await
{
| Ok((room_id, servers)) => {
@@ -423,7 +423,7 @@ async fn unban_room(&self, room: OwnedRoomOrAliasId) -> Result {
match self
.services
.alias
.resolve_alias(room_alias, None)
.resolve_alias(room_alias)
.await
{
| Ok((room_id, servers)) => {

View File

@@ -119,7 +119,7 @@ pub(super) async fn create_user(&self, username: String, password: Option<String
.is_empty()
{
for room in &self.services.server.config.auto_join_rooms {
let Ok(room_id) = self.services.alias.resolve(room).await else {
let Ok(room_id) = self.services.alias.maybe_resolve(room).await else {
error!(
%user_id,
"Failed to resolve room alias to room ID when attempting to auto join {room}, skipping"
@@ -408,7 +408,7 @@ pub(super) async fn force_join_list_of_local_users(
let (room_id, servers) = self
.services
.alias
.resolve_with_servers(&room_id, None)
.maybe_resolve_with_servers(&room_id, None)
.await?;
if !self
@@ -532,7 +532,7 @@ pub(super) async fn force_join_all_local_users(
let (room_id, servers) = self
.services
.alias
.resolve_with_servers(&room_id, None)
.maybe_resolve_with_servers(&room_id, None)
.await?;
if !self
@@ -617,7 +617,7 @@ pub(super) async fn force_join_room(
let (room_id, servers) = self
.services
.alias
.resolve_with_servers(&room_id, None)
.maybe_resolve_with_servers(&room_id, None)
.await?;
assert!(
@@ -645,7 +645,11 @@ pub(super) async fn force_leave_room(
room_id: OwnedRoomOrAliasId,
) -> Result {
let user_id = parse_local_user_id(self.services, &user_id)?;
let room_id = self.services.alias.resolve(&room_id).await?;
let room_id = self
.services
.alias
.maybe_resolve(&room_id)
.await?;
assert!(
self.services.globals.user_is_local(&user_id),
@@ -678,7 +682,11 @@ pub(super) async fn force_leave_room(
#[admin_command]
pub(super) async fn force_demote(&self, user_id: String, room_id: OwnedRoomOrAliasId) -> Result {
let user_id = parse_local_user_id(self.services, &user_id)?;
let room_id = self.services.alias.resolve(&room_id).await?;
let room_id = self
.services
.alias
.maybe_resolve(&room_id)
.await?;
assert!(
self.services.globals.user_is_local(&user_id),
@@ -744,7 +752,11 @@ pub(super) async fn force_promote(
room_id: OwnedRoomOrAliasId,
) -> Result {
let target_id = parse_user_id(self.services, &target_id)?;
let room_id = self.services.alias.resolve(&room_id).await?;
let room_id = self
.services
.alias
.maybe_resolve(&room_id)
.await?;
let state_lock = self.services.state.mutex.lock(&room_id).await;

View File

@@ -5,7 +5,7 @@ use ruma::{
OwnedServerName, RoomAliasId, RoomId,
api::client::alias::{create_alias, delete_alias, get_alias},
};
use tuwunel_core::{Err, Result, debug};
use tuwunel_core::{Err, Result, debug, err};
use tuwunel_service::Services;
use crate::Ruma;
@@ -83,13 +83,11 @@ pub(crate) async fn get_alias_route(
) -> Result<get_alias::v3::Response> {
let room_alias = body.body.room_alias;
let Ok((room_id, servers)) = services
let (room_id, servers) = services
.alias
.resolve_alias(&room_alias, None)
.resolve_alias(&room_alias)
.await
else {
return Err!(Request(NotFound("Room with alias not found.")));
};
.map_err(|_| err!(Request(NotFound("Room with alias not found."))))?;
let servers = room_available_servers(&services, &room_id, &room_alias, servers).await;
debug!(?room_alias, ?room_id, "available servers: {servers:?}");

View File

@@ -165,10 +165,7 @@ async fn get_join_params(
},
// ... if room alias, resolve and don't shuffle ...
| Err(room_alias) => {
let (room_id, servers) = services
.alias
.resolve_alias(&room_alias, Some(via.to_vec()))
.await?;
let (room_id, servers) = services.alias.resolve_alias(&room_alias).await?;
(room_id, servers, Vec::new())
},

View File

@@ -535,7 +535,7 @@ pub(crate) async fn register_route(
&& (services.config.allow_guests_auto_join_rooms || !is_guest)
{
for room in &services.server.config.auto_join_rooms {
let Ok(room_id) = services.alias.resolve(room).await else {
let Ok(room_id) = services.alias.maybe_resolve(room).await else {
error!(
"Failed to resolve room alias to room ID when attempting to auto join \
{room}, skipping"

View File

@@ -55,7 +55,7 @@ pub(crate) async fn get_room_summary(
) -> Result<get_summary::v1::Response> {
let (room_id, servers) = services
.alias
.resolve_with_servers(&body.room_id_or_alias, Some(body.via.clone()))
.maybe_resolve_with_servers(&body.room_id_or_alias, Some(body.via.clone()))
.await?;
if services.metadata.is_banned(&room_id).await {

View File

@@ -328,7 +328,7 @@ async fn allowed_to_send_state_event(
for alias in aliases {
let (alias_room_id, _servers) = services
.alias
.resolve_alias(&alias, None)
.resolve_alias(&alias)
.await
.map_err(|e| {
err!(Request(BadAlias("Failed resolving alias \"{alias}\": {e}")))

View File

@@ -1,11 +1,9 @@
mod remote;
use std::sync::Arc;
use futures::{Stream, StreamExt};
use ruma::{
OwnedRoomId, OwnedServerName, OwnedUserId, RoomAliasId, RoomId, RoomOrAliasId, UserId,
events::StateEventType,
api::federation::query::get_room_information::v1::Request, events::StateEventType,
};
use tuwunel_core::{
Err, Result, err,
@@ -99,23 +97,21 @@ impl Service {
}
#[inline]
pub async fn resolve(&self, room: &RoomOrAliasId) -> Result<OwnedRoomId> {
self.resolve_with_servers(room, None)
.await
.map(|(room_id, _)| room_id)
pub async fn maybe_resolve(&self, room: &RoomOrAliasId) -> Result<OwnedRoomId> {
match <&RoomId>::try_from(room) {
| Ok(room_id) => Ok(room_id.to_owned()),
| Err(alias) => Ok(self.resolve_alias(alias).await?.0),
}
}
pub async fn resolve_with_servers(
pub async fn maybe_resolve_with_servers(
&self,
room: &RoomOrAliasId,
servers: Option<Vec<OwnedServerName>>,
) -> Result<(OwnedRoomId, Vec<OwnedServerName>)> {
if room.is_room_id() {
let room_id: &RoomId = room.try_into().expect("valid RoomId");
Ok((room_id.to_owned(), servers.unwrap_or_default()))
} else {
let alias: &RoomAliasId = room.try_into().expect("valid RoomAliasId");
self.resolve_alias(alias, servers).await
match <&RoomId>::try_from(room) {
| Ok(room_id) => Ok((room_id.to_owned(), servers.unwrap_or_default())),
| Err(alias) => self.resolve_alias(alias).await,
}
}
@@ -123,7 +119,6 @@ impl Service {
pub async fn resolve_alias(
&self,
room_alias: &RoomAliasId,
servers: Option<Vec<OwnedServerName>>,
) -> Result<(OwnedRoomId, Vec<OwnedServerName>)> {
if self
.services
@@ -141,9 +136,24 @@ impl Service {
return Err!(Request(NotFound("Room with alias not found.")));
}
return self
.remote_resolve(room_alias, servers.unwrap_or_default())
.await;
return self.remote_resolve(room_alias).await;
}
async fn remote_resolve(
&self,
room_alias: &RoomAliasId,
) -> Result<(OwnedRoomId, Vec<OwnedServerName>)> {
let server = room_alias.server_name();
let request = Request { room_alias: room_alias.to_owned() };
let response = self
.services
.sending
.send_federation_request(server, request)
.await?;
Ok((response.room_id, response.servers))
}
#[tracing::instrument(skip(self), level = "trace")]

View File

@@ -1,73 +0,0 @@
use std::iter::once;
use federation::query::get_room_information::v1::Response;
use ruma::{OwnedRoomId, OwnedServerName, RoomAliasId, ServerName, api::federation};
use tuwunel_core::{Result, debug, debug_error, err, implement};
#[implement(super::Service)]
pub(super) async fn remote_resolve(
&self,
room_alias: &RoomAliasId,
servers: Vec<OwnedServerName>,
) -> Result<(OwnedRoomId, Vec<OwnedServerName>)> {
debug!(?room_alias, servers = ?servers, "resolve");
let servers = once(room_alias.server_name())
.map(ToOwned::to_owned)
.chain(servers.into_iter());
let mut resolved_servers = Vec::new();
let mut resolved_room_id: Option<OwnedRoomId> = None;
for server in servers {
match self.remote_request(room_alias, &server).await {
| Err(e) => debug_error!("Failed to query for {room_alias:?} from {server}: {e}"),
| Ok(Response { room_id, servers }) => {
debug!(
"Server {server} answered with {room_id:?} for {room_alias:?} servers: \
{servers:?}"
);
resolved_room_id.get_or_insert(room_id);
add_server(&mut resolved_servers, server);
if !servers.is_empty() {
add_servers(&mut resolved_servers, servers);
break;
}
},
}
}
resolved_room_id
.map(|room_id| (room_id, resolved_servers))
.ok_or_else(|| {
err!(Request(NotFound("No servers could assist in resolving the room alias")))
})
}
#[implement(super::Service)]
async fn remote_request(
&self,
room_alias: &RoomAliasId,
server: &ServerName,
) -> Result<Response> {
use federation::query::get_room_information::v1::Request;
let request = Request { room_alias: room_alias.to_owned() };
self.services
.sending
.send_federation_request(server, request)
.await
}
fn add_servers(servers: &mut Vec<OwnedServerName>, new: Vec<OwnedServerName>) {
for server in new {
add_server(servers, server);
}
}
fn add_server(servers: &mut Vec<OwnedServerName>, server: OwnedServerName) {
if !servers.contains(&server) {
servers.push(server);
}
}