Add more checks in inbox, plus some refactoring #76
|
@ -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,
|
||||||
);
|
);
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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_,
|
||||||
|
|
|
@ -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()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue