3 community::announce::GetCommunity,
4 deletion::{receive_delete_action, verify_delete_activity, DeletableObjects},
10 objects::{community::ApubCommunity, person::ApubPerson},
11 protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete},
13 use activitypub_federation::{core::object_id::ObjectId, data::Data, traits::ActivityHandler};
14 use activitystreams_kinds::activity::UndoType;
15 use lemmy_api_common::utils::blocking;
16 use lemmy_db_schema::{
18 comment::{Comment, CommentUpdateForm},
19 community::{Community, CommunityUpdateForm},
24 ModRemoveCommunityForm,
28 post::{Post, PostUpdateForm},
32 use lemmy_utils::error::LemmyError;
33 use lemmy_websocket::{
34 send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message},
40 #[async_trait::async_trait(?Send)]
41 impl ActivityHandler for UndoDelete {
42 type DataType = LemmyContext;
43 type Error = LemmyError;
45 fn id(&self) -> &Url {
49 fn actor(&self) -> &Url {
53 #[tracing::instrument(skip_all)]
56 context: &Data<LemmyContext>,
57 request_counter: &mut i32,
58 ) -> Result<(), LemmyError> {
59 let local_site_data = blocking(context.pool(), fetch_local_site_data).await??;
60 check_apub_id_valid(self.id(), &local_site_data, context.settings())
61 .map_err(LemmyError::from_message)?;
62 self.object.verify(context, request_counter).await?;
63 verify_delete_activity(
65 self.object.summary.is_some(),
73 #[tracing::instrument(skip_all)]
76 context: &Data<LemmyContext>,
77 request_counter: &mut i32,
78 ) -> Result<(), LemmyError> {
79 if self.object.summary.is_some() {
80 UndoDelete::receive_undo_remove_action(
83 .dereference(context, local_instance(context), request_counter)
85 self.object.object.id(),
90 receive_delete_action(
91 self.object.object.id(),
103 #[tracing::instrument(skip_all)]
104 pub(in crate::activities::deletion) fn new(
106 object: DeletableObjects,
108 community: Option<&Community>,
109 summary: Option<String>,
110 context: &LemmyContext,
111 ) -> Result<UndoDelete, LemmyError> {
112 let object = Delete::new(actor, object, to.clone(), community, summary, context)?;
114 let id = generate_activity_id(
116 &context.settings().get_protocol_and_hostname(),
118 let cc: Option<Url> = community.map(|c| c.actor_id.clone().into());
120 actor: ObjectId::new(actor.actor_id.clone()),
123 cc: cc.into_iter().collect(),
124 kind: UndoType::Undo,
126 unparsed: Default::default(),
130 #[tracing::instrument(skip_all)]
131 pub(in crate::activities) async fn receive_undo_remove_action(
134 context: &LemmyContext,
135 ) -> Result<(), LemmyError> {
136 use UserOperationCrud::*;
137 match DeletableObjects::read_from_db(object, context).await? {
138 DeletableObjects::Community(community) => {
140 return Err(LemmyError::from_message(
141 "Only local admin can restore community",
144 let form = ModRemoveCommunityForm {
145 mod_person_id: actor.id,
146 community_id: community.id,
147 removed: Some(false),
151 blocking(context.pool(), move |conn| {
152 ModRemoveCommunity::create(conn, &form)
155 let deleted_community = blocking(context.pool(), move |conn| {
159 &CommunityUpdateForm::builder().removed(Some(false)).build(),
163 send_community_ws_message(deleted_community.id, EditCommunity, None, None, context).await?;
165 DeletableObjects::Post(post) => {
166 let form = ModRemovePostForm {
167 mod_person_id: actor.id,
169 removed: Some(false),
172 blocking(context.pool(), move |conn| {
173 ModRemovePost::create(conn, &form)
176 let removed_post = blocking(context.pool(), move |conn| {
180 &PostUpdateForm::builder().removed(Some(false)).build(),
184 send_post_ws_message(removed_post.id, EditPost, None, None, context).await?;
186 DeletableObjects::Comment(comment) => {
187 let form = ModRemoveCommentForm {
188 mod_person_id: actor.id,
189 comment_id: comment.id,
190 removed: Some(false),
193 blocking(context.pool(), move |conn| {
194 ModRemoveComment::create(conn, &form)
197 let removed_comment = blocking(context.pool(), move |conn| {
201 &CommentUpdateForm::builder().removed(Some(false)).build(),
205 send_comment_ws_message_simple(removed_comment.id, EditComment, context).await?;
207 DeletableObjects::PrivateMessage(_) => unimplemented!(),
213 #[async_trait::async_trait(?Send)]
214 impl GetCommunity for UndoDelete {
215 #[tracing::instrument(skip_all)]
216 async fn get_community(
218 context: &LemmyContext,
219 request_counter: &mut i32,
220 ) -> Result<ApubCommunity, LemmyError> {
221 self.object.get_community(context, request_counter).await