2020-10-28 16:14:18 +00:00
|
|
|
use crate::fetcher::get_or_fetch_and_upsert_user;
|
2020-10-12 14:10:09 +00:00
|
|
|
use activitystreams::{
|
2020-10-12 16:02:28 +00:00
|
|
|
activity::{ActorAndObjectRef, ActorAndObjectRefExt},
|
2020-10-28 16:14:18 +00:00
|
|
|
base::{AsBase, BaseExt},
|
2020-10-14 15:34:11 +00:00
|
|
|
error::DomainError,
|
2020-10-12 14:10:09 +00:00
|
|
|
};
|
2020-10-28 16:14:18 +00:00
|
|
|
use anyhow::{anyhow, Context};
|
2020-12-18 18:38:32 +00:00
|
|
|
use lemmy_db_schema::source::user::User_;
|
2020-10-12 14:10:09 +00:00
|
|
|
use lemmy_utils::{location_info, LemmyError};
|
|
|
|
use lemmy_websocket::LemmyContext;
|
|
|
|
use log::debug;
|
|
|
|
use std::fmt::Debug;
|
|
|
|
use url::Url;
|
|
|
|
|
2020-10-21 17:37:50 +00:00
|
|
|
pub(crate) mod comment;
|
|
|
|
pub(crate) mod comment_undo;
|
|
|
|
pub(crate) mod community;
|
|
|
|
pub(crate) mod post;
|
|
|
|
pub(crate) mod post_undo;
|
2020-10-28 16:14:18 +00:00
|
|
|
pub(crate) mod private_message;
|
2020-10-12 14:10:09 +00:00
|
|
|
|
2020-10-19 14:29:35 +00:00
|
|
|
/// Return HTTP 501 for unsupported activities in inbox.
|
2020-10-28 16:14:18 +00:00
|
|
|
pub(crate) fn receive_unhandled_activity<A>(activity: A) -> Result<(), LemmyError>
|
2020-10-12 14:10:09 +00:00
|
|
|
where
|
|
|
|
A: Debug,
|
|
|
|
{
|
|
|
|
debug!("received unhandled activity type: {:?}", activity);
|
2020-10-28 16:14:18 +00:00
|
|
|
Err(anyhow!("Activity not supported").into())
|
2020-10-12 14:10:09 +00:00
|
|
|
}
|
2020-10-12 16:02:28 +00:00
|
|
|
|
2020-10-19 14:29:35 +00:00
|
|
|
/// Reads the actor field of an activity and returns the corresponding `User_`.
|
2020-10-13 12:09:49 +00:00
|
|
|
pub(crate) async fn get_actor_as_user<T, A>(
|
2020-10-12 16:02:28 +00:00
|
|
|
activity: &T,
|
|
|
|
context: &LemmyContext,
|
2020-10-22 18:27:32 +00:00
|
|
|
request_counter: &mut i32,
|
2020-10-12 16:02:28 +00:00
|
|
|
) -> Result<User_, LemmyError>
|
|
|
|
where
|
|
|
|
T: AsBase<A> + ActorAndObjectRef,
|
|
|
|
{
|
|
|
|
let actor = activity.actor()?;
|
|
|
|
let user_uri = actor.as_single_xsd_any_uri().context(location_info!())?;
|
2020-10-22 18:27:32 +00:00
|
|
|
get_or_fetch_and_upsert_user(&user_uri, context, request_counter).await
|
2020-10-12 16:02:28 +00:00
|
|
|
}
|
2020-10-13 12:09:49 +00:00
|
|
|
|
2020-10-19 14:29:35 +00:00
|
|
|
/// Ensure that the ID of an incoming activity comes from the same domain as the actor. Optionally
|
|
|
|
/// also checks the ID of the inner object.
|
|
|
|
///
|
|
|
|
/// The reason that this starts with the actor ID is that it was already confirmed as correct by the
|
|
|
|
/// HTTP signature.
|
2020-10-14 15:34:11 +00:00
|
|
|
pub(crate) fn verify_activity_domains_valid<T, Kind>(
|
|
|
|
activity: &T,
|
2020-10-28 16:14:18 +00:00
|
|
|
actor_id: &Url,
|
2020-10-14 15:34:11 +00:00
|
|
|
object_domain_must_match: bool,
|
|
|
|
) -> Result<(), LemmyError>
|
|
|
|
where
|
|
|
|
T: AsBase<Kind> + ActorAndObjectRef,
|
|
|
|
{
|
|
|
|
let expected_domain = actor_id.domain().context(location_info!())?;
|
|
|
|
|
|
|
|
activity.id(expected_domain)?;
|
|
|
|
|
|
|
|
let object_id = match activity.object().to_owned().single_xsd_any_uri() {
|
|
|
|
// object is just an ID
|
|
|
|
Some(id) => id,
|
|
|
|
// object is something like an activity, a comment or a post
|
|
|
|
None => activity
|
|
|
|
.object()
|
|
|
|
.to_owned()
|
|
|
|
.one()
|
|
|
|
.context(location_info!())?
|
|
|
|
.id()
|
|
|
|
.context(location_info!())?
|
|
|
|
.to_owned(),
|
|
|
|
};
|
|
|
|
|
|
|
|
if object_domain_must_match && object_id.domain() != Some(expected_domain) {
|
|
|
|
return Err(DomainError.into());
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|