diff --git a/server/lemmy_db/src/schema.rs b/server/lemmy_db/src/schema.rs index 9608fb7d..28042344 100644 --- a/server/lemmy_db/src/schema.rs +++ b/server/lemmy_db/src/schema.rs @@ -507,36 +507,36 @@ joinable!(user_mention -> comment (comment_id)); joinable!(user_mention -> user_ (recipient_id)); allow_tables_to_appear_in_same_query!( - activity, - category, - comment, - comment_aggregates_fast, - comment_like, - comment_saved, - community, - community_aggregates_fast, - community_follower, - community_moderator, - community_user_ban, - mod_add, - mod_add_community, - mod_ban, - mod_ban_from_community, - mod_lock_post, - mod_remove_comment, - mod_remove_community, - mod_remove_post, - mod_sticky_post, - password_reset_request, - post, - post_aggregates_fast, - post_like, - post_read, - post_saved, - private_message, - site, - user_, - user_ban, - user_fast, - user_mention, + activity, + category, + comment, + comment_aggregates_fast, + comment_like, + comment_saved, + community, + community_aggregates_fast, + community_follower, + community_moderator, + community_user_ban, + mod_add, + mod_add_community, + mod_ban, + mod_ban_from_community, + mod_lock_post, + mod_remove_comment, + mod_remove_community, + mod_remove_post, + mod_sticky_post, + password_reset_request, + post, + post_aggregates_fast, + post_like, + post_read, + post_saved, + private_message, + site, + user_, + user_ban, + user_fast, + user_mention, ); diff --git a/server/src/apub/activities.rs b/server/src/apub/activities.rs index 9fdfe37f..b5d6ce46 100644 --- a/server/src/apub/activities.rs +++ b/server/src/apub/activities.rs @@ -1,9 +1,9 @@ use crate::{ apub::{ + check_is_apub_id_valid, community::do_announce, extensions::signatures::sign, insert_activity, - is_apub_id_valid, ActorType, }, request::retry_custom, @@ -50,10 +50,7 @@ pub async fn send_activity( for t in to { let to_url = Url::parse(&t)?; - if !is_apub_id_valid(&to_url) { - debug!("Not sending activity to {} (invalid or blocklisted)", t); - continue; - } + check_is_apub_id_valid(&to_url)?; let res = retry_custom(|| async { let request = client.post(&t).header("Content-Type", "application/json"); diff --git a/server/src/apub/fetcher.rs b/server/src/apub/fetcher.rs index 4425757d..919b0e88 100644 --- a/server/src/apub/fetcher.rs +++ b/server/src/apub/fetcher.rs @@ -1,7 +1,7 @@ use crate::{ api::site::SearchResponse, apub::{ - is_apub_id_valid, + check_is_apub_id_valid, ActorType, FromApub, GroupExt, @@ -66,9 +66,7 @@ pub async fn fetch_remote_object( where Response: for<'de> Deserialize<'de>, { - if !is_apub_id_valid(&url) { - return Err(anyhow!("Activitypub uri invalid or blocked: {}", url).into()); - } + check_is_apub_id_valid(&url)?; let timeout = Duration::from_secs(60); diff --git a/server/src/apub/inbox/shared_inbox.rs b/server/src/apub/inbox/shared_inbox.rs index 9e0cdb3d..c1fff408 100644 --- a/server/src/apub/inbox/shared_inbox.rs +++ b/server/src/apub/inbox/shared_inbox.rs @@ -1,5 +1,6 @@ use crate::{ apub::{ + check_is_apub_id_valid, community::do_announce, extensions::signatures::verify, fetcher::{ @@ -67,9 +68,13 @@ pub async fn shared_inbox( debug!("Shared inbox received activity: {}", json); let sender = &activity.actor()?.to_owned().single_xsd_any_uri().unwrap(); - // TODO: pass this actor in instead of using get_user_from_activity() let actor = get_or_fetch_and_upsert_actor(sender, &client, &pool).await?; + + let community = get_community_id_from_activity(&activity).await; + + check_is_apub_id_valid(sender)?; + check_is_apub_id_valid(&community)?; verify(&request, actor.as_ref())?; insert_activity(actor.user_id(), activity.clone(), false, &pool).await?; @@ -112,6 +117,15 @@ where get_or_fetch_and_upsert_user(&user_uri, client, pool).await } +pub(in crate::apub::inbox) async fn get_community_id_from_activity(activity: &T) -> Url +where + T: AsBase + ActorAndObjectRef + AsObject, +{ + let cc = activity.cc().unwrap(); + let cc = cc.as_many().unwrap(); + cc.first().unwrap().as_xsd_any_uri().unwrap().to_owned() +} + pub(in crate::apub::inbox) async fn announce_if_community_is_local( activity: T, user: &User_, diff --git a/server/src/apub/mod.rs b/server/src/apub/mod.rs index e86032f6..b03ffc99 100644 --- a/server/src/apub/mod.rs +++ b/server/src/apub/mod.rs @@ -63,11 +63,9 @@ where } // Checks if the ID has a valid format, correct scheme, and is in the allowed instance list. -fn is_apub_id_valid(apub_id: &Url) -> bool { - debug!("Checking {}", apub_id); +fn check_is_apub_id_valid(apub_id: &Url) -> Result<(), LemmyError> { if apub_id.scheme() != get_apub_protocol_string() { - debug!("invalid scheme: {:?}", apub_id.scheme()); - return false; + return Err(anyhow!("invalid apub id scheme: {:?}", apub_id.scheme()).into()); } let allowed_instances: Vec = Settings::get() @@ -81,15 +79,12 @@ fn is_apub_id_valid(apub_id: &Url) -> bool { let contains = allowed_instances.contains(&d.to_owned()); if !contains { - debug!("{} not in {:?}", d, allowed_instances); + return Err(anyhow!("{} not in federation allowlist", d).into()); } - contains - } - None => { - debug!("missing domain"); - false + Ok(()) } + None => Err(anyhow!("federation allowlist is empty").into()), } }