working activity routing!

This commit is contained in:
Felix Ableitner 2021-07-07 16:40:19 +02:00
parent 9af57acfe5
commit 78aa717560
47 changed files with 739 additions and 760 deletions

View file

@ -9,7 +9,7 @@
"scripts": {
"lint": "tsc --noEmit && eslint --report-unused-disable-directives --ext .js,.ts,.tsx src",
"fix": "prettier --write src && eslint --fix src",
"api-test": "jest src/post.spec.ts -i --verbose"
"api-test": "jest src/ -i --verbose"
},
"devDependencies": {
"@types/jest": "^26.0.23",

View file

@ -88,7 +88,7 @@ test('Create a post', async () => {
let searchEpsilon = await searchPost(epsilon, postRes.post_view.post);
expect(searchEpsilon.posts[0]).toBeUndefined();
});
/*
test('Create a post in a non-existent community', async () => {
let postRes = await createPost(alpha, -2);
expect(postRes).toStrictEqual({ error: 'couldnt_create_post' });
@ -363,4 +363,3 @@ test('Enforce community ban for federated user', async () => {
let betaPost = searchBeta.posts[0];
expect(betaPost).toBeDefined();
});
*/

View file

@ -37,12 +37,6 @@ where
false
}
// TODO: remove this
pub enum Actor {
Person,
Community,
}
/// Get a remote actor from its apub ID (either a person or a community). Thin wrapper around
/// `get_or_fetch_and_upsert_person()` and `get_or_fetch_and_upsert_community()`.
///

View file

