mirror of
https://github.com/discourse/discourse.git
synced 2025-05-22 22:43:33 +08:00
FIX: make sure we can't vote on deleted polls
This commit is contained in:
@ -35,6 +35,8 @@ en:
|
|||||||
no_polls_associated_with_this_post: "No polls are associated with this post."
|
no_polls_associated_with_this_post: "No polls are associated with this post."
|
||||||
no_poll_with_this_name: "No poll named <strong>%{name}</strong> associated with this post."
|
no_poll_with_this_name: "No poll named <strong>%{name}</strong> associated with this post."
|
||||||
|
|
||||||
|
post_is_deleted: "Cannot act on a deleted post."
|
||||||
|
|
||||||
topic_must_be_open_to_vote: "The topic must be open to vote."
|
topic_must_be_open_to_vote: "The topic must be open to vote."
|
||||||
poll_must_be_open_to_vote: "Poll must be open to vote."
|
poll_must_be_open_to_vote: "Poll must be open to vote."
|
||||||
|
|
||||||
|
@ -36,6 +36,11 @@ after_initialize do
|
|||||||
DistributedMutex.synchronize("#{PLUGIN_NAME}-#{post_id}") do
|
DistributedMutex.synchronize("#{PLUGIN_NAME}-#{post_id}") do
|
||||||
post = Post.find_by(id: post_id)
|
post = Post.find_by(id: post_id)
|
||||||
|
|
||||||
|
# post must not be deleted
|
||||||
|
if post.nil? || post.trashed?
|
||||||
|
raise StandardError.new I18n.t("poll.post_is_deleted")
|
||||||
|
end
|
||||||
|
|
||||||
# topic must be open
|
# topic must be open
|
||||||
if post.topic.try(:closed) || post.topic.try(:archived)
|
if post.topic.try(:closed) || post.topic.try(:archived)
|
||||||
raise StandardError.new I18n.t("poll.topic_must_be_open_to_vote")
|
raise StandardError.new I18n.t("poll.topic_must_be_open_to_vote")
|
||||||
@ -82,11 +87,10 @@ after_initialize do
|
|||||||
def toggle_status(post_id, poll_name, status, user_id)
|
def toggle_status(post_id, poll_name, status, user_id)
|
||||||
DistributedMutex.synchronize("#{PLUGIN_NAME}-#{post_id}") do
|
DistributedMutex.synchronize("#{PLUGIN_NAME}-#{post_id}") do
|
||||||
post = Post.find_by(id: post_id)
|
post = Post.find_by(id: post_id)
|
||||||
user = User.find_by(id: user_id)
|
|
||||||
|
|
||||||
# either staff member or OP
|
# post must not be deleted
|
||||||
unless user_id == post.user_id || user.try(:staff?)
|
if post.nil? || post.trashed?
|
||||||
raise StandardError.new I18n.t("poll.only_staff_or_op_can_toggle_status")
|
raise StandardError.new I18n.t("poll.post_is_deleted")
|
||||||
end
|
end
|
||||||
|
|
||||||
# topic must be open
|
# topic must be open
|
||||||
@ -94,6 +98,13 @@ after_initialize do
|
|||||||
raise StandardError.new I18n.t("poll.topic_must_be_open_to_toggle_status")
|
raise StandardError.new I18n.t("poll.topic_must_be_open_to_toggle_status")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
user = User.find_by(id: user_id)
|
||||||
|
|
||||||
|
# either staff member or OP
|
||||||
|
unless user_id == post.user_id || user.try(:staff?)
|
||||||
|
raise StandardError.new I18n.t("poll.only_staff_or_op_can_toggle_status")
|
||||||
|
end
|
||||||
|
|
||||||
polls = post.custom_fields[POLLS_CUSTOM_FIELD]
|
polls = post.custom_fields[POLLS_CUSTOM_FIELD]
|
||||||
|
|
||||||
raise StandardError.new I18n.t("poll.no_polls_associated_with_this_post") if polls.blank?
|
raise StandardError.new I18n.t("poll.no_polls_associated_with_this_post") if polls.blank?
|
||||||
|
@ -57,6 +57,14 @@ describe ::DiscoursePoll::PollsController do
|
|||||||
expect(json["errors"][0]).to eq(I18n.t("poll.topic_must_be_open_to_vote"))
|
expect(json["errors"][0]).to eq(I18n.t("poll.topic_must_be_open_to_vote"))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "ensures post is not trashed" do
|
||||||
|
poll.trash!
|
||||||
|
xhr :put, :vote, { post_id: poll.id, poll_name: "poll", options: ["A"] }
|
||||||
|
expect(response).not_to be_success
|
||||||
|
json = ::JSON.parse(response.body)
|
||||||
|
expect(json["errors"][0]).to eq(I18n.t("poll.post_is_deleted"))
|
||||||
|
end
|
||||||
|
|
||||||
it "ensures polls are associated with the post" do
|
it "ensures polls are associated with the post" do
|
||||||
xhr :put, :vote, { post_id: Fabricate(:post).id, poll_name: "foobar", options: ["A"] }
|
xhr :put, :vote, { post_id: Fabricate(:post).id, poll_name: "foobar", options: ["A"] }
|
||||||
expect(response).not_to be_success
|
expect(response).not_to be_success
|
||||||
@ -102,6 +110,14 @@ describe ::DiscoursePoll::PollsController do
|
|||||||
expect(json["poll"]["status"]).to eq("closed")
|
expect(json["poll"]["status"]).to eq("closed")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "ensures post is not trashed" do
|
||||||
|
poll.trash!
|
||||||
|
xhr :put, :toggle_status, { post_id: poll.id, poll_name: "poll", status: "closed" }
|
||||||
|
expect(response).not_to be_success
|
||||||
|
json = ::JSON.parse(response.body)
|
||||||
|
expect(json["errors"][0]).to eq(I18n.t("poll.post_is_deleted"))
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user