]> Untitled Git - lemmy.git/commitdiff
Rewrite delete activities (#1699)
authorNutomic <me@nutomic.com>
Tue, 17 Aug 2021 18:04:58 +0000 (18:04 +0000)
committerGitHub <noreply@github.com>
Tue, 17 Aug 2021 18:04:58 +0000 (14:04 -0400)
* Limit type/method visibility in apub code

* Simplify db_queries traits by removing generics

* Simplify delete activity implementation

* Rewrite delete activities

* Implement helper functions for websocket message sending

* When receiving delete reason as empty string, change to none

65 files changed:
Cargo.lock
crates/api/src/comment.rs
crates/api/src/post.rs
crates/api/src/private_message.rs
crates/api_crud/src/comment/create.rs
crates/api_crud/src/comment/delete.rs
crates/api_crud/src/comment/update.rs
crates/api_crud/src/community/delete.rs
crates/api_crud/src/community/mod.rs
crates/api_crud/src/community/update.rs
crates/api_crud/src/post/create.rs
crates/api_crud/src/post/delete.rs
crates/api_crud/src/post/update.rs
crates/api_crud/src/private_message/create.rs
crates/api_crud/src/private_message/delete.rs
crates/api_crud/src/private_message/update.rs
crates/apub/src/activities/comment/create_or_update.rs
crates/apub/src/activities/comment/mod.rs
crates/apub/src/activities/community/announce.rs
crates/apub/src/activities/community/mod.rs
crates/apub/src/activities/community/update.rs
crates/apub/src/activities/deletion/delete.rs
crates/apub/src/activities/deletion/mod.rs
crates/apub/src/activities/deletion/undo_delete.rs
crates/apub/src/activities/post/create_or_update.rs
crates/apub/src/activities/post/mod.rs
crates/apub/src/activities/private_message/create_or_update.rs
crates/apub/src/activities/private_message/delete.rs
crates/apub/src/activities/private_message/mod.rs
crates/apub/src/activities/private_message/undo_delete.rs
crates/apub/src/activities/removal/remove.rs
crates/apub/src/activities/removal/undo_remove.rs
crates/apub/src/activities/send/comment.rs [deleted file]
crates/apub/src/activities/send/community.rs
crates/apub/src/activities/send/mod.rs
crates/apub/src/activities/send/post.rs [deleted file]
crates/apub/src/activities/voting/mod.rs
crates/apub/src/extensions/context.rs
crates/apub/src/extensions/signatures.rs
crates/apub/src/fetcher/community.rs
crates/apub/src/fetcher/mod.rs
crates/apub/src/fetcher/objects.rs
crates/apub/src/fetcher/person.rs
crates/apub/src/http/inbox_enums.rs
crates/apub/src/lib.rs
crates/apub/src/migrations.rs
crates/apub/src/objects/mod.rs
crates/db_queries/src/lib.rs
crates/db_queries/src/source/activity.rs
crates/db_queries/src/source/comment.rs
crates/db_queries/src/source/comment_report.rs
crates/db_queries/src/source/community.rs
crates/db_queries/src/source/local_user.rs
crates/db_queries/src/source/moderator.rs
crates/db_queries/src/source/password_reset_request.rs
crates/db_queries/src/source/person.rs
crates/db_queries/src/source/person_mention.rs
crates/db_queries/src/source/post.rs
crates/db_queries/src/source/post_report.rs
crates/db_queries/src/source/private_message.rs
crates/db_queries/src/source/site.rs
crates/websocket/Cargo.toml
crates/websocket/src/lib.rs
crates/websocket/src/messages.rs
crates/websocket/src/send.rs [new file with mode: 0644]

index 34431d3ad760c398c2fdb1f8b3ace1cf68e22477..844d49e1045860e08186171d777bc517655c5a08 100644 (file)
@@ -1944,6 +1944,8 @@ dependencies = [
  "lemmy_api_common",
  "lemmy_db_queries",
  "lemmy_db_schema",
+ "lemmy_db_views",
+ "lemmy_db_views_actor",
  "lemmy_utils",
  "log",
  "rand 0.8.4",
index f92e679f7afe4b455a239f42d8234d8d353f7625..06510251f61f2308de9b077064f5462f9943726b 100644 (file)
@@ -18,7 +18,7 @@ use lemmy_db_queries::{source::comment::Comment_, Likeable, Saveable};
 use lemmy_db_schema::{source::comment::*, LocalUserId};
 use lemmy_db_views::{comment_view::CommentView, local_user_view::LocalUserView};
 use lemmy_utils::{ApiError, ConnectionId, LemmyError};
-use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
+use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperation};
 use std::convert::TryInto;
 
 #[async_trait::async_trait(?Send)]
@@ -206,26 +206,15 @@ impl Perform for CreateCommentLike {
       .await?;
     }
 
-    // Have to refetch the comment to get the current state
-    let comment_id = data.comment_id;
-    let person_id = local_user_view.person.id;
-    let liked_comment = blocking(context.pool(), move |conn| {
-      CommentView::read(conn, comment_id, Some(person_id))
-    })
-    .await??;
-
-    let res = CommentResponse {
-      comment_view: liked_comment,
-      recipient_ids,
-      form_id: None,
-    };
-
-    context.chat_server().do_send(SendComment {
-      op: UserOperation::CreateCommentLike,
-      comment: res.clone(),
+    send_comment_ws_message(
+      data.comment_id,
+      UserOperation::CreateCommentLike,
       websocket_id,
-    });
-
-    Ok(res)
+      None,
+      Some(local_user_view.person.id),
+      recipient_ids,
+      context,
+    )
+    .await
   }
 }
index 684f64798e2252a6e74badc6f4b95f0baa4fb5d3..3de027313d2be0ffe11403af1a00e0a65c5c2310 100644 (file)
@@ -24,7 +24,7 @@ use lemmy_db_queries::{source::post::Post_, Crud, Likeable, Saveable};
 use lemmy_db_schema::source::{moderator::*, post::*};
 use lemmy_db_views::post_view::PostView;
 use lemmy_utils::{ApiError, ConnectionId, LemmyError};
-use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation};
+use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperation};
 use std::convert::TryInto;
 
 #[async_trait::async_trait(?Send)]
@@ -96,23 +96,14 @@ impl Perform for CreatePostLike {
     // Mark the post as read
     mark_post_as_read(person_id, post_id, context.pool()).await?;
 
-    let post_id = data.post_id;
-    let person_id = local_user_view.person.id;
-    let post_view = blocking(context.pool(), move |conn| {
-      PostView::read(conn, post_id, Some(person_id))
-    })
-    .await?
-    .map_err(|_| ApiError::err("couldnt_find_post"))?;
-
-    let res = PostResponse { post_view };
-
-    context.chat_server().do_send(SendPost {
-      op: UserOperation::CreatePostLike,
-      post: res.clone(),
+    send_post_ws_message(
+      data.post_id,
+      UserOperation::CreatePostLike,
       websocket_id,
-    });
-
-    Ok(res)
+      Some(local_user_view.person.id),
+      context,
+    )
+    .await
   }
 }
 
@@ -171,22 +162,14 @@ impl Perform for LockPost {
     )
     .await?;
 
-    // Refetch the post
-    let post_id = data.post_id;
-    let post_view = blocking(context.pool(), move |conn| {
-      PostView::read(conn, post_id, Some(local_user_view.person.id))
-    })
-    .await??;
-
-    let res = PostResponse { post_view };
-
-    context.chat_server().do_send(SendPost {
-      op: UserOperation::LockPost,
-      post: res.clone(),
+    send_post_ws_message(
+      data.post_id,
+      UserOperation::LockPost,
       websocket_id,
-    });
-
-    Ok(res)
+      Some(local_user_view.person.id),
+      context,
+    )
+    .await
   }
 }
 
@@ -249,22 +232,14 @@ impl Perform for StickyPost {
     )
     .await?;
 
-    // Refetch the post
-    let post_id = data.post_id;
-    let post_view = blocking(context.pool(), move |conn| {
-      PostView::read(conn, post_id, Some(local_user_view.person.id))
-    })
-    .await??;
-
-    let res = PostResponse { post_view };
-
-    context.chat_server().do_send(SendPost {
-      op: UserOperation::StickyPost,
-      post: res.clone(),
+    send_post_ws_message(
+      data.post_id,
+      UserOperation::StickyPost,
       websocket_id,
-    });
-
-    Ok(res)
+      Some(local_user_view.person.id),
+      context,
+    )
+    .await
   }
 }
 
index 54bc3eb0cb4fa79d6690d1fd863769ce139354a3..f23bf71cdc99fa400c411e1fcf3b6ede51098548 100644 (file)
@@ -7,9 +7,8 @@ use lemmy_api_common::{
 };
 use lemmy_db_queries::{source::private_message::PrivateMessage_, Crud};
 use lemmy_db_schema::source::private_message::PrivateMessage;
-use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::PrivateMessageView};
 use lemmy_utils::{ApiError, ConnectionId, LemmyError};
-use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation};
+use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperation};
 
 #[async_trait::async_trait(?Send)]
 impl Perform for MarkPrivateMessageAsRead {
@@ -43,32 +42,7 @@ impl Perform for MarkPrivateMessageAsRead {
     .map_err(|_| ApiError::err("couldnt_update_private_message"))?;
 
     // No need to send an apub update
-    let private_message_id = data.private_message_id;
-    let private_message_view = blocking(context.pool(), move |conn| {
-      PrivateMessageView::read(conn, private_message_id)
-    })
-    .await??;
-
-    let res = PrivateMessageResponse {
-      private_message_view,
-    };
-
-    // Send notifications to the local recipient, if one exists
-    let recipient_id = orig_private_message.recipient_id;
-    if let Ok(local_recipient) = blocking(context.pool(), move |conn| {
-      LocalUserView::read_person(conn, recipient_id)
-    })
-    .await?
-    {
-      let local_recipient_id = local_recipient.local_user.id;
-      context.chat_server().do_send(SendUserRoomMessage {
-        op: UserOperation::MarkPrivateMessageAsRead,
-        response: res.clone(),
-        local_recipient_id,
-        websocket_id,
-      });
-    }
-
-    Ok(res)
+    let op = UserOperation::MarkPrivateMessageAsRead;
+    send_pm_ws_message(data.private_message_id, op, websocket_id, context).await
   }
 }
index 5a6fec81c1688ecf7fa8487a435af0c2fa927118..a479969a734a565ca193e8514c804bfc32af0c2c 100644 (file)
@@ -20,14 +20,13 @@ use lemmy_apub::{
 };
 use lemmy_db_queries::{source::comment::Comment_, Crud, Likeable};
 use lemmy_db_schema::source::comment::*;
-use lemmy_db_views::comment_view::CommentView;
 use lemmy_utils::{
   utils::{remove_slurs, scrape_text_for_mentions},
   ApiError,
   ConnectionId,
   LemmyError,
 };
-use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperationCrud};
+use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperationCrud};
 
 #[async_trait::async_trait(?Send)]
 impl PerformCrud for CreateComment {
@@ -137,37 +136,25 @@ impl PerformCrud for CreateComment {
     )
     .await?;
 
-    let person_id = local_user_view.person.id;
-    let mut comment_view = blocking(context.pool(), move |conn| {
-      CommentView::read(conn, inserted_comment.id, Some(person_id))
-    })
-    .await??;
-
     // If its a comment to yourself, mark it as read
-    let comment_id = comment_view.comment.id;
-    if local_user_view.person.id == comment_view.get_recipient_id() {
+    if local_user_view.person.id == inserted_comment.creator_id {
+      let comment_id = inserted_comment.id;
       blocking(context.pool(), move |conn| {
         Comment::update_read(conn, comment_id, true)
       })
       .await?
       .map_err(|_| ApiError::err("couldnt_update_comment"))?;
-      comment_view.comment.read = true;
     }
 
-    let mut res = CommentResponse {
-      comment_view,
-      recipient_ids,
-      form_id: data.form_id.to_owned(),
-    };
-
-    context.chat_server().do_send(SendComment {
-      op: UserOperationCrud::CreateComment,
-      comment: res.clone(),
+    send_comment_ws_message(
+      inserted_comment.id,
+      UserOperationCrud::CreateComment,
       websocket_id,
-    });
-
-    res.recipient_ids = Vec::new(); // Necessary to avoid doubles
-
-    Ok(res)
+      data.form_id.to_owned(),
+      Some(local_user_view.person.id),
+      recipient_ids,
+      context,
+    )
+    .await
   }
 }
index e2ec3080ea87e5900dd1a675716383e8bc946b71..85917846e40f6c3192979c9e4eb6631135a6eb41 100644 (file)
@@ -8,12 +8,12 @@ use lemmy_api_common::{
   is_mod_or_admin,
   send_local_notifs,
 };
-use lemmy_apub::ApubObjectType;
-use lemmy_db_queries::{source::comment::Comment_, Crud, DeleteableOrRemoveable};
-use lemmy_db_schema::source::{comment::*, moderator::*};
+use lemmy_apub::activities::deletion::{send_apub_delete, send_apub_remove};
+use lemmy_db_queries::{source::comment::Comment_, Crud};
+use lemmy_db_schema::source::{comment::*, community::Community, moderator::*, post::Post};
 use lemmy_db_views::comment_view::CommentView;
 use lemmy_utils::{ApiError, ConnectionId, LemmyError};
