tuwunel_api/client/membership/
mod.rs1mod ban;
2mod forget;
3mod invite;
4mod join;
5mod kick;
6mod knock;
7mod leave;
8mod members;
9mod unban;
10
11use std::net::IpAddr;
12
13use axum::extract::State;
14use futures::{FutureExt, StreamExt};
15use ruma::{RoomId, RoomOrAliasId, UserId, api::client::membership::joined_rooms};
16use tuwunel_core::{Err, Result, result::LogErr, warn};
17use tuwunel_service::Services;
18
19pub(crate) use self::{
20 ban::ban_user_route,
21 forget::forget_room_route,
22 invite::invite_user_route,
23 join::{join_room_by_id_or_alias_route, join_room_by_id_route},
24 kick::kick_user_route,
25 knock::knock_room_route,
26 leave::leave_room_route,
27 members::{get_member_events_route, joined_members_route},
28 unban::unban_user_route,
29};
30use crate::Ruma;
31
32pub(crate) async fn joined_rooms_route(
36 State(services): State<crate::State>,
37 body: Ruma<joined_rooms::v3::Request>,
38) -> Result<joined_rooms::v3::Response> {
39 Ok(joined_rooms::v3::Response {
40 joined_rooms: services
41 .state_cache
42 .rooms_joined(body.sender_user())
43 .map(ToOwned::to_owned)
44 .collect()
45 .await,
46 })
47}
48
49#[tracing::instrument(skip(services))]
55pub(crate) async fn banned_room_check(
56 services: &Services,
57 user_id: &UserId,
58 room_id: &RoomId,
59 orig_room_id: Option<&RoomOrAliasId>,
60 client_ip: IpAddr,
61) -> Result {
62 if services.admin.user_is_admin(user_id).await {
63 return Ok(());
64 }
65
66 if services.metadata.is_banned(room_id).await
68 || room_id.server_name().is_some_and(|server_name| {
70 services
71 .config
72 .is_forbidden_remote_server_name(server_name)
73 })
74 || orig_room_id.is_some_and(|orig_room_id| {
76 orig_room_id.server_name().is_some_and(|orig_server_name| {
77 services
78 .config
79 .is_forbidden_remote_server_name(orig_server_name)
80 })
81 }) {
82 warn!(
83 "User {user_id} who is not an admin attempted to send an invite for or attempted to \
84 join a banned room or banned room server name: {room_id}"
85 );
86
87 maybe_deactivate(services, user_id, client_ip)
88 .await
89 .log_err()
90 .ok();
91
92 return Err!(Request(Forbidden("This room is banned on this homeserver.")));
93 }
94
95 Ok(())
96}
97
98async fn maybe_deactivate(services: &Services, user_id: &UserId, client_ip: IpAddr) -> Result {
99 if services
100 .server
101 .config
102 .auto_deactivate_banned_room_attempts
103 {
104 let notice = format!(
105 "Automatically deactivating user {user_id} due to attempted banned room join from \
106 IP {client_ip}"
107 );
108
109 warn!("{notice}");
110
111 if services.server.config.admin_room_notices {
112 services.admin.send_text(¬ice).await;
113 }
114
115 services
116 .deactivate
117 .full_deactivate(user_id, false)
118 .boxed()
119 .await?;
120 }
121
122 Ok(())
123}