votes: allow admins to remove post votes.

Allow admins to remove votes on posts. This is for fixing vote abuse.

Votes can be removed by going to the vote list on the /post_votes page,
or by clicking on a post's score, then using the "Remove" option in the
"..." dropdown menu next to the vote.

Votes are soft-deleted - they're marked as deleted in the database, but
not fully deleted. Removed votes are only visible to admins, not to
regular users. When a vote is removed by an admin, it leaves a mod
action.

Technically it's possible to undelete votes, but there's no UI for it.
This commit is contained in:
evazion
2021-11-23 22:20:01 -06:00
parent 692f2848f2
commit 353e708538
19 changed files with 261 additions and 108 deletions

View File

@@ -2,7 +2,7 @@ class PostVotesController < ApplicationController
respond_to :js, :json, :xml, :html
def index
@post_votes = authorize PostVote.visible(CurrentUser.user).paginated_search(params, count_pages: true)
@post_votes = authorize PostVote.visible(CurrentUser.user).paginated_search(params)
@post_votes = @post_votes.includes(:user, post: [:uploader, :media_asset]) if request.format.html?
@post = Post.find(params.dig(:search, :post_id)) if params.dig(:search, :post_id).present?
@@ -15,23 +15,28 @@ class PostVotesController < ApplicationController
end
def create
@post = Post.find(params[:post_id])
@post.with_lock do
@post_vote = authorize PostVote.new(post: @post, score: params[:score], user: CurrentUser.user)
PostVote.where(post: @post, user: CurrentUser.user).destroy_all
@post_vote.save
end
@post_vote = authorize PostVote.new(post_id: params[:post_id], score: params[:score], user: CurrentUser.user)
@post_vote.save
@post = @post_vote.post.reload
flash.now[:notice] = @post_vote.errors.full_messages.join("; ") if @post_vote.errors.present?
respond_with(@post_vote)
end
def destroy
@post = Post.find(params[:post_id])
@post_vote = @post.votes.find_by(user: CurrentUser.user)
if params[:post_id].present?
@post_vote = PostVote.active.find_by(post_id: params[:post_id], user_id: CurrentUser.user)
@post = Post.find(params[:post_id])
else
@post_vote = PostVote.find(params[:id])
@post = @post_vote.post
end
if @post_vote.present?
authorize(@post_vote).soft_delete(updater: CurrentUser.user)
@post.reload
end
authorize(@post_vote).destroy if @post_vote
respond_with(@post_vote)
end
end