FIX: do not allow whispers to be accepted as answers

This also cleans up the guardian so it is easier to reason about
This commit is contained in:
Sam Saffron 2020-02-23 19:16:31 +11:00
parent 26d247e3d7
commit e5b08c71c4
No known key found for this signature in database
GPG Key ID: B9606168D2FFD9F5
2 changed files with 22 additions and 11 deletions

View File

@ -188,7 +188,7 @@ SQL
topic = post.topic topic = post.topic
topic ||= Topic.with_deleted.find(post.topic_id) if guardian.is_staff? topic ||= Topic.with_deleted.find(post.topic_id) if guardian.is_staff?
guardian.ensure_can_accept_answer!(topic) guardian.ensure_can_accept_answer!(topic, post)
DiscourseSolved.accept_answer!(post, current_user, topic: topic) DiscourseSolved.accept_answer!(post, current_user, topic: topic)
@ -204,7 +204,7 @@ SQL
topic = post.topic topic = post.topic
topic ||= Topic.with_deleted.find(post.topic_id) if guardian.is_staff? topic ||= Topic.with_deleted.find(post.topic_id) if guardian.is_staff?
guardian.ensure_can_accept_answer!(topic) guardian.ensure_can_accept_answer!(topic, post)
DiscourseSolved.unaccept_answer!(post, topic: topic) DiscourseSolved.unaccept_answer!(post, topic: topic)
render json: success_json render json: success_json
@ -422,13 +422,16 @@ SQL
@@allowed_accepted_cache["allowed"].include?(category_id) @@allowed_accepted_cache["allowed"].include?(category_id)
end end
def can_accept_answer?(topic) def can_accept_answer?(topic, post)
topic && allow_accepted_answers_on_category?(topic.category_id) && ( return false if !authenticated?
is_staff? || ( return false if !topic || !post || post.whisper?
authenticated? && ((!topic.closed? && topic.user_id == current_user.id) || return false if !allow_accepted_answers_on_category?(topic.category_id)
(current_user.trust_level >= SiteSetting.accept_all_solutions_trust_level))
) return true if is_staff?
) return true if current_user.trust_level >= SiteSetting.accept_all_solutions_trust_level
topic.user_id == current_user.id && !topic.closed
end end
end end
@ -440,7 +443,7 @@ SQL
topic = (topic_view && topic_view.topic) || object.topic topic = (topic_view && topic_view.topic) || object.topic
if topic if topic
return scope.can_accept_answer?(topic) && object.post_number > 1 && !accepted_answer return scope.can_accept_answer?(topic, object) && object.post_number > 1 && !accepted_answer
end end
false false
@ -449,7 +452,7 @@ SQL
def can_unaccept_answer def can_unaccept_answer
topic = (topic_view && topic_view.topic) || object.topic topic = (topic_view && topic_view.topic) || object.topic
if topic if topic
scope.can_accept_answer?(topic) && (post_custom_fields["is_accepted_answer"] == 'true') scope.can_accept_answer?(topic, object) && (post_custom_fields["is_accepted_answer"] == 'true')
end end
end end

View File

@ -90,6 +90,14 @@ RSpec.describe "Managing Posts solved status" do
p1.reload p1.reload
expect(p1.custom_fields["is_accepted_answer"]).to eq("true") expect(p1.custom_fields["is_accepted_answer"]).to eq("true")
end end
it 'does not allow you to accept a whisper' do
whisper = Fabricate(:post, topic: topic, post_type: Post.types[:whisper])
sign_in(Fabricate(:admin))
post "/solution/accept.json", params: { id: whisper.id }
expect(response.status).to eq(403)
end
end end
describe '#unaccept' do describe '#unaccept' do