Dont allow posts to deleted / removed communities. Fixes #1827 (#1828)

* 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)
This commit is contained in:
Dessalines 2021-10-14 12:33:19 -04:00 committed by GitHub
parent f052e5f1ab
commit 2402515fcc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 67 additions and 4 deletions

View file

@ -90,7 +90,7 @@ test('Create a post', async () => {
test('Create a post in a non-existent community', async () => { test('Create a post in a non-existent community', async () => {
let postRes = await createPost(alpha, -2); 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 () => { test('Unlike a post', async () => {

View file

@ -4,6 +4,7 @@ use anyhow::Context;
use lemmy_api_common::{ use lemmy_api_common::{
blocking, blocking,
check_community_ban, check_community_ban,
check_community_deleted_or_removed,
community::*, community::*,
get_local_user_view_from_jwt, get_local_user_view_from_jwt,
is_mod_or_admin, is_mod_or_admin,
@ -70,6 +71,7 @@ impl Perform for FollowCommunity {
if community.local { if community.local {
if data.follow { if data.follow {
check_community_ban(local_user_view.person.id, community_id, context.pool()).await?; 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); let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
blocking(context.pool(), follow) blocking(context.pool(), follow)

View file

@ -3,6 +3,7 @@ use actix_web::web::Data;
use lemmy_api_common::{ use lemmy_api_common::{
blocking, blocking,
check_community_ban, check_community_ban,
check_community_deleted_or_removed,
check_downvotes_enabled, check_downvotes_enabled,
check_person_block, check_person_block,
get_local_user_view_from_jwt, 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??; 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_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?; check_person_block(local_user_view.person.id, post.creator_id, context.pool()).await?;
@ -133,6 +135,7 @@ impl Perform for LockPost {
context.pool(), context.pool(),
) )
.await?; .await?;
check_community_deleted_or_removed(orig_post.community_id, context.pool()).await?;
// Verify that only the mods can lock // Verify that only the mods can lock
is_mod_or_admin( is_mod_or_admin(
@ -200,6 +203,7 @@ impl Perform for StickyPost {
context.pool(), context.pool(),
) )
.await?; .await?;
check_community_deleted_or_removed(orig_post.community_id, context.pool()).await?;
// Verify that only the mods can sticky // Verify that only the mods can sticky
is_mod_or_admin( is_mod_or_admin(

View 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( pub async fn check_person_block(
my_id: PersonId, my_id: PersonId,
potential_blocker_id: PersonId, potential_blocker_id: PersonId,

View file

@ -3,7 +3,9 @@ use actix_web::web::Data;
use lemmy_api_common::{ use lemmy_api_common::{
blocking, blocking,
check_community_ban, check_community_ban,
check_community_deleted_or_removed,
check_person_block, check_person_block,
check_post_deleted_or_removed,
comment::*, comment::*,
get_local_user_view_from_jwt, get_local_user_view_from_jwt,
get_post, get_post,
@ -56,6 +58,8 @@ impl PerformCrud for CreateComment {
let community_id = post.community_id; let community_id = post.community_id;
check_community_ban(local_user_view.person.id, community_id, context.pool()).await?; 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?; check_person_block(local_user_view.person.id, post.creator_id, context.pool()).await?;

View file

@ -3,6 +3,8 @@ use actix_web::web::Data;
use lemmy_api_common::{ use lemmy_api_common::{
blocking, blocking,
check_community_ban, check_community_ban,
check_community_deleted_or_removed,
check_post_deleted_or_removed,
comment::*, comment::*,
get_local_user_view_from_jwt, get_local_user_view_from_jwt,
send_local_notifs, send_local_notifs,
@ -48,6 +50,8 @@ impl PerformCrud for EditComment {
context.pool(), context.pool(),
) )
.await?; .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 // Verify that only the creator can edit
if local_user_view.person.id != orig_comment.creator.id { if local_user_view.person.id != orig_comment.creator.id {

View file

@ -3,6 +3,7 @@ use actix_web::web::Data;
use lemmy_api_common::{ use lemmy_api_common::{
blocking, blocking,
check_community_ban, check_community_ban,
check_community_deleted_or_removed,
get_local_user_view_from_jwt, get_local_user_view_from_jwt,
honeypot_check, honeypot_check,
mark_post_as_read, 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_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 // Fetch post links and pictrs cached image
let data_url = data.url.as_ref(); let data_url = data.url.as_ref();

View file

@ -3,6 +3,7 @@ use actix_web::web::Data;
use lemmy_api_common::{ use lemmy_api_common::{
blocking, blocking,
check_community_ban, check_community_ban,
check_community_deleted_or_removed,
get_local_user_view_from_jwt, get_local_user_view_from_jwt,
is_mod_or_admin, is_mod_or_admin,
post::*, post::*,
@ -35,6 +36,7 @@ impl PerformCrud for DeletePost {
context.pool(), context.pool(),
) )
.await?; .await?;
check_community_deleted_or_removed(orig_post.community_id, context.pool()).await?;
// Verify that only the creator can delete // Verify that only the creator can delete
if !Post::is_post_creator(local_user_view.person.id, orig_post.creator_id) { if !Post::is_post_creator(local_user_view.person.id, orig_post.creator_id) {

View file

@ -1,6 +1,12 @@
use crate::PerformCrud; use crate::PerformCrud;
use actix_web::web::Data; 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_apub::activities::{post::create_or_update::CreateOrUpdatePost, CreateOrUpdateType};
use lemmy_db_queries::{source::post::Post_, Crud}; use lemmy_db_queries::{source::post::Post_, Crud};
use lemmy_db_schema::{naive_now, source::post::*}; use lemmy_db_schema::{naive_now, source::post::*};
@ -45,6 +51,7 @@ impl PerformCrud for EditPost {
context.pool(), context.pool(),
) )
.await?; .await?;
check_community_deleted_or_removed(orig_post.community_id, context.pool()).await?;
// Verify that only the creator can edit // Verify that only the creator can edit
if !Post::is_post_creator(local_user_view.person.id, orig_post.creator_id) { if !Post::is_post_creator(local_user_view.person.id, orig_post.creator_id) {

View file

@ -1,5 +1,6 @@
use crate::{ use crate::{
activities::{ activities::{
check_community_deleted_or_removed,
comment::{collect_non_local_mentions, get_notif_recipients}, comment::{collect_non_local_mentions, get_notif_recipients},
community::{announce::AnnouncableActivities, send_to_community}, community::{announce::AnnouncableActivities, send_to_community},
extract_community, extract_community,
@ -13,7 +14,7 @@ use crate::{
objects::{comment::Note, FromApub, ToApub}, objects::{comment::Note, FromApub, ToApub},
}; };
use activitystreams::{base::AnyBase, link::Mention, primitives::OneOrMany, unparsed::Unparsed}; 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::{ use lemmy_apub_lib::{
data::Data, data::Data,
traits::{ActivityFields, ActivityHandler, ActorType}, traits::{ActivityFields, ActivityHandler, ActorType},
@ -94,10 +95,14 @@ impl ActivityHandler for CreateOrUpdateComment {
) -> Result<(), LemmyError> { ) -> Result<(), LemmyError> {
let community = extract_community(&self.cc, context, request_counter).await?; let community = extract_community(&self.cc, context, request_counter).await?;
let community_id = ObjectId::new(community.actor_id()); 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_activity(self, &context.settings())?;
verify_person_in_community(&self.actor, &community_id, context, request_counter).await?; verify_person_in_community(&self.actor, &community_id, context, request_counter).await?;
verify_domains_match(self.actor.inner(), self.object.id_unchecked())?; 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 // TODO: should add a check that the correct community is in cc (probably needs changes to
// comment deserialization) // comment deserialization)
self.object.verify(context, request_counter).await?; self.object.verify(context, request_counter).await?;

View file

@ -133,6 +133,14 @@ fn verify_add_remove_moderator_target(
Ok(()) 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: /// Generate a unique ID for an activity, in the format:
/// `http(s)://example.com/receive/create/202daf0a-1489-45df-8d2e-c8a3173fed36` /// `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> fn generate_activity_id<T>(kind: T, protocol_and_hostname: &str) -> Result<Url, ParseError>

View file

@ -1,5 +1,6 @@
use crate::{ use crate::{
activities::{ activities::{
check_community_deleted_or_removed,
community::{announce::AnnouncableActivities, send_to_community}, community::{announce::AnnouncableActivities, send_to_community},
generate_activity_id, generate_activity_id,
verify_activity, verify_activity,
@ -87,6 +88,8 @@ impl ActivityHandler for CreateOrUpdatePost {
verify_activity(self, &context.settings())?; verify_activity(self, &context.settings())?;
let community = self.cc[0].dereference(context, request_counter).await?; let community = self.cc[0].dereference(context, request_counter).await?;
verify_person_in_community(&self.actor, &self.cc[0], 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 { match self.kind {
CreateOrUpdateType::Create => { CreateOrUpdateType::Create => {
verify_domains_match(self.actor.inner(), self.object.id_unchecked())?; verify_domains_match(self.actor.inner(), self.object.id_unchecked())?;

View file

@ -73,7 +73,7 @@ impl Note {
Ok(&self.id) Ok(&self.id)
} }
async fn get_parents( pub(crate) async fn get_parents(
&self, &self,
context: &LemmyContext, context: &LemmyContext,
request_counter: &mut i32, request_counter: &mut i32,