-use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperationCrud};
+use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperationCrud};
 
 #[async_trait::async_trait(?Send)]
 impl PerformCrud for DeleteComment {
@@ -47,63 +47,48 @@ impl PerformCrud for DeleteComment {
 
     // Do the delete
     let deleted = data.deleted;
-    let mut updated_comment = blocking(context.pool(), move |conn| {
+    let updated_comment = blocking(context.pool(), move |conn| {
       Comment::update_deleted(conn, comment_id, deleted)
     })
     .await?
     .map_err(|_| ApiError::err("couldnt_update_comment"))?;
 
     // Send the apub message
-    if deleted {
-      updated_comment = updated_comment.blank_out_deleted_or_removed_info();
-      updated_comment
-        .send_delete(&local_user_view.person, context)
-        .await?;
-    } else {
-      updated_comment
-        .send_undo_delete(&local_user_view.person, context)
-        .await?;
-    }
-
-    // Refetch it
-    let comment_id = data.comment_id;
-    let person_id = local_user_view.person.id;
-    let mut comment_view = blocking(context.pool(), move |conn| {
-      CommentView::read(conn, comment_id, Some(person_id))
+    let community = blocking(context.pool(), move |conn| {
+      Community::read(conn, orig_comment.post.community_id)
     })
     .await??;
+    send_apub_delete(
+      &local_user_view.person,
+      &community,
+      updated_comment.ap_id.clone().into(),
+      deleted,
+      context,
+    )
+    .await?;
 
-    // Blank out deleted or removed info
-    if deleted {
-      comment_view.comment = comment_view.comment.blank_out_deleted_or_removed_info();
-    }
-
-    // Build the recipients
-    let comment_view_2 = comment_view.clone();
-    let mentions = vec![];
+    let post_id = updated_comment.post_id;
+    let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
     let recipient_ids = send_local_notifs(
-      mentions,
+      vec![],
       updated_comment,
       local_user_view.person.clone(),
-      comment_view_2.post,
+      post,
       context.pool(),
       false,
     )
     .await?;
 
-    let res = CommentResponse {
-      comment_view,
-      recipient_ids,
-      form_id: None, // TODO a comment delete might clear forms?
-    };
-
-    context.chat_server().do_send(SendComment {
-      op: UserOperationCrud::DeleteComment,
-      comment: res.clone(),
+    send_comment_ws_message(
+      data.comment_id,
+      UserOperationCrud::DeleteComment,
       websocket_id,
-    });
-
-    Ok(res)
+      None, // TODO a comment delete might clear forms?
+      Some(local_user_view.person.id),
+      recipient_ids,
+      context,
+    )
+    .await
   }
 }
 
@@ -142,7 +127,7 @@ impl PerformCrud for RemoveComment {
 
     // Do the remove
     let removed = data.removed;
-    let mut updated_comment = blocking(context.pool(), move |conn| {
+    let updated_comment = blocking(context.pool(), move |conn| {
       Comment::update_removed(conn, comment_id, removed)
     })
     .await?
@@ -161,56 +146,41 @@ impl PerformCrud for RemoveComment {
     .await??;
 
     // Send the apub message
-    if removed {
-      updated_comment = updated_comment.blank_out_deleted_or_removed_info();
-      updated_comment
-        .send_remove(&local_user_view.person, context)
-        .await?;
-    } else {
-      updated_comment
-        .send_undo_remove(&local_user_view.person, context)
-        .await?;
-    }
-
-    // Refetch it
-    let comment_id = data.comment_id;
-    let person_id = local_user_view.person.id;
-    let mut comment_view = blocking(context.pool(), move |conn| {
-      CommentView::read(conn, comment_id, Some(person_id))
+    let community = blocking(context.pool(), move |conn| {
+      Community::read(conn, orig_comment.post.community_id)
     })
     .await??;
+    send_apub_remove(
+      &local_user_view.person,
+      &community,
+      updated_comment.ap_id.clone().into(),
+      data.reason.clone().unwrap_or_else(|| "".to_string()),
+      removed,
+      context,
+    )
+    .await?;
 
-    // Blank out deleted or removed info
-    if removed {
-      comment_view.comment = comment_view.comment.blank_out_deleted_or_removed_info();
-    }
-
-    // Build the recipients
-    let comment_view_2 = comment_view.clone();
-
-    let mentions = vec![];
+    let post_id = updated_comment.post_id;
+    let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
     let recipient_ids = send_local_notifs(
-      mentions,
+      vec![],
       updated_comment,
       local_user_view.person.clone(),
-      comment_view_2.post,
+      post,
       context.pool(),
       false,
     )
     .await?;
 
-    let res = CommentResponse {
-      comment_view,
-      recipient_ids,
-      form_id: None, // TODO maybe this might clear other forms
-    };
-
-    context.chat_server().do_send(SendComment {
-      op: UserOperationCrud::RemoveComment,
-      comment: res.clone(),
+    send_comment_ws_message(
+      data.comment_id,
+      UserOperationCrud::RemoveComment,
       websocket_id,
-    });
-
-    Ok(res)
+      None, // TODO maybe this might clear other forms
+      Some(local_user_view.person.id),
+      recipient_ids,
+      context,
+    )
+    .await
   }
 }
index d0a0e397143c06e70f9d86f051a3f650987e9a97..ee2e7e28e591fa3c71db4e3fe7251235703962d5 100644 (file)
@@ -11,7 +11,7 @@ use lemmy_apub::activities::{
   comment::create_or_update::CreateOrUpdateComment,
   CreateOrUpdateType,
 };
-use lemmy_db_queries::{source::comment::Comment_, DeleteableOrRemoveable};
+use lemmy_db_queries::source::comment::Comment_;
 use lemmy_db_schema::source::comment::*;
 use lemmy_db_views::comment_view::CommentView;
 use lemmy_utils::{
@@ -20,7 +20,7 @@ use lemmy_utils::{
   ConnectionId,
   LemmyError,
 };
-use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperationCrud};
+use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperationCrud};
 
 #[async_trait::async_trait(?Send)]
 impl PerformCrud for EditComment {
@@ -83,30 +83,15 @@ impl PerformCrud for EditComment {
     )
     .await?;
 
-    let comment_id = data.comment_id;
-    let person_id = local_user_view.person.id;
-    let mut comment_view = blocking(context.pool(), move |conn| {
-      CommentView::read(conn, comment_id, Some(person_id))
-    })
-    .await??;
-
-    // Blank out deleted or removed info
-    if comment_view.comment.deleted || comment_view.comment.removed {
-      comment_view.comment = comment_view.comment.blank_out_deleted_or_removed_info();
-    }
-
-    let res = CommentResponse {
-      comment_view,
-      recipient_ids,
-      form_id: data.form_id.to_owned(),
-    };
-
-    context.chat_server().do_send(SendComment {
-      op: UserOperationCrud::EditComment,
-      comment: res.clone(),
+    send_comment_ws_message(
+      data.comment_id,
+      UserOperationCrud::EditComment,
       websocket_id,
-    });
-
-    Ok(res)
+      data.form_id.to_owned(),
+      None,
+      recipient_ids,
+      context,
+    )
+    .await
   }
 }
index 62fb0f38fa2224f4a4d3a71c03b5861a3115571d..b957b7d6edc741a6e352ede399358593a9d05672 100644 (file)
@@ -1,18 +1,15 @@
-use crate::{community::send_community_websocket, PerformCrud};
+use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{blocking, community::*, get_local_user_view_from_jwt, is_admin};
-use lemmy_apub::CommunityType;
-use lemmy_db_queries::{source::community::Community_, Crud, DeleteableOrRemoveable};
+use lemmy_apub::activities::deletion::{send_apub_delete, send_apub_remove};
+use lemmy_db_queries::{source::community::Community_, Crud};
 use lemmy_db_schema::source::{
   community::*,
   moderator::{ModRemoveCommunity, ModRemoveCommunityForm},
 };
-use lemmy_db_views_actor::{
-  community_moderator_view::CommunityModeratorView,
-  community_view::CommunityView,
-};
+use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView;
 use lemmy_utils::{utils::naive_from_unix, ApiError, ConnectionId, LemmyError};
-use lemmy_websocket::{LemmyContext, UserOperationCrud};
+use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud};
 
 #[async_trait::async_trait(?Send)]
 impl PerformCrud for DeleteCommunity {
@@ -48,39 +45,23 @@ impl PerformCrud for DeleteCommunity {
     .map_err(|_| ApiError::err("couldnt_update_community"))?;
 
     // Send apub messages
-    if deleted {
-      updated_community
-        .blank_out_deleted_or_removed_info()
-        .send_delete(local_user_view.person.to_owned(), context)
-        .await?;
-    } else {
-      updated_community
-        .send_undo_delete(local_user_view.person.to_owned(), context)
-        .await?;
-    }
-
-    let community_id = data.community_id;
-    let person_id = local_user_view.person.id;
-    let mut community_view = blocking(context.pool(), move |conn| {
-      CommunityView::read(conn, community_id, Some(person_id))
-    })
-    .await??;
-
-    // Blank out deleted or removed info
-    if deleted {
-      community_view.community = community_view.community.blank_out_deleted_or_removed_info();
-    }
-
-    let res = CommunityResponse { community_view };
-
-    send_community_websocket(
-      &res,
+    send_apub_delete(
+      &local_user_view.person,
+      &updated_community,
+      updated_community.actor_id.clone().into(),
+      deleted,
       context,
-      websocket_id,
-      UserOperationCrud::DeleteCommunity,
-    );
+    )
+    .await?;
 
-    Ok(res)
+    send_community_ws_message(
+      data.community_id,
+      UserOperationCrud::DeleteCommunity,
+      websocket_id,
+      Some(local_user_view.person.id),
+      context,
+    )
+    .await
   }
 }
 
@@ -123,36 +104,23 @@ impl PerformCrud for RemoveCommunity {
     .await??;
 
     // Apub messages
-    if removed {
-      updated_community
-        .blank_out_deleted_or_removed_info()
-        .send_remove(context)
-        .await?;
-    } else {
-      updated_community.send_undo_remove(context).await?;
-    }
-
-    let community_id = data.community_id;
-    let person_id = local_user_view.person.id;
-    let mut community_view = blocking(context.pool(), move |conn| {
-      CommunityView::read(conn, community_id, Some(person_id))
-    })
-    .await??;
-
-    // Blank out deleted or removed info
-    if removed {
-      community_view.community = community_view.community.blank_out_deleted_or_removed_info();
-    }
-
-    let res = CommunityResponse { community_view };
-
-    send_community_websocket(
-      &res,
+    send_apub_remove(
+      &local_user_view.person,
+      &updated_community,
+      updated_community.actor_id.clone().into(),
+      data.reason.clone().unwrap_or_else(|| "".to_string()),
+      removed,
       context,
-      websocket_id,
-      UserOperationCrud::RemoveCommunity,
-    );
+    )
+    .await?;
 
-    Ok(res)
+    send_community_ws_message(
+      data.community_id,
+      UserOperationCrud::RemoveCommunity,
+      websocket_id,
+      Some(local_user_view.person.id),
+      context,
+    )
+    .await
   }
 }
index 9098cb541e8da9e6e9edade95492664632e3afe3..7168323761acf1865cb9f84c3cfba68be3ace373 100644 (file)
@@ -1,27 +1,4 @@
-use actix_web::web::Data;
-use lemmy_api_common::community::CommunityResponse;
-use lemmy_utils::ConnectionId;
-use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperationCrud};
-
 mod create;
 mod delete;
 mod read;
 mod update;
-
-pub(in crate::community) fn send_community_websocket(
-  res: &CommunityResponse,
-  context: &Data<LemmyContext>,
-  websocket_id: Option<ConnectionId>,
-  op: UserOperationCrud,
-) {
-  // Strip out the person id and subscribed when sending to others
-  let mut res_sent = res.clone();
-  res_sent.community_view.subscribed = false;
-
-  context.chat_server().do_send(SendCommunityRoomMessage {
-    op,
-    response: res_sent,
-    community_id: res.community_view.community.id,
-    websocket_id,
-  });
-}
index 49de1cfd744246eb2c22a708944c93645d9ae410..2a99c76db5e6fc46760987283eba97c1c51a352a 100644 (file)
@@ -1,4 +1,4 @@
-use crate::{community::send_community_websocket, PerformCrud};
+use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
   blocking,
@@ -6,18 +6,15 @@ use lemmy_api_common::{
   get_local_user_view_from_jwt,
 };
 use lemmy_apub::CommunityType;
-use lemmy_db_queries::{diesel_option_overwrite_to_url, Crud, DeleteableOrRemoveable};
+use lemmy_db_queries::{diesel_option_overwrite_to_url, Crud};
 use lemmy_db_schema::{
   naive_now,
   source::community::{Community, CommunityForm},
   PersonId,
 };
-use lemmy_db_views_actor::{
-  community_moderator_view::CommunityModeratorView,
-  community_view::CommunityView,
-};
+use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView;
 use lemmy_utils::{utils::check_slurs_opt, ApiError, ConnectionId, LemmyError};
-use lemmy_websocket::{LemmyContext, UserOperationCrud};
+use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud};
 
 #[async_trait::async_trait(?Send)]
 impl PerformCrud for EditCommunity {
@@ -76,27 +73,7 @@ impl PerformCrud for EditCommunity {
       .send_update(local_user_view.person.to_owned(), context)
       .await?;
 
-    let community_id = data.community_id;
-    let person_id = local_user_view.person.id;
-    let mut community_view = blocking(context.pool(), move |conn| {
-      CommunityView::read(conn, community_id, Some(person_id))
-    })
-    .await??;
-
-    // Blank out deleted or removed info
-    if community_view.community.deleted || community_view.community.removed {
-      community_view.community = community_view.community.blank_out_deleted_or_removed_info();
-    }
-
-    let res = CommunityResponse { community_view };
-
-    send_community_websocket(
-      &res,
-      context,
-      websocket_id,
-      UserOperationCrud::EditCommunity,
-    );
-
-    Ok(res)
+    let op = UserOperationCrud::EditCommunity;
+    send_community_ws_message(data.community_id, op, websocket_id, None, context).await
   }
 }
index f041a00b1b0896d71e8164ffcabbd180f46c8764..28c7396896fc78188e0a1be160a0690587375948 100644 (file)
@@ -19,7 +19,6 @@ use lemmy_apub::{
 };
 use lemmy_db_queries::{source::post::Post_, Crud, Likeable};
 use lemmy_db_schema::source::post::*;
-use lemmy_db_views::post_view::PostView;
 use lemmy_utils::{
   request::fetch_iframely_and_pictrs_data,
   utils::{check_slurs, check_slurs_opt, clean_url_params, is_valid_post_title},
@@ -27,7 +26,7 @@ use lemmy_utils::{
   ConnectionId,
   LemmyError,
 };
-use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperationCrud};
+use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud};
 
 #[async_trait::async_trait(?Send)]
 impl PerformCrud for CreatePost {
@@ -129,22 +128,13 @@ impl PerformCrud for CreatePost {
     )
     .await?;
 
-    // Refetch the view
-    let inserted_post_id = inserted_post.id;
-    let post_view = blocking(context.pool(), move |conn| {
-      PostView::read(conn, inserted_post_id, Some(local_user_view.person.id))
-    })
-    .await?
-    .map_err(|_| ApiError::err("couldnt_find_post"))?;
-
-    let res = PostResponse { post_view };
-
-    context.chat_server().do_send(SendPost {
-      op: UserOperationCrud::CreatePost,
-      post: res.clone(),
+    send_post_ws_message(
+      inserted_post.id,
+      UserOperationCrud::CreatePost,
       websocket_id,
-    });
-
-    Ok(res)
+      Some(local_user_view.person.id),
+      context,
+    )
+    .await
   }
 }
index cf48757d3f6105c8747728760ec5f584c184a130..c0ef351229c731bff1e93983afb98b7f0393c98f 100644 (file)
@@ -7,12 +7,11 @@ use lemmy_api_common::{
   is_mod_or_admin,
   post::*,
 };
-use lemmy_apub::ApubObjectType;
-use lemmy_db_queries::{source::post::Post_, Crud, DeleteableOrRemoveable};
-use lemmy_db_schema::source::{moderator::*, post::*};
-use lemmy_db_views::post_view::PostView;
+use lemmy_apub::activities::deletion::{send_apub_delete, send_apub_remove};
+use lemmy_db_queries::{source::post::Post_, Crud};
+use lemmy_db_schema::source::{community::Community, moderator::*, post::*};
 use lemmy_utils::{ApiError, ConnectionId, LemmyError};
-use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperationCrud};
+use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud};
 
 #[async_trait::async_trait(?Send)]
 impl PerformCrud for DeletePost {
@@ -50,37 +49,27 @@ impl PerformCrud for DeletePost {
     .await??;
 
     // apub updates
-    if deleted {
-      updated_post
-        .blank_out_deleted_or_removed_info()
-        .send_delete(&local_user_view.person, context)
-        .await?;
-    } else {
-      updated_post
-        .send_undo_delete(&local_user_view.person, context)
-        .await?;
-    }
-
-    // Refetch the post
-    let post_id = data.post_id;
-    let mut post_view = blocking(context.pool(), move |conn| {
-      PostView::read(conn, post_id, Some(local_user_view.person.id))
+    let community = blocking(context.pool(), move |conn| {
+      Community::read(conn, orig_post.community_id)
     })
     .await??;
+    send_apub_delete(
+      &local_user_view.person,
+      &community,
+      updated_post.ap_id.into(),
+      deleted,
+      context,
+    )
+    .await?;
 
-    if deleted {
-      post_view.post = post_view.post.blank_out_deleted_or_removed_info();
-    }
-
-    let res = PostResponse { post_view };
-
-    context.chat_server().do_send(SendPost {
-      op: UserOperationCrud::DeletePost,
-      post: res.clone(),
+    send_post_ws_message(
+      data.post_id,
+      UserOperationCrud::DeletePost,
       websocket_id,
-    });
-
-    Ok(res)
+      Some(local_user_view.person.id),
+      context,
+    )
+    .await
   }
 }
 
@@ -135,38 +124,27 @@ impl PerformCrud for RemovePost {
     .await??;
 
     // apub updates
-    if removed {
-      updated_post
-        .blank_out_deleted_or_removed_info()
-        .send_remove(&local_user_view.person, context)
-        .await?;
-    } else {
-      updated_post
-        .send_undo_remove(&local_user_view.person, context)
-        .await?;
-    }
-
-    // Refetch the post
-    let post_id = data.post_id;
-    let person_id = local_user_view.person.id;
-    let mut post_view = blocking(context.pool(), move |conn| {
-      PostView::read(conn, post_id, Some(person_id))
+    let community = blocking(context.pool(), move |conn| {
+      Community::read(conn, orig_post.community_id)
     })
     .await??;
+    send_apub_remove(
+      &local_user_view.person,
+      &community,
+      updated_post.ap_id.into(),
+      data.reason.clone().unwrap_or_else(|| "".to_string()),
+      removed,
+      context,
+    )
+    .await?;
 
-    // Blank out deleted or removed info
-    if removed {
-      post_view.post = post_view.post.blank_out_deleted_or_removed_info();
-    }
-
-    let res = PostResponse { post_view };
-
-    context.chat_server().do_send(SendPost {
-      op: UserOperationCrud::RemovePost,
-      post: res.clone(),
+    send_post_ws_message(
+      data.post_id,
+      UserOperationCrud::RemovePost,
       websocket_id,
-    });
-
-    Ok(res)
+      Some(local_user_view.person.id),
+      context,
+    )
+    .await
   }
 }
index c9fe7e3320b511c57a1fbae87df7e89004f0e217..4b63ebd2c448d43a1c45834091520620f5dcb5b0 100644 (file)
@@ -2,9 +2,8 @@ use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{blocking, check_community_ban, get_local_user_view_from_jwt, post::*};
 use lemmy_apub::activities::{post::create_or_update::CreateOrUpdatePost, CreateOrUpdateType};
-use lemmy_db_queries::{source::post::Post_, Crud, DeleteableOrRemoveable};
+use lemmy_db_queries::{source::post::Post_, Crud};
 use lemmy_db_schema::{naive_now, source::post::*};
-use lemmy_db_views::post_view::PostView;
 use lemmy_utils::{
   request::fetch_iframely_and_pictrs_data,
   utils::{check_slurs_opt, clean_url_params, is_valid_post_title},
@@ -12,7 +11,7 @@ use lemmy_utils::{
   ConnectionId,
   LemmyError,
 };
-use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperationCrud};
+use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud};
 
 #[async_trait::async_trait(?Send)]
 impl PerformCrud for EditPost {
@@ -100,25 +99,13 @@ impl PerformCrud for EditPost {
     )
     .await?;
 
-    let post_id = data.post_id;
-    let mut post_view = blocking(context.pool(), move |conn| {
-      PostView::read(conn, post_id, Some(local_user_view.person.id))
-    })
-    .await??;
-
-    // Blank out deleted info
-    if post_view.post.deleted || post_view.post.removed {
-      post_view.post = post_view.post.blank_out_deleted_or_removed_info();
-    }
-
-    let res = PostResponse { post_view };
-
-    context.chat_server().do_send(SendPost {
-      op: UserOperationCrud::EditPost,
-      post: res.clone(),
+    send_post_ws_message(
+      data.post_id,
+      UserOperationCrud::EditPost,
       websocket_id,
-    });
-
-    Ok(res)
+      Some(local_user_view.person.id),
+      context,
+    )
+    .await
   }
 }
index 1da6466dfa7484084212f401f5c02fdcb08089e9..aa0bc8f4c40051fa010dd660cde70667dd15ad59 100644 (file)
@@ -16,9 +16,9 @@ use lemmy_apub::{
 };
 use lemmy_db_queries::{source::private_message::PrivateMessage_, Crud};
 use lemmy_db_schema::source::private_message::{PrivateMessage, PrivateMessageForm};
-use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::PrivateMessageView};
+use lemmy_db_views::local_user_view::LocalUserView;
 use lemmy_utils::{utils::remove_slurs, ApiError, ConnectionId, LemmyError};
-use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperationCrud};
+use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
 
 #[async_trait::async_trait(?Send)]
 impl PerformCrud for CreatePrivateMessage {
@@ -78,36 +78,27 @@ impl PerformCrud for CreatePrivateMessage {
     )
     .await?;
 
-    let private_message_view = blocking(context.pool(), move |conn| {
-      PrivateMessageView::read(conn, inserted_private_message.id)
-    })
-    .await??;
-
-    let res = PrivateMessageResponse {
-      private_message_view,
-    };
+    let res = send_pm_ws_message(
+      inserted_private_message.id,
+      UserOperationCrud::CreatePrivateMessage,
+      websocket_id,
+      context,
+    )
+    .await?;
 
-    // Send notifications to the local recipient, if one exists
-    let recipient_id = data.recipient_id;
-    if let Ok(local_recipient) = blocking(context.pool(), move |conn| {
-      LocalUserView::read_person(conn, recipient_id)
-    })
-    .await?
-    {
+    // Send email to the local recipient, if one exists
+    if res.private_message_view.recipient.local {
+      let recipient_id = data.recipient_id;
+      let local_recipient = blocking(context.pool(), move |conn| {
+        LocalUserView::read_person(conn, recipient_id)
+      })
+      .await??;
       send_email_to_user(
         &local_recipient,
         "Private Message from",
         "Private Message",
         &content_slurs_removed,
       );
-
-      let local_recipient_id = local_recipient.local_user.id;
-      context.chat_server().do_send(SendUserRoomMessage {
-        op: UserOperationCrud::CreatePrivateMessage,
-        response: res.clone(),
-        local_recipient_id,
-        websocket_id,
-      });
     }
 
     Ok(res)
index 78dcd931122cd609d602dbaa8a126674caaeab6d..6cd2b44f2085871d24d50872f18a79f6e75ee9b1 100644 (file)
@@ -11,9 +11,8 @@ use lemmy_apub::activities::private_message::{
 };
 use lemmy_db_queries::{source::private_message::PrivateMessage_, Crud, DeleteableOrRemoveable};
 use lemmy_db_schema::source::private_message::PrivateMessage;
-use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::PrivateMessageView};
 use lemmy_utils::{ApiError, ConnectionId, LemmyError};
-use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperationCrud};
+use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
 
 #[async_trait::async_trait(?Send)]
 impl PerformCrud for DeletePrivateMessage {
@@ -59,39 +58,7 @@ impl PerformCrud for DeletePrivateMessage {
         .await?;
     }
 
-    let private_message_id = data.private_message_id;
-    let mut private_message_view = blocking(context.pool(), move |conn| {
-      PrivateMessageView::read(conn, private_message_id)
-    })
-    .await??;
-
-    // Blank out deleted or removed info
-    if deleted {
-      private_message_view.private_message = private_message_view
-        .private_message
-        .blank_out_deleted_or_removed_info();
-    }
-
-    let res = PrivateMessageResponse {
-      private_message_view,
-    };
-
-    // Send notifications to the local recipient, if one exists
-    let recipient_id = orig_private_message.recipient_id;
-    if let Ok(local_recipient) = blocking(context.pool(), move |conn| {
-      LocalUserView::read_person(conn, recipient_id)
-    })
-    .await?
-    {
-      let local_recipient_id = local_recipient.local_user.id;
-      context.chat_server().do_send(SendUserRoomMessage {
-        op: UserOperationCrud::DeletePrivateMessage,
-        response: res.clone(),
-        local_recipient_id,
-        websocket_id,
-      });
-    }
-
-    Ok(res)
+    let op = UserOperationCrud::DeletePrivateMessage;
+    send_pm_ws_message(data.private_message_id, op, websocket_id, context).await
   }
 }
