3 community::announce::GetCommunity,
4 deletion::{receive_delete_action, verify_delete_activity, DeletableObjects},
8 objects::{community::ApubCommunity, person::ApubPerson},
9 protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete},
11 use activitypub_federation::{core::object_id::ObjectId, data::Data, traits::ActivityHandler};
12 use activitystreams_kinds::activity::UndoType;
13 use lemmy_db_schema::{
15 comment::{Comment, CommentUpdateForm},
16 community::{Community, CommunityUpdateForm},
21 ModRemoveCommunityForm,
25 post::{Post, PostUpdateForm},
29 use lemmy_utils::error::LemmyError;
30 use lemmy_websocket::{
31 send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message},
37 #[async_trait::async_trait(?Send)]
38 impl ActivityHandler for UndoDelete {
39 type DataType = LemmyContext;
40 type Error = LemmyError;
42 fn id(&self) -> &Url {
46 fn actor(&self) -> &Url {
50 #[tracing::instrument(skip_all)]
53 context: &Data<LemmyContext>,
54 request_counter: &mut i32,
55 ) -> Result<(), LemmyError> {
56 self.object.verify(context, request_counter).await?;
57 verify_delete_activity(
59 self.object.summary.is_some(),
67 #[tracing::instrument(skip_all)]
70 context: &Data<LemmyContext>,
71 request_counter: &mut i32,
72 ) -> Result<(), LemmyError> {
73 if self.object.summary.is_some() {
74 UndoDelete::receive_undo_remove_action(
77 .dereference(context, local_instance(context).await, request_counter)
79 self.object.object.id(),
84 receive_delete_action(
85 self.object.object.id(),
97 #[tracing::instrument(skip_all)]
98 pub(in crate::activities::deletion) fn new(
100 object: DeletableObjects,
102 community: Option<&Community>,
103 summary: Option<String>,
104 context: &LemmyContext,
105 ) -> Result<UndoDelete, LemmyError> {
106 let object = Delete::new(actor, object, to.clone(), community, summary, context)?;
108 let id = generate_activity_id(
110 &context.settings().get_protocol_and_hostname(),
112 let cc: Option<Url> = community.map(|c| c.actor_id.clone().into());
114 actor: ObjectId::new(actor.actor_id.clone()),
117 cc: cc.into_iter().collect(),
118 kind: UndoType::Undo,
120 unparsed: Default::default(),
124 #[tracing::instrument(skip_all)]
125 pub(in crate::activities) async fn receive_undo_remove_action(
128 context: &LemmyContext,
129 ) -> Result<(), LemmyError> {
130 use UserOperationCrud::*;
131 match DeletableObjects::read_from_db(object, context).await? {
132 DeletableObjects::Community(community) => {
134 return Err(LemmyError::from_message(
135 "Only local admin can restore community",
138 let form = ModRemoveCommunityForm {
139 mod_person_id: actor.id,
140 community_id: community.id,
141 removed: Some(false),
145 ModRemoveCommunity::create(context.pool(), &form).await?;
146 let deleted_community = Community::update(
149 &CommunityUpdateForm::builder().removed(Some(false)).build(),
152 send_community_ws_message(deleted_community.id, EditCommunity, None, None, context).await?;
154 DeletableObjects::Post(post) => {
155 let form = ModRemovePostForm {
156 mod_person_id: actor.id,
158 removed: Some(false),
161 ModRemovePost::create(context.pool(), &form).await?;
162 let removed_post = Post::update(
165 &PostUpdateForm::builder().removed(Some(false)).build(),
168 send_post_ws_message(removed_post.id, EditPost, None, None, context).await?;
170 DeletableObjects::Comment(comment) => {
171 let form = ModRemoveCommentForm {
172 mod_person_id: actor.id,
173 comment_id: comment.id,
174 removed: Some(false),
177 ModRemoveComment::create(context.pool(), &form).await?;
178 let removed_comment = Comment::update(
181 &CommentUpdateForm::builder().removed(Some(false)).build(),
184 send_comment_ws_message_simple(removed_comment.id, EditComment, context).await?;
186 DeletableObjects::PrivateMessage(_) => unimplemented!(),
192 #[async_trait::async_trait(?Send)]
193 impl GetCommunity for UndoDelete {
194 #[tracing::instrument(skip_all)]
195 async fn get_community(
197 context: &LemmyContext,
198 request_counter: &mut i32,
199 ) -> Result<ApubCommunity, LemmyError> {
200 self.object.get_community(context, request_counter).await