|
|
|
@ -23,6 +23,8 @@ use crate::{
|
|
|
|
|
get_activity_to_and_cc,
|
|
|
|
|
inbox_verify_http_signature,
|
|
|
|
|
is_activity_already_known,
|
|
|
|
|
is_addressed_to_community_followers,
|
|
|
|
|
is_addressed_to_local_user,
|
|
|
|
|
is_addressed_to_public,
|
|
|
|
|
receive_for_community::{
|
|
|
|
|
receive_create_for_community,
|
|
|
|
@ -99,6 +101,7 @@ pub async fn user_inbox(
|
|
|
|
|
})
|
|
|
|
|
.await??;
|
|
|
|
|
let to_and_cc = get_activity_to_and_cc(&activity)?;
|
|
|
|
|
// TODO: we should also accept activities that are sent to community followers
|
|
|
|
|
if !to_and_cc.contains(&&user.actor_id()?) {
|
|
|
|
|
return Err(anyhow!("Activity delivered to wrong user").into());
|
|
|
|
|
}
|
|
|
|
@ -130,9 +133,7 @@ pub(crate) async fn user_receive_message(
|
|
|
|
|
context: &LemmyContext,
|
|
|
|
|
request_counter: &mut i32,
|
|
|
|
|
) -> Result<HttpResponse, LemmyError> {
|
|
|
|
|
// TODO: must be addressed to one or more local users, or to followers of a remote community
|
|
|
|
|
|
|
|
|
|
// TODO: if it is addressed to community followers, check that at least one local user is following it
|
|
|
|
|
is_for_user_inbox(context, &activity).await?;
|
|
|
|
|
|
|
|
|
|
let any_base = activity.clone().into_any_base()?;
|
|
|
|
|
let kind = activity.kind().context(location_info!())?;
|
|
|
|
@ -162,6 +163,41 @@ pub(crate) async fn user_receive_message(
|
|
|
|
|
Ok(HttpResponse::Ok().finish())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns true if the activity is addressed directly to one or more local users, or if it is
|
|
|
|
|
/// addressed to the followers collection of a remote community, and at least one local user follows
|
|
|
|
|
/// it.
|
|
|
|
|
async fn is_for_user_inbox(
|
|
|
|
|
context: &LemmyContext,
|
|
|
|
|
activity: &UserAcceptedActivities,
|
|
|
|
|
) -> Result<(), LemmyError> {
|
|
|
|
|
let to_and_cc = get_activity_to_and_cc(activity)?;
|
|
|
|
|
// Check if it is addressed directly to any local user
|
|
|
|
|
if is_addressed_to_local_user(&to_and_cc, context.pool()).await? {
|
|
|
|
|
return Ok(());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check if it is addressed to any followers collection of a remote community, and that the
|
|
|
|
|
// community has local followers.
|
|
|
|
|
let community = is_addressed_to_community_followers(&to_and_cc, context.pool()).await?;
|
|
|
|
|
if let Some(c) = community {
|
|
|
|
|
let community_id = c.id;
|
|
|
|
|
let has_local_followers = blocking(&context.pool(), move |conn| {
|
|
|
|
|
CommunityFollower::has_local_followers(conn, community_id)
|
|
|
|
|
})
|
|
|
|
|
.await??;
|
|
|
|
|
if c.local {
|
|
|
|
|
return Err(
|
|
|
|
|
anyhow!("Remote activity cant be addressed to followers of local community").into(),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if has_local_followers {
|
|
|
|
|
return Ok(());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Err(anyhow!("Not addressed for any local user").into())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Handle accepted follows.
|
|
|
|
|
async fn receive_accept(
|
|
|
|
|
context: &LemmyContext,
|
|
|
|
|