also use actor type for routing, VerifyActivity and SendActivity traits

pull/1652/head
Felix Ableitner 3 years ago
parent 6d447c81cf
commit fa7778218f

@ -1,12 +1,11 @@
use crate::ActorType;
use activitystreams::unparsed::UnparsedMutExt;
use activitystreams_ext::UnparsedExtension;
use actix_web::HttpRequest;
use anyhow::{anyhow, Context};
use anyhow::anyhow;
use http::{header::HeaderName, HeaderMap, HeaderValue};
use http_signature_normalization_actix::Config as ConfigActix;
use http_signature_normalization_reqwest::prelude::{Config, SignExt};
use lemmy_utils::{location_info, LemmyError};
use lemmy_utils::LemmyError;
use log::debug;
use openssl::{
hash::MessageDigest,
@ -65,8 +64,7 @@ pub(crate) async fn sign_and_send(
}
/// Verifies the HTTP signature on an incoming inbox request.
pub fn verify_signature(request: &HttpRequest, actor: &dyn ActorType) -> Result<(), LemmyError> {
let public_key = actor.public_key().context(location_info!())?;
pub fn verify_signature(request: &HttpRequest, public_key: &str) -> Result<(), LemmyError> {
let verified = CONFIG2
.begin_verify(
request.method(),

@ -14,7 +14,10 @@ use crate::{
};
use chrono::NaiveDateTime;
use http::StatusCode;
use lemmy_db_schema::naive_now;
use lemmy_db_schema::{
naive_now,
source::{community::Community, person::Person},
};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use serde::Deserialize;
@ -55,6 +58,27 @@ pub async fn get_or_fetch_and_upsert_actor(
Ok(actor)
}
pub enum Actor {
Person(Person),
Community(Community),
}
// TODO: use this and get rid of ActorType
pub async fn get_or_fetch_and_upsert_actor2(
apub_id: &Url,
context: &LemmyContext,
recursion_counter: &mut i32,
) -> Result<Actor, LemmyError> {
let community = get_or_fetch_and_upsert_community(apub_id, context, recursion_counter).await;
let actor: Actor = match community {
Ok(c) => Actor::Community(c),
Err(_) => {
Actor::Person(get_or_fetch_and_upsert_person(apub_id, context, recursion_counter).await?)
}
};
Ok(actor)
}
/// Determines when a remote actor should be refetched from its instance. In release builds, this is
/// `ACTOR_REFETCH_INTERVAL_SECONDS` after the last refetch, in debug builds
/// `ACTOR_REFETCH_INTERVAL_SECONDS_DEBUG`.

@ -31,13 +31,17 @@ pub enum PublicUrl {
Public,
}
// todo: later add a similar trait SendActivity
// todo: maybe add a separate method verify()
#[async_trait::async_trait(?Send)]
pub trait ReceiveActivity {
pub trait ActivityHandler {
type Actor;
// TODO: also need to check for instance/community blocks in here
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError>;
// todo: later handle request_counter completely inside library
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError>;
@ -50,12 +54,6 @@ pub fn verify_domains_match(a: &Url, b: &Url) -> Result<(), LemmyError> {
Ok(())
}
#[async_trait::async_trait(?Send)]
pub trait VerifyActivity {
// TODO: also need to check for instance/actor blocks in here i think
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError>;
}
// todo: instead of phantomdata, might use option<kind> to cache the fetched object (or just fetch on construction)
pub struct ObjectId<'a, Kind>(Url, &'a PhantomData<Kind>);

@ -3,9 +3,9 @@ use crate::{
inbox::new_inbox_routing::Activity,
};
use activitystreams::{activity::kind::CreateType, base::BaseExt};
use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, NoteExt};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_db_schema::source::comment::Comment;
use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, ActorType, NoteExt};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::{comment::Comment, person::Person};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -21,25 +21,25 @@ pub struct CreateComment {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<CreateComment> {
impl ActivityHandler for Activity<CreateComment> {
type Actor = Person;
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
self.inner.object.id(self.actor.as_str())?;
check_is_apub_id_valid(&self.actor, false)
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<CreateComment> {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let comment = Comment::from_apub(
&self.inner.object,
context,
self.actor.clone(),
actor.actor_id(),
request_counter,
false,
)

@ -2,9 +2,9 @@ use crate::{activities::comment::send_websocket_message, inbox::new_inbox_routin
use activitystreams::activity::kind::DeleteType;
use lemmy_api_common::blocking;
use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_comment};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::source::comment::Comment_;
use lemmy_db_schema::source::comment::Comment;
use lemmy_db_schema::source::{comment::Comment, person::Person};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -20,18 +20,18 @@ pub struct DeleteComment {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<DeleteComment> {
impl ActivityHandler for Activity<DeleteComment> {
type Actor = Person;
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
verify_domains_match(&self.actor, &self.inner.object)?;
check_is_apub_id_valid(&self.actor, false)
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<DeleteComment> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {

@ -1,7 +1,8 @@
use crate::{activities::comment::like_or_dislike_comment, inbox::new_inbox_routing::Activity};
use activitystreams::activity::kind::DislikeType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::person::Person;
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -17,27 +18,20 @@ pub struct DislikeComment {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<DislikeComment> {
impl ActivityHandler for Activity<DislikeComment> {
type Actor = Person;
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
check_is_apub_id_valid(&self.actor, false)
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<DislikeComment> {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
like_or_dislike_comment(
-1,
&self.actor,
&self.inner.object,
context,
request_counter,
)
.await
like_or_dislike_comment(-1, &actor, &self.inner.object, context, request_counter).await
}
}

@ -1,7 +1,8 @@
use crate::{activities::comment::like_or_dislike_comment, inbox::new_inbox_routing::Activity};
use activitystreams::activity::kind::LikeType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::person::Person;
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -17,27 +18,20 @@ pub struct LikeComment {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<LikeComment> {
impl ActivityHandler for Activity<LikeComment> {
type Actor = Person;
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
check_is_apub_id_valid(&self.actor, false)
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<LikeComment> {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
like_or_dislike_comment(
-1,
&self.actor,
&self.inner.object,
context,
request_counter,
)
.await
like_or_dislike_comment(-1, &actor, &self.inner.object, context, request_counter).await
}
}

@ -7,6 +7,7 @@ use lemmy_db_queries::{Crud, Likeable};
use lemmy_db_schema::{
source::{
comment::{Comment, CommentLike, CommentLikeForm},
person::Person,
post::Post,
},
CommentId,
@ -78,22 +79,21 @@ async fn send_websocket_message<OP: ToString + Send + lemmy_websocket::Operation
async fn like_or_dislike_comment(
score: i16,
actor: &Url,
actor: &Person,
object: &Url,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let person = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
let comment = get_or_fetch_and_insert_comment(object, context, request_counter).await?;
let comment_id = comment.id;
let like_form = CommentLikeForm {
comment_id,
post_id: comment.post_id,
person_id: person.id,
person_id: actor.id,
score,
};
let person_id = person.id;
let person_id = actor.id;
blocking(context.pool(), move |conn| {
CommentLike::remove(conn, person_id, comment_id)?;
CommentLike::like(conn, &like_form)
@ -110,16 +110,15 @@ async fn like_or_dislike_comment(
}
async fn undo_like_or_dislike_comment(
actor: &Url,
actor: &Person,
object: &Url,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let person = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
let comment = get_or_fetch_and_insert_comment(object, context, request_counter).await?;
let comment_id = comment.id;
let person_id = person.id;
let person_id = actor.id;
blocking(context.pool(), move |conn| {
CommentLike::remove(conn, person_id, comment_id)
})

@ -5,9 +5,9 @@ use crate::{
use activitystreams::activity::kind::RemoveType;
use lemmy_api_common::blocking;
use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_comment};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::source::comment::Comment_;
use lemmy_db_schema::source::comment::Comment;
use lemmy_db_schema::source::{comment::Comment, person::Person};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -23,18 +23,18 @@ pub struct RemoveComment {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<RemoveComment> {
impl ActivityHandler for Activity<RemoveComment> {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
check_is_apub_id_valid(&self.actor, false)?;
verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<RemoveComment> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {

@ -5,9 +5,9 @@ use crate::{
use activitystreams::activity::kind::UndoType;
use lemmy_api_common::blocking;
use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_comment};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::source::comment::Comment_;
use lemmy_db_schema::source::comment::Comment;
use lemmy_db_schema::source::{comment::Comment, person::Person};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -23,19 +23,19 @@ pub struct UndoDeleteComment {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UndoDeleteComment> {
impl ActivityHandler for Activity<UndoDeleteComment> {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
verify_domains_match(&self.actor, &self.inner.object.actor)?;
check_is_apub_id_valid(&self.actor, false)?;
self.inner.object.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UndoDeleteComment> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {

@ -4,7 +4,8 @@ use crate::{
};
use activitystreams::activity::kind::UndoType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::person::Person;
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -20,24 +21,24 @@ pub struct UndoDislikeComment {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UndoDislikeComment> {
impl ActivityHandler for Activity<UndoDislikeComment> {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
verify_domains_match(&self.actor, &self.inner.object.inner.object)?;
check_is_apub_id_valid(&self.actor, false)?;
self.inner.object.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UndoDislikeComment> {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
undo_like_or_dislike_comment(
&self.actor,
&actor,
&self.inner.object.inner.object,
context,
request_counter,

@ -4,7 +4,8 @@ use crate::{
};
use activitystreams::activity::kind::UndoType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::person::Person;
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -20,24 +21,24 @@ pub struct UndoLikeComment {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UndoLikeComment> {
impl ActivityHandler for Activity<UndoLikeComment> {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
verify_domains_match(&self.actor, &self.inner.object.inner.object)?;
check_is_apub_id_valid(&self.actor, false)?;
self.inner.object.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UndoLikeComment> {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
undo_like_or_dislike_comment(
&self.actor,
&actor,
&self.inner.object.inner.object,
context,
request_counter,

@ -8,9 +8,9 @@ use crate::{
use activitystreams::activity::kind::UndoType;
use lemmy_api_common::blocking;
use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_comment};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::source::comment::Comment_;
use lemmy_db_schema::source::comment::Comment;
use lemmy_db_schema::source::{comment::Comment, person::Person};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -26,19 +26,19 @@ pub struct UndoRemoveComment {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UndoRemoveComment> {
impl ActivityHandler for Activity<UndoRemoveComment> {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
check_is_apub_id_valid(&self.actor, false)?;
verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await?;
self.inner.object.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UndoRemoveComment> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {

@ -3,9 +3,9 @@ use crate::{
inbox::new_inbox_routing::Activity,
};
use activitystreams::{activity::kind::UpdateType, base::BaseExt};
use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, NoteExt};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_db_schema::source::comment::Comment;
use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, ActorType, NoteExt};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::{comment::Comment, person::Person};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -21,18 +21,18 @@ pub struct UpdateComment {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UpdateComment> {
impl ActivityHandler for Activity<UpdateComment> {
type Actor = Person;
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
self.inner.object.id(self.actor.as_str())?;
check_is_apub_id_valid(&self.actor, false)
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UpdateComment> {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
@ -45,7 +45,8 @@ impl ReceiveActivity for Activity<UpdateComment> {
)
.await?;
let recipients = get_notif_recipients(&self.actor, &comment, context, request_counter).await?;
let recipients =
get_notif_recipients(&actor.actor_id(), &comment, context, request_counter).await?;
send_websocket_message(
comment.id,
recipients,

@ -9,16 +9,19 @@ use lemmy_apub::{
fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person},
CommunityType,
};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::{source::community::CommunityModerator_, Joinable};
use lemmy_db_schema::source::community::{CommunityModerator, CommunityModeratorForm};
use lemmy_db_schema::source::{
community::{CommunityModerator, CommunityModeratorForm},
person::Person,
};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AddModToCommunity {
pub struct AddMod {
to: PublicUrl,
object: Url,
target: Url,
@ -28,7 +31,9 @@ pub struct AddModToCommunity {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<AddModToCommunity> {
impl ActivityHandler for Activity<AddMod> {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
verify_domains_match(&self.inner.target, &self.inner.cc[0])?;
@ -36,12 +41,10 @@ impl VerifyActivity for Activity<AddModToCommunity> {
verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await?;
verify_add_remove_moderator_target(&self.inner.target, self.inner.cc[0].clone())
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<AddModToCommunity> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {

@ -37,8 +37,9 @@ use crate::{
inbox::{is_activity_already_known, new_inbox_routing::Activity},
};
use activitystreams::activity::kind::RemoveType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub::{check_is_apub_id_valid, fetcher::person::get_or_fetch_and_upsert_person};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::{community::Community, person::Person};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -76,20 +77,20 @@ pub enum AnnouncableActivities {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for AnnouncableActivities {
impl ActivityHandler for AnnouncableActivities {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
self.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for AnnouncableActivities {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
self.receive(context, request_counter).await
self.receive(actor, context, request_counter).await
}
}
@ -104,30 +105,32 @@ pub struct AnnounceActivity {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<AnnounceActivity> {
impl ActivityHandler for Activity<AnnounceActivity> {
type Actor = Community;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
verify_domains_match(&self.actor, &self.inner.cc[0])?;
check_is_apub_id_valid(&self.actor, false)?;
self.inner.object.inner.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<AnnounceActivity> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
if is_activity_already_known(context.pool(), &self.inner.object.id_unchecked()).await? {
return Ok(());
}
let inner_actor =
get_or_fetch_and_upsert_person(&self.inner.object.actor, context, request_counter).await?;
self
.inner
.object
.inner
.receive(context, request_counter)
.receive(inner_actor, context, request_counter)
.await
}
}

@ -5,13 +5,16 @@ use lemmy_apub::{
check_is_apub_id_valid,
fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person},
};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::{Bannable, Followable};
use lemmy_db_schema::source::community::{
CommunityFollower,
CommunityFollowerForm,
CommunityPersonBan,
CommunityPersonBanForm,
use lemmy_db_schema::source::{
community::{
CommunityFollower,
CommunityFollowerForm,
CommunityPersonBan,
CommunityPersonBanForm,
},
person::Person,
};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
@ -28,18 +31,18 @@ pub struct BlockUserFromCommunity {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<BlockUserFromCommunity> {
impl ActivityHandler for Activity<BlockUserFromCommunity> {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
check_is_apub_id_valid(&self.actor, false)?;
verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<BlockUserFromCommunity> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {

@ -10,7 +10,7 @@ use lemmy_apub::{
ActorType,
CommunityType,
};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::{source::community::Community_, ApubObject};
use lemmy_db_schema::source::community::Community;
use lemmy_utils::LemmyError;
@ -31,7 +31,9 @@ pub struct DeleteCommunity {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<DeleteCommunity> {
impl ActivityHandler for Activity<DeleteCommunity> {
type Actor = lemmy_apub::fetcher::Actor;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
let object = self.inner.object.clone();
@ -51,15 +53,14 @@ impl VerifyActivity for Activity<DeleteCommunity> {
verify_domains_match(&self.actor, &self.inner.cc[0])
}
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<DeleteCommunity> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
// TODO: match on actor to decide what to do
let actor = self.inner.object.clone();
let community = blocking(context.pool(), move |conn| {
Community::read_from_apub_id(conn, &actor.into())

@ -2,7 +2,7 @@ use crate::{activities::community::send_websocket_message, inbox::new_inbox_rout
use activitystreams::activity::kind::RemoveType;
use lemmy_api_common::blocking;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::{source::community::Community_, ApubObject};
use lemmy_db_schema::source::community::Community;
use lemmy_utils::LemmyError;
@ -20,19 +20,19 @@ pub struct RemoveCommunity {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<RemoveCommunity> {
impl ActivityHandler for Activity<RemoveCommunity> {
type Actor = lemmy_apub::fetcher::Actor;
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
check_is_apub_id_valid(&self.actor, false)?;
verify_domains_match(&self.actor, &self.inner.object)?;
verify_domains_match(&self.actor, &self.inner.cc[0])
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<RemoveCommunity> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
_request_counter: &mut i32,
) -> Result<(), LemmyError> {

@ -9,16 +9,19 @@ use lemmy_apub::{
fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person},
CommunityType,
};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::Joinable;
use lemmy_db_schema::source::community::{CommunityModerator, CommunityModeratorForm};
use lemmy_db_schema::source::{
community::{CommunityModerator, CommunityModeratorForm},
person::Person,
};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RemoveModToCommunity {
pub struct RemoveMod {
to: PublicUrl,
object: Url,
target: Url,
@ -28,7 +31,9 @@ pub struct RemoveModToCommunity {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<RemoveModToCommunity> {
impl ActivityHandler for Activity<RemoveMod> {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
verify_domains_match(&self.inner.target, &self.inner.cc[0])?;
@ -36,12 +41,10 @@ impl VerifyActivity for Activity<RemoveModToCommunity> {
verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await?;
verify_add_remove_moderator_target(&self.inner.target, self.inner.cc[0].clone())
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<RemoveModToCommunity> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {

@ -8,9 +8,12 @@ use lemmy_apub::{
check_is_apub_id_valid,
fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person},
};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::Bannable;
use lemmy_db_schema::source::community::{CommunityPersonBan, CommunityPersonBanForm};
use lemmy_db_schema::source::{
community::{CommunityPersonBan, CommunityPersonBanForm},
person::Person,
};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -26,19 +29,19 @@ pub struct UndoBlockUserFromCommunity {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UndoBlockUserFromCommunity> {
impl ActivityHandler for Activity<UndoBlockUserFromCommunity> {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
check_is_apub_id_valid(&self.actor, false)?;
verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await?;
self.inner.object.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UndoBlockUserFromCommunity> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {

@ -14,7 +14,7 @@ use lemmy_apub::{
ActorType,
CommunityType,
};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::{source::community::Community_, ApubObject};
use lemmy_db_schema::source::community::Community;
use lemmy_utils::LemmyError;
@ -35,7 +35,9 @@ pub struct UndoDeleteCommunity {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UndoDeleteCommunity> {
impl ActivityHandler for Activity<UndoDeleteCommunity> {
type Actor = lemmy_apub::fetcher::Actor;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
let object = self.inner.object.inner.object.clone();
@ -56,18 +58,16 @@ impl VerifyActivity for Activity<UndoDeleteCommunity> {
}
self.inner.object.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UndoDeleteCommunity> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let actor = self.inner.object.inner.object.clone();
let object = self.inner.object.inner.object.clone();
let community = blocking(context.pool(), move |conn| {
Community::read_from_apub_id(conn, &actor.into())
Community::read_from_apub_id(conn, &object.into())
})
.await?;
let community_id = match community {

@ -5,7 +5,7 @@ use crate::{
use activitystreams::activity::kind::RemoveType;
use lemmy_api_common::blocking;
use lemmy_apub::{check_is_apub_id_valid, fetcher::community::get_or_fetch_and_upsert_community};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::source::community::Community_;
use lemmy_db_schema::source::community::Community;
use lemmy_utils::LemmyError;
@ -23,7 +23,9 @@ pub struct UndoRemoveCommunity {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UndoRemoveCommunity> {
impl ActivityHandler for Activity<UndoRemoveCommunity> {
type Actor = lemmy_apub::fetcher::Actor;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
check_is_apub_id_valid(&self.actor, false)?;
@ -31,12 +33,10 @@ impl VerifyActivity for Activity<UndoRemoveCommunity> {
verify_domains_match(&self.actor, &self.inner.cc[0])?;
self.inner.object.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UndoRemoveCommunity> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {

@ -5,9 +5,12 @@ use crate::{
use activitystreams::{activity::kind::UpdateType, base::BaseExt};
use lemmy_api_common::blocking;
use lemmy_apub::{check_is_apub_id_valid, objects::FromApubToForm, GroupExt};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::{ApubObject, Crud};
use lemmy_db_schema::source::community::{Community, CommunityForm};
use lemmy_db_schema::source::{
community::{Community, CommunityForm},
person::Person,
};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -25,19 +28,19 @@ pub struct UpdateCommunity {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UpdateCommunity> {
impl ActivityHandler for Activity<UpdateCommunity> {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
self.inner.object.id(self.inner.cc[0].as_str())?;
check_is_apub_id_valid(&self.actor, false)?;
verify_is_community_mod(self.actor.clone(), self.inner.cc[0].clone(), context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UpdateCommunity> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {

@ -1,13 +1,10 @@
use crate::{activities::follow::follow::FollowCommunity, inbox::new_inbox_routing::Activity};
use activitystreams::activity::kind::AcceptType;
use lemmy_api_common::blocking;
use lemmy_apub::{
check_is_apub_id_valid,
fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person},
};
use lemmy_apub_lib::{verify_domains_match, ReceiveActivity, VerifyActivity};
use lemmy_apub::{check_is_apub_id_valid, fetcher::person::get_or_fetch_and_upsert_person};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler};
use lemmy_db_queries::Followable;
use lemmy_db_schema::source::community::CommunityFollower;
use lemmy_db_schema::source::community::{Community, CommunityFollower};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -21,29 +18,27 @@ pub struct AcceptFollowCommunity {
kind: AcceptType,
}
/// Handle accepted follows
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<AcceptFollowCommunity> {
impl ActivityHandler for Activity<AcceptFollowCommunity> {
type Actor = Community;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
check_is_apub_id_valid(&self.actor, false)?;
self.inner.object.verify(context).await
}
}
/// Handle accepted follows
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<AcceptFollowCommunity> {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let community =
get_or_fetch_and_upsert_community(&self.actor, context, request_counter).await?;
let person = get_or_fetch_and_upsert_person(&self.inner.to, context, request_counter).await?;
// This will throw an error if no follow was requested
blocking(&context.pool(), move |conn| {
CommunityFollower::follow_accepted(conn, community.id, person.id)
CommunityFollower::follow_accepted(conn, actor.id, person.id)
})
.await??;

@ -7,12 +7,15 @@ use anyhow::Context;
use lemmy_api_common::blocking;
use lemmy_apub::{
check_is_apub_id_valid,
fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person},
fetcher::community::get_or_fetch_and_upsert_community,
CommunityType,
};
use lemmy_apub_lib::{verify_domains_match, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler};
use lemmy_db_queries::Followable;
use lemmy_db_schema::source::community::{CommunityFollower, CommunityFollowerForm};
use lemmy_db_schema::source::{
community::{CommunityFollower, CommunityFollowerForm},
person::Person,
};
use lemmy_utils::{location_info, LemmyError};
use lemmy_websocket::LemmyContext;
use url::Url;
@ -27,27 +30,26 @@ pub struct FollowCommunity {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<FollowCommunity> {
impl ActivityHandler for Activity<FollowCommunity> {
type Actor = Person;
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
verify_domains_match(&self.inner.to, &self.inner.object)?;
check_is_apub_id_valid(&self.actor, false)
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<FollowCommunity> {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let community =
get_or_fetch_and_upsert_community(&self.inner.object, context, request_counter).await?;
let person = get_or_fetch_and_upsert_person(&self.actor, context, request_counter).await?;
let community_follower_form = CommunityFollowerForm {
community_id: community.id,
person_id: person.id,
person_id: actor.id,
pending: false,
};

@ -1,13 +1,13 @@
use crate::{activities::follow::follow::FollowCommunity, inbox::new_inbox_routing::Activity};
use activitystreams::activity::kind::UndoType;
use lemmy_api_common::blocking;
use lemmy_apub::{
check_is_apub_id_valid,
fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person},
};
use lemmy_apub_lib::{verify_domains_match, ReceiveActivity, VerifyActivity};
use lemmy_apub::{check_is_apub_id_valid, fetcher::community::get_or_fetch_and_upsert_community};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler};
use lemmy_db_queries::Followable;
use lemmy_db_schema::source::community::{CommunityFollower, CommunityFollowerForm};
use lemmy_db_schema::source::{
community::{CommunityFollower, CommunityFollowerForm},
person::Person,
};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -22,29 +22,28 @@ pub struct UndoFollowCommunity {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UndoFollowCommunity> {
impl ActivityHandler for Activity<UndoFollowCommunity> {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
verify_domains_match(&self.inner.to, &self.inner.object.inner.object)?;
check_is_apub_id_valid(&self.actor, false)?;
self.inner.object.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UndoFollowCommunity> {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let community =
get_or_fetch_and_upsert_community(&self.inner.to, context, request_counter).await?;
let person = get_or_fetch_and_upsert_person(&self.actor, context, request_counter).await?;
let community_follower_form = CommunityFollowerForm {
community_id: community.id,
person_id: person.id,
person_id: actor.id,
pending: false,
};

@ -1,14 +1,8 @@
use crate::{activities::post::send_websocket_message, inbox::new_inbox_routing::Activity};
use activitystreams::{activity::kind::CreateType, base::BaseExt};
use lemmy_apub::{
check_is_apub_id_valid,
fetcher::person::get_or_fetch_and_upsert_person,
objects::FromApub,
ActorType,
PageExt,
};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_db_schema::source::post::Post;
use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, ActorType, PageExt};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::{person::Person, post::Post};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -24,27 +18,25 @@ pub struct CreatePost {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<CreatePost> {
impl ActivityHandler for Activity<CreatePost> {
type Actor = Person;
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(self.id_unchecked(), &self.actor)?;
self.inner.object.id(self.actor.as_str())?;
check_is_apub_id_valid(&self.actor, false)
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<CreatePost> {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let person = get_or_fetch_and_upsert_person(&self.actor, context, request_counter).await?;
let post = Post::from_apub(
&self.inner.object,
context,
person.actor_id(),
actor.actor_id(),
request_counter,
false,
)

@ -2,9 +2,9 @@ use crate::{activities::post::send_websocket_message, inbox::new_inbox_routing::
use activitystreams::activity::kind::DeleteType;
use lemmy_api_common::blocking;
use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_post};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::source::post::Post_;
use lemmy_db_schema::source::post::Post;
use lemmy_db_schema::source::{person::Person, post::Post};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -20,18 +20,18 @@ pub struct DeletePost {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<DeletePost> {
impl ActivityHandler for Activity<DeletePost> {
type Actor = Person;
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
verify_domains_match(&self.actor, &self.inner.object)?;
check_is_apub_id_valid(&self.actor, false)
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<DeletePost> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {

@ -1,7 +1,8 @@
use crate::{activities::post::like_or_dislike_post, inbox::new_inbox_routing::Activity};
use activitystreams::activity::kind::DislikeType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::person::Person;
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -17,27 +18,20 @@ pub struct DislikePost {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<DislikePost> {
impl ActivityHandler for Activity<DislikePost> {
type Actor = Person;
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
check_is_apub_id_valid(&self.actor, false)
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<DislikePost> {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
like_or_dislike_post(
-1,
&self.actor,
&self.inner.object,
context,
request_counter,
)
.await
like_or_dislike_post(-1, &actor, &self.inner.object, context, request_counter).await
}
}

@ -1,7 +1,8 @@
use crate::{activities::post::like_or_dislike_post, inbox::new_inbox_routing::Activity};
use activitystreams::activity::kind::LikeType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::person::Person;
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -17,20 +18,20 @@ pub struct LikePost {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<LikePost> {
impl ActivityHandler for Activity<LikePost> {
type Actor = Person;
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
check_is_apub_id_valid(&self.actor, false)
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<LikePost> {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
like_or_dislike_post(1, &self.actor, &self.inner.object, context, request_counter).await
like_or_dislike_post(1, &actor, &self.inner.object, context, request_counter).await
}
}

@ -1,11 +1,11 @@
use lemmy_api_common::{blocking, post::PostResponse};
use lemmy_apub::fetcher::{
objects::get_or_fetch_and_insert_post,
person::get_or_fetch_and_upsert_person,
};
use lemmy_apub::fetcher::objects::get_or_fetch_and_insert_post;
use lemmy_db_queries::Likeable;
use lemmy_db_schema::{
source::post::{PostLike, PostLikeForm},
source::{
person::Person,
post::{PostLike, PostLikeForm},
},
PostId,
};
use lemmy_db_views::post_view::PostView;
@ -47,21 +47,20 @@ async fn send_websocket_message<OP: ToString + Send + lemmy_websocket::Operation
async fn like_or_dislike_post(
score: i16,
actor: &Url,
actor: &Person,
object: &Url,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let person = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
let post = get_or_fetch_and_insert_post(object, context, request_counter).await?;
let post_id = post.id;
let like_form = PostLikeForm {
post_id: post.id,
person_id: person.id,
person_id: actor.id,
score,
};
let person_id = person.id;
let person_id = actor.id;
blocking(context.pool(), move |conn| {
PostLike::remove(conn, person_id, post_id)?;
PostLike::like(conn, &like_form)
@ -72,16 +71,15 @@ async fn like_or_dislike_post(
}
async fn undo_like_or_dislike_post(
actor: &Url,
actor: &Person,
object: &Url,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let person = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
let post = get_or_fetch_and_insert_post(object, context, request_counter).await?;
let post_id = post.id;
let person_id = person.id;
let person_id = actor.id;
blocking(context.pool(), move |conn| {
PostLike::remove(conn, person_id, post_id)
})

@ -5,9 +5,9 @@ use crate::{
use activitystreams::activity::kind::RemoveType;
use lemmy_api_common::blocking;
use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_post};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::source::post::Post_;
use lemmy_db_schema::source::post::Post;
use lemmy_db_schema::source::{person::Person, post::Post};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -23,18 +23,18 @@ pub struct RemovePost {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<RemovePost> {
impl ActivityHandler for Activity<RemovePost> {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
check_is_apub_id_valid(&self.actor, false)?;
verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<RemovePost> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {

@ -5,9 +5,9 @@ use crate::{
use activitystreams::activity::kind::UndoType;
use lemmy_api_common::blocking;
use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_post};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::source::post::Post_;
use lemmy_db_schema::source::post::Post;
use lemmy_db_schema::source::{person::Person, post::Post};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -23,19 +23,19 @@ pub struct UndoDeletePost {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UndoDeletePost> {
impl ActivityHandler for Activity<UndoDeletePost> {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
verify_domains_match(&self.actor, &self.inner.object.actor)?;
check_is_apub_id_valid(&self.actor, false)?;
self.inner.object.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UndoDeletePost> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {

@ -4,7 +4,8 @@ use crate::{
};
use activitystreams::activity::kind::UndoType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::person::Person;
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -20,24 +21,24 @@ pub struct UndoDislikePost {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UndoDislikePost> {
impl ActivityHandler for Activity<UndoDislikePost> {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
verify_domains_match(&self.actor, &self.inner.object.inner.object)?;
check_is_apub_id_valid(&self.actor, false)?;
self.inner.object.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UndoDislikePost> {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
undo_like_or_dislike_post(
&self.actor,
&actor,
&self.inner.object.inner.object,
context,
request_counter,

@ -4,7 +4,8 @@ use crate::{
};
use activitystreams::activity::kind::UndoType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::person::Person;
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -18,26 +19,25 @@ pub struct UndoLikePost {
#[serde(rename = "type")]
kind: UndoType,
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UndoLikePost> {
impl ActivityHandler for Activity<UndoLikePost> {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
verify_domains_match(&self.actor, &self.inner.object.inner.object)?;
check_is_apub_id_valid(&self.actor, false)?;
self.inner.object.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UndoLikePost> {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
undo_like_or_dislike_post(
&self.actor,
&actor,
&self.inner.object.inner.object,
context,
request_counter,

@ -8,9 +8,9 @@ use crate::{
use activitystreams::activity::kind::UndoType;
use lemmy_api_common::blocking;
use lemmy_apub::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_post};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::source::post::Post_;
use lemmy_db_schema::source::post::Post;
use lemmy_db_schema::source::{person::Person, post::Post};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -26,19 +26,19 @@ pub struct UndoRemovePost {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UndoRemovePost> {
impl ActivityHandler for Activity<UndoRemovePost> {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
check_is_apub_id_valid(&self.actor, false)?;
verify_mod_action(self.actor.clone(), self.inner.cc[0].clone(), context).await?;
self.inner.object.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UndoRemovePost> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {

@ -4,16 +4,16 @@ use anyhow::Context;
use lemmy_api_common::blocking;
use lemmy_apub::{
check_is_apub_id_valid,
fetcher::person::get_or_fetch_and_upsert_person,
objects::{FromApub, FromApubToForm},
ActorType,
PageExt,
};
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_queries::{ApubObject, Crud};
use lemmy_db_schema::{
source::{
community::Community,
person::Person,
post::{Post, PostForm},
},
DbUrl,
@ -33,26 +33,25 @@ pub struct UpdatePost {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UpdatePost> {
impl ActivityHandler for Activity<UpdatePost> {
type Actor = Person;
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
self.inner.object.id(self.actor.as_str())?;
check_is_apub_id_valid(&self.actor, false)
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UpdatePost> {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let person = get_or_fetch_and_upsert_person(&self.actor, context, request_counter).await?;
let temp_post = PostForm::from_apub(
&self.inner.object,
context,
person.actor_id(),
actor.actor_id(),
request_counter,
false,
)
@ -84,7 +83,7 @@ impl ReceiveActivity for Activity<UpdatePost> {
let post = Post::from_apub(
&self.inner.object,
context,
person.actor_id(),
actor.actor_id(),
request_counter,
mod_action_allowed,
)

@ -3,9 +3,9 @@ use crate::{
inbox::new_inbox_routing::Activity,
};
use activitystreams::{activity::kind::CreateType, base::BaseExt};
use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, NoteExt};
use lemmy_apub_lib::{verify_domains_match, ReceiveActivity, VerifyActivity};
use lemmy_db_schema::source::private_message::PrivateMessage;
use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, ActorType, NoteExt};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler};
use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -20,25 +20,25 @@ pub struct CreatePrivateMessage {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<CreatePrivateMessage> {
impl ActivityHandler for Activity<CreatePrivateMessage> {
type Actor = Person;
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(self.id_unchecked(), &self.actor)?;
self.inner.object.id(self.actor.as_str())?;
check_is_apub_id_valid(&self.actor, false)
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<CreatePrivateMessage> {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let private_message = PrivateMessage::from_apub(
&self.inner.object,
context,
self.actor.clone(),
actor.actor_id(),
request_counter,
false,
)

@ -5,9 +5,9 @@ use crate::{
use activitystreams::activity::kind::DeleteType;
use lemmy_api_common::blocking;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler};
use lemmy_db_queries::{source::private_message::PrivateMessage_, ApubObject};
use lemmy_db_schema::source::private_message::PrivateMessage;
use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -22,18 +22,18 @@ pub struct DeletePrivateMessage {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<DeletePrivateMessage> {
impl ActivityHandler for Activity<DeletePrivateMessage> {
type Actor = Person;
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
verify_domains_match(&self.actor, &self.inner.object)?;
check_is_apub_id_valid(&self.actor, false)
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<DeletePrivateMessage> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
_request_counter: &mut i32,
) -> Result<(), LemmyError> {

@ -5,9 +5,9 @@ use crate::{
use activitystreams::activity::kind::UndoType;
use lemmy_api_common::blocking;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler};
use lemmy_db_queries::{source::private_message::PrivateMessage_, ApubObject};
use lemmy_db_schema::source::private_message::PrivateMessage;
use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -22,19 +22,19 @@ pub struct UndoDeletePrivateMessage {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UndoDeletePrivateMessage> {
impl ActivityHandler for Activity<UndoDeletePrivateMessage> {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(&self.actor, self.id_unchecked())?;
verify_domains_match(&self.actor, &self.inner.object.id_unchecked())?;
check_is_apub_id_valid(&self.actor, false)?;
self.inner.object.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UndoDeletePrivateMessage> {
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
_request_counter: &mut i32,
) -> Result<(), LemmyError> {

@ -3,9 +3,9 @@ use crate::{
inbox::new_inbox_routing::Activity,
};
use activitystreams::{activity::kind::UpdateType, base::BaseExt};
use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, NoteExt};
use lemmy_apub_lib::{verify_domains_match, ReceiveActivity, VerifyActivity};
use lemmy_db_schema::source::private_message::PrivateMessage;
use lemmy_apub::{check_is_apub_id_valid, objects::FromApub, ActorType, NoteExt};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler};
use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -20,25 +20,25 @@ pub struct UpdatePrivateMessage {
}
#[async_trait::async_trait(?Send)]
impl VerifyActivity for Activity<UpdatePrivateMessage> {
impl ActivityHandler for Activity<UpdatePrivateMessage> {
type Actor = Person;
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
verify_domains_match(self.id_unchecked(), &self.actor)?;
self.inner.object.id(self.actor.as_str())?;
check_is_apub_id_valid(&self.actor, false)
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for Activity<UpdatePrivateMessage> {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let private_message = PrivateMessage::from_apub(
&self.inner.object,
context,
self.actor.clone(),
actor.actor_id(),
request_counter,
false,
)

@ -12,10 +12,12 @@ use crate::activities::{
update::UpdateComment,
},
community::{
add_mod::AddMod,
announce::AnnounceActivity,
block_user::BlockUserFromCommunity,
delete::DeleteCommunity,
remove::RemoveCommunity,
remove_mod::RemoveMod,
undo_block_user::UndoBlockUserFromCommunity,
undo_delete::UndoDeleteCommunity,
undo_remove::UndoRemoveCommunity,
@ -42,7 +44,7 @@ use crate::activities::{
},
};
use activitystreams::{base::AnyBase, primitives::OneOrMany, unparsed::Unparsed};
use lemmy_apub_lib::{ReceiveActivity, VerifyActivity};
use lemmy_apub_lib::ActivityHandler;
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -105,27 +107,28 @@ pub enum SharedInboxActivities {
UpdateCommunity(UpdateCommunity),
DeleteCommunity(DeleteCommunity),
RemoveCommunity(RemoveCommunity),
AddMod(AddMod),
RemoveMod(RemoveMod),
UndoDeleteCommunity(UndoDeleteCommunity),
UndoRemoveCommunity(UndoRemoveCommunity),
BlockUserFromCommunity(BlockUserFromCommunity),
UndoBlockUserFromCommunity(UndoBlockUserFromCommunity),
}
// todo: can probably get rid of these?
#[async_trait::async_trait(?Send)]
impl VerifyActivity for SharedInboxActivities {
impl ActivityHandler for SharedInboxActivities {
type Actor = lemmy_apub::fetcher::Actor;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
self.verify(context).await
}
}
#[async_trait::async_trait(?Send)]
impl ReceiveActivity for SharedInboxActivities {
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
self.receive(context, request_counter).await
self.receive(actor, context, request_counter).await
}
}

@ -4,14 +4,15 @@ use crate::inbox::{
new_inbox_routing::{Activity, SharedInboxActivities},
};
use actix_web::{web, HttpRequest, HttpResponse};
use anyhow::Context;
use lemmy_apub::{
check_is_apub_id_valid,
extensions::signatures::verify_signature,
fetcher::get_or_fetch_and_upsert_actor,
fetcher::{get_or_fetch_and_upsert_actor2, Actor},
insert_activity,
};
use lemmy_apub_lib::{ReceiveActivity, VerifyActivity};
use lemmy_utils::LemmyError;
use lemmy_apub_lib::ActivityHandler;
use lemmy_utils::{location_info, LemmyError};
use lemmy_websocket::LemmyContext;
pub async fn shared_inbox(
@ -30,8 +31,12 @@ pub async fn shared_inbox(
activity.inner.verify(&context).await?;
let request_counter = &mut 0;
let actor = get_or_fetch_and_upsert_actor(&activity.actor, &context, request_counter).await?;
verify_signature(&request, actor.as_ref())?;
let actor = get_or_fetch_and_upsert_actor2(&activity.actor, &context, request_counter).await?;
let public_key = match &actor {
Actor::Person(p) => p.public_key.as_ref().context(location_info!())?,
Actor::Community(c) => c.public_key.as_ref().context(location_info!())?,
};
verify_signature(&request, &public_key)?;
// Log the activity, so we avoid receiving and parsing it twice. Note that this could still happen
// if we receive the same activity twice in very quick succession.
@ -44,7 +49,9 @@ pub async fn shared_inbox(
)
.await?;
// TODO: pass the actor in somehow
activity.inner.receive(&context, request_counter).await?;
activity
.inner
.receive(actor, &context, request_counter)
.await?;
return Ok(HttpResponse::Ok().finish());
}

Loading…
Cancel
Save