2024-07-16 08:05:25 +00:00
|
|
|
use axum::extract::State;
|
2026-04-09 11:39:53 -04:00
|
|
|
use conduwuit::{Err, Result};
|
|
|
|
|
use ruma::{UInt, api::client::space::get_hierarchy, assign};
|
|
|
|
|
use service::rooms::summary::Accessibility;
|
2024-03-16 16:09:11 -04:00
|
|
|
|
2025-02-07 07:09:45 +00:00
|
|
|
use crate::Ruma;
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2026-04-09 11:39:53 -04:00
|
|
|
const MAX_MAX_DEPTH: u32 = 10;
|
|
|
|
|
|
2024-03-22 21:51:21 -04:00
|
|
|
/// # `GET /_matrix/client/v1/rooms/{room_id}/hierarchy`
|
2023-07-02 16:06:54 +02:00
|
|
|
///
|
|
|
|
|
/// Paginates over the space tree in a depth-first manner to locate child rooms
|
|
|
|
|
/// of a given space.
|
2024-07-16 08:05:25 +00:00
|
|
|
pub(crate) async fn get_hierarchy_route(
|
2024-12-15 00:05:47 -05:00
|
|
|
State(services): State<crate::State>,
|
|
|
|
|
body: Ruma<get_hierarchy::v1::Request>,
|
2024-07-16 08:05:25 +00:00
|
|
|
) -> Result<get_hierarchy::v1::Response> {
|
2026-04-09 11:39:53 -04:00
|
|
|
// 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.
|
2023-07-02 16:06:54 +02:00
|
|
|
|
2026-07-23 14:36:58 +02:00
|
|
|
// Default to MAX_MAX_DEPTH when the client doesn't specify one, so an
|
|
|
|
|
// unbounded traversal can never happen.
|
2026-07-23 15:55:30 +02:00
|
|
|
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));
|
2023-07-02 16:06:54 +02:00
|
|
|
|
2026-04-09 11:39:53 -04:00
|
|
|
let hierarchy = services
|
|
|
|
|
.rooms
|
|
|
|
|
.summary
|
|
|
|
|
.get_room_hierarchy_for_user(
|
2026-05-27 12:15:16 -04:00
|
|
|
body.identity.expect_sender_user()?,
|
2026-04-09 11:39:53 -04:00
|
|
|
body.room_id.clone(),
|
|
|
|
|
max_depth,
|
|
|
|
|
body.suggested_only,
|
|
|
|
|
)
|
|
|
|
|
.await?;
|
2023-07-02 16:06:54 +02:00
|
|
|
|
2026-04-09 11:39:53 -04:00
|
|
|
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))
|
|
|
|
|
},
|
2024-03-16 16:09:11 -04:00
|
|
|
}
|
2025-02-06 20:08:00 +00:00
|
|
|
}
|