#[derive(Debug, Deserialize, Clone)]
pub struct Settings {
pub setup: Option<Setup>,
- pub database: Database,
+ pub database: DatabaseConfig,
pub hostname: String,
pub bind: IpAddr,
pub port: u16,
pub pictrs_url: String,
pub rate_limit: RateLimitConfig,
pub email: Option<EmailConfig>,
- pub federation: Federation,
+ pub federation: FederationConfig,
pub captcha: CaptchaConfig,
}
}
#[derive(Debug, Deserialize, Clone)]
-pub struct Database {
+pub struct DatabaseConfig {
pub user: String,
pub password: String,
pub host: String,
}
#[derive(Debug, Deserialize, Clone)]
-pub struct Federation {
+pub struct FederationConfig {
pub enabled: bool,
pub tls_enabled: bool,
pub allowed_instances: String,
+ pub blocked_instances: String,
}
lazy_static! {
allowed_instances
}
+ pub fn get_blocked_instances(&self) -> Vec<String> {
+ let mut blocked_instances: Vec<String> = self
+ .federation
+ .blocked_instances
+ .split(',')
+ .map(|d| d.to_string())
+ .collect();
+
+ // The defaults.hjson config always returns a [""]
+ blocked_instances.retain(|d| !d.eq(""));
+
+ blocked_instances
+ }
+
pub fn save_config_file(data: &str) -> Result<String, Error> {
fs::write(CONFIG_FILE, data)?;
return Err(anyhow!("invalid apub id scheme: {:?}", apub_id.scheme()).into());
}
- let mut allowed_instances: Vec<String> = Settings::get().get_allowed_instances();
-
- // need to allow this explicitly because apub activities might contain objects from our local
- // instance. replace is needed to remove the port in our federation test setup.
- let settings = Settings::get();
- let local_instance = settings.hostname.split(':').collect::<Vec<&str>>();
- allowed_instances.push(
- local_instance
- .first()
- .context(location_info!())?
- .to_string(),
- );
-
- match apub_id.domain() {
- Some(d) => {
- let contains = allowed_instances.contains(&d.to_owned());
-
- if !contains {
- return Err(anyhow!("{} not in federation allowlist", d).into());
- }
+ let mut allowed_instances = Settings::get().get_allowed_instances();
+ let blocked_instances = Settings::get().get_blocked_instances();
+
+ let domain = apub_id.domain().context(location_info!())?.to_string();
+ if !allowed_instances.is_empty() {
+ // need to allow this explicitly because apub activities might contain objects from our local
+ // instance. split is needed to remove the port in our federation test setup.
+ let settings = Settings::get();
+ let local_instance = settings.hostname.split(':').collect::<Vec<&str>>();
+ allowed_instances.push(
+ local_instance
+ .first()
+ .context(location_info!())?
+ .to_string(),
+ );
+ if allowed_instances.contains(&domain) {
Ok(())
+ } else {
+ Err(anyhow!("{} not in federation allowlist", domain).into())
}
- None => Err(anyhow!("federation allowlist is empty").into()),
+ } else if !blocked_instances.is_empty() {
+ if blocked_instances.contains(&domain) {
+ Err(anyhow!("{} is in federation blocklist", domain).into())
+ } else {
+ Ok(())
+ }
+ } else {
+ panic!("Invalid config, both allowed_instances and blocked_instances are specified");
}
}