index 5f5f7b845b2ca71e2fe9113de80b3bff88672c4d..72ca4fbbf2d15e0c09bfe9281f6a0da739840dc0 100644 (file)
@@ -9,11 +9,10 @@ use lemmy_apub::activities::{
   private_message::create_or_update::CreateOrUpdatePrivateMessage,
   CreateOrUpdateType,
 };
-use lemmy_db_queries::{source::private_message::PrivateMessage_, Crud, DeleteableOrRemoveable};
+use lemmy_db_queries::{source::private_message::PrivateMessage_, Crud};
 use lemmy_db_schema::source::private_message::PrivateMessage;
-use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::PrivateMessageView};
 use lemmy_utils::{utils::remove_slurs, ApiError, ConnectionId, LemmyError};
-use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperationCrud};
+use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
 
 #[async_trait::async_trait(?Send)]
 impl PerformCrud for EditPrivateMessage {
@@ -55,39 +54,7 @@ impl PerformCrud for EditPrivateMessage {
     )
     .await?;
 
-    let private_message_id = data.private_message_id;
-    let mut private_message_view = blocking(context.pool(), move |conn| {
-      PrivateMessageView::read(conn, private_message_id)
-    })
-    .await??;
-
-    // Blank out deleted or removed info
-    if private_message_view.private_message.deleted {
-      private_message_view.private_message = private_message_view
-        .private_message
-        .blank_out_deleted_or_removed_info();
-    }
-
-    let res = PrivateMessageResponse {
-      private_message_view,
-    };
-
-    // Send notifications to the local recipient, if one exists
-    let recipient_id = orig_private_message.recipient_id;
-    if let Ok(local_recipient) = blocking(context.pool(), move |conn| {
-      LocalUserView::read_person(conn, recipient_id)
-    })
-    .await?
-    {
-      let local_recipient_id = local_recipient.local_user.id;
-      context.chat_server().do_send(SendUserRoomMessage {
-        op: UserOperationCrud::EditPrivateMessage,
-        response: res.clone(),
-        local_recipient_id,
-        websocket_id,
-      });
-    }
-
-    Ok(res)
+    let op = UserOperationCrud::EditPrivateMessage;
+    send_pm_ws_message(data.private_message_id, op, websocket_id, context).await
   }
 }
index bfc1b7fe6d4544ed63f85b4a032a5b91d200d689..cb9b2349781f43f26642d1ed7ba65299fc1affac 100644 (file)
@@ -1,6 +1,6 @@
 use crate::{
   activities::{
-    comment::{collect_non_local_mentions, get_notif_recipients, send_websocket_message},
+    comment::{collect_non_local_mentions, get_notif_recipients},
     community::announce::AnnouncableActivities,
     extract_community,
     generate_activity_id,
@@ -24,7 +24,7 @@ use lemmy_apub_lib::{
 use lemmy_db_queries::Crud;
 use lemmy_db_schema::source::{comment::Comment, community::Community, person::Person, post::Post};
 use lemmy_utils::LemmyError;
-use lemmy_websocket::{LemmyContext, UserOperationCrud};
+use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperationCrud};
 use serde::{Deserialize, Serialize};
 use url::Url;
 
@@ -116,7 +116,11 @@ impl ActivityHandler for CreateOrUpdateComment {
       CreateOrUpdateType::Create => UserOperationCrud::CreateComment,
       CreateOrUpdateType::Update => UserOperationCrud::EditComment,
     };
-    send_websocket_message(comment.id, recipients, notif_type, context).await
+    send_comment_ws_message(
+      comment.id, notif_type, None, None, None, recipients, context,
+    )
+    .await?;
+    Ok(())
   }
 
   fn common(&self) -> &ActivityCommonFields {
index e7499718cb8e0b829c9be35cb2591d72ef8f92f3..228a5f804c518d0acc6e3b69f7d5fc550797f3f2 100644 (file)
@@ -5,21 +5,19 @@ use activitystreams::{
 };
 use anyhow::anyhow;
 use itertools::Itertools;
-use lemmy_api_common::{blocking, comment::CommentResponse, send_local_notifs, WebFingerResponse};
+use lemmy_api_common::{blocking, send_local_notifs, WebFingerResponse};
 use lemmy_db_queries::{Crud, DbPool};
 use lemmy_db_schema::{
   source::{comment::Comment, community::Community, person::Person, post::Post},
-  CommentId,
   LocalUserId,
 };
-use lemmy_db_views::comment_view::CommentView;
 use lemmy_utils::{
   request::{retry, RecvError},
   settings::structs::Settings,
   utils::{scrape_text_for_mentions, MentionData},
   LemmyError,
 };
-use lemmy_websocket::{messages::SendComment, LemmyContext};
+use lemmy_websocket::LemmyContext;
 use log::debug;
 use reqwest::Client;
 use url::Url;
@@ -45,37 +43,6 @@ async fn get_notif_recipients(
   send_local_notifs(mentions, comment.clone(), actor, post, context.pool(), true).await
 }
 
-// TODO: in many call sites we are setting an empty vec for recipient_ids, we should get the actual
-//       recipient actors from somewhere
-pub(crate) async fn send_websocket_message<
-  OP: ToString + Send + lemmy_websocket::OperationType + 'static,
->(
-  comment_id: CommentId,
-  recipient_ids: Vec<LocalUserId>,
-  op: OP,
-  context: &LemmyContext,
-) -> Result<(), LemmyError> {
-  // Refetch the view
-  let comment_view = blocking(context.pool(), move |conn| {
-    CommentView::read(conn, comment_id, None)
-  })
-  .await??;
-
-  let res = CommentResponse {
-    comment_view,
-    recipient_ids,
-    form_id: None,
-  };
-
-  context.chat_server().do_send(SendComment {
-    op,
-    comment: res,
-    websocket_id: None,
-  });
-
-  Ok(())
-}
-
 pub struct MentionsAndAddresses {
   pub ccs: Vec<Url>,
   pub inboxes: Vec<Url>,
index fc3bebfedf58cd70ea890168f8e7ff15bfa25b76..734fed00e61ba1f8d7b45efa1802ef06720a12d7 100644 (file)
@@ -7,16 +7,10 @@ use crate::{
       list_community_follower_inboxes,
       undo_block_user::UndoBlockUserFromCommunity,
     },
-    deletion::{
-      delete::DeletePostCommentOrCommunity,
-      undo_delete::UndoDeletePostCommentOrCommunity,
-    },
+    deletion::{delete::Delete, undo_delete::UndoDelete},
     generate_activity_id,
     post::create_or_update::CreateOrUpdatePost,
-    removal::{
-      remove::RemovePostCommentCommunityOrMod,
-      undo_remove::UndoRemovePostCommentOrCommunity,
-    },
+    removal::{remove::RemoveMod, undo_remove::UndoRemovePostCommentOrCommunity},
     verify_activity,
     verify_community,
     voting::{undo_vote::UndoVote, vote::Vote},
@@ -43,13 +37,13 @@ pub enum AnnouncableActivities {
   CreateOrUpdatePost(Box<CreateOrUpdatePost>),
   Vote(Vote),
   UndoVote(UndoVote),
-  DeletePostCommentOrCommunity(DeletePostCommentOrCommunity),
-  UndoDeletePostCommentOrCommunity(UndoDeletePostCommentOrCommunity),
-  RemovePostCommentCommunityOrMod(RemovePostCommentCommunityOrMod),
+  Delete(Delete),
+  UndoDelete(UndoDelete),
   UndoRemovePostCommentOrCommunity(UndoRemovePostCommentOrCommunity),
   BlockUserFromCommunity(BlockUserFromCommunity),
   UndoBlockUserFromCommunity(UndoBlockUserFromCommunity),
   AddMod(AddMod),
+  RemoveMod(RemoveMod),
 }
 
 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
index 4151471ad1634a2d90c83e829f54681b925ea28b..49cf9615f527c3b45c416619b5d5caf9342c6988 100644 (file)
@@ -1,10 +1,8 @@
 use crate::{check_is_apub_id_valid, CommunityType};
 use itertools::Itertools;
-use lemmy_api_common::{blocking, community::CommunityResponse};
-use lemmy_db_schema::{source::community::Community, CommunityId};
-use lemmy_db_views_actor::community_view::CommunityView;
+use lemmy_db_schema::source::community::Community;
 use lemmy_utils::{settings::structs::Settings, LemmyError};
-use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext};
+use lemmy_websocket::LemmyContext;
 use url::Url;
 
 pub mod add_mod;
@@ -13,30 +11,6 @@ pub mod block_user;
 pub mod undo_block_user;
 pub mod update;
 
-pub(crate) async fn send_websocket_message<
-  OP: ToString + Send + lemmy_websocket::OperationType + 'static,
->(
-  community_id: CommunityId,
-  op: OP,
-  context: &LemmyContext,
-) -> Result<(), LemmyError> {
-  let community_view = blocking(context.pool(), move |conn| {
-    CommunityView::read(conn, community_id, None)
-  })
-  .await??;
-
-  let res = CommunityResponse { community_view };
-
-  context.chat_server().do_send(SendCommunityRoomMessage {
-    op,
-    response: res,
-    community_id,
-    websocket_id: None,
-  });
-
-  Ok(())
-}
-
 async fn list_community_follower_inboxes(
   community: &Community,
   additional_inboxes: Vec<Url>,
index 964a423889d727d1faa077f945e0ad111f18dc9b..d38d722bfc6a8fc45f8c6bfeb6e4db14f766ff53 100644 (file)
@@ -1,10 +1,5 @@
 use crate::{
-  activities::{
-    community::send_websocket_message,
-    verify_activity,
-    verify_mod_action,
-    verify_person_in_community,
-  },
+  activities::{verify_activity, verify_mod_action, verify_person_in_community},
   objects::community::Group,
 };
 use activitystreams::activity::kind::UpdateType;
@@ -13,7 +8,7 @@ use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler};
 use lemmy_db_queries::{ApubObject, Crud};
 use lemmy_db_schema::source::community::{Community, CommunityForm};
 use lemmy_utils::LemmyError;
-use lemmy_websocket::{LemmyContext, UserOperationCrud};
+use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud};
 use url::Url;
 
 /// This activity is received from a remote community mod, and updates the description or other
@@ -71,12 +66,15 @@ impl ActivityHandler for UpdateCommunity {
     })
     .await??;
 
-    send_websocket_message(
+    send_community_ws_message(
       updated_community.id,
       UserOperationCrud::EditCommunity,
+      None,
+      None,
       context,
     )
-    .await
+    .await?;
+    Ok(())
   }
 
   fn common(&self) -> &ActivityCommonFields {
index d377a6696bdf731945dc93f6694e23527022b090..093919b88e5ce68692afa554396e87dbd4756ea2 100644 (file)
@@ -1,31 +1,48 @@
 use crate::{
   activities::{
-    comment::send_websocket_message as send_comment_message,
-    community::send_websocket_message as send_community_message,
-    post::send_websocket_message as send_post_message,
+    community::announce::AnnouncableActivities,
+    deletion::{
+      receive_delete_action,
+      verify_delete_activity,
+      DeletableObjects,
+      WebsocketMessages,
+    },
+    generate_activity_id,
     verify_activity,
-    verify_mod_action,
-    verify_person_in_community,
-  },
-  fetcher::{
-    community::get_or_fetch_and_upsert_community,
-    objects::get_or_fetch_and_insert_post_or_comment,
-    person::get_or_fetch_and_upsert_person,
   },
+  activity_queue::send_to_community_new,
+  extensions::context::lemmy_context,
+  fetcher::person::get_or_fetch_and_upsert_person,
   ActorType,
-  CommunityType,
-  PostOrComment,
 };
 use activitystreams::activity::kind::DeleteType;
+use anyhow::anyhow;
 use lemmy_api_common::blocking;
-use lemmy_apub_lib::{values::PublicUrl, verify_urls_match, ActivityCommonFields, ActivityHandler};
+use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler};
 use lemmy_db_queries::{
   source::{comment::Comment_, community::Community_, post::Post_},
   Crud,
 };
-use lemmy_db_schema::source::{comment::Comment, community::Community, person::Person, post::Post};
+use lemmy_db_schema::source::{
+  comment::Comment,
+  community::Community,
+  moderator::{
+    ModRemoveComment,
+    ModRemoveCommentForm,
+    ModRemoveCommunity,
+    ModRemoveCommunityForm,
+    ModRemovePost,
+    ModRemovePostForm,
+  },
+  person::Person,
+  post::Post,
+};
 use lemmy_utils::LemmyError;
-use lemmy_websocket::{LemmyContext, UserOperationCrud};
+use lemmy_websocket::{
+  send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message},
+  LemmyContext,
+  UserOperationCrud,
+};
 use url::Url;
 
 /// This is very confusing, because there are four distinct cases to handle:
@@ -38,38 +55,36 @@ use url::Url;
 /// wrapping it in an announce just like other activities, instead of having the community send it.
 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
 #[serde(rename_all = "camelCase")]
-pub struct DeletePostCommentOrCommunity {
-  to: PublicUrl,
+pub struct Delete {
+  pub(in crate::activities::deletion) to: PublicUrl,
   pub(in crate::activities::deletion) object: Url,
-  cc: [Url; 1],
+  pub(in crate::activities::deletion) cc: [Url; 1],
   #[serde(rename = "type")]
-  kind: DeleteType,
+  pub(in crate::activities::deletion) kind: DeleteType,
+  /// If summary is present, this is a mod action (Remove in Lemmy terms). Otherwise, its a user
+  /// deleting their own content.
+  pub(in crate::activities::deletion) summary: Option<String>,
   #[serde(flatten)]
-  common: ActivityCommonFields,
+  pub(in crate::activities::deletion) common: ActivityCommonFields,
 }
 
 #[async_trait::async_trait(?Send)]
-impl ActivityHandler for DeletePostCommentOrCommunity {
+impl ActivityHandler for Delete {
   async fn verify(
     &self,
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
     verify_activity(self.common())?;
-    let object_community =
-      get_or_fetch_and_upsert_community(&self.object, context, request_counter).await;
-    // deleting a community (set counter 0 to only fetch from local db)
-    if object_community.is_ok() {
-      verify_mod_action(&self.common.actor, self.object.clone(), context).await?;
-    }
-    // deleting a post or comment
-    else {
-      verify_person_in_community(&self.common().actor, &self.cc[0], 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)?;
-    }
+    verify_delete_activity(
+      &self.object,
+      &self.cc[0],
+      &self.common,
+      self.summary.is_some(),
+      context,
+      request_counter,
+    )
+    .await?;
     Ok(())
   }
 
@@ -78,55 +93,36 @@ impl ActivityHandler for DeletePostCommentOrCommunity {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    let object_community =
-      get_or_fetch_and_upsert_community(&self.object, context, request_counter).await;
-    // deleting a community
-    if let Ok(community) = object_community {
-      if community.local {
-        // repeat these checks just to be sure
-        verify_person_in_community(&self.common().actor, &self.cc[0], context, request_counter)
-          .await?;
-        verify_mod_action(&self.common.actor, self.object.clone(), context).await?;
-        let mod_ =
-          get_or_fetch_and_upsert_person(&self.common.actor, context, request_counter).await?;
-        community.send_delete(mod_, context).await?;
-      }
-      let deleted_community = blocking(context.pool(), move |conn| {
-        Community::update_deleted(conn, community.id, true)
-      })
-      .await??;
-
-      send_community_message(
-        deleted_community.id,
-        UserOperationCrud::DeleteCommunity,
+    if let Some(reason) = self.summary {
+      // We set reason to empty string if it doesn't exist, to distinguish between delete and
+      // remove. Here we change it back to option, so we don't write it to db.
+      let reason = if reason.is_empty() {
+        None
+      } else {
+        Some(reason)
+      };
+      receive_remove_action(
+        &self.common.actor,
+        &self.object,
+        reason,
         context,
+        request_counter,
+      )
+      .await
+    } else {
+      receive_delete_action(
+        &self.object,
+        &self.common.actor,
+        WebsocketMessages {
+          community: UserOperationCrud::DeleteCommunity,
+          post: UserOperationCrud::DeletePost,
+          comment: UserOperationCrud::DeleteComment,
+        },
+        true,
+        context,
+        request_counter,
       )
       .await
-    }
-    // deleting a post or comment
-    else {
-      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
-        }
-      }
     }
   }
 
@@ -135,25 +131,102 @@ impl ActivityHandler for DeletePostCommentOrCommunity {
   }
 }
 
-async fn get_post_or_comment_actor_id(
+impl Delete {
+  pub(in crate::activities::deletion) async fn send(
+    actor: &Person,
+    community: &Community,
+    object_id: Url,
+    summary: Option<String>,
+    context: &LemmyContext,
+  ) -> Result<(), LemmyError> {
+    let id = generate_activity_id(DeleteType::Delete)?;
+    let delete = Delete {
+      to: PublicUrl::Public,
+      object: object_id,
+      cc: [community.actor_id()],
+      kind: DeleteType::Delete,
+      summary,
+      common: ActivityCommonFields {
+        context: lemmy_context(),
+        id: id.clone(),
+        actor: actor.actor_id(),
+        unparsed: Default::default(),
+      },
+    };
+
+    let activity = AnnouncableActivities::Delete(delete);
+    send_to_community_new(activity, &id, actor, community, vec![], context).await
+  }
+}
+
+pub(in crate::activities) async fn receive_remove_action(
+  actor: &Url,
   object: &Url,
+  reason: Option<String>,
   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()
+) -> Result<(), LemmyError> {
+  let actor = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
+  use UserOperationCrud::*;
+  match DeletableObjects::read_from_db(object, context).await? {
+    DeletableObjects::Community(community) => {
+      if community.local {
+        return Err(anyhow!("Only local admin can remove community").into());
       }
-    };
-  Ok(actor_id)
+      let form = ModRemoveCommunityForm {
+        mod_person_id: actor.id,
+        community_id: community.id,
+        removed: Some(true),
+        reason,
+        expires: None,
+      };
+      blocking(context.pool(), move |conn| {
+        ModRemoveCommunity::create(conn, &form)
+      })
+      .await??;
+      let deleted_community = blocking(context.pool(), move |conn| {
+        Community::update_removed(conn, community.id, true)
+      })
+      .await??;
+
+      send_community_ws_message(deleted_community.id, RemoveCommunity, None, None, context).await?;
+    }
+    DeletableObjects::Post(post) => {
+      let form = ModRemovePostForm {
+        mod_person_id: actor.id,
+        post_id: post.id,
+        removed: Some(true),
+        reason,
+      };
+      blocking(context.pool(), move |conn| {
+        ModRemovePost::create(conn, &form)
+      })
+      .await??;
+      let removed_post = blocking(context.pool(), move |conn| {
+        Post::update_removed(conn, post.id, true)
+      })
+      .await??;
+
+      send_post_ws_message(removed_post.id, RemovePost, None, None, context).await?;
+    }
+    DeletableObjects::Comment(comment) => {
+      let form = ModRemoveCommentForm {
+        mod_person_id: actor.id,
+        comment_id: comment.id,
+        removed: Some(true),
+        reason,
+      };
+      blocking(context.pool(), move |conn| {
+        ModRemoveComment::create(conn, &form)
+      })
+      .await??;
+      let removed_comment = blocking(context.pool(), move |conn| {
+        Comment::update_removed(conn, comment.id, true)
+      })
+      .await??;
+
+      send_comment_ws_message_simple(removed_comment.id, RemoveComment, context).await?;
+    }
+  }
+  Ok(())
 }
index b440edd68da14fc719addf79d41a1d6fd0c7108f..cf73be097654ea98e675e3164535530d56efef29 100644 (file)
@@ -1,2 +1,209 @@
+use crate::{
+  activities::{
+    deletion::{delete::Delete, undo_delete::UndoDelete},
+    verify_mod_action,
+    verify_person_in_community,
+  },
+  fetcher::person::get_or_fetch_and_upsert_person,
+  ActorType,
+};
+use lemmy_api_common::blocking;
+use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields};
+use lemmy_db_queries::{
+  source::{comment::Comment_, community::Community_, post::Post_},
+  ApubObject,
+};
+use lemmy_db_schema::{
+  source::{comment::Comment, community::Community, person::Person, post::Post},
+  DbUrl,
+};
+use lemmy_utils::LemmyError;
+use lemmy_websocket::{
+  send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message},
+  LemmyContext,
+  UserOperationCrud,
+};
+use url::Url;
+
 pub mod delete;
 pub mod undo_delete;
