sync upstream spaces/hierarchy federation MR

also had to fix a million clippy lints

fix(spaces): deal with hierarchy recursion
fix(spaces): properly handle max_depth
refactor(spaces): token scheme to prevent clients from modifying max_depth and suggested_only
perf(spaces): use tokens to skip to room to start populating results at
feat(spaces): request hierarchy from servers in via field of child event

Co-authored-by: Matthias Ahouansou <matthias@ahouansou.cz>
Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
strawberry 2024-07-02 16:42:07 -04:00
parent 9115901c66
commit 28ac3790c2
5 changed files with 433 additions and 784 deletions

View file

@ -2,10 +2,10 @@ use std::str::FromStr;
use ruma::{
api::client::{error::ErrorKind, space::get_hierarchy},
uint, UInt,
UInt,
};
use crate::{service::rooms::spaces::PagnationToken, services, Error, Result, Ruma};
use crate::{service::rooms::spaces::PaginationToken, services, Error, Result, Ruma};
/// # `GET /_matrix/client/v1/rooms/{room_id}/hierarchy`
///
@ -14,12 +14,10 @@ use crate::{service::rooms::spaces::PagnationToken, services, Error, Result, Rum
pub(crate) async fn get_hierarchy_route(body: Ruma<get_hierarchy::v1::Request>) -> Result<get_hierarchy::v1::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
let limit: usize = body
let limit = body
.limit
.unwrap_or_else(|| uint!(10))
.try_into()
.unwrap_or(10)
.min(100);
.unwrap_or_else(|| UInt::from(10_u32))
.min(UInt::from(100_u32));
let max_depth = body
.max_depth
@ -29,7 +27,7 @@ pub(crate) async fn get_hierarchy_route(body: Ruma<get_hierarchy::v1::Request>)
let key = body
.from
.as_ref()
.and_then(|s| PagnationToken::from_str(s).ok());
.and_then(|s| PaginationToken::from_str(s).ok());
// Should prevent unexpeded behaviour in (bad) clients
if let Some(ref token) = key {
@ -47,8 +45,8 @@ pub(crate) async fn get_hierarchy_route(body: Ruma<get_hierarchy::v1::Request>)
.get_client_hierarchy(
sender_user,
&body.room_id,
limit,
key.map_or(0, |token| token.skip.try_into().unwrap_or(0)),
limit.try_into().unwrap_or(10),
key.map_or(vec![], |token| token.short_room_ids),
max_depth.try_into().unwrap_or(3),
body.suggested_only,
)