diff --git a/conduit-example.toml b/conduit-example.toml index 74cbb074..018c13ca 100644 --- a/conduit-example.toml +++ b/conduit-example.toml @@ -72,3 +72,9 @@ address = "127.0.0.1" # This makes sure Conduit can only be reached using the re # If you want to override these defaults, uncomment and edit the following lines accordingly: #server = your.server.name:443 #client = https://your.server.name + + +# [global.moderation] +# servers = ["matrix.org"] +# users = [] +# rooms = [] diff --git a/src/config/mod.rs b/src/config/mod.rs index 378ab929..8b11921b 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,10 +1,13 @@ use std::{ - collections::BTreeMap, + collections::{BTreeMap, BTreeSet}, fmt, net::{IpAddr, Ipv4Addr}, + ops::Deref, + str::FromStr, }; -use ruma::{OwnedServerName, RoomVersionId}; +use hyper::client::connect::dns; +use ruma::{OwnedRoomOrAliasId, OwnedServerName, OwnedUserId, RoomVersionId, ServerName}; use serde::{de::IgnoredAny, Deserialize}; use tracing::warn; use url::Url; @@ -67,6 +70,8 @@ pub struct Config { pub tracing_flame: bool, #[serde(default)] pub proxy: ProxyConfig, + #[serde(default)] + pub moderation: ModerationConfig, pub jwt_secret: Option, #[serde(default = "default_trusted_servers")] pub trusted_servers: Vec, @@ -101,6 +106,28 @@ pub struct WellKnownConfig { pub server: Option, } +#[derive(Clone, Debug, Deserialize, Default)] +pub struct ModerationConfig { + pub users: BTreeSet, + pub rooms: BTreeSet, + #[serde(deserialize_with = "deserialize_dns_name")] + pub servers: Vec, +} + +fn deserialize_dns_name<'de, D>(deserializer: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + BTreeSet::::deserialize(deserializer).and_then(|set| { + set.iter() + .map(Deref::deref) + .map(ServerName::as_str) + .map(dns::Name::from_str) + .collect::>() + .map_err(serde::de::Error::custom) + }) +} + const DEPRECATED_KEYS: &[&str] = &["cache_capacity"]; impl Config { diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs index f5979301..145c3dee 100644 --- a/src/service/globals/mod.rs +++ b/src/service/globals/mod.rs @@ -22,6 +22,7 @@ use ruma::{ }, DeviceId, RoomVersionId, ServerName, UserId, }; +use std::net::Ipv4Addr; use std::{ collections::{BTreeMap, HashMap}, error::Error as StdError, @@ -125,6 +126,16 @@ impl Resolver { impl Resolve for Resolver { fn resolve(&self, name: Name) -> Resolving { + let blocked = services() + .globals + .config + .moderation + .servers + .iter() + .find(|blocked| name.as_str().ends_with(blocked.as_str())) + .is_some(); + dbg!(&name); + self.overrides .read() .unwrap() @@ -139,9 +150,20 @@ impl Resolve for Resolver { }) .unwrap_or_else(|| { let this = &mut self.inner.clone(); - Box::pin(HyperService::::call(this, name).map(|result| { + Box::pin(HyperService::::call(this, name).map(move |result| { result - .map(|addrs| -> Addrs { Box::new(addrs) }) + .map(|addrs| -> Addrs { + if blocked { + Box::new(addrs.map(|addr| { + SocketAddr::new( + IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), + addr.port(), + ) + })) + } else { + Box::new(addrs) + } + }) .map_err(|err| -> Box { Box::new(err) }) })) })