+
+pub async fn send_apub_delete(
+  actor: &Person,
+  community: &Community,
+  object_id: Url,
+  deleted: bool,
+  context: &LemmyContext,
+) -> Result<(), LemmyError> {
+  if deleted {
+    Delete::send(actor, community, object_id, None, context).await
+  } else {
+    UndoDelete::send(actor, community, object_id, None, context).await
+  }
+}
+
+// TODO: remove reason is actually optional in lemmy. we set an empty string in that case, but its
+//       ugly
+pub async fn send_apub_remove(
+  actor: &Person,
+  community: &Community,
+  object_id: Url,
+  reason: String,
+  removed: bool,
+  context: &LemmyContext,
+) -> Result<(), LemmyError> {
+  if removed {
+    Delete::send(actor, community, object_id, Some(reason), context).await
+  } else {
+    UndoDelete::send(actor, community, object_id, Some(reason), context).await
+  }
+}
+
+pub enum DeletableObjects {
+  Community(Box<Community>),
+  Comment(Box<Comment>),
+  Post(Box<Post>),
+}
+
+impl DeletableObjects {
+  pub(crate) async fn read_from_db(
+    ap_id: &Url,
+    context: &LemmyContext,
+  ) -> Result<DeletableObjects, LemmyError> {
+    let id: DbUrl = ap_id.clone().into();
+
+    if let Some(c) = DeletableObjects::read_type_from_db::<Community>(id.clone(), context).await? {
+      return Ok(DeletableObjects::Community(Box::new(c)));
+    }
+    if let Some(p) = DeletableObjects::read_type_from_db::<Post>(id.clone(), context).await? {
+      return Ok(DeletableObjects::Post(Box::new(p)));
+    }
+    if let Some(c) = DeletableObjects::read_type_from_db::<Comment>(id.clone(), context).await? {
+      return Ok(DeletableObjects::Comment(Box::new(c)));
+    }
+    Err(diesel::NotFound.into())
+  }
+
+  // TODO: a method like this should be provided by fetcher module
+  async fn read_type_from_db<Type: ApubObject + Send + 'static>(
+    ap_id: DbUrl,
+    context: &LemmyContext,
+  ) -> Result<Option<Type>, LemmyError> {
+    blocking(context.pool(), move |conn| {
+      Type::read_from_apub_id(conn, &ap_id).ok()
+    })
+    .await
+  }
+}
+
+pub(in crate::activities) async fn verify_delete_activity(
+  object: &Url,
+  cc: &Url,
+  common: &ActivityCommonFields,
+  is_mod_action: bool,
+  context: &LemmyContext,
+  request_counter: &mut i32,
+) -> Result<(), LemmyError> {
+  let object = DeletableObjects::read_from_db(object, context).await?;
+  match object {
+    DeletableObjects::Community(c) => {
+      if c.local {
+        // can only do this check for local community, in remote case it would try to fetch the
+        // deleted community (which fails)
+        verify_person_in_community(&common.actor, cc, context, request_counter).await?;
+      }
+      // community deletion is always a mod (or admin) action
+      verify_mod_action(&common.actor, c.actor_id(), context).await?;
+    }
+    DeletableObjects::Post(p) => {
+      verify_delete_activity_post_or_comment(
+        cc,
+        common,
+        &p.ap_id.into(),
+        is_mod_action,
+        context,
+        request_counter,
+      )
+      .await?;
+    }
+    DeletableObjects::Comment(c) => {
+      verify_delete_activity_post_or_comment(
+        cc,
+        common,
+        &c.ap_id.into(),
+        is_mod_action,
+        context,
+        request_counter,
+      )
+      .await?;
+    }
+  }
+  Ok(())
+}
+
+async fn verify_delete_activity_post_or_comment(
+  cc: &Url,
+  common: &ActivityCommonFields,
+  object_id: &Url,
+  is_mod_action: bool,
+  context: &LemmyContext,
+  request_counter: &mut i32,
+) -> Result<(), LemmyError> {
+  verify_person_in_community(&common.actor, cc, context, request_counter).await?;
+  if is_mod_action {
+    verify_mod_action(&common.actor, cc.clone(), context).await?;
+  } else {
+    // domain of post ap_id and post.creator ap_id are identical, so we just check the former
+    verify_domains_match(&common.actor, object_id)?;
+  }
+  Ok(())
+}
+
+struct WebsocketMessages {
+  community: UserOperationCrud,
+  post: UserOperationCrud,
+  comment: UserOperationCrud,
+}
+
+/// Write deletion or restoring of an object to the database, and send websocket message.
+/// TODO: we should do something similar for receive_remove_action(), but its much more complicated
+///       because of the mod log
+async fn receive_delete_action(
+  object: &Url,
+  actor: &Url,
+  ws_messages: WebsocketMessages,
+  deleted: bool,
+  context: &LemmyContext,
+  request_counter: &mut i32,
+) -> Result<(), LemmyError> {
+  match DeletableObjects::read_from_db(object, context).await? {
+    DeletableObjects::Community(community) => {
+      if community.local {
+        let mod_ = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
+        let object = community.actor_id();
+        send_apub_delete(&mod_, &community.clone(), object, true, context).await?;
+      }
+
+      let community = blocking(context.pool(), move |conn| {
+        Community::update_deleted(conn, community.id, deleted)
+      })
+      .await??;
+      send_community_ws_message(community.id, ws_messages.community, None, None, context).await?;
+    }
+    DeletableObjects::Post(post) => {
+      let deleted_post = blocking(context.pool(), move |conn| {
+        Post::update_deleted(conn, post.id, deleted)
+      })
+      .await??;
+      send_post_ws_message(deleted_post.id, ws_messages.post, None, None, context).await?;
+    }
+    DeletableObjects::Comment(comment) => {
+      let deleted_comment = blocking(context.pool(), move |conn| {
+        Comment::update_deleted(conn, comment.id, deleted)
+      })
+      .await??;
+      send_comment_ws_message_simple(deleted_comment.id, ws_messages.comment, context).await?;
+    }
+  }
+  Ok(())
+}
index e57e6b401c950a320f3c9464322d2b1903df6660..0114acac81aa2c387190c8fcf3b8ea31e58dc42c 100644 (file)
@@ -1,35 +1,39 @@
 use crate::{
   activities::{
-    comment::send_websocket_message as send_comment_message,
-    community::send_websocket_message as send_community_message,
-    deletion::delete::DeletePostCommentOrCommunity,
-    post::send_websocket_message as send_post_message,
+    community::announce::AnnouncableActivities,
+    deletion::{
+      delete::Delete,
+      receive_delete_action,
+      verify_delete_activity,
+      DeletableObjects,
+      WebsocketMessages,
+    },
+    generate_activity_id,
     verify_activity,
-    verify_mod_action,
-    verify_person_in_community,
   },
-  fetcher::{
-    community::get_or_fetch_and_upsert_community,
-    objects::get_or_fetch_and_insert_post_or_comment,
-    person::get_or_fetch_and_upsert_person,
-  },
-  CommunityType,
-  PostOrComment,
+  activity_queue::send_to_community_new,
+  extensions::context::lemmy_context,
+  ActorType,
 };
-use activitystreams::activity::kind::UndoType;
+use activitystreams::activity::kind::{DeleteType, UndoType};
+use anyhow::anyhow;
 use lemmy_api_common::blocking;
-use lemmy_apub_lib::{values::PublicUrl, verify_urls_match, ActivityCommonFields, ActivityHandler};
+use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler};
 use lemmy_db_queries::source::{comment::Comment_, community::Community_, post::Post_};
-use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post};
+use lemmy_db_schema::source::{comment::Comment, community::Community, person::Person, post::Post};
 use lemmy_utils::LemmyError;
-use lemmy_websocket::{LemmyContext, UserOperationCrud};
+use lemmy_websocket::{
+  send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message},
+  LemmyContext,
+  UserOperationCrud,
+};
 use url::Url;
 
 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
 #[serde(rename_all = "camelCase")]
-pub struct UndoDeletePostCommentOrCommunity {
+pub struct UndoDelete {
   to: PublicUrl,
-  object: DeletePostCommentOrCommunity,
+  object: Delete,
   cc: [Url; 1],
   #[serde(rename = "type")]
   kind: UndoType,
@@ -38,7 +42,7 @@ pub struct UndoDeletePostCommentOrCommunity {
 }
 
 #[async_trait::async_trait(?Send)]
-impl ActivityHandler for UndoDeletePostCommentOrCommunity {
+impl ActivityHandler for UndoDelete {
   async fn verify(
     &self,
     context: &LemmyContext,
@@ -46,18 +50,15 @@ impl ActivityHandler for UndoDeletePostCommentOrCommunity {
   ) -> Result<(), LemmyError> {
     verify_activity(self.common())?;
     self.object.verify(context, request_counter).await?;
-    let object_community =
-      get_or_fetch_and_upsert_community(&self.object.object, context, request_counter).await;
-    // restoring a community
-    if object_community.is_ok() {
-      verify_mod_action(&self.common.actor, self.object.object.clone(), context).await?;
-    }
-    // restoring a post or comment
-    else {
-      verify_person_in_community(&self.common().actor, &self.cc[0], context, request_counter)
-        .await?;
-      verify_urls_match(&self.common.actor, &self.object.common().actor)?;
-    }
+    verify_delete_activity(
+      &self.object.object,
+      &self.cc[0],
+      &self.common,
+      self.object.summary.is_some(),
+      context,
+      request_counter,
+    )
+    .await?;
     Ok(())
   }
 
@@ -66,61 +67,101 @@ impl ActivityHandler for UndoDeletePostCommentOrCommunity {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    let object_community =
-      get_or_fetch_and_upsert_community(&self.object.object, context, request_counter).await;
-    // restoring a community
-    if let Ok(community) = object_community {
-      if community.local {
-        // repeat these checks just to be sure
-        verify_person_in_community(&self.common().actor, &self.cc[0], context, request_counter)
-          .await?;
-        verify_mod_action(&self.common.actor, self.object.object.clone(), context).await?;
-        let mod_ =
-          get_or_fetch_and_upsert_person(&self.common.actor, context, request_counter).await?;
-        community.send_undo_delete(mod_, context).await?;
-      }
-      let deleted_community = blocking(context.pool(), move |conn| {
-        Community::update_deleted(conn, community.id, false)
-      })
-      .await??;
-
-      send_community_message(
-        deleted_community.id,
-        UserOperationCrud::EditCommunity,
+    if self.object.summary.is_some() {
+      UndoDelete::receive_undo_remove_action(&self.object.object, context).await
+    } else {
+      receive_delete_action(
+        &self.object.object,
+        &self.common.actor,
+        WebsocketMessages {
+          community: UserOperationCrud::EditCommunity,
+          post: UserOperationCrud::EditPost,
+          comment: UserOperationCrud::EditComment,
+        },
+        false,
         context,
+        request_counter,
       )
       .await
     }
-    // restoring a post or comment
-    else {
-      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
   }
 }
+
+impl UndoDelete {
+  pub(in crate::activities::deletion) async fn send(
+    actor: &Person,
+    community: &Community,
+    object_id: Url,
+    summary: Option<String>,
+    context: &LemmyContext,
+  ) -> Result<(), LemmyError> {
+    let delete = Delete {
+      to: PublicUrl::Public,
+      object: object_id,
+      cc: [community.actor_id()],
+      kind: DeleteType::Delete,
+      summary,
+      common: ActivityCommonFields {
+        context: lemmy_context(),
+        id: generate_activity_id(DeleteType::Delete)?,
+        actor: actor.actor_id(),
+        unparsed: Default::default(),
+      },
+    };
+
+    let id = generate_activity_id(UndoType::Undo)?;
+    let undo = UndoDelete {
+      to: PublicUrl::Public,
+      object: delete,
+      cc: [community.actor_id()],
+      kind: UndoType::Undo,
+      common: ActivityCommonFields {
+        context: lemmy_context(),
+        id: id.clone(),
+        actor: actor.actor_id(),
+        unparsed: Default::default(),
+      },
+    };
+
+    let activity = AnnouncableActivities::UndoDelete(undo);
+    send_to_community_new(activity, &id, actor, community, vec![], context).await
+  }
+
+  pub(in crate::activities) async fn receive_undo_remove_action(
+    object: &Url,
+    context: &LemmyContext,
+  ) -> Result<(), LemmyError> {
+    use UserOperationCrud::*;
+    match DeletableObjects::read_from_db(object, context).await? {
+      DeletableObjects::Community(community) => {
+        if community.local {
+          return Err(anyhow!("Only local admin can restore community").into());
+        }
+        let deleted_community = blocking(context.pool(), move |conn| {
+          Community::update_removed(conn, community.id, false)
+        })
+        .await??;
+        send_community_ws_message(deleted_community.id, EditCommunity, None, None, context).await?;
+      }
+      DeletableObjects::Post(post) => {
+        let removed_post = blocking(context.pool(), move |conn| {
+          Post::update_removed(conn, post.id, false)
+        })
+        .await??;
+        send_post_ws_message(removed_post.id, EditPost, None, None, context).await?;
+      }
+      DeletableObjects::Comment(comment) => {
+        let removed_comment = blocking(context.pool(), move |conn| {
+          Comment::update_removed(conn, comment.id, false)
+        })
+        .await??;
+        send_comment_ws_message_simple(removed_comment.id, EditComment, context).await?;
+      }
+    }
+    Ok(())
+  }
+}
index 94838e16f496df39838f9f4e1334627e59ca11ea..1a9c776896a61c73a67df7e97c6f9d5450bca19c 100644 (file)
@@ -3,7 +3,6 @@ use crate::{
     community::announce::AnnouncableActivities,
     extract_community,
     generate_activity_id,
-    post::send_websocket_message,
     verify_activity,
     verify_mod_action,
     verify_person_in_community,
@@ -27,7 +26,7 @@ use lemmy_apub_lib::{
 use lemmy_db_queries::Crud;
 use lemmy_db_schema::source::{community::Community, person::Person, post::Post};
 use lemmy_utils::LemmyError;
-use lemmy_websocket::{LemmyContext, UserOperationCrud};
+use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud};
 use url::Url;
 
 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
@@ -126,7 +125,8 @@ impl ActivityHandler for CreateOrUpdatePost {
       CreateOrUpdateType::Create => UserOperationCrud::CreatePost,
       CreateOrUpdateType::Update => UserOperationCrud::EditPost,
     };
-    send_websocket_message(post.id, notif_type, context).await
+    send_post_ws_message(post.id, notif_type, None, None, context).await?;
+    Ok(())
   }
 
   fn common(&self) -> &ActivityCommonFields {
index b60348ed0c3bc6879679bf55ee4ef1a5be097b32..e903f52ff15cf96ef8feaff467f6562a82fc988c 100644 (file)
@@ -1,30 +1 @@
-use lemmy_api_common::{blocking, post::PostResponse};
-use lemmy_db_schema::PostId;
-use lemmy_db_views::post_view::PostView;
-use lemmy_utils::LemmyError;
-use lemmy_websocket::{messages::SendPost, LemmyContext};
-
 pub mod create_or_update;
-
-pub(crate) async fn send_websocket_message<
-  OP: ToString + Send + lemmy_websocket::OperationType + 'static,
->(
-  post_id: PostId,
-  op: OP,
-  context: &LemmyContext,
-) -> Result<(), LemmyError> {
-  let post_view = blocking(context.pool(), move |conn| {
-    PostView::read(conn, post_id, None)
-  })
-  .await??;
-
-  let res = PostResponse { post_view };
-
-  context.chat_server().do_send(SendPost {
-    op,
-    post: res,
-    websocket_id: None,
-  });
-
-  Ok(())
-}
index 09582689be35f189b54a0b03292ce04efa2fd35a..cd3c657444a32bd6fb9c94b11da53207addb5ac8 100644 (file)
@@ -1,11 +1,5 @@
 use crate::{
-  activities::{
-    generate_activity_id,
-    private_message::send_websocket_message,
-    verify_activity,
-    verify_person,
-    CreateOrUpdateType,
-  },
+  activities::{generate_activity_id, verify_activity, verify_person, CreateOrUpdateType},
   activity_queue::send_activity_new,
   extensions::context::lemmy_context,
   objects::{private_message::Note, FromApub, ToApub},
@@ -16,7 +10,7 @@ use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandler
 use lemmy_db_queries::Crud;
 use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage};
 use lemmy_utils::LemmyError;
-use lemmy_websocket::{LemmyContext, UserOperationCrud};
+use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
 use url::Url;
 
 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
@@ -83,7 +77,7 @@ impl ActivityHandler for CreateOrUpdatePrivateMessage {
       CreateOrUpdateType::Create => UserOperationCrud::CreatePrivateMessage,
       CreateOrUpdateType::Update => UserOperationCrud::EditPrivateMessage,
     };
-    send_websocket_message(private_message.id, notif_type, context).await?;
+    send_pm_ws_message(private_message.id, notif_type, None, context).await?;
 
     Ok(())
   }
index 4c990a2d177ce4fbffbbb536535ecf8ac953c11d..e6c03093b057c95dab9f8af18304cb6771b030f5 100644 (file)
@@ -1,10 +1,5 @@
 use crate::{
-  activities::{
-    generate_activity_id,
-    private_message::send_websocket_message,
-    verify_activity,
-    verify_person,
-  },
+  activities::{generate_activity_id, verify_activity, verify_person},
   activity_queue::send_activity_new,
   extensions::context::lemmy_context,
   ActorType,
@@ -15,7 +10,7 @@ use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandler
 use lemmy_db_queries::{source::private_message::PrivateMessage_, ApubObject, Crud};
 use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage};
 use lemmy_utils::LemmyError;
-use lemmy_websocket::{LemmyContext, UserOperationCrud};
+use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
 use url::Url;
 
 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
@@ -84,9 +79,10 @@ impl ActivityHandler for DeletePrivateMessage {
     })
     .await??;
 
-    send_websocket_message(
+    send_pm_ws_message(
       deleted_private_message.id,
       UserOperationCrud::DeletePrivateMessage,
+      None,
       context,
     )
     .await?;
index 0c0557286600cab177671114f21ffb8f0a243e35..4bcda7c7b9121da7850562da32e0f1f106d5fbd5 100644 (file)
@@ -1,41 +1,3 @@
-use lemmy_api_common::{blocking, person::PrivateMessageResponse};
-use lemmy_db_schema::PrivateMessageId;
-use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::PrivateMessageView};
-use lemmy_utils::LemmyError;
-use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperationCrud};
-
 pub mod create_or_update;
 pub mod delete;
 pub mod undo_delete;
-
-async fn send_websocket_message(
-  private_message_id: PrivateMessageId,
-  op: UserOperationCrud,
-  context: &LemmyContext,
-) -> Result<(), LemmyError> {
-  let message = blocking(context.pool(), move |conn| {
-    PrivateMessageView::read(conn, private_message_id)
-  })
-  .await??;
-  let res = PrivateMessageResponse {
-    private_message_view: message,
-  };
-
-  // Send notifications to the local recipient, if one exists
-  let recipient_id = res.private_message_view.recipient.id;
-  let local_recipient_id = blocking(context.pool(), move |conn| {
-    LocalUserView::read_person(conn, recipient_id)
-  })
-  .await??
-  .local_user
-  .id;
-
-  context.chat_server().do_send(SendUserRoomMessage {
-    op,
-    response: res,
-    local_recipient_id,
-    websocket_id: None,
-  });
-
-  Ok(())
-}
index 5bbca90e6e28a28b873adf98b2693e10b03a35cb..4cd2a139d0ec16c09caf385cab00a316e137353c 100644 (file)
@@ -1,7 +1,7 @@
 use crate::{
   activities::{
     generate_activity_id,
-    private_message::{delete::DeletePrivateMessage, send_websocket_message},
+    private_message::delete::DeletePrivateMessage,
     verify_activity,
     verify_person,
   },
@@ -20,7 +20,7 @@ use lemmy_apub_lib::{
 use lemmy_db_queries::{source::private_message::PrivateMessage_, ApubObject, Crud};
 use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage};
 use lemmy_utils::LemmyError;
-use lemmy_websocket::{LemmyContext, UserOperationCrud};
+use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
 use url::Url;
 
 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
@@ -104,9 +104,10 @@ impl ActivityHandler for UndoDeletePrivateMessage {
     })
     .await??;
 
-    send_websocket_message(
+    send_pm_ws_message(
       deleted_private_message.id,
       UserOperationCrud::EditPrivateMessage,
+      None,
       context,
     )
     .await?;
index 83aaabc6f1a35598219f4400391e2a442c4e9c5a..1bd6e0a0372379e4c6ac72f217e9ebcde3655ee3 100644 (file)
@@ -1,77 +1,59 @@
 use crate::{
   activities::{
-    comment::send_websocket_message as send_comment_message,
-    community::send_websocket_message as send_community_message,
-    post::send_websocket_message as send_post_message,
+    deletion::{delete::receive_remove_action, verify_delete_activity},
     verify_activity,
     verify_add_remove_moderator_target,
     verify_mod_action,
     verify_person_in_community,
   },
-  fetcher::{
-    community::get_or_fetch_and_upsert_community,
-    objects::get_or_fetch_and_insert_post_or_comment,
-    person::get_or_fetch_and_upsert_person,
-  },
+  fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person},
   CommunityType,
-  PostOrComment,
 };
 use activitystreams::{activity::kind::RemoveType, base::AnyBase};
-use anyhow::anyhow;
 use lemmy_api_common::blocking;
 use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler};
-use lemmy_db_queries::{
-  source::{comment::Comment_, community::Community_, post::Post_},
-  Joinable,
-};
-use lemmy_db_schema::source::{
-  comment::Comment,
-  community::{Community, CommunityModerator, CommunityModeratorForm},
-  post::Post,
-};
+use lemmy_db_queries::Joinable;
+use lemmy_db_schema::source::community::{CommunityModerator, CommunityModeratorForm};
 use lemmy_utils::LemmyError;
-use lemmy_websocket::{LemmyContext, UserOperationCrud};
+use lemmy_websocket::LemmyContext;
 use url::Url;
 
-// TODO: we can probably deduplicate a bunch of code between this and DeletePostCommentOrCommunity
 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
 #[serde(rename_all = "camelCase")]
-pub struct RemovePostCommentCommunityOrMod {
+pub struct RemoveMod {
   to: PublicUrl,
   pub(in crate::activities::removal) object: Url,
   cc: [Url; 1],
   #[serde(rename = "type")]
   kind: RemoveType,
   // if target is set, this is means remove mod from community
-  target: Option<Url>,
+  pub(in crate::activities::removal) target: Option<Url>,
   #[serde(flatten)]
   common: ActivityCommonFields,
 }
 
 #[async_trait::async_trait(?Send)]
-impl ActivityHandler for RemovePostCommentCommunityOrMod {
+impl ActivityHandler for RemoveMod {
   async fn verify(
     &self,
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
     verify_activity(self.common())?;
-    let object_community =
-      get_or_fetch_and_upsert_community(&self.object, context, request_counter).await;
-    // removing a community
-    if object_community.is_ok() {
-      verify_mod_action(&self.common.actor, self.object.clone(), context).await?;
-    }
-    // removing community mod
-    else if let Some(target) = &self.target {
+    if let Some(target) = &self.target {
       verify_person_in_community(&self.common.actor, &self.cc[0], context, request_counter).await?;
       verify_mod_action(&self.common.actor, self.cc[0].clone(), context).await?;
       verify_add_remove_moderator_target(target, self.cc[0].clone())?;
-    }
-    // removing a post or comment
-    else {
-      verify_person_in_community(&self.common.actor, &self.cc[0], context, request_counter).await?;
-      verify_mod_action(&self.common.actor, self.cc[0].clone(), context).await?;
+    } else {
+      verify_delete_activity(
+        &self.object,
+        &self.cc[0],
+        self.common(),
+        true,
+        context,
+        request_counter,
+      )
+      .await?;
     }
     Ok(())
   }
@@ -81,27 +63,7 @@ impl ActivityHandler for RemovePostCommentCommunityOrMod {
     context: &LemmyContext,
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    let object_community =
-      get_or_fetch_and_upsert_community(&self.object, context, request_counter).await;
-    // removing a community
-    if let Ok(community) = object_community {
-      if community.local {
-        return Err(anyhow!("Only local admin can remove community").into());
-      }
-      let deleted_community = blocking(context.pool(), move |conn| {
-        Community::update_removed(conn, community.id, true)
-      })
-      .await??;
-
-      send_community_message(
-        deleted_community.id,
-        UserOperationCrud::RemoveCommunity,
-        context,
-      )
-      .await
-    }
-    // removing community mod
-    else if self.target.is_some() {
+    if self.target.is_some() {
       let community =
         get_or_fetch_and_upsert_community(&self.cc[0], context, request_counter).await?;
       let remove_mod =
@@ -121,31 +83,15 @@ impl ActivityHandler for RemovePostCommentCommunityOrMod {
         .await?;
       // TODO: send websocket notification about removed mod
       Ok(())
-    }
-    // removing a post or comment
-    else {
-      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
-        }
-      }
+    } else {
+      receive_remove_action(
+        &self.common.actor,
+        &self.object,
+        None,
+        context,
+        request_counter,
+      )
+      .await
     }
   }
 
index 003eb4aaa281e237f8dac06c9e76a063f4915606..e2c7ef76f34a64dcecd214c64a9d739b412ba700 100644 (file)
@@ -1,34 +1,20 @@
-use crate::{
-  activities::{
-    comment::send_websocket_message as send_comment_message,
-    community::send_websocket_message as send_community_message,
-    post::send_websocket_message as send_post_message,
-    removal::remove::RemovePostCommentCommunityOrMod,
-    verify_activity,
-    verify_mod_action,
-    verify_person_in_community,
-  },
-  fetcher::{
-    community::get_or_fetch_and_upsert_community,
-    objects::get_or_fetch_and_insert_post_or_comment,
-  },
-  PostOrComment,
+use crate::activities::{
+  deletion::{undo_delete::UndoDelete, verify_delete_activity},
+  removal::remove::RemoveMod,
+  verify_activity,
 };
 use activitystreams::activity::kind::UndoType;
-use anyhow::anyhow;
-use lemmy_api_common::blocking;
 use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler};
-use lemmy_db_queries::source::{comment::Comment_, community::Community_, post::Post_};
-use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post};
 use lemmy_utils::LemmyError;
-use lemmy_websocket::{LemmyContext, UserOperationCrud};
+use lemmy_websocket::LemmyContext;
 use url::Url;
 
 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
 #[serde(rename_all = "camelCase")]
 pub struct UndoRemovePostCommentOrCommunity {
   to: PublicUrl,
-  object: RemovePostCommentCommunityOrMod,
+  // Note, there is no such thing as Undo/Remove/Mod, so we ignore that
+  object: RemoveMod,
   cc: [Url; 1],
   #[serde(rename = "type")]
   kind: UndoType,
@@ -44,74 +30,26 @@ impl ActivityHandler for UndoRemovePostCommentOrCommunity {
     request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
     verify_activity(self.common())?;
-    let object_community =
-      get_or_fetch_and_upsert_community(&self.object.object, context, request_counter).await;
-    // removing a community
-    if object_community.is_ok() {
-      verify_mod_action(&self.common.actor, self.object.object.clone(), context).await?;
-    }
-    // removing a post or comment
-    else {
-      verify_person_in_community(&self.common.actor, &self.cc[0], 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
+
+    verify_delete_activity(
+      &self.object.object,
+      &self.cc[0],
+      self.common(),
+      true,
+      context,
+      request_counter,
+    )
+    .await?;
     Ok(())
   }
 
   async fn receive(
     self,
     context: &LemmyContext,
-    request_counter: &mut i32,
+    _request_counter: &mut i32,
   ) -> Result<(), LemmyError> {
-    let object_community =
-      get_or_fetch_and_upsert_community(&self.object.object, context, request_counter).await;
-    // restoring a community
-    if let Ok(community) = object_community {
-      if community.local {
-        return Err(anyhow!("Only local admin can undo remove community").into());
-      }
-      let deleted_community = blocking(context.pool(), move |conn| {
-        Community::update_removed(conn, community.id, false)
-      })
-      .await??;
-
-      send_community_message(
-        deleted_community.id,
-        UserOperationCrud::EditCommunity,
-        context,
-      )
-      .await
-    }
-    // restoring a post or comment
-    else {
-      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
-        }
-      }
-    }
+    UndoDelete::receive_undo_remove_action(&self.object.object, context).await
   }
 
   fn common(&self) -> &ActivityCommonFields {
diff --git a/crates/apub/src/activities/send/comment.rs b/crates/apub/src/activities/send/comment.rs
deleted file mode 100644 (file)
index 8b44686..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-use crate::{
-  activities::generate_activity_id,
-  activity_queue::send_to_community,
-  extensions::context::lemmy_context,
-  ActorType,
-  ApubObjectType,
-};
-use activitystreams::{
-  activity::{
-    kind::{DeleteType, RemoveType, UndoType},
-    Delete,
-    Remove,
-    Undo,
-  },
-  prelude::*,
-  public,
-};
-use lemmy_api_common::blocking;
-use lemmy_db_queries::Crud;
-use lemmy_db_schema::source::{comment::Comment, community::Community, person::Person, post::Post};
-use lemmy_utils::LemmyError;
-use lemmy_websocket::LemmyContext;
-
-#[async_trait::async_trait(?Send)]
-impl ApubObjectType for Comment {
-  async fn send_delete(&self, creator: &Person, context: &LemmyContext) -> Result<(), LemmyError> {
-    let post_id = self.post_id;
-    let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
-
-    let community_id = post.community_id;
-    let community = blocking(context.pool(), move |conn| {
-      Community::read(conn, community_id)
-    })
-    .await??;
-
-    let mut delete = Delete::new(
-      creator.actor_id.to_owned().into_inner(),
-      self.ap_id.to_owned().into_inner(),
-    );
-    delete
-      .set_many_contexts(lemmy_context())
-      .set_id(generate_activity_id(DeleteType::Delete)?)
-      .set_to(public())
-      .set_many_ccs(vec![community.actor_id()]);
-
-    send_to_community(delete, creator, &community, None, context).await?;
-    Ok(())
-  }
-
-  async fn send_undo_delete(
-    &self,
-    creator: &Person,
-    context: &LemmyContext,
-  ) -> Result<(), LemmyError> {
-    let post_id = self.post_id;
-    let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
-
-    let community_id = post.community_id;
-    let community = blocking(context.pool(), move |conn| {
-      Community::read(conn, community_id)
-    })
-    .await??;
-
-    // Generate a fake delete activity, with the correct object
-    let mut delete = Delete::new(
-      creator.actor_id.to_owned().into_inner(),
-      self.ap_id.to_owned().into_inner(),
-    );
-    delete
-      .set_many_contexts(lemmy_context())
-      .set_id(generate_activity_id(DeleteType::Delete)?)
-      .set_to(public())
-      .set_many_ccs(vec![community.actor_id()]);
-
-    // Undo that fake activity
-    let mut undo = Undo::new(
-      creator.actor_id.to_owned().into_inner(),
-      delete.into_any_base()?,
-    );
-    undo
-      .set_many_contexts(lemmy_context())
-      .set_id(generate_activity_id(UndoType::Undo)?)
-      .set_to(public())
-      .set_many_ccs(vec![community.actor_id()]);
-
-    send_to_community(undo, creator, &community, None, context).await?;
-    Ok(())
-  }
-
-  async fn send_remove(&self, mod_: &Person, context: &LemmyContext) -> Result<(), LemmyError> {
-    let post_id = self.post_id;
-    let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
-
-    let community_id = post.community_id;
-    let community = blocking(context.pool(), move |conn| {
-      Community::read(conn, community_id)
-    })
-    .await??;
-
-    let mut remove = Remove::new(
-      mod_.actor_id.to_owned().into_inner(),
-      self.ap_id.to_owned().into_inner(),
-    );
-    remove
-      .set_many_contexts(lemmy_context())
-      .set_id(generate_activity_id(RemoveType::Remove)?)
-      .set_to(public())
-      .set_many_ccs(vec![community.actor_id()]);
-
-    send_to_community(remove, mod_, &community, None, context).await?;
-    Ok(())
-  }
-
-  async fn send_undo_remove(
-    &self,
-    mod_: &Person,
-    context: &LemmyContext,
-  ) -> Result<(), LemmyError> {
-    let post_id = self.post_id;
-    let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
-
-    let community_id = post.community_id;
-    let community = blocking(context.pool(), move |conn| {
-      Community::read(conn, community_id)
-    })
-    .await??;
-
-    // Generate a fake delete activity, with the correct object
-    let mut remove = Remove::new(
-      mod_.actor_id.to_owned().into_inner(),
-      self.ap_id.to_owned().into_inner(),
-    );
-    remove
-      .set_many_contexts(lemmy_context())
-      .set_id(generate_activity_id(RemoveType::Remove)?)
-      .set_to(public())
-      .set_many_ccs(vec![community.actor_id()]);
-
-    // Undo that fake activity
-    let mut undo = Undo::new(
-      mod_.actor_id.to_owned().into_inner(),
-      remove.into_any_base()?,
-    );
-    undo
-      .set_many_contexts(lemmy_context())
-      .set_id(generate_activity_id(UndoType::Undo)?)
-      .set_to(public())
-      .set_many_ccs(vec![community.actor_id()]);
-
-    send_to_community(undo, mod_, &community, None, context).await?;
-    Ok(())
-  }
-}
index 6f88dd36fb76848c559de8ff8853d845073c60ba..a103f95c6951322724a18b31d4f90b38d59ad0b7 100644 (file)
@@ -12,20 +12,10 @@ use crate::{
 };
 use activitystreams::{
   activity::{
-    kind::{
-      AddType,
-      AnnounceType,
-      BlockType,
-      DeleteType,
-      LikeType,
-      RemoveType,
-      UndoType,
-      UpdateType,
-    },
+    kind::{AddType, AnnounceType, BlockType, RemoveType, UndoType, UpdateType},
     Add,
     Announce,
     Block,
-    Delete,
     OptTargetRefExt,
     Remove,
     Undo,
@@ -97,112 +87,6 @@ impl CommunityType for Community {
     Ok(())
   }
 
-  /// If the creator of a community deletes the community, send this to all followers.
-  ///
-  /// We need to handle deletion by a remote mod separately.
-  async fn send_delete(&self, mod_: Person, context: &LemmyContext) -> Result<(), LemmyError> {
-    // Local mod, send directly from community to followers
-    if self.local {
-      let mut delete = Delete::new(self.actor_id(), self.actor_id());
-      delete
-        .set_many_contexts(lemmy_context())
-        .set_id(generate_activity_id(DeleteType::Delete)?)
-        .set_to(public())
-        .set_many_ccs(vec![self.followers_url()]);
-
-      send_to_community_followers(delete, self, None, context).await?;
-    }
-    // Remote mod, send from mod to community
-    else {
-      let mut delete = Delete::new(mod_.actor_id(), self.actor_id());
-      delete
-        .set_many_contexts(lemmy_context())
-        .set_id(generate_activity_id(DeleteType::Delete)?)
-        .set_to(public())
-        .set_many_ccs(vec![self.actor_id()]);
-
-      send_to_community(delete, &mod_, self, None, context).await?;
-    }
-    Ok(())
-  }
-
-  /// If the creator of a community reverts the deletion of a community, send this to all followers.
-  ///
-  /// We need to handle undelete by a remote mod separately.
-  async fn send_undo_delete(&self, mod_: Person, context: &LemmyContext) -> Result<(), LemmyError> {
-    // Local mod, send directly from community to followers
-    if self.local {
-      let mut delete = Delete::new(self.actor_id(), self.actor_id());
-      delete
-        .set_many_contexts(lemmy_context())
-        .set_id(generate_activity_id(DeleteType::Delete)?)
-        .set_to(public())
-        .set_many_ccs(vec![self.followers_url()]);
-
-      let mut undo = Undo::new(self.actor_id(), delete.into_any_base()?);
-      undo
-        .set_many_contexts(lemmy_context())
-        .set_id(generate_activity_id(UndoType::Undo)?)
-        .set_to(public())
-        .set_many_ccs(vec![self.followers_url()]);
-
-      send_to_community_followers(undo, self, None, context).await?;
-    }
-    // Remote mod, send from mod to community
-    else {
-      let mut delete = Delete::new(mod_.actor_id(), self.actor_id());
-      delete
-        .set_many_contexts(lemmy_context())
-        .set_id(generate_activity_id(DeleteType::Delete)?)
-        .set_to(public())
-        .set_many_ccs(vec![self.actor_id()]);
-
-      let mut undo = Undo::new(mod_.actor_id(), delete.into_any_base()?);
-      undo
-        .set_many_contexts(lemmy_context())
-        .set_id(generate_activity_id(UndoType::Undo)?)
-        .set_to(public())
-        .set_many_ccs(vec![self.actor_id()]);
-
-      send_to_community(undo, &mod_, self, None, context).await?;
-    }
-    Ok(())
-  }
-
-  /// If an admin removes a community, send this to all followers.
-  async fn send_remove(&self, context: &LemmyContext) -> Result<(), LemmyError> {
-    let mut remove = Remove::new(self.actor_id(), self.actor_id());
-    remove
-      .set_many_contexts(lemmy_context())
-      .set_id(generate_activity_id(RemoveType::Remove)?)
-      .set_to(public())
-      .set_many_ccs(vec![self.followers_url()]);
-
-    send_to_community_followers(remove, self, None, context).await?;
-    Ok(())
-  }
-
-  /// If an admin reverts the removal of a community, send this to all followers.
-  async fn send_undo_remove(&self, context: &LemmyContext) -> Result<(), LemmyError> {
-    let mut remove = Remove::new(self.actor_id(), self.actor_id());
-    remove
-      .set_many_contexts(lemmy_context())
-      .set_id(generate_activity_id(RemoveType::Remove)?)
-      .set_to(public())
-      .set_many_ccs(vec![self.followers_url()]);
-
-    // Undo that fake activity
-    let mut undo = Undo::new(self.actor_id(), remove.into_any_base()?);
-    undo
-      .set_many_contexts(lemmy_context())
-      .set_id(generate_activity_id(LikeType::Like)?)
-      .set_to(public())
-      .set_many_ccs(vec![self.followers_url()]);
-
-    send_to_community_followers(undo, self, None, context).await?;
-    Ok(())
-  }
-
   /// Wraps an activity sent to the community in an announce, and then sends the announce to all
   /// community followers.
   ///
index c00ecb1a7d89b382b60b758e7e375703a2bfb61a..a01cddd6da7db6dab96f482ea7948b6cfb283914 100644 (file)
@@ -1,4 +1,2 @@
-pub(crate) mod comment;
 pub(crate) mod community;
 pub(crate) mod person;
-pub(crate) mod post;
diff --git a/crates/apub/src/activities/send/post.rs b/crates/apub/src/activities/send/post.rs
deleted file mode 100644 (file)
index b971366..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-use crate::{
-  activities::generate_activity_id,
-  activity_queue::send_to_community,
-  extensions::context::lemmy_context,
-  ActorType,
-  ApubObjectType,
-};
-use activitystreams::{
-  activity::{
-    kind::{DeleteType, RemoveType, UndoType},
-    Delete,
-    Remove,
-    Undo,
-  },
-  prelude::*,
-  public,
-};
-use lemmy_api_common::blocking;
-use lemmy_db_queries::Crud;
-use lemmy_db_schema::source::{community::Community, person::Person, post::Post};
-use lemmy_utils::LemmyError;
-use lemmy_websocket::LemmyContext;
-
-#[async_trait::async_trait(?Send)]
-impl ApubObjectType for Post {
-  async fn send_delete(&self, creator: &Person, context: &LemmyContext) -> Result<(), LemmyError> {
-    let community_id = self.community_id;
-    let community = blocking(context.pool(), move |conn| {
-      Community::read(conn, community_id)
-    })
-    .await??;
-
-    let mut delete = Delete::new(
-      creator.actor_id.to_owned().into_inner(),
-      self.ap_id.to_owned().into_inner(),
-    );
-    delete
-      .set_many_contexts(lemmy_context())
-      .set_id(generate_activity_id(DeleteType::Delete)?)
-      .set_to(public())
-      .set_many_ccs(vec![community.actor_id()]);
-
-    send_to_community(delete, creator, &community, None, context).await?;
-    Ok(())
-  }
-
-  async fn send_undo_delete(
-    &self,
-    creator: &Person,
-    context: &LemmyContext,
-  ) -> Result<(), LemmyError> {
-    let community_id = self.community_id;
-    let community = blocking(context.pool(), move |conn| {
-      Community::read(conn, community_id)
-    })
-    .await??;
-
-    let mut delete = Delete::new(
-      creator.actor_id.to_owned().into_inner(),
-      self.ap_id.to_owned().into_inner(),
-    );
-    delete
-      .set_many_contexts(lemmy_context())
-      .set_id(generate_activity_id(DeleteType::Delete)?)
-      .set_to(public())
-      .set_many_ccs(vec![community.actor_id()]);
-
-    // Undo that fake activity
-    let mut undo = Undo::new(
-      creator.actor_id.to_owned().into_inner(),
-      delete.into_any_base()?,
-    );
-    undo
-      .set_many_contexts(lemmy_context())
-      .set_id(generate_activity_id(UndoType::Undo)?)
-      .set_to(public())
-      .set_many_ccs(vec![community.actor_id()]);
-
-    send_to_community(undo, creator, &community, None, context).await?;
-    Ok(())
-  }
-
-  async fn send_remove(&self, mod_: &Person, context: &LemmyContext) -> Result<(), LemmyError> {
-    let community_id = self.community_id;
-    let community = blocking(context.pool(), move |conn| {
-      Community::read(conn, community_id)
-    })
-    .await??;
-
-    let mut remove = Remove::new(
-      mod_.actor_id.to_owned().into_inner(),
-      self.ap_id.to_owned().into_inner(),
-    );
-    remove
-      .set_many_contexts(lemmy_context())
-      .set_id(generate_activity_id(RemoveType::Remove)?)
-      .set_to(public())
-      .set_many_ccs(vec![community.actor_id()]);
-
-    send_to_community(remove, mod_, &community, None, context).await?;
-    Ok(())
-  }
-
-  async fn send_undo_remove(
-    &self,
-    mod_: &Person,
-    context: &LemmyContext,
-  ) -> Result<(), LemmyError> {
-    let community_id = self.community_id;
-    let community = blocking(context.pool(), move |conn| {
-      Community::read(conn, community_id)
-    })
-    .await??;
-
-    let mut remove = Remove::new(
-      mod_.actor_id.to_owned().into_inner(),
-      self.ap_id.to_owned().into_inner(),
-    );
-    remove
-      .set_many_contexts(lemmy_context())
-      .set_id(generate_activity_id(RemoveType::Remove)?)
-      .set_to(public())
-      .set_many_ccs(vec![community.actor_id()]);
-
-    // Undo that fake activity
-    let mut undo = Undo::new(
-      mod_.actor_id.to_owned().into_inner(),
-      remove.into_any_base()?,
-    );
-    undo
-      .set_many_contexts(lemmy_context())
-      .set_id(generate_activity_id(UndoType::Undo)?)
-      .set_to(public())
-      .set_many_ccs(vec![community.actor_id()]);
-
-    send_to_community(undo, mod_, &community, None, context).await?;
-    Ok(())
-  }
-}
index 48d9446f8f704829eb7473df9f7f9fd7d35b9bfe..48d44c0eeeac99054728ff436073471c742cb08f 100644 (file)
@@ -1,8 +1,4 @@
-use crate::activities::{
-  comment::send_websocket_message as send_comment_message,
-  post::send_websocket_message as send_post_message,
-  voting::vote::VoteType,
-};
+use crate::activities::voting::vote::VoteType;
 use lemmy_api_common::blocking;
 use lemmy_db_queries::Likeable;
 use lemmy_db_schema::source::{
@@ -11,7 +7,11 @@ use lemmy_db_schema::source::{
   post::{Post, PostLike, PostLikeForm},
 };
 use lemmy_utils::LemmyError;
-use lemmy_websocket::{LemmyContext, UserOperation};
+use lemmy_websocket::{
+  send::{send_comment_ws_message_simple, send_post_ws_message},
+  LemmyContext,
+  UserOperation,
+};
 
 pub mod undo_vote;
 pub mod vote;
@@ -36,13 +36,8 @@ async fn vote_comment(
   })
   .await??;
 
-  send_comment_message(
-    comment_id,
-    vec![],
-    UserOperation::CreateCommentLike,
-    context,
-  )
-  .await
+  send_comment_ws_message_simple(comment_id, UserOperation::CreateCommentLike, context).await?;
+  Ok(())
 }
 
 async fn vote_post(
@@ -64,7 +59,8 @@ async fn vote_post(
   })
   .await??;
 
-  send_post_message(post.id, UserOperation::CreatePostLike, context).await
+  send_post_ws_message(post.id, UserOperation::CreatePostLike, None, None, context).await?;
+  Ok(())
 }
 
 async fn undo_vote_comment(
@@ -79,13 +75,8 @@ async fn undo_vote_comment(
   })
   .await??;
 
-  send_comment_message(
-    comment.id,
-    vec![],
-    UserOperation::CreateCommentLike,
-    context,
-  )
-  .await
+  send_comment_ws_message_simple(comment_id, UserOperation::CreateCommentLike, context).await?;
+  Ok(())
 }
 
 async fn undo_vote_post(
@@ -99,5 +90,7 @@ async fn undo_vote_post(
     PostLike::remove(conn, person_id, post_id)
   })
   .await??;
-  send_post_message(post.id, UserOperation::CreatePostLike, context).await
+
+  send_post_ws_message(post_id, UserOperation::CreatePostLike, None, None, context).await?;
+  Ok(())
 }
index 1d6f83bd74df9519d3454355cf506aeb18abc897..bc58052f0496219c5308e8f95a64a65156a51933 100644 (file)
@@ -2,7 +2,7 @@ use activitystreams::{base::AnyBase, context, primitives::OneOrMany};
 use serde_json::json;
 use url::Url;
 
-pub fn lemmy_context() -> OneOrMany<AnyBase> {
+pub(crate) fn lemmy_context() -> OneOrMany<AnyBase> {
   let context_ext = AnyBase::from_arbitrary_json(json!(
   {
     "sc": "http://schema.org#",
index 8fded5152c82e6c65eb6d1f528a0889bde5bc3d8..675740365a3562bcb39e164965c110b393716ea2 100644 (file)
@@ -62,7 +62,7 @@ pub(crate) async fn sign_and_send(
 }
 
 /// Verifies the HTTP signature on an incoming inbox request.
-pub fn verify_signature(request: &HttpRequest, public_key: &str) -> Result<(), LemmyError> {
+pub(crate) fn verify_signature(request: &HttpRequest, public_key: &str) -> Result<(), LemmyError> {
   let verified = CONFIG2
     .begin_verify(
       request.method(),
index ff94129bed3e87df73aba1b9a3f2093ed267140d..83aa7b51e291425dba29a27785e72fd1e1240936 100644 (file)
@@ -25,7 +25,7 @@ use url::Url;
 ///
 /// If it exists locally and `!should_refetch_actor()`, it is returned directly from the database.
 /// Otherwise it is fetched from the remote instance, stored and returned.
-pub async fn get_or_fetch_and_upsert_community(
+pub(crate) async fn get_or_fetch_and_upsert_community(
   apub_id: &Url,
   context: &LemmyContext,
   recursion_counter: &mut i32,
index 477cecc87b900c26f4adc210585f3df3e48df88e..9d9e2b8e3cd9a7f69fb64ad39c0f48a90ad1a157 100644 (file)
@@ -42,7 +42,7 @@ where
 ///
 /// If it exists locally and `!should_refetch_actor()`, it is returned directly from the database.
 /// Otherwise it is fetched from the remote instance, stored and returned.
-pub async fn get_or_fetch_and_upsert_actor(
+pub(crate) async fn get_or_fetch_and_upsert_actor(
   apub_id: &Url,
   context: &LemmyContext,
   recursion_counter: &mut i32,
index 835bf63a3199763cd5f9ec4c52a8d27a49606c32..e538982db45c64e6c3ee1f910ace33f5d8500610 100644 (file)
@@ -17,7 +17,7 @@ use url::Url;
 /// pulled from its apub ID, inserted and returned.
 ///
 /// The parent community is also pulled if necessary. Comments are not pulled.
-pub async fn get_or_fetch_and_insert_post(
+pub(crate) async fn get_or_fetch_and_insert_post(
   post_ap_id: &Url,
   context: &LemmyContext,
   recursion_counter: &mut i32,
@@ -46,7 +46,7 @@ pub async fn get_or_fetch_and_insert_post(
 /// pulled from its apub ID, inserted and returned.
 ///
 /// The parent community, post and comment are also pulled if necessary.
-pub async fn get_or_fetch_and_insert_comment(
+pub(crate) async fn get_or_fetch_and_insert_comment(
   comment_ap_id: &Url,
   context: &LemmyContext,
   recursion_counter: &mut i32,
@@ -80,7 +80,7 @@ pub async fn get_or_fetch_and_insert_comment(
   }
 }
 
-pub async fn get_or_fetch_and_insert_post_or_comment(
+pub(crate) async fn get_or_fetch_and_insert_post_or_comment(
   ap_id: &Url,
   context: &LemmyContext,
   recursion_counter: &mut i32,
index 3acedb0863f183b27bd67149b8bc6250d15024b7..ed3ca057f49dbedf7ee0eb2c4d339405c861d061 100644 (file)
@@ -16,7 +16,7 @@ use url::Url;
 ///
 /// If it exists locally and `!should_refetch_actor()`, it is returned directly from the database.
 /// Otherwise it is fetched from the remote instance, stored and returned.
-pub async fn get_or_fetch_and_upsert_person(
+pub(crate) async fn get_or_fetch_and_upsert_person(
   apub_id: &Url,
   context: &LemmyContext,
   recursion_counter: &mut i32,
index 03404877739fae50a08b52a1e0405f77043a2811..1ed210bb594edb9d59a9de676454620523878ea7 100644 (file)
@@ -7,7 +7,7 @@ use crate::activities::{
     undo_block_user::UndoBlockUserFromCommunity,
     update::UpdateCommunity,
   },
-  deletion::{delete::DeletePostCommentOrCommunity, undo_delete::UndoDeletePostCommentOrCommunity},
+  deletion::{delete::Delete, undo_delete::UndoDelete},
   following::{accept::AcceptFollowCommunity, follow::FollowCommunity, undo::UndoFollowCommunity},
   post::create_or_update::CreateOrUpdatePost,
   private_message::{
@@ -15,10 +15,7 @@ use crate::activities::{
     delete::DeletePrivateMessage,
     undo_delete::UndoDeletePrivateMessage,
   },
-  removal::{
-    remove::RemovePostCommentCommunityOrMod,
-    undo_remove::UndoRemovePostCommentOrCommunity,
-  },
+  removal::{remove::RemoveMod, undo_remove::UndoRemovePostCommentOrCommunity},
   voting::{undo_vote::UndoVote, vote::Vote},
 };
 use lemmy_apub_lib::{ActivityCommonFields, ActivityHandler};
@@ -45,14 +42,14 @@ pub enum GroupInboxActivities {
   CreateOrUpdatePost(Box<CreateOrUpdatePost>),
   Vote(Vote),
   UndoVote(UndoVote),
-  DeletePostCommentOrCommunity(DeletePostCommentOrCommunity),
-  UndoDeletePostCommentOrCommunity(UndoDeletePostCommentOrCommunity),
-  RemovePostCommentOrCommunity(RemovePostCommentCommunityOrMod),
+  DeletePostCommentOrCommunity(Delete),
+  UndoDeletePostCommentOrCommunity(UndoDelete),
   UndoRemovePostCommentOrCommunity(UndoRemovePostCommentOrCommunity),
   UpdateCommunity(Box<UpdateCommunity>),
   BlockUserFromCommunity(BlockUserFromCommunity),
   UndoBlockUserFromCommunity(UndoBlockUserFromCommunity),
   AddMod(AddMod),
+  RemoveMod(RemoveMod),
 }
 
 #[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler)]
@@ -65,14 +62,14 @@ pub enum SharedInboxActivities {
   CreateOrUpdatePost(Box<CreateOrUpdatePost>),
   Vote(Vote),
   UndoVote(UndoVote),
-  DeletePostCommentOrCommunity(DeletePostCommentOrCommunity),
-  UndoDeletePostCommentOrCommunity(UndoDeletePostCommentOrCommunity),
-  RemovePostCommentOrCommunity(RemovePostCommentCommunityOrMod),
+  Delete(Delete),
+  UndoDelete(UndoDelete),
   UndoRemovePostCommentOrCommunity(UndoRemovePostCommentOrCommunity),
   UpdateCommunity(Box<UpdateCommunity>),
   BlockUserFromCommunity(BlockUserFromCommunity),
   UndoBlockUserFromCommunity(UndoBlockUserFromCommunity),
   AddMod(AddMod),
+  RemoveMod(RemoveMod),
   // received by person
   AcceptFollowCommunity(AcceptFollowCommunity),
   // Note, pm activities need to be at the end, otherwise comments will end up here. We can probably
index 950f11dc414fc8229771c6ef69f805d8d37c16b6..47714300932f371d6b694c6e6dbcac9f32d58507 100644 (file)
@@ -34,7 +34,7 @@ use serde::Serialize;
 use std::net::IpAddr;
 use url::{ParseError, Url};
 
-pub static APUB_JSON_CONTENT_TYPE: &str = "application/activity+json";
+static APUB_JSON_CONTENT_TYPE: &str = "application/activity+json";
 
 /// Checks if the ID is allowed for sending or receiving.
 ///
@@ -102,28 +102,9 @@ pub(crate) fn check_is_apub_id_valid(
   Ok(())
 }
 
-/// Common functions for ActivityPub objects, which are implemented by most (but not all) objects
-/// and actors in Lemmy.
-#[async_trait::async_trait(?Send)]
-pub trait ApubObjectType {
-  async fn send_delete(&self, creator: &DbPerson, context: &LemmyContext)
-    -> Result<(), LemmyError>;
-  async fn send_undo_delete(
-    &self,
-    creator: &DbPerson,
-    context: &LemmyContext,
-  ) -> Result<(), LemmyError>;
-  async fn send_remove(&self, mod_: &DbPerson, context: &LemmyContext) -> Result<(), LemmyError>;
-  async fn send_undo_remove(
-    &self,
-    mod_: &DbPerson,
-    context: &LemmyContext,
-  ) -> Result<(), LemmyError>;
-}
-
 /// Common methods provided by ActivityPub actors (community and person). Not all methods are
 /// implemented by all actors.
-pub trait ActorType {
+trait ActorType {
   fn is_local(&self) -> bool;
   fn actor_id(&self) -> Url;
   fn name(&self) -> String;
@@ -160,11 +141,6 @@ pub trait CommunityType {
   async fn get_follower_inboxes(&self, pool: &DbPool) -> Result<Vec<Url>, LemmyError>;
 
   async fn send_update(&self, mod_: Person, context: &LemmyContext) -> Result<(), LemmyError>;
-  async fn send_delete(&self, mod_: Person, context: &LemmyContext) -> Result<(), LemmyError>;
-  async fn send_undo_delete(&self, mod_: Person, context: &LemmyContext) -> Result<(), LemmyError>;
-
-  async fn send_remove(&self, context: &LemmyContext) -> Result<(), LemmyError>;
-  async fn send_undo_remove(&self, context: &LemmyContext) -> Result<(), LemmyError>;
 
   async fn send_announce(
     &self,
@@ -209,7 +185,7 @@ pub enum EndpointType {
 }
 
 /// Generates an apub endpoint for a given domain, IE xyz.tld
-pub(crate) fn generate_apub_endpoint_for_domain(
+fn generate_apub_endpoint_for_domain(
   endpoint_type: EndpointType,
   name: &str,
   domain: &str,
@@ -260,7 +236,7 @@ pub fn generate_shared_inbox_url(actor_id: &DbUrl) -> Result<DbUrl, LemmyError>
   Ok(Url::parse(&url)?.into())
 }
 
-pub fn generate_moderators_url(community_id: &DbUrl) -> Result<DbUrl, LemmyError> {
+fn generate_moderators_url(community_id: &DbUrl) -> Result<DbUrl, LemmyError> {
   Ok(Url::parse(&format!("{}/moderators", community_id))?.into())
 }
 
@@ -286,7 +262,7 @@ pub fn build_actor_id_from_shortname(
 
 /// Store a sent or received activity in the database, for logging purposes. These records are not
 /// persistent.
-pub(crate) async fn insert_activity<T>(
+async fn insert_activity<T>(
   ap_id: &Url,
   activity: T,
   local: bool,
@@ -348,7 +324,7 @@ pub(crate) async fn find_post_or_comment_by_id(
 }
 
 #[derive(Debug)]
-pub enum Object {
+enum Object {
   Comment(Box<Comment>),
   Post(Box<Post>),
   Community(Box<Community>),
@@ -356,10 +332,7 @@ pub enum Object {
   PrivateMessage(Box<PrivateMessage>),
 }
 
-pub(crate) async fn find_object_by_id(
-  context: &LemmyContext,
-  apub_id: Url,
-) -> Result<Object, LemmyError> {
+async fn find_object_by_id(context: &LemmyContext, apub_id: Url) -> Result<Object, LemmyError> {
   let ap_id = apub_id.clone();
   if let Ok(pc) = find_post_or_comment_by_id(context, ap_id.to_owned()).await {
     return Ok(match pc {
@@ -397,7 +370,7 @@ pub(crate) async fn find_object_by_id(
   Err(NotFound.into())
 }
 
-pub(crate) async fn check_community_or_site_ban(
+async fn check_community_or_site_ban(
   person: &Person,
   community_id: CommunityId,
   pool: &DbPool,
index 0f18d2f376b6aad6ca05430205ab1de4ee8558ea..59eeacce9252a1b19ac4ceaa7a6ac5e1846db4f6 100644 (file)
@@ -15,3 +15,15 @@ pub enum CommentInReplyToMigration {
   Old(Vec<Url>),
   New(Url),
 }
+
+// Another migration we are doing is to handle all deletions and removals using Delete activity.
+// This is because Remove is for removing an object from a collection, so using it that way doesn't
+// really make sense. It is also a problem because we have a RemoveMod activity, which was awkward
+// to handle together with removing posts etc.
+//
+// v0.11: send and receive mod removals as Remove
+// v0.12: receive removals as Remove, send as Delete (compatible with v0.11)
+// v0.13: send and receive mod removals as Delete (compatible with v0.12)
+//
+// For v0.13, delete [`UndoRemovePostCommentOrCommunity`], and don't handle object deletion in
+// [`RemoveMod`] handler.
index 2114a1d89ae8436267edb2ae92265668fbeea710..33a93915a3a1ff8697a9de56afa60e6571b9ff45 100644 (file)
@@ -19,14 +19,14 @@ pub(crate) mod private_message;
 
 /// Trait for converting an object or actor into the respective ActivityPub type.
 #[async_trait::async_trait(?Send)]
-pub trait ToApub {
+pub(crate) trait ToApub {
   type ApubType;
   async fn to_apub(&self, pool: &DbPool) -> Result<Self::ApubType, LemmyError>;
   fn to_tombstone(&self) -> Result<Tombstone, LemmyError>;
 }
 
 #[async_trait::async_trait(?Send)]
-pub trait FromApub {
+pub(crate) trait FromApub {
   type ApubType;
   /// Converts an object from ActivityPub type to Lemmy internal type.
   ///
index adc0717acd8ae65395e888c94890a2ae4b08ab01..fb5b8cd5d0365abcd8f2c901f5253bd228851c4c 100644 (file)
@@ -25,17 +25,19 @@ pub mod source;
 
 pub type DbPool = diesel::r2d2::Pool<diesel::r2d2::ConnectionManager<diesel::PgConnection>>;
 
-pub trait Crud<Form, IdType> {
-  fn create(conn: &PgConnection, form: &Form) -> Result<Self, Error>
+pub trait Crud {
+  type Form;
+  type IdType;
+  fn create(conn: &PgConnection, form: &Self::Form) -> Result<Self, Error>
   where
     Self: Sized;
-  fn read(conn: &PgConnection, id: IdType) -> Result<Self, Error>
+  fn read(conn: &PgConnection, id: Self::IdType) -> Result<Self, Error>
   where
     Self: Sized;
-  fn update(conn: &PgConnection, id: IdType, form: &Form) -> Result<Self, Error>
+  fn update(conn: &PgConnection, id: Self::IdType, form: &Self::Form) -> Result<Self, Error>
   where
     Self: Sized;
-  fn delete(_conn: &PgConnection, _id: IdType) -> Result<usize, Error>
+  fn delete(_conn: &PgConnection, _id: Self::IdType) -> Result<usize, Error>
   where
     Self: Sized,
   {
@@ -43,8 +45,9 @@ pub trait Crud<Form, IdType> {
   }
 }
 
-pub trait Followable<Form> {
-  fn follow(conn: &PgConnection, form: &Form) -> Result<Self, Error>
+pub trait Followable {
+  type Form;
+  fn follow(conn: &PgConnection, form: &Self::Form) -> Result<Self, Error>
   where
     Self: Sized;
   fn follow_accepted(
@@ -54,59 +57,70 @@ pub trait Followable<Form> {
   ) -> Result<Self, Error>
   where
     Self: Sized;
-  fn unfollow(conn: &PgConnection, form: &Form) -> Result<usize, Error>
+  fn unfollow(conn: &PgConnection, form: &Self::Form) -> Result<usize, Error>
   where
     Self: Sized;
   fn has_local_followers(conn: &PgConnection, community_id: CommunityId) -> Result<bool, Error>;
 }
 
-pub trait Joinable<Form> {
-  fn join(conn: &PgConnection, form: &Form) -> Result<Self, Error>
+pub trait Joinable {
+  type Form;
+  fn join(conn: &PgConnection, form: &Self::Form) -> Result<Self, Error>
   where
     Self: Sized;
-  fn leave(conn: &PgConnection, form: &Form) -> Result<usize, Error>
+  fn leave(conn: &PgConnection, form: &Self::Form) -> Result<usize, Error>
   where
     Self: Sized;
 }
 
-pub trait Likeable<Form, IdType> {
-  fn like(conn: &PgConnection, form: &Form) -> Result<Self, Error>
+pub trait Likeable {
+  type Form;
+  type IdType;
+  fn like(conn: &PgConnection, form: &Self::Form) -> Result<Self, Error>
   where
     Self: Sized;
-  fn remove(conn: &PgConnection, person_id: PersonId, item_id: IdType) -> Result<usize, Error>
+  fn remove(
+    conn: &PgConnection,
+    person_id: PersonId,
+    item_id: Self::IdType,
+  ) -> Result<usize, Error>
   where
     Self: Sized;
 }
 
-pub trait Bannable<Form> {
-  fn ban(conn: &PgConnection, form: &Form) -> Result<Self, Error>
+pub trait Bannable {
+  type Form;
+  fn ban(conn: &PgConnection, form: &Self::Form) -> Result<Self, Error>
   where
     Self: Sized;
-  fn unban(conn: &PgConnection, form: &Form) -> Result<usize, Error>
+  fn unban(conn: &PgConnection, form: &Self::Form) -> Result<usize, Error>
   where
     Self: Sized;
 }
 
-pub trait Saveable<Form> {
-  fn save(conn: &PgConnection, form: &Form) -> Result<Self, Error>
+pub trait Saveable {
+  type Form;
+  fn save(conn: &PgConnection, form: &Self::Form) -> Result<Self, Error>
   where
     Self: Sized;
-  fn unsave(conn: &PgConnection, form: &Form) -> Result<usize, Error>
+  fn unsave(conn: &PgConnection, form: &Self::Form) -> Result<usize, Error>
   where
     Self: Sized;
 }
 
-pub trait Readable<Form> {
-  fn mark_as_read(conn: &PgConnection, form: &Form) -> Result<Self, Error>
+pub trait Readable {
+  type Form;
+  fn mark_as_read(conn: &PgConnection, form: &Self::Form) -> Result<Self, Error>
   where
     Self: Sized;
-  fn mark_as_unread(conn: &PgConnection, form: &Form) -> Result<usize, Error>
+  fn mark_as_unread(conn: &PgConnection, form: &Self::Form) -> Result<usize, Error>
   where
     Self: Sized;
 }
 
-pub trait Reportable<Form> {
-  fn report(conn: &PgConnection, form: &Form) -> Result<Self, Error>
+pub trait Reportable {
+  type Form;
+  fn report(conn: &PgConnection, form: &Self::Form) -> Result<Self, Error>
   where
     Self: Sized;
   fn resolve(conn: &PgConnection, report_id: i32, resolver_id: PersonId) -> Result<usize, Error>
@@ -121,11 +135,12 @@ pub trait DeleteableOrRemoveable {
   fn blank_out_deleted_or_removed_info(self) -> Self;
 }
 
-pub trait ApubObject<Form> {
+pub trait ApubObject {
+  type Form;
   fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Self, Error>
   where
     Self: Sized;
-  fn upsert(conn: &PgConnection, user_form: &Form) -> Result<Self, Error>
+  fn upsert(conn: &PgConnection, user_form: &Self::Form) -> Result<Self, Error>
   where
     Self: Sized;
 }
index f87cf73306390b61ed03d0b0e0ca181695d70703..1f158370ed5d8fb1d349f1be1d3e926d0d4ab3b3 100644 (file)
@@ -9,7 +9,9 @@ use std::{
   io::{Error as IoError, ErrorKind},
 };
 
-impl Crud<ActivityForm, i32> for Activity {
+impl Crud for Activity {
+  type Form = ActivityForm;
+  type IdType = i32;
   fn read(conn: &PgConnection, activity_id: i32) -> Result<Self, Error> {
     use lemmy_db_schema::schema::activity::dsl::*;
     activity.find(activity_id).first::<Self>(conn)
index d0171cb8ddfa80b1f7dbba889a8427ae12107556..1e97227145bfe1bd7f424128bb73570493349a12 100644 (file)
@@ -135,7 +135,9 @@ impl Comment_ for Comment {
   }
 }
 
-impl Crud<CommentForm, CommentId> for Comment {
+impl Crud for Comment {
+  type Form = CommentForm;
+  type IdType = CommentId;
   fn read(conn: &PgConnection, comment_id: CommentId) -> Result<Self, Error> {
     use lemmy_db_schema::schema::comment::dsl::*;
     comment.find(comment_id).first::<Self>(conn)
@@ -165,7 +167,8 @@ impl Crud<CommentForm, CommentId> for Comment {
   }
 }
 
-impl ApubObject<CommentForm> for Comment {
+impl ApubObject for Comment {
+  type Form = CommentForm;
   fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Self, Error> {
     use lemmy_db_schema::schema::comment::dsl::*;
     comment.filter(ap_id.eq(object_id)).first::<Self>(conn)
@@ -182,7 +185,9 @@ impl ApubObject<CommentForm> for Comment {
   }
 }
 
-impl Likeable<CommentLikeForm, CommentId> for CommentLike {
+impl Likeable for CommentLike {
+  type Form = CommentLikeForm;
+  type IdType = CommentId;
   fn like(conn: &PgConnection, comment_like_form: &CommentLikeForm) -> Result<Self, Error> {
     use lemmy_db_schema::schema::comment_like::dsl::*;
     insert_into(comment_like)
@@ -207,7 +212,8 @@ impl Likeable<CommentLikeForm, CommentId> for CommentLike {
   }
 }
 
-impl Saveable<CommentSavedForm> for CommentSaved {
+impl Saveable for CommentSaved {
+  type Form = CommentSavedForm;
   fn save(conn: &PgConnection, comment_saved_form: &CommentSavedForm) -> Result<Self, Error> {
     use lemmy_db_schema::schema::comment_saved::dsl::*;
     insert_into(comment_saved)
index 87b9360628cab3664d405799b07b938ac5ce2aed..738ec3e299436c2ab990e6011b6af58096780c99 100644 (file)
@@ -6,7 +6,8 @@ use lemmy_db_schema::{
   PersonId,
 };
 
-impl Reportable<CommentReportForm> for CommentReport {
+impl Reportable for CommentReport {
+  type Form = CommentReportForm;
   /// creates a comment report and returns it
   ///
   /// * `conn` - the postgres connection
index 2a62193397d607cc840f6a0156a17ceecb90e73d..eaaa2ba298b6ab339254282d6feeb65e8b9921c5 100644 (file)
@@ -60,7 +60,9 @@ mod safe_type {
   }
 }
 
-impl Crud<CommunityForm, CommunityId> for Community {
+impl Crud for Community {
+  type Form = CommunityForm;
+  type IdType = CommunityId;
   fn read(conn: &PgConnection, community_id: CommunityId) -> Result<Self, Error> {
     use lemmy_db_schema::schema::community::dsl::*;
     community.find(community_id).first::<Self>(conn)
@@ -90,7 +92,8 @@ impl Crud<CommunityForm, CommunityId> for Community {
   }
 }
 
-impl ApubObject<CommunityForm> for Community {
+impl ApubObject for Community {
+  type Form = CommunityForm;
   fn read_from_apub_id(conn: &PgConnection, for_actor_id: &DbUrl) -> Result<Self, Error> {
     use lemmy_db_schema::schema::community::dsl::*;
     community
@@ -175,7 +178,8 @@ impl Community_ for Community {
   }
 }
 
-impl Joinable<CommunityModeratorForm> for CommunityModerator {
+impl Joinable for CommunityModerator {
+  type Form = CommunityModeratorForm;
   fn join(
     conn: &PgConnection,
     community_moderator_form: &CommunityModeratorForm,
@@ -252,7 +256,8 @@ impl CommunityModerator_ for CommunityModerator {
   }
 }
 
-impl Bannable<CommunityPersonBanForm> for CommunityPersonBan {
+impl Bannable for CommunityPersonBan {
+  type Form = CommunityPersonBanForm;
   fn ban(
     conn: &PgConnection,
     community_person_ban_form: &CommunityPersonBanForm,
@@ -277,7 +282,8 @@ impl Bannable<CommunityPersonBanForm> for CommunityPersonBan {
   }
 }
 
-impl Followable<CommunityFollowerForm> for CommunityFollower {
+impl Followable for CommunityFollower {
+  type Form = CommunityFollowerForm;
   fn follow(
     conn: &PgConnection,
     community_follower_form: &CommunityFollowerForm,
index b711c82aa03638c9fc678722279ad076b4fcca71..91eac3308ecd4c3f2ed92db92cc49b98dcd132aa 100644 (file)
@@ -91,7 +91,9 @@ impl LocalUser_ for LocalUser {
   }
 }
 
-impl Crud<LocalUserForm, LocalUserId> for LocalUser {
+impl Crud for LocalUser {
+  type Form = LocalUserForm;
+  type IdType = LocalUserId;
   fn read(conn: &PgConnection, local_user_id: LocalUserId) -> Result<Self, Error> {
     local_user.find(local_user_id).first::<Self>(conn)
   }
index 14bb07f1c8ec4bd84ddc78d8ba8d56cca54eabc8..25ef1416d140591f14e20b82643516ee8e24d26d 100644 (file)
@@ -2,7 +2,9 @@ use crate::Crud;
 use diesel::{dsl::*, result::Error, *};
 use lemmy_db_schema::source::moderator::*;
 
-impl Crud<ModRemovePostForm, i32> for ModRemovePost {
+impl Crud for ModRemovePost {
+  type Form = ModRemovePostForm;
+  type IdType = i32;
   fn read(conn: &PgConnection, from_id: i32) -> Result<Self, Error> {
     use lemmy_db_schema::schema::mod_remove_post::dsl::*;
     mod_remove_post.find(from_id).first::<Self>(conn)
@@ -23,7 +25,9 @@ impl Crud<ModRemovePostForm, i32> for ModRemovePost {
   }
 }
 
-impl Crud<ModLockPostForm, i32> for ModLockPost {
+impl Crud for ModLockPost {
+  type Form = ModLockPostForm;
+  type IdType = i32;
   fn read(conn: &PgConnection, from_id: i32) -> Result<Self, Error> {
     use lemmy_db_schema::schema::mod_lock_post::dsl::*;
     mod_lock_post.find(from_id).first::<Self>(conn)
@@ -44,7 +48,9 @@ impl Crud<ModLockPostForm, i32> for ModLockPost {
   }
 }
 
-impl Crud<ModStickyPostForm, i32> for ModStickyPost {
+impl Crud for ModStickyPost {
+  type Form = ModStickyPostForm;
+  type IdType = i32;
   fn read(conn: &PgConnection, from_id: i32) -> Result<Self, Error> {
     use lemmy_db_schema::schema::mod_sticky_post::dsl::*;
     mod_sticky_post.find(from_id).first::<Self>(conn)
@@ -65,7 +71,9 @@ impl Crud<ModStickyPostForm, i32> for ModStickyPost {
   }
 }
 
-impl Crud<ModRemoveCommentForm, i32> for ModRemoveComment {
+impl Crud for ModRemoveComment {
+  type Form = ModRemoveCommentForm;
+  type IdType = i32;
   fn read(conn: &PgConnection, from_id: i32) -> Result<Self, Error> {
     use lemmy_db_schema::schema::mod_remove_comment::dsl::*;
     mod_remove_comment.find(from_id).first::<Self>(conn)
@@ -86,7 +94,9 @@ impl Crud<ModRemoveCommentForm, i32> for ModRemoveComment {
   }
 }
 
-impl Crud<ModRemoveCommunityForm, i32> for ModRemoveCommunity {
+impl Crud for ModRemoveCommunity {
+  type Form = ModRemoveCommunityForm;
+  type IdType = i32;
   fn read(conn: &PgConnection, from_id: i32) -> Result<Self, Error> {
     use lemmy_db_schema::schema::mod_remove_community::dsl::*;
     mod_remove_community.find(from_id).first::<Self>(conn)
@@ -111,7 +121,9 @@ impl Crud<ModRemoveCommunityForm, i32> for ModRemoveCommunity {
   }
 }
 
-impl Crud<ModBanFromCommunityForm, i32> for ModBanFromCommunity {
+impl Crud for ModBanFromCommunity {
+  type Form = ModBanFromCommunityForm;
+  type IdType = i32;
   fn read(conn: &PgConnection, from_id: i32) -> Result<Self, Error> {
     use lemmy_db_schema::schema::mod_ban_from_community::dsl::*;
     mod_ban_from_community.find(from_id).first::<Self>(conn)
@@ -136,7 +148,9 @@ impl Crud<ModBanFromCommunityForm, i32> for ModBanFromCommunity {
   }
 }
 
-impl Crud<ModBanForm, i32> for ModBan {
+impl Crud for ModBan {
+  type Form = ModBanForm;
+  type IdType = i32;
   fn read(conn: &PgConnection, from_id: i32) -> Result<Self, Error> {
     use lemmy_db_schema::schema::mod_ban::dsl::*;
     mod_ban.find(from_id).first::<Self>(conn)
@@ -155,7 +169,9 @@ impl Crud<ModBanForm, i32> for ModBan {
   }
 }
 
-impl Crud<ModAddCommunityForm, i32> for ModAddCommunity {
+impl Crud for ModAddCommunity {
+  type Form = ModAddCommunityForm;
+  type IdType = i32;
   fn read(conn: &PgConnection, from_id: i32) -> Result<Self, Error> {
     use lemmy_db_schema::schema::mod_add_community::dsl::*;
     mod_add_community.find(from_id).first::<Self>(conn)
@@ -176,7 +192,9 @@ impl Crud<ModAddCommunityForm, i32> for ModAddCommunity {
   }
 }
 
-impl Crud<ModAddForm, i32> for ModAdd {
+impl Crud for ModAdd {
+  type Form = ModAddForm;
+  type IdType = i32;
   fn read(conn: &PgConnection, from_id: i32) -> Result<Self, Error> {
     use lemmy_db_schema::schema::mod_add::dsl::*;
     mod_add.find(from_id).first::<Self>(conn)
index d04a1ac4bc39a9c3a51670320dd3fed23df7ee30..a71cdae26481aac14ac3ab2c3d98d2dc3b78aa52 100644 (file)
@@ -7,7 +7,9 @@ use lemmy_db_schema::{
 };
 use sha2::{Digest, Sha256};
 
-impl Crud<PasswordResetRequestForm, i32> for PasswordResetRequest {
+impl Crud for PasswordResetRequest {
+  type Form = PasswordResetRequestForm;
+  type IdType = i32;
   fn read(conn: &PgConnection, password_reset_request_id: i32) -> Result<Self, Error> {
     password_reset_request
       .find(password_reset_request_id)
index a7266aa27c0d799b5b584a7117eb808de5a9fb7a..6172b4e1eb2c28cdc80d4d426ab5a50400b48535 100644 (file)
@@ -158,7 +158,9 @@ mod safe_type_alias_2 {
   }
 }
 
-impl Crud<PersonForm, PersonId> for Person {
+impl Crud for Person {
+  type Form = PersonForm;
+  type IdType = PersonId;
   fn read(conn: &PgConnection, person_id: PersonId) -> Result<Self, Error> {
     person
       .filter(deleted.eq(false))
@@ -178,7 +180,8 @@ impl Crud<PersonForm, PersonId> for Person {
   }
 }
 
-impl ApubObject<PersonForm> for Person {
+impl ApubObject for Person {
+  type Form = PersonForm;
   fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Self, Error> {
     use lemmy_db_schema::schema::person::dsl::*;
     person
index 45689420037a304f346b56294a3c25bcaeb23009..774f791852b3245862f76d2573432e23405db9e6 100644 (file)
@@ -2,7 +2,9 @@ use crate::Crud;
 use diesel::{dsl::*, result::Error, *};
 use lemmy_db_schema::{source::person_mention::*, PersonId, PersonMentionId};
 
-impl Crud<PersonMentionForm, PersonMentionId> for PersonMention {
+impl Crud for PersonMention {
+  type Form = PersonMentionForm;
+  type IdType = PersonMentionId;
   fn read(conn: &PgConnection, person_mention_id: PersonMentionId) -> Result<Self, Error> {
     use lemmy_db_schema::schema::person_mention::dsl::*;
     person_mention.find(person_mention_id).first::<Self>(conn)
index f0cf109357ec949a98eff698be2f473a2b8fddce..02ae4d6e2d461cce5c339d832055bdb4c0be5f2a 100644 (file)
@@ -18,7 +18,9 @@ use lemmy_db_schema::{
   PostId,
 };
 
-impl Crud<PostForm, PostId> for Post {
+impl Crud for Post {
+  type Form = PostForm;
+  type IdType = PostId;
   fn read(conn: &PgConnection, post_id: PostId) -> Result<Self, Error> {
     use lemmy_db_schema::schema::post::dsl::*;
     post.find(post_id).first::<Self>(conn)
@@ -179,7 +181,8 @@ impl Post_ for Post {
   }
 }
 
-impl ApubObject<PostForm> for Post {
+impl ApubObject for Post {
+  type Form = PostForm;
   fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Self, Error> {
     use lemmy_db_schema::schema::post::dsl::*;
     post.filter(ap_id.eq(object_id)).first::<Self>(conn)
@@ -196,7 +199,9 @@ impl ApubObject<PostForm> for Post {
   }
 }
 
-impl Likeable<PostLikeForm, PostId> for PostLike {
+impl Likeable for PostLike {
+  type Form = PostLikeForm;
+  type IdType = PostId;
   fn like(conn: &PgConnection, post_like_form: &PostLikeForm) -> Result<Self, Error> {
     use lemmy_db_schema::schema::post_like::dsl::*;
     insert_into(post_like)
@@ -217,7 +222,8 @@ impl Likeable<PostLikeForm, PostId> for PostLike {
   }
 }
 
-impl Saveable<PostSavedForm> for PostSaved {
+impl Saveable for PostSaved {
+  type Form = PostSavedForm;
   fn save(conn: &PgConnection, post_saved_form: &PostSavedForm) -> Result<Self, Error> {
     use lemmy_db_schema::schema::post_saved::dsl::*;
     insert_into(post_saved)
@@ -238,7 +244,8 @@ impl Saveable<PostSavedForm> for PostSaved {
   }
 }
 
-impl Readable<PostReadForm> for PostRead {
+impl Readable for PostRead {
+  type Form = PostReadForm;
   fn mark_as_read(conn: &PgConnection, post_read_form: &PostReadForm) -> Result<Self, Error> {
     use lemmy_db_schema::schema::post_read::dsl::*;
     insert_into(post_read)
index b4e85573107347ead1483c5136ff0af3bddcd25b..19cd5dfea7f9b2a46fabefe80b17da73a35b9849 100644 (file)
@@ -2,7 +2,8 @@ use crate::Reportable;
 use diesel::{dsl::*, result::Error, *};
 use lemmy_db_schema::{naive_now, source::post_report::*, PersonId};
 
-impl Reportable<PostReportForm> for PostReport {
+impl Reportable for PostReport {
+  type Form = PostReportForm;
   /// creates a post report and returns it
   ///
   /// * `conn` - the postgres connection
index da1c5abd5989c5651b58594cf7dcc0468043a1c5..c1138b979117be829785daa9e0bb6267487ac026 100644 (file)
@@ -2,7 +2,9 @@ use crate::{ApubObject, Crud, DeleteableOrRemoveable};
 use diesel::{dsl::*, result::Error, *};
 use lemmy_db_schema::{naive_now, source::private_message::*, DbUrl, PersonId, PrivateMessageId};
 
-impl Crud<PrivateMessageForm, PrivateMessageId> for PrivateMessage {
+impl Crud for PrivateMessage {
+  type Form = PrivateMessageForm;
+  type IdType = PrivateMessageId;
   fn read(conn: &PgConnection, private_message_id: PrivateMessageId) -> Result<Self, Error> {
     use lemmy_db_schema::schema::private_message::dsl::*;
     private_message.find(private_message_id).first::<Self>(conn)
@@ -27,7 +29,8 @@ impl Crud<PrivateMessageForm, PrivateMessageId> for PrivateMessage {
   }
 }
 
-impl ApubObject<PrivateMessageForm> for PrivateMessage {
+impl ApubObject for PrivateMessage {
+  type Form = PrivateMessageForm;
   fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Self, Error>
   where
     Self: Sized,
index d688546f80d9cf7958384eda7aa759b6748cf7bd..b2bad71384999d2fff7deff8c3ef87772ec8ab8d 100644 (file)
@@ -2,7 +2,9 @@ use crate::Crud;
 use diesel::{dsl::*, result::Error, *};
 use lemmy_db_schema::{naive_now, source::site::*, PersonId};
 
-impl Crud<SiteForm, i32> for Site {
+impl Crud for Site {
+  type Form = SiteForm;
+  type IdType = i32;
   fn read(conn: &PgConnection, _site_id: i32) -> Result<Self, Error> {
     use lemmy_db_schema::schema::site::dsl::*;
     site.first::<Self>(conn)
index 3571d0c325af27e00b6c25fd4a0625e10ff8c5e8..6262beb50eef5ec29355391ccd515045f708d59f 100644 (file)
@@ -15,6 +15,8 @@ lemmy_utils = { version = "=0.11.3", path = "../utils" }
 lemmy_api_common = { version = "=0.11.3", path = "../api_common" }
 lemmy_db_queries = { version = "=0.11.3", path = "../db_queries" }
 lemmy_db_schema = { version = "=0.11.3", path = "../db_schema" }
+lemmy_db_views = { version = "=0.11.3", path = "../db_views" }
+lemmy_db_views_actor = { version = "=0.11.3", path = "../db_views_actor" }
 reqwest = { version = "0.11.4", features = ["json"] }
 log = "0.4.14"
 rand = "0.8.4"
index f5f5f08045e5dfb69bd3cbcbb49d79dfb0e18019..b866a2a211d6e245b668d5f8c473ba5e2db7f143 100644 (file)
@@ -13,6 +13,7 @@ pub mod chat_server;
 pub mod handlers;
 pub mod messages;
 pub mod routes;
+pub mod send;
 
 pub struct LemmyContext {
   pub pool: DbPool,
index 1ef3da5b55283eea859de85d2863113a00f420d8..3c16ec2730f4169e612144adf463352d664b5c1c 100644 (file)
@@ -75,7 +75,7 @@ pub struct SendModRoomMessage<Response> {
 
 #[derive(Message)]
 #[rtype(result = "()")]
-pub struct SendPost<OP: ToString> {
+pub(crate) struct SendPost<OP: ToString> {
   pub op: OP,
   pub post: PostResponse,
   pub websocket_id: Option<ConnectionId>,
@@ -83,7 +83,7 @@ pub struct SendPost<OP: ToString> {
 
 #[derive(Message)]
 #[rtype(result = "()")]
-pub struct SendComment<OP: ToString> {
+pub(crate) struct SendComment<OP: ToString> {
   pub op: OP,
   pub comment: CommentResponse,
   pub websocket_id: Option<ConnectionId>,
diff --git a/crates/websocket/src/send.rs b/crates/websocket/src/send.rs
new file mode 100644 (file)
index 0000000..130d94a
--- /dev/null
@@ -0,0 +1,162 @@
+use crate::{
+  messages::{SendComment, SendCommunityRoomMessage, SendPost, SendUserRoomMessage},
+  LemmyContext,
+  OperationType,
+};
+use lemmy_api_common::{
+  blocking,
+  comment::CommentResponse,
+  community::CommunityResponse,
+  person::PrivateMessageResponse,
+  post::PostResponse,
+};
+use lemmy_db_queries::DeleteableOrRemoveable;
+use lemmy_db_schema::{CommentId, CommunityId, LocalUserId, PersonId, PostId, PrivateMessageId};
+use lemmy_db_views::{
+  comment_view::CommentView,
+  local_user_view::LocalUserView,
+  post_view::PostView,
+  private_message_view::PrivateMessageView,
+};
+use lemmy_db_views_actor::community_view::CommunityView;
+use lemmy_utils::{ConnectionId, LemmyError};
+
+pub async fn send_post_ws_message<OP: ToString + Send + OperationType + 'static>(
+  post_id: PostId,
+  op: OP,
+  websocket_id: Option<ConnectionId>,
+  person_id: Option<PersonId>,
+  context: &LemmyContext,
+) -> Result<PostResponse, LemmyError> {
+  let mut post_view = blocking(context.pool(), move |conn| {
+    PostView::read(conn, post_id, person_id)
+  })
+  .await??;
+
+  if post_view.post.deleted || post_view.post.removed {
+    post_view.post = post_view.post.blank_out_deleted_or_removed_info();
+  }
+
+  let res = PostResponse { post_view };
+
+  context.chat_server().do_send(SendPost {
+    op,
+    post: res.clone(),
+    websocket_id,
+  });
+
+  Ok(res)
+}
+
+// TODO: in many call sites in apub crate, we are setting an empty vec for recipient_ids,
+//       we should get the actual recipient actors from somewhere
+pub async fn send_comment_ws_message_simple<OP: ToString + Send + OperationType + 'static>(
+  comment_id: CommentId,
+  op: OP,
+  context: &LemmyContext,
+) -> Result<CommentResponse, LemmyError> {
+  send_comment_ws_message(comment_id, op, None, None, None, vec![], context).await
+}
+
+pub async fn send_comment_ws_message<OP: ToString + Send + OperationType + 'static>(
+  comment_id: CommentId,
+  op: OP,
+  websocket_id: Option<ConnectionId>,
+  form_id: Option<String>,
+  person_id: Option<PersonId>,
+  recipient_ids: Vec<LocalUserId>,
+  context: &LemmyContext,
+) -> Result<CommentResponse, LemmyError> {
+  let mut view = blocking(context.pool(), move |conn| {
+    CommentView::read(conn, comment_id, person_id)
+  })
+  .await??;
+
+  if view.comment.deleted || view.comment.removed {
+    view.comment = view.comment.blank_out_deleted_or_removed_info();
+  }
+
+  let res = CommentResponse {
+    comment_view: view,
+    recipient_ids,
+    form_id,
+  };
+
+  context.chat_server().do_send(SendComment {
+    op,
+    comment: res.clone(),
+    websocket_id,
+  });
+
+  Ok(res)
+}
+
+pub async fn send_community_ws_message<OP: ToString + Send + OperationType + 'static>(
+  community_id: CommunityId,
+  op: OP,
+  websocket_id: Option<ConnectionId>,
+  person_id: Option<PersonId>,
+  context: &LemmyContext,
+) -> Result<CommunityResponse, LemmyError> {
+  let mut community_view = blocking(context.pool(), move |conn| {
+    CommunityView::read(conn, community_id, person_id)
+  })
+  .await??;
+  // Blank out deleted or removed info
+  if community_view.community.deleted || community_view.community.removed {
+    community_view.community = community_view.community.blank_out_deleted_or_removed_info();
+  }
+
+  let res = CommunityResponse { community_view };
+
+  // Strip out the person id and subscribed when sending to others
+  let mut res_mut = res.clone();
+  res_mut.community_view.subscribed = false;
+
+  context.chat_server().do_send(SendCommunityRoomMessage {
+    op,
+    response: res_mut,
+    community_id: res.community_view.community.id,
+    websocket_id,
+  });
+
+  Ok(res)
+}
+
+pub async fn send_pm_ws_message<OP: ToString + Send + OperationType + 'static>(
+  private_message_id: PrivateMessageId,
+  op: OP,
+  websocket_id: Option<ConnectionId>,
+  context: &LemmyContext,
+) -> Result<PrivateMessageResponse, LemmyError> {
+  let mut view = blocking(context.pool(), move |conn| {
+    PrivateMessageView::read(conn, private_message_id)
+  })
+  .await??;
+
+  // Blank out deleted or removed info
+  if view.private_message.deleted {
+    view.private_message = view.private_message.blank_out_deleted_or_removed_info();
+  }
+
+  let res = PrivateMessageResponse {
+    private_message_view: view,
+  };
+
+  // Send notifications to the local recipient, if one exists
+  if res.private_message_view.recipient.local {
+    let recipient_id = res.private_message_view.recipient.id;
+    let local_recipient = blocking(context.pool(), move |conn| {
+      LocalUserView::read_person(conn, recipient_id)
+    })
+    .await??;
+    context.chat_server().do_send(SendUserRoomMessage {
+      op,
+      response: res.clone(),
+      local_recipient_id: local_recipient.local_user.id,
+      websocket_id,
+    });
+  }
+
+  Ok(res)
+}