Dont allow posts to deleted / removed communities. Fixes #1827 (#1828)
authorDessalines <dessalines@users.noreply.github.com>
Thu, 14 Oct 2021 16:33:19 +0000 (12:33 -0400)
committerGitHub <noreply@github.com>
Thu, 14 Oct 2021 16:33:19 +0000 (16:33 +0000)
* Dont allow posts to deleted / removed communities. Fixes #1827

* Fixing couldnt find community error.

* Adding check in createorupdate post and comment.

* make sure post wasn't deleted or removed.

* Adding a post not deleted or removed check to creatorupdatecomment.

* Using pub(crate)

13 files changed:
api_tests/src/post.spec.ts
crates/api/src/community.rs
crates/api/src/post.rs
crates/api_common/src/lib.rs
crates/api_crud/src/comment/create.rs
crates/api_crud/src/comment/update.rs
crates/api_crud/src/post/create.rs
crates/api_crud/src/post/delete.rs
crates/api_crud/src/post/update.rs
crates/apub/src/activities/comment/create_or_update.rs
crates/apub/src/activities/mod.rs
crates/apub/src/activities/post/create_or_update.rs
crates/apub/src/objects/comment.rs

index 5072620479d3174cab814ec736a063f3895f8635..280396b003eb86cadc06d09a83643e44a3db92b9 100644 (file)
@@ -90,7 +90,7 @@ test('Create a post', async () => {
 
 test('Create a post in a non-existent community', async () => {
   let postRes = await createPost(alpha, -2);
-  expect(postRes).toStrictEqual({ error: 'couldnt_create_post' });
+  expect(postRes).toStrictEqual({ error: 'couldnt_find_community' });
 });
 
 test('Unlike a post', async () => {
index 7a5e622ca9d337aaf440cfd8d5a40c0bd113e1ef..ccf0edbfdc473c111da7c3300343191144ba8555 100644 (file)
@@ -4,6 +4,7 @@ use anyhow::Context;
 use lemmy_api_common::{
   blocking,
   check_community_ban,
+  check_community_deleted_or_removed,
   community::*,
   get_local_user_view_from_jwt,
   is_mod_or_admin,
@@ -70,6 +71,7 @@ impl Perform for FollowCommunity {
     if community.local {
       if data.follow {
         check_community_ban(local_user_view.person.id, community_id, context.pool()).await?;
+        check_community_deleted_or_removed(community_id, context.pool()).await?;
 
         let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
         blocking(context.pool(), follow)
index d2440b7a38a9f149bbdb4222f1ffe82c753bcc55..a79a4bb5e252f221baaa3e96019fa217d1a01e2c 100644 (file)
@@ -3,6 +3,7 @@ use actix_web::web::Data;
 use lemmy_api_common::{
   blocking,
   check_community_ban,
+  check_community_deleted_or_removed,
   check_downvotes_enabled,
   check_person_block,
   get_local_user_view_from_jwt,
@@ -49,6 +50,7 @@ impl Perform for CreatePostLike {
     let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
 
     check_community_ban(local_user_view.person.id, post.community_id, context.pool()).await?;
+    check_community_deleted_or_removed(post.community_id, context.pool()).await?;
 
     check_person_block(local_user_view.person.id, post.creator_id, context.pool()).await?;
 
@@ -133,6 +135,7 @@ impl Perform for LockPost {
       context.pool(),
     )
     .await?;
+    check_community_deleted_or_removed(orig_post.community_id, context.pool()).await?;
 
     // Verify that only the mods can lock
     is_mod_or_admin(
@@ -200,6 +203,7 @@ impl Perform for StickyPost {
       context.pool(),
     )
     .await?;
+    check_community_deleted_or_removed(orig_post.community_id, context.pool()).await?;
 
     // Verify that only the mods can sticky
     is_mod_or_admin(
index 07edab0f7240fc9d267edcb50a447a9d60d19ca3..c4b1dd6f5690eaff22117d57a9efa405c31e2350 100644 (file)
@@ -357,6 +357,28 @@ pub async fn check_community_ban(
   }
 }
 
+pub async fn check_community_deleted_or_removed(
+  community_id: CommunityId,
+  pool: &DbPool,
+) -> Result<(), LemmyError> {
+  let community = blocking(pool, move |conn| Community::read(conn, community_id))
+    .await?
+    .map_err(|e| ApiError::err("couldnt_find_community", e))?;
+  if community.deleted || community.removed {
+    Err(ApiError::err_plain("deleted").into())
+  } else {
+    Ok(())
+  }
+}
+
+pub fn check_post_deleted_or_removed(post: &Post) -> Result<(), LemmyError> {
+  if post.deleted || post.removed {
+    Err(ApiError::err_plain("deleted").into())
+  } else {
+    Ok(())
+  }
+}
+
 pub async fn check_person_block(
   my_id: PersonId,
   potential_blocker_id: PersonId,
index 674914629a6f0b483eb0f202c85a5f109b7f2273..37ecb2f05dff4c0771a440f0f798b1b0b3b57c21 100644 (file)
@@ -3,7 +3,9 @@ use actix_web::web::Data;
 use lemmy_api_common::{
   blocking,
   check_community_ban,
+  check_community_deleted_or_removed,
   check_person_block,
+  check_post_deleted_or_removed,
   comment::*,
   get_local_user_view_from_jwt,
   get_post,
@@ -56,6 +58,8 @@ impl PerformCrud for CreateComment {
     let community_id = post.community_id;
 
     check_community_ban(local_user_view.person.id, community_id, context.pool()).await?;
+    check_community_deleted_or_removed(community_id, context.pool()).await?;
+    check_post_deleted_or_removed(&post)?;
 
     check_person_block(local_user_view.person.id, post.creator_id, context.pool()).await?;
 
index 800e124d5bb8f8f23c55f1204f87a5bd61b0781a..b0892c58c538c027a08aa45c63e10ec112645696 100644 (file)
@@ -3,6 +3,8 @@ use actix_web::web::Data;
 use lemmy_api_common::{
   blocking,
   check_community_ban,
+  check_community_deleted_or_removed,
+  check_post_deleted_or_removed,
   comment::*,
   get_local_user_view_from_jwt,
   send_local_notifs,
@@ -48,6 +50,8 @@ impl PerformCrud for EditComment {
       context.pool(),
     )
     .await?;
+    check_community_deleted_or_removed(orig_comment.community.id, context.pool()).await?;
+    check_post_deleted_or_removed(&orig_comment.post)?;
 
     // Verify that only the creator can edit
     if local_user_view.person.id != orig_comment.creator.id {
index 89e664631e215790b2bc7abc37777e7fe7b0b53c..108205b7c24f043599ec88bfa5926e6092214960 100644 (file)
@@ -3,6 +3,7 @@ use actix_web::web::Data;
 use lemmy_api_common::{
   blocking,
   check_community_ban,
+  check_community_deleted_or_removed,
   get_local_user_view_from_jwt,
   honeypot_check,
   mark_post_as_read,
@@ -54,6 +55,7 @@ impl PerformCrud for CreatePost {
     }
 
     check_community_ban(local_user_view.person.id, data.community_id, context.pool()).await?;
+    check_community_deleted_or_removed(data.community_id, context.pool()).await?;
 
     // Fetch post links and pictrs cached image
     let data_url = data.url.as_ref();
index f4086f39d3ff98eb4377f8e8e6f9340780f44b2d..01fa0575b657935cf7d8cda0d3c97322829d5716 100644 (file)
@@ -3,6 +3,7 @@ use actix_web::web::Data;
 use lemmy_api_common::{
   blocking,
   check_community_ban,
+  check_community_deleted_or_removed,
   get_local_user_view_from_jwt,
   is_mod_or_admin,
   post::*,
@@ -35,6 +36,7 @@ impl PerformCrud for DeletePost {
       context.pool(),
     )
     .await?;
+    check_community_deleted_or_removed(orig_post.community_id, context.pool()).await?;
 
     // Verify that only the creator can delete
     if !Post::is_post_creator(local_user_view.person.id, orig_post.creator_id) {
index 9ccb2c052b4b607c57f7926185fa77e3a3db75ee..c84901cc8aeb74457419ba341aa92d90a431380c 100644 (file)
@@ -1,6 +1,12 @@
 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_api_common::{
+  blocking,
+  check_community_ban,
+  check_community_deleted_or_removed,
+  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};
 use lemmy_db_schema::{naive_now, source::post::*};
@@ -45,6 +51,7 @@ impl PerformCrud for EditPost {
       context.pool(),
     )
     .await?;
+    check_community_deleted_or_removed(orig_post.community_id, context.pool()).await?;
 
     // Verify that only the creator can edit
     if !Post::is_post_creator(local_user_view.person.id, orig_post.creator_id) {
index c225300f379cab34d621269a84f2560289173986..b22c240e6617d0d0c6d32309c5694dd846e445d9 100644 (file)
@@ -1,5 +1,6 @@
 use crate::{
   activities::{
+    check_community_deleted_or_removed,
     comment::{collect_non_local_mentions, get_notif_recipients},
     community::{announce::AnnouncableActivities, send_to_community},
     extract_community,
@@ -13,7 +14,7 @@ use crate::{
   objects::{comment::Note, FromApub, ToApub},
 };
 use activitystreams::{base::AnyBase, link::Mention, primitives::OneOrMany, unparsed::Unparsed};
-use lemmy_api_common::blocking;
+use lemmy_api_common::{blocking, check_post_deleted_or_removed};
 use lemmy_apub_lib::{
   data::Data,
   traits::{ActivityFields, ActivityHandler, ActorType},
@@ -94,10 +95,14 @@ impl ActivityHandler for CreateOrUpdateComment {
   ) -> Result<(), LemmyError> {
     let community = extract_community(&self.cc, context, request_counter).await?;
     let community_id = ObjectId::new(community.actor_id());
+    let post = self.object.get_parents(context, request_counter).await?.0;
 
     verify_activity(self, &context.settings())?;
     verify_person_in_community(&self.actor, &community_id, context, request_counter).await?;
     verify_domains_match(self.actor.inner(), self.object.id_unchecked())?;
+    check_community_deleted_or_removed(&community)?;
+    check_post_deleted_or_removed(&post)?;
+
     // TODO: should add a check that the correct community is in cc (probably needs changes to
     //       comment deserialization)
     self.object.verify(context, request_counter).await?;
index 5c775f801ae923fc08bc15811264f5cda0a05fec..43f86572fa2a117367a0a601c09c7a7bad2576b1 100644 (file)
@@ -133,6 +133,14 @@ fn verify_add_remove_moderator_target(
   Ok(())
 }
 
+pub(crate) fn check_community_deleted_or_removed(community: &Community) -> Result<(), LemmyError> {
+  if community.deleted || community.removed {
+    Err(anyhow!("New post or comment cannot be created in deleted or removed community").into())
+  } else {
+    Ok(())
+  }
+}
+
 /// Generate a unique ID for an activity, in the format:
 /// `http(s)://example.com/receive/create/202daf0a-1489-45df-8d2e-c8a3173fed36`
 fn generate_activity_id<T>(kind: T, protocol_and_hostname: &str) -> Result<Url, ParseError>
index 8065cc8798c829e74758e378750d6f59b86840d3..f1a33668013aa4212d282117de4772d988440f4d 100644 (file)
@@ -1,5 +1,6 @@
 use crate::{
   activities::{
+    check_community_deleted_or_removed,
     community::{announce::AnnouncableActivities, send_to_community},
     generate_activity_id,
     verify_activity,
@@ -87,6 +88,8 @@ impl ActivityHandler for CreateOrUpdatePost {
     verify_activity(self, &context.settings())?;
     let community = self.cc[0].dereference(context, request_counter).await?;
     verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?;
+    check_community_deleted_or_removed(&community)?;
+
     match self.kind {
       CreateOrUpdateType::Create => {
         verify_domains_match(self.actor.inner(), self.object.id_unchecked())?;
index 1e01b3f5629ec532fd7d6e23c5e894e3f18033c5..f47c11bfb039f4c4f967e030f3e94ba5bb3fe1ad 100644 (file)
@@ -73,7 +73,7 @@ impl Note {
     Ok(&self.id)
   }
 
-  async fn get_parents(
+  pub(crate) async fn get_parents(
     &self,
     context: &LemmyContext,
     request_counter: &mut i32,