tuwunel_api_client/membership/
forget.rs1use axum::extract::State;
2use futures::TryFutureExt;
3use ruma::{api::client::membership::forget_room, events::room::member::MembershipState};
4use tuwunel_core::{
5 Err, Result, is_matching,
6 utils::{FutureBoolExt, TryFutureExtExt},
7};
8
9use crate::Ruma;
10
11pub(crate) async fn forget_room_route(
22 State(services): State<crate::State>,
23 body: Ruma<forget_room::v3::Request>,
24) -> Result<forget_room::v3::Response> {
25 let user_id = body.sender_user();
26 let room_id = &body.room_id;
27 let _state_lock = services.state.mutex.lock(room_id).await;
28
29 let joined = services.state_cache.is_joined(user_id, room_id);
30 let knocked = services.state_cache.is_knocked(user_id, room_id);
31 let invited = services.state_cache.is_invited(user_id, room_id);
32
33 if joined.or2(knocked, invited).await {
34 return Err!(Request(Unknown("You must leave the room before forgetting it")));
35 }
36
37 let left = services.state_cache.is_left(user_id, room_id);
38 let left_or_banned = services
39 .state_accessor
40 .get_member(room_id, user_id)
41 .map_ok(|member| member.membership)
42 .map_ok_or(false, is_matching!(MembershipState::Leave | MembershipState::Ban));
43
44 if left.or(left_or_banned).await {
45 services
46 .state_cache
47 .forget(room_id, user_id)
48 .await?;
49 }
50
51 Ok(forget_room::v3::Response::new())
52}