use axum::extract::State; use conduwuit::{Err, Result}; use ruma::{UInt, api::client::space::get_hierarchy, assign}; use service::rooms::summary::Accessibility; use crate::Ruma; const MAX_MAX_DEPTH: u32 = 10; /// # `GET /_matrix/client/v1/rooms/{room_id}/hierarchy` /// /// Paginates over the space tree in a depth-first manner to locate child rooms /// of a given space. pub(crate) async fn get_hierarchy_route( State(services): State, body: Ruma, ) -> Result { // We don't do pagination for this route (and therefore ignore `limit`), // since there's no reasonable way to handle a space hierarchy changing // during pagination. // Default to MAX_MAX_DEPTH when the client doesn't specify one, so an // unbounded traversal can never happen. let max_max_depth = UInt::from(MAX_MAX_DEPTH); let max_depth = Some(body.max_depth.unwrap_or(max_max_depth).min(max_max_depth)); let hierarchy = services .rooms .summary .get_room_hierarchy_for_user( body.identity.expect_sender_user()?, body.room_id.clone(), max_depth, body.suggested_only, ) .await?; match hierarchy { | Accessibility::Accessible(rooms) => Ok(assign!(get_hierarchy::v1::Response::new(), { rooms: rooms })), | Accessibility::Inaccessible => { Err!(Request(Forbidden("You may not preview this room."), FORBIDDEN)) }, | Accessibility::NotFound => { Err!(Request(Forbidden("This room does not exist."), FORBIDDEN)) }, } }