@ -65,6 +65,7 @@ pub trait ActivityHandlerNew {
request_counter: &mut i32,
) -> Result<(), LemmyError>;
// todo: later handle request_counter completely inside library
async fn receive(
&self,
context: &LemmyContext,
@ -73,22 +74,6 @@ pub trait ActivityHandlerNew {
fn common(&self) -> &ActivityCommonFields;
}
#[async_trait::async_trait(?Send)]
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>;
}
pub fn verify_domains_match(a: &Url, b: &Url) -> Result<(), LemmyError> {
if a.domain() != b.domain() {
return Err(DomainError.into());

View file

@ -1,11 +1,8 @@
use crate::activities::{
comment::{get_notif_recipients, send_websocket_message},
LemmyActivity,
};
use crate::activities::comment::{get_notif_recipients, send_websocket_message};
use activitystreams::{activity::kind::CreateType, base::BaseExt};
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_apub::{check_is_apub_id_valid, objects::FromApub, NoteExt};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_schema::source::comment::Comment;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -18,33 +15,33 @@ pub struct CreateComment {
cc: Vec<Url>,
#[serde(rename = "type")]
kind: CreateType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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)
impl ActivityHandlerNew for CreateComment {
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
self.object.id(self.common.actor.as_str())?;
check_is_apub_id_valid(&self.common.actor, false)
}
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let comment = Comment::from_apub(
&self.inner.object,
&self.object,
context,
actor.actor_id(),
self.common.actor.clone(),
request_counter,
false,
)
.await?;
let recipients = get_notif_recipients(&self.actor, &comment, context, request_counter).await?;
let recipients =
get_notif_recipients(&self.common.actor, &comment, context, request_counter).await?;
send_websocket_message(
comment.id,
recipients,
@ -53,4 +50,8 @@ impl ActivityHandler for LemmyActivity<CreateComment> {
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,10 +1,10 @@
use crate::activities::{comment::send_websocket_message, LemmyActivity};
use crate::activities::comment::send_websocket_message;
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, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::comment::Comment_;
use lemmy_db_schema::source::{comment::Comment, person::Person};
use lemmy_db_schema::source::comment::Comment;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -17,26 +17,24 @@ pub struct DeleteComment {
cc: [Url; 1],
#[serde(rename = "type")]
kind: DeleteType,
#[serde(flatten)]
pub(in crate::activities::comment) common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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)
impl ActivityHandlerNew for DeleteComment {
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
verify_domains_match(&self.common.actor, &self.object)?;
check_is_apub_id_valid(&self.common.actor, false)
}
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let comment =
get_or_fetch_and_insert_comment(&self.inner.object, context, request_counter).await?;
let comment = get_or_fetch_and_insert_comment(&self.object, context, request_counter).await?;
let deleted_comment = blocking(context.pool(), move |conn| {
Comment::update_deleted(conn, comment.id, true)
@ -51,4 +49,8 @@ impl ActivityHandler for LemmyActivity<DeleteComment> {
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,8 +1,7 @@
use crate::activities::{comment::like_or_dislike_comment, LemmyActivity};
use crate::activities::comment::like_or_dislike_comment;
use activitystreams::activity::kind::DislikeType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::person::Person;
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -15,23 +14,33 @@ pub struct DislikeComment {
cc: [Url; 1],
#[serde(rename = "type")]
kind: DislikeType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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)
impl ActivityHandlerNew for DislikeComment {
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
check_is_apub_id_valid(&self.common.actor, false)
}
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
like_or_dislike_comment(-1, &actor, &self.inner.object, context, request_counter).await
like_or_dislike_comment(
-1,
&self.common.actor,
&self.object,
context,
request_counter,
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,8 +1,7 @@
use crate::activities::{comment::like_or_dislike_comment, LemmyActivity};
use crate::activities::comment::like_or_dislike_comment;
use activitystreams::activity::kind::LikeType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::person::Person;
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -15,23 +14,33 @@ pub struct LikeComment {
cc: [Url; 1],
#[serde(rename = "type")]
kind: LikeType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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)
impl ActivityHandlerNew for LikeComment {
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
check_is_apub_id_valid(&self.common.actor, false)
}
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
like_or_dislike_comment(-1, &actor, &self.inner.object, context, request_counter).await
like_or_dislike_comment(
-1,
&self.common.actor,
&self.object,
context,
request_counter,
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -7,7 +7,6 @@ use lemmy_db_queries::{Crud, Likeable};
use lemmy_db_schema::{
source::{
comment::{Comment, CommentLike, CommentLikeForm},
person::Person,
post::Post,
},
CommentId,
@ -79,11 +78,12 @@ async fn send_websocket_message<OP: ToString + Send + lemmy_websocket::Operation
async fn like_or_dislike_comment(
score: i16,
actor: &Person,
actor: &Url,
object: &Url,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let actor = 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;
@ -110,11 +110,12 @@ async fn like_or_dislike_comment(
}
async fn undo_like_or_dislike_comment(
actor: &Person,
actor: &Url,
object: &Url,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let actor = 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;

View file

@ -1,10 +1,10 @@
use crate::activities::{comment::send_websocket_message, verify_mod_action, LemmyActivity};
use crate::activities::{comment::send_websocket_message, verify_mod_action};
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, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::comment::Comment_;
use lemmy_db_schema::source::{comment::Comment, person::Person};
use lemmy_db_schema::source::comment::Comment;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -17,26 +17,24 @@ pub struct RemoveComment {
cc: [Url; 1],
#[serde(rename = "type")]
kind: RemoveType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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
impl ActivityHandlerNew for RemoveComment {
async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
check_is_apub_id_valid(&self.common.actor, false)?;
verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await
}
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let comment =
get_or_fetch_and_insert_comment(&self.inner.object, context, request_counter).await?;
let comment = get_or_fetch_and_insert_comment(&self.object, context, request_counter).await?;
let removed_comment = blocking(context.pool(), move |conn| {
Comment::update_removed(conn, comment.id, true)
@ -51,4 +49,8 @@ impl ActivityHandler for LemmyActivity<RemoveComment> {
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,13 +1,10 @@
use crate::activities::{
comment::{delete::DeleteComment, send_websocket_message},
LemmyActivity,
};
use crate::activities::comment::{delete::DeleteComment, send_websocket_message};
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, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::comment::Comment_;
use lemmy_db_schema::source::{comment::Comment, person::Person};
use lemmy_db_schema::source::comment::Comment;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -16,32 +13,34 @@ use url::Url;
#[serde(rename_all = "camelCase")]
pub struct UndoDeleteComment {
to: PublicUrl,
object: LemmyActivity<DeleteComment>,
object: DeleteComment,
cc: [Url; 1],
#[serde(rename = "type")]
kind: UndoType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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
impl ActivityHandlerNew for UndoDeleteComment {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
verify_domains_match(&self.common.actor, &self.object.common.actor)?;
check_is_apub_id_valid(&self.common.actor, false)?;
self.object.verify(context, request_counter).await
}
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let comment =
get_or_fetch_and_insert_comment(&self.inner.object.inner.object, context, request_counter)
.await?;
get_or_fetch_and_insert_comment(&self.object.object, context, request_counter).await?;
let deleted_comment = blocking(context.pool(), move |conn| {
Comment::update_deleted(conn, comment.id, false)
@ -56,4 +55,8 @@ impl ActivityHandler for LemmyActivity<UndoDeleteComment> {
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,11 +1,7 @@
use crate::activities::{
comment::{dislike::DislikeComment, undo_like_or_dislike_comment},
LemmyActivity,
};
use crate::activities::comment::{dislike::DislikeComment, undo_like_or_dislike_comment};
use activitystreams::activity::kind::UndoType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::person::Person;
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -14,35 +10,42 @@ use url::Url;
#[serde(rename_all = "camelCase")]
pub struct UndoDislikeComment {
to: PublicUrl,
object: LemmyActivity<DislikeComment>,
object: DislikeComment,
cc: [Url; 1],
#[serde(rename = "type")]
kind: UndoType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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
impl ActivityHandlerNew for UndoDislikeComment {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
verify_domains_match(&self.common.actor, &self.object.object)?;
check_is_apub_id_valid(&self.common.actor, false)?;
self.object.verify(context, request_counter).await
}
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
undo_like_or_dislike_comment(
&actor,
&self.inner.object.inner.object,
&self.common.actor,
&self.object.object,
context,
request_counter,
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,11 +1,7 @@
use crate::activities::{
comment::{like::LikeComment, undo_like_or_dislike_comment},
LemmyActivity,
};
use crate::activities::comment::{like::LikeComment, undo_like_or_dislike_comment};
use activitystreams::activity::kind::UndoType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::person::Person;
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -14,35 +10,42 @@ use url::Url;
#[serde(rename_all = "camelCase")]
pub struct UndoLikeComment {
to: PublicUrl,
object: LemmyActivity<LikeComment>,
object: LikeComment,
cc: [Url; 1],
#[serde(rename = "type")]
kind: UndoType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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
impl ActivityHandlerNew for UndoLikeComment {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
verify_domains_match(&self.common.actor, &self.object.object)?;
check_is_apub_id_valid(&self.common.actor, false)?;
self.object.verify(context, request_counter).await
}
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
undo_like_or_dislike_comment(
&actor,
&self.inner.object.inner.object,
&self.common.actor,
&self.object.object,
context,
request_counter,
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,14 +1,13 @@
use crate::activities::{
comment::{remove::RemoveComment, send_websocket_message},
verify_mod_action,
LemmyActivity,
};
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, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::comment::Comment_;
use lemmy_db_schema::source::{comment::Comment, person::Person};
use lemmy_db_schema::source::comment::Comment;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -17,32 +16,34 @@ use url::Url;
#[serde(rename_all = "camelCase")]
pub struct UndoRemoveComment {
to: PublicUrl,
object: LemmyActivity<RemoveComment>,
object: RemoveComment,
cc: [Url; 1],
#[serde(rename = "type")]
kind: UndoType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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
impl ActivityHandlerNew for UndoRemoveComment {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
check_is_apub_id_valid(&self.common.actor, false)?;
verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await?;
self.object.verify(context, request_counter).await
}
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let comment =
get_or_fetch_and_insert_comment(&self.inner.object.inner.object, context, request_counter)
.await?;
get_or_fetch_and_insert_comment(&self.object.object, context, request_counter).await?;
let removed_comment = blocking(context.pool(), move |conn| {
Comment::update_removed(conn, comment.id, false)
@ -57,4 +58,8 @@ impl ActivityHandler for LemmyActivity<UndoRemoveComment> {
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,11 +1,8 @@
use crate::activities::{
comment::{get_notif_recipients, send_websocket_message},
LemmyActivity,
};
use crate::activities::comment::{get_notif_recipients, send_websocket_message};
use activitystreams::{activity::kind::UpdateType, base::BaseExt};
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_apub::{check_is_apub_id_valid, objects::FromApub, NoteExt};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_schema::source::comment::Comment;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -18,35 +15,34 @@ pub struct UpdateComment {
cc: Vec<Url>,
#[serde(rename = "type")]
kind: UpdateType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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)
impl ActivityHandlerNew for UpdateComment {
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
self.object.id(self.common.actor.as_str())?;
check_is_apub_id_valid(&self.common.actor, false)
}
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let comment = Comment::from_apub(
&self.inner.object,
&self.object,
context,
self.actor.clone(),
self.common.actor.clone(),
request_counter,
false,
)
.await?;
let recipients =
get_notif_recipients(&actor.actor_id(), &comment, context, request_counter).await?;
get_notif_recipients(&self.common.actor, &comment, context, request_counter).await?;
send_websocket_message(
comment.id,
recipients,
@ -55,4 +51,8 @@ impl ActivityHandler for LemmyActivity<UpdateComment> {
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,8 +1,4 @@
use crate::activities::{
community::verify_add_remove_moderator_target,
verify_mod_action,
LemmyActivity,
};
use crate::activities::{community::verify_add_remove_moderator_target, verify_mod_action};
use activitystreams::{activity::kind::AddType, base::AnyBase};
use lemmy_api_common::blocking;
use lemmy_apub::{
@ -10,12 +6,9 @@ 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, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::{source::community::CommunityModerator_, Joinable};
use lemmy_db_schema::source::{
community::{CommunityModerator, CommunityModeratorForm},
person::Person,
};
use lemmy_db_schema::source::community::{CommunityModerator, CommunityModeratorForm};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -29,30 +22,28 @@ pub struct AddMod {
cc: [Url; 1],
#[serde(rename = "type")]
kind: AddType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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])?;
check_is_apub_id_valid(&self.actor, false)?;
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())
impl ActivityHandlerNew for AddMod {
async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
verify_domains_match(&self.target, &self.cc[0])?;
check_is_apub_id_valid(&self.common.actor, false)?;
verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await?;
verify_add_remove_moderator_target(&self.target, self.cc[0].clone())
}
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.cc[0], context, request_counter).await?;
let new_mod =
get_or_fetch_and_upsert_person(&self.inner.object, context, request_counter).await?;
get_or_fetch_and_upsert_community(&self.cc[0], context, request_counter).await?;
let new_mod = get_or_fetch_and_upsert_person(&self.object, context, request_counter).await?;
// If we had to refetch the community while parsing the activity, then the new mod has already
// been added. Skip it here as it would result in a duplicate key error.
@ -74,10 +65,14 @@ impl ActivityHandler for LemmyActivity<AddMod> {
if community.local {
let anybase = AnyBase::from_arbitrary_json(serde_json::to_string(self)?)?;
community
.send_announce(anybase, Some(self.inner.object.clone()), context)
.send_announce(anybase, Some(self.object.clone()), context)
.await?;
}
// TODO: send websocket notification about added mod
Ok(())
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -25,19 +25,18 @@ use crate::{
undo_remove::UndoRemovePost,
update::UpdatePost,
},
LemmyActivity,
},
http::is_activity_already_known,
};
use activitystreams::activity::kind::RemoveType;
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_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use serde::{Deserialize, Serialize};
use url::Url;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandlerNew)]
pub enum AnnouncableActivities {
CreateComment(CreateComment),
UpdateComment(UpdateComment),
@ -63,61 +62,43 @@ pub enum AnnouncableActivities {
UndoBlockUserFromCommunity(UndoBlockUserFromCommunity),
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for AnnouncableActivities {
type Actor = Person;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
self.verify(context).await
}
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
self.receive(actor, context, request_counter).await
}
}
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AnnounceActivity {
to: PublicUrl,
object: LemmyActivity<AnnouncableActivities>,
object: AnnouncableActivities,
cc: [Url; 1],
#[serde(rename = "type")]
kind: RemoveType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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
impl ActivityHandlerNew for AnnounceActivity {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
verify_domains_match(&self.common.actor, &self.cc[0])?;
check_is_apub_id_valid(&self.common.actor, false)?;
self.object.verify(context, request_counter).await
}
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? {
if is_activity_already_known(context.pool(), self.object.common().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(inner_actor, context, request_counter)
.await
self.object.receive(context, request_counter).await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,20 +1,17 @@
use crate::activities::{verify_mod_action, LemmyActivity};
use crate::activities::verify_mod_action;
use activitystreams::activity::kind::BlockType;
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, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::{Bannable, Followable};
use lemmy_db_schema::source::{
community::{
CommunityFollower,
CommunityFollowerForm,
CommunityPersonBan,
CommunityPersonBanForm,
},
person::Person,
use lemmy_db_schema::source::community::{
CommunityFollower,
CommunityFollowerForm,
CommunityPersonBan,
CommunityPersonBanForm,
};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
@ -28,28 +25,27 @@ pub struct BlockUserFromCommunity {
cc: [Url; 1],
#[serde(rename = "type")]
kind: BlockType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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
impl ActivityHandlerNew for BlockUserFromCommunity {
async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
check_is_apub_id_valid(&self.common.actor, false)?;
verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await
}
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.cc[0], context, request_counter).await?;
get_or_fetch_and_upsert_community(&self.cc[0], context, request_counter).await?;
let blocked_user =
get_or_fetch_and_upsert_person(&self.inner.object, context, request_counter).await?;
get_or_fetch_and_upsert_person(&self.object, context, request_counter).await?;
let community_user_ban_form = CommunityPersonBanForm {
community_id: community.id,
@ -75,4 +71,8 @@ impl ActivityHandler for LemmyActivity<BlockUserFromCommunity> {
Ok(())
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,7 +1,4 @@
use crate::activities::{
community::{send_websocket_message, verify_is_community_mod},
LemmyActivity,
};
use crate::activities::community::{send_websocket_message, verify_is_community_mod};
use activitystreams::activity::kind::DeleteType;
use lemmy_api_common::blocking;
use lemmy_apub::{
@ -10,7 +7,7 @@ use lemmy_apub::{
ActorType,
CommunityType,
};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::{source::community::Community_, ApubObject};
use lemmy_db_schema::source::community::Community;
use lemmy_utils::LemmyError;
@ -28,40 +25,39 @@ pub struct DeleteCommunity {
cc: [Url; 1],
#[serde(rename = "type")]
kind: DeleteType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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();
impl ActivityHandlerNew for DeleteCommunity {
async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
let object = self.object.clone();
let community = blocking(context.pool(), move |conn| {
Community::read_from_apub_id(conn, &object.into())
})
.await?;
// remote mod action on local community
if let Ok(c) = community {
verify_domains_match(&self.inner.object, &self.inner.cc[0])?;
check_is_apub_id_valid(&self.actor, false)?;
verify_is_community_mod(self.actor.clone(), c.actor_id(), context).await
verify_domains_match(&self.object, &self.cc[0])?;
check_is_apub_id_valid(&self.common.actor, false)?;
verify_is_community_mod(self.common.actor.clone(), c.actor_id(), context).await
}
// community action sent to followers
else {
verify_domains_match(&self.actor, &self.inner.object)?;
verify_domains_match(&self.actor, &self.inner.cc[0])
verify_domains_match(&self.common.actor, &self.object)?;
verify_domains_match(&self.common.actor, &self.cc[0])
}
}
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 actor = self.object.clone();
let community = blocking(context.pool(), move |conn| {
Community::read_from_apub_id(conn, &actor.into())
})
@ -69,14 +65,15 @@ impl ActivityHandler for LemmyActivity<DeleteCommunity> {
let community_id = match community {
Ok(c) => {
// remote mod sent delete to local community, forward it to followers
let actor = get_or_fetch_and_upsert_person(&self.actor, context, request_counter).await?;
let actor =
get_or_fetch_and_upsert_person(&self.common.actor, context, request_counter).await?;
c.send_delete(actor, context).await?;
c.id
}
Err(_) => {
// refetch the remote community
let community =
get_or_fetch_and_upsert_community(&self.inner.object, context, request_counter).await?;
get_or_fetch_and_upsert_community(&self.object, context, request_counter).await?;
community.id
}
};
@ -92,4 +89,8 @@ impl ActivityHandler for LemmyActivity<DeleteCommunity> {
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,8 +1,8 @@
use crate::activities::{community::send_websocket_message, LemmyActivity};
use crate::activities::community::send_websocket_message;
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, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::{source::community::Community_, ApubObject};
use lemmy_db_schema::source::community::Community;
use lemmy_utils::LemmyError;
@ -17,26 +17,25 @@ pub struct RemoveCommunity {
cc: [Url; 1],
#[serde(rename = "type")]
kind: RemoveType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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])
impl ActivityHandlerNew for RemoveCommunity {
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
check_is_apub_id_valid(&self.common.actor, false)?;
verify_domains_match(&self.common.actor, &self.object)?;
verify_domains_match(&self.common.actor, &self.cc[0])
}
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
_request_counter: &mut i32,
) -> Result<(), LemmyError> {
let object = self.inner.object.clone();
let object = self.object.clone();
// only search in local database, there is no reason to fetch something thats deleted
let community = blocking(context.pool(), move |conn| {
Community::read_from_apub_id(conn, &object.into())
@ -54,4 +53,8 @@ impl ActivityHandler for LemmyActivity<RemoveCommunity> {
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,8 +1,4 @@
use crate::activities::{
community::verify_add_remove_moderator_target,
verify_mod_action,
LemmyActivity,
};
use crate::activities::{community::verify_add_remove_moderator_target, verify_mod_action};
use activitystreams::{activity::kind::RemoveType, base::AnyBase};
use lemmy_api_common::blocking;
use lemmy_apub::{
@ -10,12 +6,9 @@ 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, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::Joinable;
use lemmy_db_schema::source::{
community::{CommunityModerator, CommunityModeratorForm},
person::Person,
};
use lemmy_db_schema::source::community::{CommunityModerator, CommunityModeratorForm};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -29,30 +22,28 @@ pub struct RemoveMod {
cc: [Url; 1],
#[serde(rename = "type")]
kind: RemoveType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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])?;
check_is_apub_id_valid(&self.actor, false)?;
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())
impl ActivityHandlerNew for RemoveMod {
async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
verify_domains_match(&self.target, &self.cc[0])?;
check_is_apub_id_valid(&self.common.actor, false)?;
verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await?;
verify_add_remove_moderator_target(&self.target, self.cc[0].clone())
}
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.cc[0], context, request_counter).await?;
let add_mod =
get_or_fetch_and_upsert_person(&self.inner.object, context, request_counter).await?;
get_or_fetch_and_upsert_community(&self.cc[0], context, request_counter).await?;
let add_mod = get_or_fetch_and_upsert_person(&self.object, context, request_counter).await?;
let form = CommunityModeratorForm {
community_id: community.id,
@ -64,9 +55,13 @@ impl ActivityHandler for LemmyActivity<RemoveMod> {
.await??;
let anybase = AnyBase::from_arbitrary_json(serde_json::to_string(self)?)?;
community
.send_announce(anybase, Some(self.inner.object.clone()), context)
.send_announce(anybase, Some(self.object.clone()), context)
.await?;
// TODO: send websocket notification about removed mod
Ok(())
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,20 +1,13 @@
use crate::activities::{
community::block_user::BlockUserFromCommunity,
verify_mod_action,
LemmyActivity,
};
use crate::activities::{community::block_user::BlockUserFromCommunity, verify_mod_action};
use activitystreams::activity::kind::BlockType;
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, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::Bannable;
use lemmy_db_schema::source::{
community::{CommunityPersonBan, CommunityPersonBanForm},
person::Person,
};
use lemmy_db_schema::source::community::{CommunityPersonBan, CommunityPersonBanForm};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -23,34 +16,36 @@ use url::Url;
#[serde(rename_all = "camelCase")]
pub struct UndoBlockUserFromCommunity {
to: PublicUrl,
object: LemmyActivity<BlockUserFromCommunity>,
object: BlockUserFromCommunity,
cc: [Url; 1],
#[serde(rename = "type")]
kind: BlockType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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
impl ActivityHandlerNew for UndoBlockUserFromCommunity {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
check_is_apub_id_valid(&self.common.actor, false)?;
verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await?;
self.object.verify(context, request_counter).await
}
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.cc[0], context, request_counter).await?;
get_or_fetch_and_upsert_community(&self.cc[0], context, request_counter).await?;
let blocked_user =
get_or_fetch_and_upsert_person(&self.inner.object.inner.object, context, request_counter)
.await?;
get_or_fetch_and_upsert_person(&self.object.object, context, request_counter).await?;
let community_user_ban_form = CommunityPersonBanForm {
community_id: community.id,
@ -64,4 +59,8 @@ impl ActivityHandler for LemmyActivity<UndoBlockUserFromCommunity> {
Ok(())
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,6 +1,7 @@
use crate::activities::{
community::{delete::DeleteCommunity, send_websocket_message, verify_is_community_mod},
LemmyActivity,
use crate::activities::community::{
delete::DeleteCommunity,
send_websocket_message,
verify_is_community_mod,
};
use activitystreams::activity::kind::DeleteType;
use lemmy_api_common::blocking;
@ -10,7 +11,7 @@ use lemmy_apub::{
ActorType,
CommunityType,
};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::{source::community::Community_, ApubObject};
use lemmy_db_schema::source::community::Community;
use lemmy_utils::LemmyError;
@ -24,44 +25,47 @@ use url::Url;
#[serde(rename_all = "camelCase")]
pub struct UndoDeleteCommunity {
to: PublicUrl,
object: LemmyActivity<DeleteCommunity>,
object: DeleteCommunity,
cc: [Url; 1],
#[serde(rename = "type")]
kind: DeleteType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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();
impl ActivityHandlerNew for UndoDeleteCommunity {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
let object = self.object.object.clone();
let community = blocking(context.pool(), move |conn| {
Community::read_from_apub_id(conn, &object.into())
})
.await?;
// remote mod action on local community
if let Ok(c) = community {
verify_domains_match(&self.inner.object.inner.object, &self.inner.cc[0])?;
check_is_apub_id_valid(&self.actor, false)?;
verify_is_community_mod(self.actor.clone(), c.actor_id(), context).await?;
verify_domains_match(&self.object.object, &self.cc[0])?;
check_is_apub_id_valid(&self.common.actor, false)?;
verify_is_community_mod(self.common.actor.clone(), c.actor_id(), context).await?;
}
// community action sent to followers
else {
verify_domains_match(&self.actor, &self.inner.object.inner.object)?;
verify_domains_match(&self.actor, &self.inner.cc[0])?;
verify_domains_match(&self.common.actor, &self.object.object)?;
verify_domains_match(&self.common.actor, &self.cc[0])?;
}
self.inner.object.verify(context).await
self.object.verify(context, request_counter).await
}
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let object = self.inner.object.inner.object.clone();
let object = self.object.object.clone();
let community = blocking(context.pool(), move |conn| {
Community::read_from_apub_id(conn, &object.into())
})
@ -69,18 +73,15 @@ impl ActivityHandler for LemmyActivity<UndoDeleteCommunity> {
let community_id = match community {
Ok(c) => {
// remote mod sent undo to local community, forward it to followers
let actor = get_or_fetch_and_upsert_person(&self.actor, context, request_counter).await?;
let actor =
get_or_fetch_and_upsert_person(&self.common.actor, context, request_counter).await?;
c.send_delete(actor, context).await?;
c.id
}
Err(_) => {
// refetch the remote community
let community = get_or_fetch_and_upsert_community(
&self.inner.object.inner.object,
context,
request_counter,
)
.await?;
let community =
get_or_fetch_and_upsert_community(&self.object.object, context, request_counter).await?;
community.id
}
};
@ -96,4 +97,8 @@ impl ActivityHandler for LemmyActivity<UndoDeleteCommunity> {
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,11 +1,8 @@
use crate::activities::{
community::{remove::RemoveCommunity, send_websocket_message},
LemmyActivity,
};
use crate::activities::community::{remove::RemoveCommunity, send_websocket_message};
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, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::community::Community_;
use lemmy_db_schema::source::community::Community;
use lemmy_utils::LemmyError;
@ -16,31 +13,34 @@ use url::Url;
#[serde(rename_all = "camelCase")]
pub struct UndoRemoveCommunity {
to: PublicUrl,
object: LemmyActivity<RemoveCommunity>,
object: RemoveCommunity,
cc: [Url; 1],
#[serde(rename = "type")]
kind: RemoveType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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)?;
verify_domains_match(&self.actor, &self.inner.object.inner.object)?;
verify_domains_match(&self.actor, &self.inner.cc[0])?;
self.inner.object.verify(context).await
impl ActivityHandlerNew for UndoRemoveCommunity {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
check_is_apub_id_valid(&self.common.actor, false)?;
verify_domains_match(&self.common.actor, &self.object.object)?;
verify_domains_match(&self.common.actor, &self.cc[0])?;
self.object.verify(context, request_counter).await
}
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let community_id = self.inner.object.inner.object.clone();
let community_id = self.object.object.clone();
let community =
get_or_fetch_and_upsert_community(&community_id, context, request_counter).await?;
@ -56,4 +56,8 @@ impl ActivityHandler for LemmyActivity<UndoRemoveCommunity> {
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,16 +1,10 @@
use crate::activities::{
community::{send_websocket_message, verify_is_community_mod},
LemmyActivity,
};
use crate::activities::community::{send_websocket_message, verify_is_community_mod};
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, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::{ApubObject, Crud};
use lemmy_db_schema::source::{
community::{Community, CommunityForm},
person::Person,
};
use lemmy_db_schema::source::community::{Community, CommunityForm};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -25,33 +19,32 @@ pub struct UpdateCommunity {
cc: [Url; 1],
#[serde(rename = "type")]
kind: UpdateType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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
impl ActivityHandlerNew for UpdateCommunity {
async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
self.object.id(self.cc[0].as_str())?;
check_is_apub_id_valid(&self.common.actor, false)?;
verify_is_community_mod(self.common.actor.clone(), self.cc[0].clone(), context).await
}
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let cc = self.inner.cc[0].clone().into();
let cc = self.cc[0].clone().into();
let community = blocking(context.pool(), move |conn| {
Community::read_from_apub_id(conn, &cc)
})
.await??;
let updated_community = CommunityForm::from_apub(
&self.inner.object,
&self.object,
context,
community.actor_id.clone().into(),
request_counter,
@ -80,4 +73,8 @@ impl ActivityHandler for LemmyActivity<UpdateCommunity> {
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,16 +1,11 @@
use crate::activities::{following::follow::FollowCommunity, LemmyActivity};
use crate::activities::following::follow::FollowCommunity;
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,
ActivityCommonFields,
ActivityHandler,
ActivityHandlerNew,
};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew};
use lemmy_db_queries::Followable;
use lemmy_db_schema::source::community::CommunityFollower;
use lemmy_utils::LemmyError;
@ -21,7 +16,7 @@ use url::Url;
#[serde(rename_all = "camelCase")]
pub struct AcceptFollowCommunity {
to: Url,
object: LemmyActivity<FollowCommunity>,
object: FollowCommunity,
#[serde(rename = "type")]
kind: AcceptType,
#[serde(flatten)]
@ -31,10 +26,14 @@ pub struct AcceptFollowCommunity {
/// Handle accepted follows
#[async_trait::async_trait(?Send)]
impl ActivityHandlerNew for AcceptFollowCommunity {
async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, &self.common.id_unchecked())?;
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
check_is_apub_id_valid(&self.common.actor, false)?;
self.object.verify(context).await
self.object.verify(context, request_counter).await
}
async fn receive(

View file

@ -1,4 +1,3 @@
use crate::activities::LemmyActivity;
use activitystreams::{
activity::{kind::FollowType, Follow},
base::{AnyBase, ExtendsExt},
@ -7,15 +6,12 @@ use anyhow::Context;
use lemmy_api_common::blocking;
use lemmy_apub::{
check_is_apub_id_valid,
fetcher::community::get_or_fetch_and_upsert_community,
fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person},
CommunityType,
};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew};
use lemmy_db_queries::Followable;
use lemmy_db_schema::source::{
community::{CommunityFollower, CommunityFollowerForm},
person::Person,
};
use lemmy_db_schema::source::community::{CommunityFollower, CommunityFollowerForm};
use lemmy_utils::{location_info, LemmyError};
use lemmy_websocket::LemmyContext;
use url::Url;
@ -27,26 +23,27 @@ pub struct FollowCommunity {
pub(in crate::activities::following) object: Url,
#[serde(rename = "type")]
kind: FollowType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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)
impl ActivityHandlerNew for FollowCommunity {
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
verify_domains_match(&self.to, &self.object)?;
check_is_apub_id_valid(&self.common.actor, false)
}
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let actor =
get_or_fetch_and_upsert_person(&self.common.actor, context, request_counter).await?;
let community =
get_or_fetch_and_upsert_community(&self.inner.object, context, request_counter).await?;
get_or_fetch_and_upsert_community(&self.object, context, request_counter).await?;
let community_follower_form = CommunityFollowerForm {
community_id: community.id,
person_id: actor.id,
@ -64,4 +61,8 @@ impl ActivityHandler for LemmyActivity<FollowCommunity> {
let anybase = Follow::from_any_base(anybase)?.context(location_info!())?;
community.send_accept_follow(anybase, context).await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,13 +1,13 @@
use crate::activities::{following::follow::FollowCommunity, LemmyActivity};
use crate::activities::following::follow::FollowCommunity;
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};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler};
use lemmy_db_queries::Followable;
use lemmy_db_schema::source::{
community::{CommunityFollower, CommunityFollowerForm},
person::Person,
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, ActivityCommonFields, ActivityHandlerNew};
use lemmy_db_queries::Followable;
use lemmy_db_schema::source::community::{CommunityFollower, CommunityFollowerForm};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -16,30 +16,34 @@ use url::Url;
#[serde(rename_all = "camelCase")]
pub struct UndoFollowCommunity {
to: Url,
object: LemmyActivity<FollowCommunity>,
object: FollowCommunity,
#[serde(rename = "type")]
kind: UndoType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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
impl ActivityHandlerNew for UndoFollowCommunity {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
verify_domains_match(&self.to, &self.object.object)?;
check_is_apub_id_valid(&self.common.actor, false)?;
self.object.verify(context, request_counter).await
}
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 actor =
get_or_fetch_and_upsert_person(&self.common.actor, context, request_counter).await?;
let community = get_or_fetch_and_upsert_community(&self.to, context, request_counter).await?;
let community_follower_form = CommunityFollowerForm {
community_id: community.id,
@ -54,4 +58,8 @@ impl ActivityHandler for LemmyActivity<UndoFollowCommunity> {
.await?;
Ok(())
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,4 +1,3 @@
use activitystreams::{base::AnyBase, primitives::OneOrMany, unparsed::Unparsed};
use anyhow::anyhow;
use lemmy_api_common::blocking;
use lemmy_db_queries::ApubObject;
@ -14,30 +13,6 @@ pub mod following;
pub mod post;
pub mod private_message;
// TODO: remove this
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct LemmyActivity<Kind> {
#[serde(rename = "@context")]
context: OneOrMany<AnyBase>,
id: Url,
pub(crate) actor: Url,
/// type-specific fields
#[serde(flatten)]
pub inner: Kind,
// unparsed fields
#[serde(flatten)]
unparsed: Unparsed,
}
impl<Kind> LemmyActivity<Kind> {
pub fn id_unchecked(&self) -> &Url {
&self.id
}
}
async fn verify_mod_action(
actor_id: Url,
activity_cc: Url,

View file

@ -1,10 +1,10 @@
use crate::activities::{post::send_websocket_message, LemmyActivity};
use crate::activities::post::send_websocket_message;
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, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::post::Post_;
use lemmy_db_schema::source::{person::Person, post::Post};
use lemmy_db_schema::source::post::Post;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -17,25 +17,24 @@ pub struct DeletePost {
cc: [Url; 1],
#[serde(rename = "type")]
kind: DeleteType,
#[serde(flatten)]
pub(in crate::activities::post) common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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)
impl ActivityHandlerNew for DeletePost {
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
verify_domains_match(&self.common.actor, &self.object)?;
check_is_apub_id_valid(&self.common.actor, false)
}
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let post = get_or_fetch_and_insert_post(&self.inner.object, context, request_counter).await?;
let post = get_or_fetch_and_insert_post(&self.object, context, request_counter).await?;
let deleted_post = blocking(context.pool(), move |conn| {
Post::update_deleted(conn, post.id, true)
@ -44,4 +43,8 @@ impl ActivityHandler for LemmyActivity<DeletePost> {
send_websocket_message(deleted_post.id, UserOperationCrud::EditPost, context).await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,8 +1,7 @@
use crate::activities::{post::like_or_dislike_post, LemmyActivity};
use crate::activities::post::like_or_dislike_post;
use activitystreams::activity::kind::DislikeType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::person::Person;
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -15,23 +14,33 @@ pub struct DislikePost {
cc: [Url; 1],
#[serde(rename = "type")]
kind: DislikeType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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)
impl ActivityHandlerNew for DislikePost {
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
check_is_apub_id_valid(&self.common.actor, false)
}
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
like_or_dislike_post(-1, &actor, &self.inner.object, context, request_counter).await
like_or_dislike_post(
-1,
&self.common.actor,
&self.object,
context,
request_counter,
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,6 +1,6 @@
use crate::activities::post::like_or_dislike_post;
use activitystreams::activity::kind::LikeType;
use lemmy_apub::{check_is_apub_id_valid, fetcher::person::get_or_fetch_and_upsert_person};
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
@ -30,9 +30,14 @@ impl ActivityHandlerNew for LikePost {
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let actor =
get_or_fetch_and_upsert_person(&self.common.actor, context, request_counter).await?;
like_or_dislike_post(1, &actor, &self.object, context, request_counter).await
like_or_dislike_post(
1,
&self.common.actor,
&self.object,
context,
request_counter,
)
.await
}
fn common(&self) -> &ActivityCommonFields {

View file

@ -1,11 +1,11 @@
use lemmy_api_common::{blocking, post::PostResponse};
use lemmy_apub::fetcher::objects::get_or_fetch_and_insert_post;
use lemmy_apub::fetcher::{
objects::get_or_fetch_and_insert_post,
person::get_or_fetch_and_upsert_person,
};
use lemmy_db_queries::Likeable;
use lemmy_db_schema::{
source::{
person::Person,
post::{PostLike, PostLikeForm},
},
source::post::{PostLike, PostLikeForm},
PostId,
};
use lemmy_db_views::post_view::PostView;
@ -47,11 +47,12 @@ async fn send_websocket_message<OP: ToString + Send + lemmy_websocket::Operation
async fn like_or_dislike_post(
score: i16,
actor: &Person,
actor: &Url,
object: &Url,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let actor = 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;
@ -71,11 +72,12 @@ async fn like_or_dislike_post(
}
async fn undo_like_or_dislike_post(
actor: &Person,
actor: &Url,
object: &Url,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let actor = 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;

View file

@ -1,10 +1,10 @@
use crate::activities::{post::send_websocket_message, verify_mod_action, LemmyActivity};
use crate::activities::{post::send_websocket_message, verify_mod_action};
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, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::post::Post_;
use lemmy_db_schema::source::{person::Person, post::Post};
use lemmy_db_schema::source::post::Post;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -17,26 +17,25 @@ pub struct RemovePost {
cc: [Url; 1],
#[serde(rename = "type")]
kind: RemoveType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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
impl ActivityHandlerNew for RemovePost {
async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
check_is_apub_id_valid(&self.common.actor, false)?;
verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await
}
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
// TODO: check that actor is instance mod if community is local (same for undo, RemoveComment)
let post = get_or_fetch_and_insert_post(&self.inner.object, context, request_counter).await?;
let post = get_or_fetch_and_insert_post(&self.object, context, request_counter).await?;
let removed_post = blocking(context.pool(), move |conn| {
Post::update_removed(conn, post.id, true)
@ -45,4 +44,8 @@ impl ActivityHandler for LemmyActivity<RemovePost> {
send_websocket_message(removed_post.id, UserOperationCrud::EditPost, context).await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,13 +1,10 @@
use crate::activities::{
post::{delete::DeletePost, send_websocket_message},
LemmyActivity,
};
use crate::activities::post::{delete::DeletePost, send_websocket_message};
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, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::post::Post_;
use lemmy_db_schema::source::{person::Person, post::Post};
use lemmy_db_schema::source::post::Post;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -16,32 +13,33 @@ use url::Url;
#[serde(rename_all = "camelCase")]
pub struct UndoDeletePost {
to: PublicUrl,
object: LemmyActivity<DeletePost>,
object: DeletePost,
cc: [Url; 1],
#[serde(rename = "type")]
kind: UndoType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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
impl ActivityHandlerNew for UndoDeletePost {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
verify_domains_match(&self.common.actor, &self.object.common.actor)?;
check_is_apub_id_valid(&self.common.actor, false)?;
self.object.verify(context, request_counter).await
}
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let post =
get_or_fetch_and_insert_post(&self.inner.object.inner.object, context, request_counter)
.await?;
let post = get_or_fetch_and_insert_post(&self.object.object, context, request_counter).await?;
let deleted_post = blocking(context.pool(), move |conn| {
Post::update_deleted(conn, post.id, false)
@ -50,4 +48,8 @@ impl ActivityHandler for LemmyActivity<UndoDeletePost> {
send_websocket_message(deleted_post.id, UserOperationCrud::EditPost, context).await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,11 +1,7 @@
use crate::activities::{
post::{dislike::DislikePost, undo_like_or_dislike_post},
LemmyActivity,
};
use crate::activities::post::{dislike::DislikePost, undo_like_or_dislike_post};
use activitystreams::activity::kind::UndoType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::person::Person;
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -14,35 +10,42 @@ use url::Url;
#[serde(rename_all = "camelCase")]
pub struct UndoDislikePost {
to: PublicUrl,
object: LemmyActivity<DislikePost>,
object: DislikePost,
cc: [Url; 1],
#[serde(rename = "type")]
kind: UndoType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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
impl ActivityHandlerNew for UndoDislikePost {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
verify_domains_match(&self.common.actor, &self.object.object)?;
check_is_apub_id_valid(&self.common.actor, false)?;
self.object.verify(context, request_counter).await
}
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
undo_like_or_dislike_post(
&actor,
&self.inner.object.inner.object,
&self.common.actor,
&self.object.object,
context,
request_counter,
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,11 +1,7 @@
use crate::activities::{
post::{like::LikePost, undo_like_or_dislike_post},
LemmyActivity,
};
use crate::activities::post::{like::LikePost, undo_like_or_dislike_post};
use activitystreams::activity::kind::UndoType;
use lemmy_apub::check_is_apub_id_valid;
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_db_schema::source::person::Person;
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
@ -14,34 +10,41 @@ use url::Url;
#[serde(rename_all = "camelCase")]
pub struct UndoLikePost {
to: PublicUrl,
object: LemmyActivity<LikePost>,
object: LikePost,
cc: [Url; 1],
#[serde(rename = "type")]
kind: UndoType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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
impl ActivityHandlerNew for UndoLikePost {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
verify_domains_match(&self.common.actor, &self.object.object)?;
check_is_apub_id_valid(&self.common.actor, false)?;
self.object.verify(context, request_counter).await
}
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
undo_like_or_dislike_post(
&actor,
&self.inner.object.inner.object,
&self.common.actor,
&self.object.object,
context,
request_counter,
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,14 +1,13 @@
use crate::activities::{
post::{remove::RemovePost, send_websocket_message},
verify_mod_action,
LemmyActivity,
};
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, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::post::Post_;
use lemmy_db_schema::source::{person::Person, post::Post};
use lemmy_db_schema::source::post::Post;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -17,32 +16,33 @@ use url::Url;
#[serde(rename_all = "camelCase")]
pub struct UndoRemovePost {
to: PublicUrl,
object: LemmyActivity<RemovePost>,
object: RemovePost,
cc: [Url; 1],
#[serde(rename = "type")]
kind: UndoType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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
impl ActivityHandlerNew for UndoRemovePost {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
check_is_apub_id_valid(&self.common.actor, false)?;
verify_mod_action(self.common.actor.clone(), self.cc[0].clone(), context).await?;
self.object.verify(context, request_counter).await
}
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let post =
get_or_fetch_and_insert_post(&self.inner.object.inner.object, context, request_counter)
.await?;
let post = get_or_fetch_and_insert_post(&self.object.object, context, request_counter).await?;
let removed_post = blocking(context.pool(), move |conn| {
Post::update_removed(conn, post.id, false)
@ -51,4 +51,8 @@ impl ActivityHandler for LemmyActivity<UndoRemovePost> {
send_websocket_message(removed_post.id, UserOperationCrud::EditPost, context).await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,19 +1,17 @@
use crate::activities::{post::send_websocket_message, LemmyActivity};
use crate::activities::post::send_websocket_message;
use activitystreams::{activity::kind::UpdateType, base::BaseExt};
use anyhow::Context;
use lemmy_api_common::blocking;
use lemmy_apub::{
check_is_apub_id_valid,
objects::{FromApub, FromApubToForm},
ActorType,
PageExt,
};
use lemmy_apub_lib::{verify_domains_match, ActivityHandler, PublicUrl};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::{ApubObject, Crud};
use lemmy_db_schema::{
source::{
community::Community,
person::Person,
post::{Post, PostForm},
},
DbUrl,
@ -30,28 +28,27 @@ pub struct UpdatePost {
cc: Vec<Url>,
#[serde(rename = "type")]
kind: UpdateType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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)
impl ActivityHandlerNew for UpdatePost {
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
self.object.id(self.common.actor.as_str())?;
check_is_apub_id_valid(&self.common.actor, false)
}
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let temp_post = PostForm::from_apub(
&self.inner.object,
&self.object,
context,
actor.actor_id(),
self.common.actor.clone(),
request_counter,
false,
)
@ -81,9 +78,9 @@ impl ActivityHandler for LemmyActivity<UpdatePost> {
}
let post = Post::from_apub(
&self.inner.object,
&self.object,
context,
actor.actor_id(),
self.common.actor.clone(),
request_counter,
mod_action_allowed,
)
@ -91,4 +88,8 @@ impl ActivityHandler for LemmyActivity<UpdatePost> {
send_websocket_message(post.id, UserOperationCrud::EditPost, context).await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,8 +1,8 @@
use crate::activities::{private_message::send_websocket_message, LemmyActivity};
use crate::activities::private_message::send_websocket_message;
use activitystreams::{activity::kind::CreateType, base::BaseExt};
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_apub::{check_is_apub_id_valid, objects::FromApub, NoteExt};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew};
use lemmy_db_schema::source::private_message::PrivateMessage;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -14,28 +14,27 @@ pub struct CreatePrivateMessage {
object: NoteExt,
#[serde(rename = "type")]
kind: CreateType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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)
impl ActivityHandlerNew for CreatePrivateMessage {
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(self.common.id_unchecked(), &self.common.actor)?;
self.object.id(self.common.actor.as_str())?;
check_is_apub_id_valid(&self.common.actor, false)
}
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let private_message = PrivateMessage::from_apub(
&self.inner.object,
&self.object,
context,
actor.actor_id(),
self.common.actor.clone(),
request_counter,
false,
)
@ -50,4 +49,8 @@ impl ActivityHandler for LemmyActivity<CreatePrivateMessage> {
Ok(())
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,10 +1,10 @@
use crate::activities::{private_message::send_websocket_message, LemmyActivity};
use crate::activities::private_message::send_websocket_message;
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, ActivityHandler};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew};
use lemmy_db_queries::{source::private_message::PrivateMessage_, ApubObject};
use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage};
use lemmy_db_schema::source::private_message::PrivateMessage;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -16,25 +16,24 @@ pub struct DeletePrivateMessage {
pub(in crate::activities::private_message) object: Url,
#[serde(rename = "type")]
kind: DeleteType,
#[serde(flatten)]
pub(in crate::activities::private_message) common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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)
impl ActivityHandlerNew for DeletePrivateMessage {
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
verify_domains_match(&self.common.actor, &self.object)?;
check_is_apub_id_valid(&self.common.actor, false)
}
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
_request_counter: &mut i32,
) -> Result<(), LemmyError> {
let ap_id = self.inner.object.clone();
let ap_id = self.object.clone();
let private_message = blocking(context.pool(), move |conn| {
PrivateMessage::read_from_apub_id(conn, &ap_id.into())
})
@ -53,4 +52,8 @@ impl ActivityHandler for LemmyActivity<DeletePrivateMessage> {
Ok(())
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,13 +1,10 @@
use crate::activities::{
private_message::{delete::DeletePrivateMessage, send_websocket_message},
LemmyActivity,
};
use crate::activities::private_message::{delete::DeletePrivateMessage, send_websocket_message};
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, ActivityHandler};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew};
use lemmy_db_queries::{source::private_message::PrivateMessage_, ApubObject};
use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage};
use lemmy_db_schema::source::private_message::PrivateMessage;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -16,29 +13,32 @@ use url::Url;
#[serde(rename_all = "camelCase")]
pub struct UndoDeletePrivateMessage {
to: Url,
object: LemmyActivity<DeletePrivateMessage>,
object: DeletePrivateMessage,
#[serde(rename = "type")]
kind: UndoType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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
impl ActivityHandlerNew for UndoDeletePrivateMessage {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
verify_domains_match(&self.common.actor, self.object.common.id_unchecked())?;
check_is_apub_id_valid(&self.common.actor, false)?;
self.object.verify(context, request_counter).await
}
async fn receive(
&self,
_actor: Self::Actor,
context: &LemmyContext,
_request_counter: &mut i32,
) -> Result<(), LemmyError> {
let ap_id = self.inner.object.inner.object.clone();
let ap_id = self.object.object.clone();
let private_message = blocking(context.pool(), move |conn| {
PrivateMessage::read_from_apub_id(conn, &ap_id.into())
})
@ -58,4 +58,8 @@ impl ActivityHandler for LemmyActivity<UndoDeletePrivateMessage> {
Ok(())
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,8 +1,8 @@
use crate::activities::{private_message::send_websocket_message, LemmyActivity};
use crate::activities::private_message::send_websocket_message;
use activitystreams::{activity::kind::UpdateType, base::BaseExt};
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_apub::{check_is_apub_id_valid, objects::FromApub, NoteExt};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew};
use lemmy_db_schema::source::private_message::PrivateMessage;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
@ -14,28 +14,27 @@ pub struct UpdatePrivateMessage {
object: NoteExt,
#[serde(rename = "type")]
kind: UpdateType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for LemmyActivity<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)
impl ActivityHandlerNew for UpdatePrivateMessage {
async fn verify(&self, _context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(self.common.id_unchecked(), &self.common.actor)?;
self.object.id(self.common.actor.as_str())?;
check_is_apub_id_valid(&self.common.actor, false)
}
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let private_message = PrivateMessage::from_apub(
&self.inner.object,
&self.object,
context,
actor.actor_id(),
self.common.actor.clone(),
request_counter,
false,
)
@ -50,4 +49,8 @@ impl ActivityHandler for LemmyActivity<UpdatePrivateMessage> {
Ok(())
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,18 +1,16 @@
use crate::{
activities::LemmyActivity,
http::{
create_apub_response,
create_apub_tombstone_response,
inbox_enums::GroupInboxActivities,
receive_activity,
},
use crate::http::{
create_apub_response,
create_apub_tombstone_response,
inbox_enums::GroupInboxActivities,
payload_to_string,
receive_activity,
};
use activitystreams::{
base::{AnyBase, BaseExt},
collection::{CollectionExt, OrderedCollection, UnorderedCollection},
url::Url,
};
use actix_web::{body::Body, web, HttpRequest, HttpResponse};
use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse};
use lemmy_api_common::blocking;
use lemmy_apub::{
extensions::context::lemmy_context,
@ -57,12 +55,12 @@ pub(crate) async fn get_apub_community_http(
/// Handler for all incoming receive to community inboxes.
pub async fn community_inbox(
request: HttpRequest,
input: web::Json<LemmyActivity<GroupInboxActivities>>,
payload: Payload,
path: web::Path<String>,
context: web::Data<LemmyContext>,
) -> Result<HttpResponse, LemmyError> {
//receive_activity(request, input.into_inner(), Some(path.0), context).await
todo!()
let unparsed = payload_to_string(payload).await?;
receive_activity::<GroupInboxActivities>(request, &unparsed, Some(path.0), context).await
}
/// Returns an empty followers collection, only populating the size (for privacy).

View file

@ -43,12 +43,12 @@ use crate::activities::{
update::UpdatePrivateMessage,
},
};
use lemmy_apub_lib::ActivityHandler;
use lemmy_apub_lib::{ActivityCommonFields, ActivityHandlerNew};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandlerNew)]
#[serde(untagged)]
pub enum PersonInboxActivities {
AcceptFollowCommunity(AcceptFollowCommunity),
@ -59,7 +59,7 @@ pub enum PersonInboxActivities {
AnnounceActivity(Box<AnnounceActivity>),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandlerNew)]
#[serde(untagged)]
pub enum GroupInboxActivities {
FollowCommunity(FollowCommunity),
@ -95,7 +95,7 @@ pub enum GroupInboxActivities {
RemoveMod(RemoveMod),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandlerNew)]
#[serde(untagged)]
pub enum SharedInboxActivities {
// received by person
@ -138,57 +138,3 @@ pub enum SharedInboxActivities {
AddMod(AddMod),
RemoveMod(RemoveMod),
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for SharedInboxActivities {
type Actor = lemmy_apub::fetcher::Actor;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
self.verify(context).await
}
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
self.receive(actor, context, request_counter).await
}
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for PersonInboxActivities {
type Actor = lemmy_apub::fetcher::Actor;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
self.verify(context).await
}
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
self.receive(actor, context, request_counter).await
}
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for GroupInboxActivities {
type Actor = lemmy_apub::fetcher::Actor;
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
self.verify(context).await
}
async fn receive(
&self,
actor: Self::Actor,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
self.receive(actor, context, request_counter).await
}
}

View file

@ -2,7 +2,13 @@ use crate::activities::{
following::accept::AcceptFollowCommunity,
post::{create::CreatePost, like::LikePost},
};
use actix_web::{body::Body, web, web::Bytes, HttpRequest, HttpResponse};
use actix_web::{
body::Body,
web,
web::{Bytes, BytesMut, Payload},
HttpRequest,
HttpResponse,
};
use anyhow::{anyhow, Context};
use futures::StreamExt;
use http::StatusCode;
@ -40,18 +46,22 @@ enum Ac {
pub async fn shared_inbox(
request: HttpRequest,
mut body: web::Payload,
payload: Payload,
context: web::Data<LemmyContext>,
) -> Result<HttpResponse, LemmyError> {
let mut bytes = web::BytesMut::new();
while let Some(item) = body.next().await {
bytes.extend_from_slice(&item?);
}
let mut unparsed: String = String::new();
Bytes::from(bytes).as_ref().read_to_string(&mut unparsed)?;
let unparsed = payload_to_string(payload).await?;
receive_activity::<Ac>(request, &unparsed, None, context).await
}
async fn payload_to_string(mut payload: Payload) -> Result<String, LemmyError> {
let mut bytes = BytesMut::new();
while let Some(item) = payload.next().await {
bytes.extend_from_slice(&item?);
}
let mut unparsed = String::new();
Bytes::from(bytes).as_ref().read_to_string(&mut unparsed)?;
Ok(unparsed)
}
async fn receive_activity<'a, T>(
request: HttpRequest,
activity: &'a str,

View file

@ -1,17 +1,15 @@
use crate::{
activities::LemmyActivity,
http::{
create_apub_response,
create_apub_tombstone_response,
inbox_enums::PersonInboxActivities,
receive_activity,
},
use crate::http::{
create_apub_response,
create_apub_tombstone_response,
inbox_enums::PersonInboxActivities,
payload_to_string,
receive_activity,
};
use activitystreams::{
base::BaseExt,
collection::{CollectionExt, OrderedCollection},
};
use actix_web::{body::Body, web, HttpRequest, HttpResponse};
use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse};
use lemmy_api_common::blocking;
use lemmy_apub::{extensions::context::lemmy_context, objects::ToApub, ActorType};
use lemmy_db_queries::source::person::Person_;
@ -49,12 +47,12 @@ pub(crate) async fn get_apub_person_http(
pub async fn person_inbox(
request: HttpRequest,
input: web::Json<LemmyActivity<PersonInboxActivities>>,
payload: Payload,
path: web::Path<String>,
context: web::Data<LemmyContext>,
) -> Result<HttpResponse, LemmyError> {
//receive_activity(request, input.into_inner(), Some(path.0), context).await
todo!()
let unparsed = payload_to_string(payload).await?;
receive_activity::<PersonInboxActivities>(request, &unparsed, Some(path.0), context).await
}
pub(crate) async fn get_apub_person_outbox(