tuwunel_service/rooms/event_handler/
acl_check.rs1use ruma::{
2 RoomId, ServerName,
3 events::{StateEventType, room::server_acl::RoomServerAclEventContent},
4};
5use tuwunel_core::{Err, Result, debug, implement, trace, warn};
6
7#[implement(super::Service)]
9#[tracing::instrument(skip_all, level = "debug")]
10pub async fn acl_check(&self, server_name: &ServerName, room_id: &RoomId) -> Result {
11 let Ok(acl_event_content) = self
12 .services
13 .state_accessor
14 .room_state_get_content(room_id, &StateEventType::RoomServerAcl, "")
15 .await
16 .map(|c: RoomServerAclEventContent| c)
17 .inspect(|acl| trace!(%room_id, "ACL content found: {acl:?}"))
18 .inspect_err(|e| trace!(%room_id, "No ACL content found: {e:?}"))
19 else {
20 return Ok(());
21 };
22
23 if acl_event_content.allow.is_empty() {
24 warn!(%room_id, "Ignoring broken ACL event (allow key is empty)");
25 return Ok(());
26 }
27
28 if acl_event_content
29 .deny
30 .contains(&String::from("*"))
31 && acl_event_content
32 .allow
33 .contains(&String::from("*"))
34 {
35 warn!(%room_id, "Ignoring broken ACL event (allow key and deny key both contain wildcard \"*\"");
36 return Ok(());
37 }
38
39 if acl_event_content.is_allowed(server_name) {
40 trace!("server {server_name} is allowed by ACL");
41 Ok(())
42 } else {
43 debug!("Server {server_name} was denied by room ACL in {room_id}");
44 Err!(Request(Forbidden("Server was denied by room ACL")))
45 }
46}