From c240a8bd80e54cefa036186acb7fd8a77b7cdd92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Hanol?= Date: Mon, 1 Jun 2015 22:31:47 +0200 Subject: [PATCH] FIX: make sure we can't vote on deleted polls --- plugins/poll/config/locales/server.en.yml | 2 ++ plugins/poll/plugin.rb | 19 +++++++++++++++---- .../spec/controllers/polls_controller_spec.rb | 16 ++++++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/plugins/poll/config/locales/server.en.yml b/plugins/poll/config/locales/server.en.yml index 236103501af..f78da1322bf 100644 --- a/plugins/poll/config/locales/server.en.yml +++ b/plugins/poll/config/locales/server.en.yml @@ -35,6 +35,8 @@ en: no_polls_associated_with_this_post: "No polls are associated with this post." no_poll_with_this_name: "No poll named %{name} 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." poll_must_be_open_to_vote: "Poll must be open to vote." diff --git a/plugins/poll/plugin.rb b/plugins/poll/plugin.rb index 056001f8a29..5147e7f0723 100644 --- a/plugins/poll/plugin.rb +++ b/plugins/poll/plugin.rb @@ -36,6 +36,11 @@ after_initialize do DistributedMutex.synchronize("#{PLUGIN_NAME}-#{post_id}") do 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 if post.topic.try(:closed) || post.topic.try(:archived) 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) DistributedMutex.synchronize("#{PLUGIN_NAME}-#{post_id}") do post = Post.find_by(id: post_id) - 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") + # post must not be deleted + if post.nil? || post.trashed? + raise StandardError.new I18n.t("poll.post_is_deleted") end # topic must be open @@ -94,6 +98,13 @@ after_initialize do raise StandardError.new I18n.t("poll.topic_must_be_open_to_toggle_status") 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] raise StandardError.new I18n.t("poll.no_polls_associated_with_this_post") if polls.blank? diff --git a/plugins/poll/spec/controllers/polls_controller_spec.rb b/plugins/poll/spec/controllers/polls_controller_spec.rb index 54ee2c4d238..bcac39c71f1 100644 --- a/plugins/poll/spec/controllers/polls_controller_spec.rb +++ b/plugins/poll/spec/controllers/polls_controller_spec.rb @@ -57,6 +57,14 @@ describe ::DiscoursePoll::PollsController do expect(json["errors"][0]).to eq(I18n.t("poll.topic_must_be_open_to_vote")) 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 xhr :put, :vote, { post_id: Fabricate(:post).id, poll_name: "foobar", options: ["A"] } expect(response).not_to be_success @@ -102,6 +110,14 @@ describe ::DiscoursePoll::PollsController do expect(json["poll"]["status"]).to eq("closed") 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