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,
123 #[tracing::instrument(skip_all)]
124 pub(in crate::activities) async fn receive_undo_remove_action(
127 context: &LemmyContext,
128 ) -> Result<(), LemmyError> {
129 use UserOperationCrud::*;
130 match DeletableObjects::read_from_db(object, context).await? {
131 DeletableObjects::Community(community) => {
133 return Err(LemmyError::from_message(
134 "Only local admin can restore community",
137 let form = ModRemoveCommunityForm {
138 mod_person_id: actor.id,
139 community_id: community.id,
140 removed: Some(false),
144 ModRemoveCommunity::create(context.pool(), &form).await?;
145 let deleted_community = Community::update(
148 &CommunityUpdateForm::builder().removed(Some(false)).build(),
151 send_community_ws_message(deleted_community.id, EditCommunity, None, None, context).await?;
153 DeletableObjects::Post(post) => {
154 let form = ModRemovePostForm {
155 mod_person_id: actor.id,
157 removed: Some(false),
160 ModRemovePost::create(context.pool(), &form).await?;
161 let removed_post = Post::update(
164 &PostUpdateForm::builder().removed(Some(false)).build(),
167 send_post_ws_message(removed_post.id, EditPost, None, None, context).await?;
169 DeletableObjects::Comment(comment) => {
170 let form = ModRemoveCommentForm {
171 mod_person_id: actor.id,
172 comment_id: comment.id,
173 removed: Some(false),
176 ModRemoveComment::create(context.pool(), &form).await?;
177 let removed_comment = Comment::update(
180 &CommentUpdateForm::builder().removed(Some(false)).build(),
183 send_comment_ws_message_simple(removed_comment.id, EditComment, context).await?;
185 DeletableObjects::PrivateMessage(_) => unimplemented!(),
191 #[async_trait::async_trait(?Send)]
192 impl GetCommunity for UndoDelete {
193 #[tracing::instrument(skip_all)]
194 async fn get_community(
196 context: &LemmyContext,
197 request_counter: &mut i32,
198 ) -> Result<ApubCommunity, LemmyError> {
199 self.object.get_community(context, request_counter).await