Add more checks in inbox, plus some refactoring #76

Merged
dessalines merged 6 commits from more-inbox-permissions into main 2020-08-04 14:39:56 +00:00
5 changed files with 56 additions and 52 deletions
Showing only changes of commit d845ea66fe - Show all commits

View File

@ -507,36 +507,36 @@ joinable!(user_mention -> comment (comment_id));
joinable!(user_mention -> user_ (recipient_id)); joinable!(user_mention -> user_ (recipient_id));
allow_tables_to_appear_in_same_query!( allow_tables_to_appear_in_same_query!(
activity, activity,
category, category,
comment, comment,
comment_aggregates_fast, comment_aggregates_fast,
comment_like, comment_like,
comment_saved, comment_saved,
community, community,
community_aggregates_fast, community_aggregates_fast,
community_follower, community_follower,
community_moderator, community_moderator,
community_user_ban, community_user_ban,
mod_add, mod_add,
mod_add_community, mod_add_community,
mod_ban, mod_ban,
mod_ban_from_community, mod_ban_from_community,
mod_lock_post, mod_lock_post,
mod_remove_comment, mod_remove_comment,
mod_remove_community, mod_remove_community,
mod_remove_post, mod_remove_post,
mod_sticky_post, mod_sticky_post,
password_reset_request, password_reset_request,
post, post,
post_aggregates_fast, post_aggregates_fast,
post_like, post_like,
post_read, post_read,
post_saved, post_saved,
private_message, private_message,
site, site,
user_, user_,
user_ban, user_ban,
user_fast, user_fast,
user_mention, user_mention,
); );

View File

@ -1,9 +1,9 @@
use crate::{ use crate::{
apub::{ apub::{
check_is_apub_id_valid,
community::do_announce, community::do_announce,
extensions::signatures::sign, extensions::signatures::sign,
insert_activity, insert_activity,
is_apub_id_valid,
ActorType, ActorType,
}, },
request::retry_custom, request::retry_custom,
@ -50,10 +50,7 @@ pub async fn send_activity(
for t in to { for t in to {
let to_url = Url::parse(&t)?; let to_url = Url::parse(&t)?;
if !is_apub_id_valid(&to_url) { check_is_apub_id_valid(&to_url)?;
debug!("Not sending activity to {} (invalid or blocklisted)", t);
continue;
}
let res = retry_custom(|| async { let res = retry_custom(|| async {
let request = client.post(&t).header("Content-Type", "application/json"); let request = client.post(&t).header("Content-Type", "application/json");

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
api::site::SearchResponse, api::site::SearchResponse,
apub::{ apub::{
is_apub_id_valid, check_is_apub_id_valid,
ActorType, ActorType,
FromApub, FromApub,
GroupExt, GroupExt,
@ -66,9 +66,7 @@ pub async fn fetch_remote_object<Response>(
where where
Response: for<'de> Deserialize<'de>, Response: for<'de> Deserialize<'de>,
{ {
if !is_apub_id_valid(&url) { check_is_apub_id_valid(&url)?;
return Err(anyhow!("Activitypub uri invalid or blocked: {}", url).into());
}
let timeout = Duration::from_secs(60); let timeout = Duration::from_secs(60);

View File

@ -1,5 +1,6 @@
use crate::{ use crate::{
apub::{ apub::{
check_is_apub_id_valid,
community::do_announce, community::do_announce,
extensions::signatures::verify, extensions::signatures::verify,
fetcher::{ fetcher::{
@ -67,9 +68,13 @@ pub async fn shared_inbox(
debug!("Shared inbox received activity: {}", json); debug!("Shared inbox received activity: {}", json);
let sender = &activity.actor()?.to_owned().single_xsd_any_uri().unwrap(); let sender = &activity.actor()?.to_owned().single_xsd_any_uri().unwrap();
// TODO: pass this actor in instead of using get_user_from_activity() // 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 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())?; verify(&request, actor.as_ref())?;
insert_activity(actor.user_id(), activity.clone(), false, &pool).await?; 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 get_or_fetch_and_upsert_user(&user_uri, client, pool).await
} }
pub(in crate::apub::inbox) async fn get_community_id_from_activity<T, A>(activity: &T) -> Url
where
T: AsBase<A> + ActorAndObjectRef + AsObject<A>,
{
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<T, Kind>( pub(in crate::apub::inbox) async fn announce_if_community_is_local<T, Kind>(
activity: T, activity: T,
user: &User_, user: &User_,

View File

@ -63,11 +63,9 @@ where
} }
// Checks if the ID has a valid format, correct scheme, and is in the allowed instance list. // 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 { fn check_is_apub_id_valid(apub_id: &Url) -> Result<(), LemmyError> {
debug!("Checking {}", apub_id);
if apub_id.scheme() != get_apub_protocol_string() { if apub_id.scheme() != get_apub_protocol_string() {
debug!("invalid scheme: {:?}", apub_id.scheme()); return Err(anyhow!("invalid apub id scheme: {:?}", apub_id.scheme()).into());
return false;
} }
let allowed_instances: Vec<String> = Settings::get() let allowed_instances: Vec<String> = Settings::get()
@ -81,15 +79,12 @@ fn is_apub_id_valid(apub_id: &Url) -> bool {
let contains = allowed_instances.contains(&d.to_owned()); let contains = allowed_instances.contains(&d.to_owned());
if !contains { if !contains {
debug!("{} not in {:?}", d, allowed_instances); return Err(anyhow!("{} not in federation allowlist", d).into());
} }
contains Ok(())
}
None => {
debug!("missing domain");
false
} }
None => Err(anyhow!("federation allowlist is empty").into()),
} }
} }