Rewrite remove/delete post/comment, fix tests, test manually

This commit is contained in:
Felix Ableitner 2021-07-11 17:38:40 +02:00
parent 99f55a4627
commit caba7e4cf0
18 changed files with 389 additions and 426 deletions

View file

@ -35,13 +35,9 @@ impl ActivityHandlerNew for CreateComment {
context: &LemmyContext, context: &LemmyContext,
request_counter: &mut i32, request_counter: &mut i32,
) -> Result<(), LemmyError> { ) -> Result<(), LemmyError> {
dbg!("1");
verify_activity(self.common())?; verify_activity(self.common())?;
dbg!("2");
verify_person_in_community(&self.common.actor, &self.cc, context, request_counter).await?; verify_person_in_community(&self.common.actor, &self.cc, context, request_counter).await?;
dbg!("3");
verify_domains_match_opt(&self.common.actor, self.object.id_unchecked())?; verify_domains_match_opt(&self.common.actor, self.object.id_unchecked())?;
dbg!("4");
// TODO: should add a check that the correct community is in cc (probably needs changes to // TODO: should add a check that the correct community is in cc (probably needs changes to
// comment deserialization) // comment deserialization)
Ok(()) Ok(())
@ -52,7 +48,6 @@ impl ActivityHandlerNew for CreateComment {
context: &LemmyContext, context: &LemmyContext,
request_counter: &mut i32, request_counter: &mut i32,
) -> Result<(), LemmyError> { ) -> Result<(), LemmyError> {
dbg!("5");
let comment = Comment::from_apub( let comment = Comment::from_apub(
&self.object, &self.object,
context, context,
@ -61,7 +56,6 @@ impl ActivityHandlerNew for CreateComment {
false, false,
) )
.await?; .await?;
dbg!("6");
let recipients = let recipients =
get_notif_recipients(&self.common.actor, &comment, context, request_counter).await?; get_notif_recipients(&self.common.actor, &comment, context, request_counter).await?;
send_websocket_message( send_websocket_message(

View file

@ -1,56 +0,0 @@
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, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::comment::Comment_;
use lemmy_db_schema::source::comment::Comment;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DeleteComment {
to: PublicUrl,
pub(in crate::activities::comment) object: Url,
cc: [Url; 1],
#[serde(rename = "type")]
kind: DeleteType,
#[serde(flatten)]
pub(in crate::activities::comment) common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
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,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
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)
})
.await??;
send_websocket_message(
deleted_comment.id,
vec![],
UserOperationCrud::EditComment,
context,
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -12,10 +12,6 @@ use lemmy_websocket::{messages::SendComment, LemmyContext};
use url::Url; use url::Url;
pub mod create; pub mod create;
pub mod delete;
pub mod remove;
pub mod undo_delete;
pub mod undo_remove;
pub mod update; pub mod update;
async fn get_notif_recipients( async fn get_notif_recipients(

View file

@ -1,62 +0,0 @@
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, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::comment::Comment_;
use lemmy_db_schema::source::comment::Comment;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct UndoDeleteComment {
to: PublicUrl,
object: DeleteComment,
cc: [Url; 1],
#[serde(rename = "type")]
kind: UndoType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
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,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
let comment =
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)
})
.await??;
send_websocket_message(
deleted_comment.id,
vec![],
UserOperationCrud::EditComment,
context,
)
.await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,3 +1,23 @@
use crate::{
activities::{
comment::{create::CreateComment, update::UpdateComment},
community::{block_user::BlockUserFromCommunity, undo_block_user::UndoBlockUserFromCommunity},
post::{create::CreatePost, update::UpdatePost},
post_or_comment::{
delete::DeletePostOrComment,
dislike::DislikePostOrComment,
like::LikePostOrComment,
remove::RemovePostOrComment,
undo_delete::UndoDeletePostOrComment,
undo_dislike::UndoDislikePostOrComment,
undo_like::UndoLikePostOrComment,
undo_remove::UndoRemovePostOrComment,
},
verify_activity,
verify_community,
},
http::is_activity_already_known,
};
use activitystreams::activity::kind::AnnounceType; use activitystreams::activity::kind::AnnounceType;
use lemmy_apub_lib::{ActivityCommonFields, ActivityHandlerNew, PublicUrl}; use lemmy_apub_lib::{ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_utils::LemmyError; use lemmy_utils::LemmyError;
@ -5,56 +25,21 @@ use lemmy_websocket::LemmyContext;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use url::Url; use url::Url;
use crate::{
activities::{
comment::{
create::CreateComment,
delete::DeleteComment,
remove::RemoveComment,
undo_delete::UndoDeleteComment,
undo_remove::UndoRemoveComment,
update::UpdateComment,
},
community::{block_user::BlockUserFromCommunity, undo_block_user::UndoBlockUserFromCommunity},
post::{
create::CreatePost,
delete::DeletePost,
remove::RemovePost,
undo_delete::UndoDeletePost,
undo_remove::UndoRemovePost,
update::UpdatePost,
},
post_or_comment::{
dislike::DislikePostOrComment,
like::LikePostOrComment,
undo_dislike::UndoDislikePostOrComment,
undo_like::UndoLikePostOrComment,
},
verify_activity,
verify_community,
},
http::is_activity_already_known,
};
#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandlerNew)] #[derive(Clone, Debug, Deserialize, Serialize, ActivityHandlerNew)]
#[serde(untagged)] #[serde(untagged)]
pub enum AnnouncableActivities { pub enum AnnouncableActivities {
CreateComment(CreateComment), CreateComment(CreateComment),
UpdateComment(UpdateComment), UpdateComment(UpdateComment),
DeleteComment(DeleteComment),
UndoDeleteComment(UndoDeleteComment),
RemoveComment(RemoveComment),
UndoRemoveComment(UndoRemoveComment),
CreatePost(CreatePost), CreatePost(CreatePost),
UpdatePost(UpdatePost), UpdatePost(UpdatePost),
DeletePost(DeletePost),
UndoDeletePost(UndoDeletePost),
RemovePost(RemovePost),
UndoRemovePost(UndoRemovePost),
LikePostOrComment(LikePostOrComment), LikePostOrComment(LikePostOrComment),
DislikePostOrComment(DislikePostOrComment), DislikePostOrComment(DislikePostOrComment),
UndoLikePostOrComment(UndoLikePostOrComment), UndoLikePostOrComment(UndoLikePostOrComment),
UndoDislikePostOrComment(UndoDislikePostOrComment), UndoDislikePostOrComment(UndoDislikePostOrComment),
DeletePostOrComment(DeletePostOrComment),
RemovePostOrComment(RemovePostOrComment),
UndoRemovePostOrComment(UndoRemovePostOrComment),
UndoDeletePostOrComment(UndoDeletePostOrComment),
BlockUserFromCommunity(BlockUserFromCommunity), BlockUserFromCommunity(BlockUserFromCommunity),
UndoBlockUserFromCommunity(UndoBlockUserFromCommunity), UndoBlockUserFromCommunity(UndoBlockUserFromCommunity),
} }

View file

@ -1,50 +0,0 @@
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, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::post::Post_;
use lemmy_db_schema::source::post::Post;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DeletePost {
to: PublicUrl,
pub(in crate::activities::post) object: Url,
cc: [Url; 1],
#[serde(rename = "type")]
kind: DeleteType,
#[serde(flatten)]
pub(in crate::activities::post) common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
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,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
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)
})
.await??;
send_websocket_message(deleted_post.id, UserOperationCrud::EditPost, context).await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -5,10 +5,6 @@ use lemmy_utils::LemmyError;
use lemmy_websocket::{messages::SendPost, LemmyContext}; use lemmy_websocket::{messages::SendPost, LemmyContext};
pub mod create; pub mod create;
pub mod delete;
pub mod remove;
pub mod undo_delete;
pub mod undo_remove;
pub mod update; pub mod update;
pub(crate) async fn send_websocket_message< pub(crate) async fn send_websocket_message<

View file

@ -1,51 +0,0 @@
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, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::post::Post_;
use lemmy_db_schema::source::post::Post;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RemovePost {
to: PublicUrl,
pub(in crate::activities::post) object: Url,
cc: [Url; 1],
#[serde(rename = "type")]
kind: RemoveType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
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, self.cc[0].clone(), context).await
}
async fn receive(
&self,
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.object, context, request_counter).await?;
let removed_post = blocking(context.pool(), move |conn| {
Post::update_removed(conn, post.id, true)
})
.await??;
send_websocket_message(removed_post.id, UserOperationCrud::EditPost, context).await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,55 +0,0 @@
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, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::post::Post_;
use lemmy_db_schema::source::post::Post;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct UndoDeletePost {
to: PublicUrl,
object: DeletePost,
cc: [Url; 1],
#[serde(rename = "type")]
kind: UndoType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
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,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
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)
})
.await??;
send_websocket_message(deleted_post.id, UserOperationCrud::EditPost, context).await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,58 +0,0 @@
use crate::activities::{
post::{remove::RemovePost, send_websocket_message},
verify_mod_action,
};
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, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::post::Post_;
use lemmy_db_schema::source::post::Post;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct UndoRemovePost {
to: PublicUrl,
object: RemovePost,
cc: [Url; 1],
#[serde(rename = "type")]
kind: UndoType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
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, self.cc[0].clone(), context).await?;
self.object.verify(context, request_counter).await
}
async fn receive(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
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)
})
.await??;
send_websocket_message(removed_post.id, UserOperationCrud::EditPost, context).await
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -0,0 +1,106 @@
use crate::activities::{
comment::send_websocket_message as send_comment_message,
post::send_websocket_message as send_post_message,
verify_activity,
verify_person_in_community,
};
use activitystreams::activity::kind::DeleteType;
use lemmy_api_common::blocking;
use lemmy_apub::{
fetcher::objects::get_or_fetch_and_insert_post_or_comment,
ActorType,
PostOrComment,
};
use lemmy_apub_lib::{verify_urls_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::{
source::{comment::Comment_, post::Post_},
Crud,
};
use lemmy_db_schema::source::{comment::Comment, person::Person, post::Post};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DeletePostOrComment {
to: PublicUrl,
pub(in crate::activities::post_or_comment) object: Url,
cc: [Url; 1],
#[serde(rename = "type")]
kind: DeleteType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandlerNew for DeletePostOrComment {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_activity(self.common())?;
verify_person_in_community(&self.common().actor, &self.cc, context, request_counter).await?;
let object_creator =
get_post_or_comment_actor_id(&self.object, context, request_counter).await?;
verify_urls_match(&self.common.actor, &object_creator)?;
Ok(())
}
async fn receive(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
match get_or_fetch_and_insert_post_or_comment(&self.object, context, request_counter).await? {
PostOrComment::Post(post) => {
let deleted_post = blocking(context.pool(), move |conn| {
Post::update_deleted(conn, post.id, true)
})
.await??;
send_post_message(deleted_post.id, UserOperationCrud::EditPost, context).await
}
PostOrComment::Comment(comment) => {
let deleted_comment = blocking(context.pool(), move |conn| {
Comment::update_deleted(conn, comment.id, true)
})
.await??;
send_comment_message(
deleted_comment.id,
vec![],
UserOperationCrud::EditComment,
context,
)
.await
}
}
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}
async fn get_post_or_comment_actor_id(
object: &Url,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<Url, LemmyError> {
let actor_id =
match get_or_fetch_and_insert_post_or_comment(object, context, request_counter).await? {
PostOrComment::Post(post) => {
let creator_id = post.creator_id;
blocking(context.pool(), move |conn| Person::read(conn, creator_id))
.await??
.actor_id()
}
PostOrComment::Comment(comment) => {
let creator_id = comment.creator_id;
blocking(context.pool(), move |conn| Person::read(conn, creator_id))
.await??
.actor_id()
}
};
Ok(actor_id)
}

View file

@ -1,5 +1,9 @@
pub mod delete;
pub mod dislike; pub mod dislike;
pub mod like; pub mod like;
pub mod remove;
pub mod undo_delete;
pub mod undo_dislike; pub mod undo_dislike;
pub mod undo_like; pub mod undo_like;
pub mod undo_remove;
mod voting; mod voting;

View file

@ -0,0 +1,75 @@
use crate::activities::{
comment::send_websocket_message as send_comment_message,
post::send_websocket_message as send_post_message,
verify_activity,
verify_mod_action,
verify_person_in_community,
};
use activitystreams::activity::kind::RemoveType;
use lemmy_api_common::blocking;
use lemmy_apub::{fetcher::objects::get_or_fetch_and_insert_post_or_comment, PostOrComment};
use lemmy_apub_lib::{ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::{comment::Comment_, post::Post_};
use lemmy_db_schema::source::{comment::Comment, post::Post};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RemovePostOrComment {
to: PublicUrl,
pub(in crate::activities::post_or_comment) object: Url,
cc: [Url; 1],
#[serde(rename = "type")]
kind: RemoveType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandlerNew for RemovePostOrComment {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_activity(self.common())?;
verify_person_in_community(&self.common().actor, &self.cc, context, request_counter).await?;
verify_mod_action(&self.common.actor, self.cc[0].clone(), context).await?;
Ok(())
}
async fn receive(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
match get_or_fetch_and_insert_post_or_comment(&self.object, context, request_counter).await? {
PostOrComment::Post(post) => {
let removed_post = blocking(context.pool(), move |conn| {
Post::update_removed(conn, post.id, true)
})
.await??;
send_post_message(removed_post.id, UserOperationCrud::EditPost, context).await
}
PostOrComment::Comment(comment) => {
let removed_comment = blocking(context.pool(), move |conn| {
Comment::update_removed(conn, comment.id, true)
})
.await??;
send_comment_message(
removed_comment.id,
vec![],
UserOperationCrud::EditComment,
context,
)
.await
}
}
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -0,0 +1,78 @@
use crate::activities::{
comment::send_websocket_message as send_comment_message,
post::send_websocket_message as send_post_message,
post_or_comment::delete::DeletePostOrComment,
verify_activity,
verify_person_in_community,
};
use activitystreams::activity::kind::UndoType;
use lemmy_api_common::blocking;
use lemmy_apub::{fetcher::objects::get_or_fetch_and_insert_post_or_comment, PostOrComment};
use lemmy_apub_lib::{verify_urls_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::{comment::Comment_, post::Post_};
use lemmy_db_schema::source::{comment::Comment, post::Post};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct UndoDeletePostOrComment {
to: PublicUrl,
object: DeletePostOrComment,
cc: [Url; 1],
#[serde(rename = "type")]
kind: UndoType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandlerNew for UndoDeletePostOrComment {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_activity(self.common())?;
verify_person_in_community(&self.common().actor, &self.cc, context, request_counter).await?;
verify_urls_match(&self.common.actor, &self.object.common().actor)?;
self.object.verify(context, request_counter).await?;
Ok(())
}
async fn receive(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
match get_or_fetch_and_insert_post_or_comment(&self.object.object, context, request_counter)
.await?
{
PostOrComment::Post(post) => {
let deleted_post = blocking(context.pool(), move |conn| {
Post::update_deleted(conn, post.id, false)
})
.await??;
send_post_message(deleted_post.id, UserOperationCrud::EditPost, context).await
}
PostOrComment::Comment(comment) => {
let deleted_comment = blocking(context.pool(), move |conn| {
Comment::update_deleted(conn, comment.id, false)
})
.await??;
send_comment_message(
deleted_comment.id,
vec![],
UserOperationCrud::EditComment,
context,
)
.await
}
}
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -0,0 +1,81 @@
use crate::activities::{
comment::send_websocket_message as send_comment_message,
post::send_websocket_message as send_post_message,
post_or_comment::remove::RemovePostOrComment,
verify_activity,
verify_mod_action,
verify_person_in_community,
};
use activitystreams::activity::kind::UndoType;
use lemmy_api_common::blocking;
use lemmy_apub::{fetcher::objects::get_or_fetch_and_insert_post_or_comment, PostOrComment};
use lemmy_apub_lib::{ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::source::{comment::Comment_, post::Post_};
use lemmy_db_schema::source::{comment::Comment, post::Post};
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
use url::Url;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct UndoRemovePostOrComment {
to: PublicUrl,
object: RemovePostOrComment,
cc: [Url; 1],
#[serde(rename = "type")]
kind: UndoType,
#[serde(flatten)]
common: ActivityCommonFields,
}
#[async_trait::async_trait(?Send)]
impl ActivityHandlerNew for UndoRemovePostOrComment {
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_activity(self.common())?;
verify_person_in_community(&self.common().actor, &self.cc, context, request_counter).await?;
verify_mod_action(&self.common.actor, self.cc[0].clone(), context).await?;
self.object.verify(context, request_counter).await?;
// dont check that actor and object.actor are identical, so that one mod can
// undo the action of another
Ok(())
}
async fn receive(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
match get_or_fetch_and_insert_post_or_comment(&self.object.object, context, request_counter)
.await?
{
PostOrComment::Post(post) => {
let removed_post = blocking(context.pool(), move |conn| {
Post::update_removed(conn, post.id, false)
})
.await??;
send_post_message(removed_post.id, UserOperationCrud::EditPost, context).await
}
PostOrComment::Comment(comment) => {
let removed_comment = blocking(context.pool(), move |conn| {
Comment::update_removed(conn, comment.id, false)
})
.await??;
send_comment_message(
removed_comment.id,
vec![],
UserOperationCrud::EditComment,
context,
)
.await
}
}
}
fn common(&self) -> &ActivityCommonFields {
&self.common
}
}

View file

@ -1,6 +1,6 @@
use crate::activities::{ use crate::activities::{
comment::send_websocket_message as send_comment_websocket_message, comment::send_websocket_message as send_comment_message,
post::send_websocket_message as send_post_websocket_message, post::send_websocket_message as send_post_message,
}; };
use lemmy_api_common::blocking; use lemmy_api_common::blocking;
use lemmy_apub::{ use lemmy_apub::{
@ -60,7 +60,7 @@ async fn like_or_dislike_comment(
}) })
.await??; .await??;
send_comment_websocket_message( send_comment_message(
comment_id, comment_id,
vec![], vec![],
UserOperation::CreateCommentLike, UserOperation::CreateCommentLike,
@ -91,7 +91,7 @@ async fn like_or_dislike_post(
}) })
.await??; .await??;
send_post_websocket_message(post.id, UserOperation::CreatePostLike, context).await send_post_message(post.id, UserOperation::CreatePostLike, context).await
} }
pub(in crate::activities::post_or_comment) async fn receive_undo_like_or_dislike( pub(in crate::activities::post_or_comment) async fn receive_undo_like_or_dislike(
@ -125,7 +125,7 @@ async fn undo_like_or_dislike_comment(
}) })
.await??; .await??;
send_comment_websocket_message( send_comment_message(
comment.id, comment.id,
vec![], vec![],
UserOperation::CreateCommentLike, UserOperation::CreateCommentLike,
@ -148,5 +148,5 @@ async fn undo_like_or_dislike_post(
PostLike::remove(conn, person_id, post_id) PostLike::remove(conn, person_id, post_id)
}) })
.await??; .await??;
send_post_websocket_message(post.id, UserOperation::CreatePostLike, context).await send_post_message(post.id, UserOperation::CreatePostLike, context).await
} }

View file

@ -1,12 +1,5 @@
use crate::activities::{ use crate::activities::{
comment::{ comment::{create::CreateComment, update::UpdateComment},
create::CreateComment,
delete::DeleteComment,
remove::RemoveComment,
undo_delete::UndoDeleteComment,
undo_remove::UndoRemoveComment,
update::UpdateComment,
},
community::{ community::{
add_mod::AddMod, add_mod::AddMod,
announce::AnnounceActivity, announce::AnnounceActivity,
@ -20,19 +13,16 @@ use crate::activities::{
update::UpdateCommunity, update::UpdateCommunity,
}, },
following::{accept::AcceptFollowCommunity, follow::FollowCommunity, undo::UndoFollowCommunity}, following::{accept::AcceptFollowCommunity, follow::FollowCommunity, undo::UndoFollowCommunity},
post::{ post::{create::CreatePost, update::UpdatePost},
create::CreatePost,
delete::DeletePost,
remove::RemovePost,
undo_delete::UndoDeletePost,
undo_remove::UndoRemovePost,
update::UpdatePost,
},
post_or_comment::{ post_or_comment::{
delete::DeletePostOrComment,
dislike::DislikePostOrComment, dislike::DislikePostOrComment,
like::LikePostOrComment, like::LikePostOrComment,
remove::RemovePostOrComment,
undo_delete::UndoDeletePostOrComment,
undo_dislike::UndoDislikePostOrComment, undo_dislike::UndoDislikePostOrComment,
undo_like::UndoLikePostOrComment, undo_like::UndoLikePostOrComment,
undo_remove::UndoRemovePostOrComment,
}, },
private_message::{ private_message::{
create::CreatePrivateMessage, create::CreatePrivateMessage,
@ -64,20 +54,16 @@ pub enum GroupInboxActivities {
UndoFollowCommunity(UndoFollowCommunity), UndoFollowCommunity(UndoFollowCommunity),
CreateComment(CreateComment), CreateComment(CreateComment),
UpdateComment(UpdateComment), UpdateComment(UpdateComment),
DeleteComment(DeleteComment),
UndoDeleteComment(UndoDeleteComment),
RemoveComment(RemoveComment),
UndoRemoveComment(UndoRemoveComment),
CreatePost(CreatePost), CreatePost(CreatePost),
UpdatePost(UpdatePost), UpdatePost(UpdatePost),
DeletePost(DeletePost),
UndoDeletePost(UndoDeletePost),
RemovePost(RemovePost),
UndoRemovePost(UndoRemovePost),
LikePostOrComment(LikePostOrComment), LikePostOrComment(LikePostOrComment),
DislikePostOrComment(DislikePostOrComment), DislikePostOrComment(DislikePostOrComment),
UndoLikePostOrComment(UndoLikePostOrComment), UndoLikePostOrComment(UndoLikePostOrComment),
UndoDislikePostOrComment(UndoDislikePostOrComment), UndoDislikePostOrComment(UndoDislikePostOrComment),
DeletePostOrComment(DeletePostOrComment),
UndoDeletePostOrComment(UndoDeletePostOrComment),
RemovePostOrComment(RemovePostOrComment),
UndoRemovePostOrComment(UndoRemovePostOrComment),
UpdateCommunity(Box<UpdateCommunity>), UpdateCommunity(Box<UpdateCommunity>),
DeleteCommunity(DeleteCommunity), DeleteCommunity(DeleteCommunity),
RemoveCommunity(RemoveCommunity), RemoveCommunity(RemoveCommunity),
@ -97,20 +83,16 @@ pub enum SharedInboxActivities {
UndoFollowCommunity(UndoFollowCommunity), UndoFollowCommunity(UndoFollowCommunity),
CreateComment(CreateComment), CreateComment(CreateComment),
UpdateComment(UpdateComment), UpdateComment(UpdateComment),
DeleteComment(DeleteComment),
UndoDeleteComment(UndoDeleteComment),
RemoveComment(RemoveComment),
UndoRemoveComment(UndoRemoveComment),
CreatePost(CreatePost), CreatePost(CreatePost),
UpdatePost(UpdatePost), UpdatePost(UpdatePost),
DeletePost(DeletePost),
UndoDeletePost(UndoDeletePost),
RemovePost(RemovePost),
UndoRemovePost(UndoRemovePost),
LikePostOrComment(LikePostOrComment), LikePostOrComment(LikePostOrComment),
DislikePostOrComment(DislikePostOrComment), DislikePostOrComment(DislikePostOrComment),
UndoDislikePostOrComment(UndoDislikePostOrComment), UndoDislikePostOrComment(UndoDislikePostOrComment),
UndoLikePostOrComment(UndoLikePostOrComment), UndoLikePostOrComment(UndoLikePostOrComment),
DeletePostOrComment(DeletePostOrComment),
UndoDeletePostOrComment(UndoDeletePostOrComment),
RemovePostOrComment(RemovePostOrComment),
UndoRemovePostOrComment(UndoRemovePostOrComment),
UpdateCommunity(Box<UpdateCommunity>), UpdateCommunity(Box<UpdateCommunity>),
DeleteCommunity(DeleteCommunity), DeleteCommunity(DeleteCommunity),
RemoveCommunity(RemoveCommunity), RemoveCommunity(RemoveCommunity),

View file

@ -58,9 +58,7 @@ async fn receive_activity<'a, T>(
where where
T: ActivityHandlerNew + Clone + Deserialize<'a> + Serialize + std::fmt::Debug + Send + 'static, T: ActivityHandlerNew + Clone + Deserialize<'a> + Serialize + std::fmt::Debug + Send + 'static,
{ {
let activity = serde_json::from_str::<T>(activity); let activity = serde_json::from_str::<T>(activity)?;
dbg!(&activity);
let activity = activity?;
let activity_data = activity.common(); let activity_data = activity.common();
// TODO: which order to check things? // TODO: which order to check things?
// Do nothing if we received the same activity before // Do nothing if we received the same activity before