diff --git a/crates/api/src/comment/like.rs b/crates/api/src/comment/like.rs index ce7282411..514c571ca 100644 --- a/crates/api/src/comment/like.rs +++ b/crates/api/src/comment/like.rs @@ -5,7 +5,7 @@ use lemmy_api_common::{ comment::{CommentResponse, CreateCommentLike}, context::LemmyContext, send_activity::{ActivityChannel, SendActivityData}, - utils::{check_community_user_action, check_vote_permission}, + utils::{check_bot_account, check_community_user_action, check_downvotes_enabled}, }; use lemmy_db_schema::{ newtypes::LocalUserId, @@ -30,11 +30,13 @@ pub async fn like_comment( let mut recipient_ids = Vec::::new(); + // Don't do a downvote if site has downvotes disabled + check_downvotes_enabled(data.score, &local_site)?; + check_bot_account(&local_user_view.person)?; + let comment_id = data.comment_id; let orig_comment = CommentView::read(&mut context.pool(), comment_id, None).await?; - check_vote_permission(data.score, &local_site, &local_user_view.person).await?; - check_community_user_action( &local_user_view.person, orig_comment.community.id, diff --git a/crates/api/src/post/like.rs b/crates/api/src/post/like.rs index f1de63bf5..176eaae16 100644 --- a/crates/api/src/post/like.rs +++ b/crates/api/src/post/like.rs @@ -5,7 +5,12 @@ use lemmy_api_common::{ context::LemmyContext, post::{CreatePostLike, PostResponse}, send_activity::{ActivityChannel, SendActivityData}, - utils::{check_community_user_action, check_vote_permission, mark_post_as_read}, + utils::{ + check_bot_account, + check_community_user_action, + check_downvotes_enabled, + mark_post_as_read, + }, }; use lemmy_db_schema::{ source::{ @@ -27,12 +32,14 @@ pub async fn like_post( ) -> Result, LemmyError> { let local_site = LocalSite::read(&mut context.pool()).await?; + // Don't do a downvote if site has downvotes disabled + check_downvotes_enabled(data.score, &local_site)?; + check_bot_account(&local_user_view.person)?; + // Check for a community ban let post_id = data.post_id; let post = Post::read(&mut context.pool(), post_id).await?; - check_vote_permission(data.score, &local_site, &local_user_view.person).await?; - check_community_user_action( &local_user_view.person, post.community_id, diff --git a/crates/api_common/src/utils.rs b/crates/api_common/src/utils.rs index ed94d44a6..605733efc 100644 --- a/crates/api_common/src/utils.rs +++ b/crates/api_common/src/utils.rs @@ -287,6 +287,25 @@ pub async fn check_person_instance_community_block( Ok(()) } +#[tracing::instrument(skip_all)] +pub fn check_downvotes_enabled(score: i16, local_site: &LocalSite) -> Result<(), LemmyError> { + if score == -1 && !local_site.enable_downvotes { + Err(LemmyErrorType::DownvotesAreDisabled)? + } else { + Ok(()) + } +} + +/// Dont allow bots to do certain actions, like voting +#[tracing::instrument(skip_all)] +pub fn check_bot_account(person: &Person) -> Result<(), LemmyError> { + if person.bot_account { + Err(LemmyErrorType::InvalidBotAction)? + } else { + Ok(()) + } +} + #[tracing::instrument(skip_all)] pub fn check_private_instance( local_user_view: &Option, @@ -829,26 +848,6 @@ fn limit_expire_time(expires: DateTime) -> LemmyResult } } -/// Enforce various voting restrictions: -/// - Bots are not allowed to vote -/// - Instances can disable downvotes -pub async fn check_vote_permission( - score: i16, - local_site: &LocalSite, - person: &Person, -) -> LemmyResult<()> { - // check downvotes enabled - if score == -1 && !local_site.enable_downvotes { - return Err(LemmyErrorType::DownvotesAreDisabled)?; - } - - // prevent bots from voting - if person.bot_account { - return Err(LemmyErrorType::InvalidBotAction)?; - } - Ok(()) -} - #[cfg(test)] mod tests { #![allow(clippy::unwrap_used)] diff --git a/crates/apub/src/activities/voting/mod.rs b/crates/apub/src/activities/voting/mod.rs index 26e3c258c..0f9876f1a 100644 --- a/crates/apub/src/activities/voting/mod.rs +++ b/crates/apub/src/activities/voting/mod.rs @@ -16,13 +16,12 @@ use lemmy_db_schema::{ activity::ActivitySendTargets, comment::{CommentLike, CommentLikeForm}, community::Community, - local_site::LocalSite, person::Person, post::{PostLike, PostLikeForm}, }, traits::Likeable, }; -use lemmy_utils::error::{LemmyError, LemmyResult}; +use lemmy_utils::error::LemmyError; pub mod undo_vote; pub mod vote; @@ -67,8 +66,8 @@ async fn vote_comment( person_id: actor.id, score: vote_type.into(), }; - check_vote_permission(Some(vote_type), &actor, context).await?; - CommentLike::remove(&mut context.pool(), actor.id, comment_id).await?; + let person_id = actor.id; + CommentLike::remove(&mut context.pool(), person_id, comment_id).await?; CommentLike::like(&mut context.pool(), &like_form).await?; Ok(()) } @@ -86,9 +85,8 @@ async fn vote_post( person_id: actor.id, score: vote_type.into(), }; - - check_vote_permission(Some(vote_type), &actor, context).await?; - PostLike::remove(&mut context.pool(), actor.id, post_id).await?; + let person_id = actor.id; + PostLike::remove(&mut context.pool(), person_id, post_id).await?; PostLike::like(&mut context.pool(), &like_form).await?; Ok(()) } @@ -99,8 +97,9 @@ async fn undo_vote_comment( comment: &ApubComment, context: &Data, ) -> Result<(), LemmyError> { - check_vote_permission(None, &actor, context).await?; - CommentLike::remove(&mut context.pool(), actor.id, comment.id).await?; + let comment_id = comment.id; + let person_id = actor.id; + CommentLike::remove(&mut context.pool(), person_id, comment_id).await?; Ok(()) } @@ -110,18 +109,8 @@ async fn undo_vote_post( post: &ApubPost, context: &Data, ) -> Result<(), LemmyError> { - check_vote_permission(None, &actor, context).await?; - PostLike::remove(&mut context.pool(), actor.id, post.id).await?; - Ok(()) -} - -pub async fn check_vote_permission( - vote_type: Option<&VoteType>, - person: &Person, - context: &LemmyContext, -) -> LemmyResult<()> { - let local_site = LocalSite::read(&mut context.pool()).await?; - let score = vote_type.map(std::convert::Into::into).unwrap_or(0); - lemmy_api_common::utils::check_vote_permission(score, &local_site, person).await?; + let post_id = post.id; + let person_id = actor.id; + PostLike::remove(&mut context.pool(), person_id, post_id).await?; Ok(()) } diff --git a/crates/apub/src/activities/voting/vote.rs b/crates/apub/src/activities/voting/vote.rs index 2257f85f0..e15c3882b 100644 --- a/crates/apub/src/activities/voting/vote.rs +++ b/crates/apub/src/activities/voting/vote.rs @@ -18,7 +18,7 @@ use activitypub_federation::{ traits::{ActivityHandler, Actor}, }; use anyhow::anyhow; -use lemmy_api_common::context::LemmyContext; +use lemmy_api_common::{context::LemmyContext, utils::check_bot_account}; use lemmy_db_schema::source::local_site::LocalSite; use lemmy_utils::error::LemmyError; use url::Url; @@ -75,6 +75,8 @@ impl ActivityHandler for Vote { let actor = self.actor.dereference(context).await?; let object = self.object.dereference(context).await?; + check_bot_account(&actor.0)?; + match object { PostOrComment::Post(p) => vote_post(&self.kind, actor, &p, context).await, PostOrComment::Comment(c) => vote_comment(&self.kind, actor, &c, context).await,