* 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:
parent
f052e5f1ab
commit
2402515fcc
13 changed files with 67 additions and 4 deletions
|
@ -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 () => {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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?;
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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?;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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())?;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue