diff --git a/upub/core/src/config.rs b/upub/core/src/config.rs index 7036995..c51477b 100644 --- a/upub/core/src/config.rs +++ b/upub/core/src/config.rs @@ -18,6 +18,9 @@ pub struct Config { #[serde(default)] pub files: FileStorageConfig, + #[serde(default)] + pub reject: RejectConfig, + // TODO should i move app keys here? } @@ -122,6 +125,19 @@ pub struct FileStorageConfig { pub path: String, } +#[serde_inline_default::serde_inline_default] +#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, serde_default::DefaultFromSerde)] +pub struct RejectConfig { + #[serde(default)] + pub everything: Vec, + + #[serde(default)] + pub media: Vec, + + #[serde(default)] + pub delivery: Vec, +} + impl Config { pub fn load(path: Option<&std::path::PathBuf>) -> Self { let Some(cfg_path) = path else { return Config::default() }; diff --git a/upub/routes/src/activitypub/application.rs b/upub/routes/src/activitypub/application.rs index 266df32..f15790b 100644 --- a/upub/routes/src/activitypub/application.rs +++ b/upub/routes/src/activitypub/application.rs @@ -120,6 +120,11 @@ pub async fn cloak_proxy( let uri = ctx.uncloak(&hmac, &uri) .ok_or_else(ApiError::unauthorized)?; + let stripped = uri.replace("https://", "").replace("http://", ""); + if ctx.cfg().reject.media.iter().any(|x| stripped.starts_with(x)) { + return Err(ApiError::Status(axum::http::StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS)); + } + let resp = Context::client(ctx.domain()) .get(uri) .send() diff --git a/upub/routes/src/activitypub/inbox.rs b/upub/routes/src/activitypub/inbox.rs index 4711257..e5292ce 100644 --- a/upub/routes/src/activitypub/inbox.rs +++ b/upub/routes/src/activitypub/inbox.rs @@ -43,7 +43,7 @@ pub async fn post( AuthIdentity(auth): AuthIdentity, Json(activity): Json ) -> crate::ApiResult { - let Identity::Remote { domain: _server, user: uid, .. } = auth else { + let Identity::Remote { domain, user: uid, .. } = auth else { if matches!(activity.activity_type(), Ok(ActivityType::Delete)) { // this is spammy af, ignore them! // we basically received a delete for a user we can't fetch and verify, meaning remote @@ -64,6 +64,10 @@ pub async fn post( } }; + if ctx.cfg().reject.everything.contains(&domain) { + return Err(crate::ApiError::Status(StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS)); + } + let aid = activity.id()?.to_string(); let server = upub::Context::server(&aid); diff --git a/upub/worker/src/outbound.rs b/upub/worker/src/outbound.rs index 13a0220..bab2a0d 100644 --- a/upub/worker/src/outbound.rs +++ b/upub/worker/src/outbound.rs @@ -185,6 +185,18 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult< targets.push(relay); } } + + targets + .retain(|target| { + let stripped = target.replace("https://", "").replace("http://", ""); + if ctx.cfg().reject.delivery.iter().any(|x| stripped.starts_with(x)) { + tracing::warn!("rejecting delivery of {} to {target}", job.activity); + false + } else { + true + } + }); + ctx.deliver(targets, &job.activity, &job.actor, &tx).await?; tx.commit().await?;