mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-21 00:18:33 +08:00
Extracts `accept_answer!` and `unaccept_answer!` from plugin.rb and moves the logic into separate service objects, along with adding more detailed test coverage for each service. --------- Co-authored-by: Loïc Guitaut <loic@discourse.org>
51 lines
1.9 KiB
Ruby
Vendored
51 lines
1.9 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
class DiscourseSolved::AnswerController < ::ApplicationController
|
|
requires_plugin DiscourseSolved::PLUGIN_NAME
|
|
|
|
before_action :limit_accepts
|
|
|
|
def accept
|
|
DiscourseSolved::AcceptAnswer.call(params: { post_id: params[:id] }, guardian:) do
|
|
on_success { |topic:| render_json_dump(topic.accepted_answer_post_info) }
|
|
on_model_not_found(:post) { raise Discourse::NotFound }
|
|
on_model_not_found(:topic) { raise Discourse::NotFound }
|
|
on_failed_policy(:can_accept_answer) { raise Discourse::InvalidAccess }
|
|
on_model_errors(:solved) do |model|
|
|
render_json_error(model, type: :record_invalid, status: 422)
|
|
end
|
|
on_failed_contract do |contract|
|
|
render json: failed_json.merge(errors: contract.errors.full_messages), status: :bad_request
|
|
end
|
|
on_failure { render json: failed_json, status: :unprocessable_entity }
|
|
end
|
|
end
|
|
|
|
def unaccept
|
|
DiscourseSolved::UnacceptAnswer.call(params: { post_id: params[:id] }, guardian:) do
|
|
on_success { render json: success_json }
|
|
on_model_not_found(:post) { raise Discourse::NotFound }
|
|
on_model_not_found(:topic) { raise Discourse::NotFound }
|
|
on_failed_policy(:can_unaccept_answer) { raise Discourse::InvalidAccess }
|
|
on_failed_contract do |contract|
|
|
render json: failed_json.merge(errors: contract.errors.full_messages), status: :bad_request
|
|
end
|
|
on_failure { render json: failed_json, status: :unprocessable_entity }
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def limit_accepts
|
|
return if current_user.staff?
|
|
run_rate_limiter =
|
|
DiscoursePluginRegistry.apply_modifier(
|
|
:solved_answers_controller_run_rate_limiter,
|
|
true,
|
|
current_user,
|
|
)
|
|
return if !run_rate_limiter
|
|
RateLimiter.new(nil, "accept-hr-#{current_user.id}", 20, 1.hour).performed!
|
|
RateLimiter.new(nil, "accept-min-#{current_user.id}", 4, 30.seconds).performed!
|
|
end
|
|
end
|