From 298221116757f394bd00855028472bd5241a6db0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 4 Jun 2019 20:10:26 +0200 Subject: [PATCH] Fix poll API not requiring authentication on non-public polls (#10960) * Fix poll API not requiring authentication on non-public polls That API does not reveal the content of the status, i.e. the question itself, nor who the author is, nor which status it belongs to, but it does reveal the poll options and how many answers they got Fix #10959 * Add test --- app/controllers/api/v1/polls_controller.rb | 17 ++++++++++++++++- .../api/v1/polls_controller_spec.rb | 18 +++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/v1/polls_controller.rb b/app/controllers/api/v1/polls_controller.rb index 4f4a6858dbac18..031e6d42d668e3 100644 --- a/app/controllers/api/v1/polls_controller.rb +++ b/app/controllers/api/v1/polls_controller.rb @@ -1,13 +1,28 @@ # frozen_string_literal: true class Api::V1::PollsController < Api::BaseController + include Authorization + before_action -> { authorize_if_got_token! :read, :'read:statuses' }, only: :show + before_action :set_poll + before_action :refresh_poll respond_to :json def show + render json: @poll, serializer: REST::PollSerializer, include_results: true + end + + private + + def set_poll @poll = Poll.attached.find(params[:id]) + authorize @poll.status, :show? + rescue Mastodon::NotPermittedError + raise ActiveRecord::RecordNotFound + end + + def refresh_poll ActivityPub::FetchRemotePollService.new.call(@poll, current_account) if user_signed_in? && @poll.possibly_stale? - render json: @poll, serializer: REST::PollSerializer, include_results: true end end diff --git a/spec/controllers/api/v1/polls_controller_spec.rb b/spec/controllers/api/v1/polls_controller_spec.rb index 2b8d5f3ef54343..851bccb7e2dce4 100644 --- a/spec/controllers/api/v1/polls_controller_spec.rb +++ b/spec/controllers/api/v1/polls_controller_spec.rb @@ -10,14 +10,26 @@ before { allow(controller).to receive(:doorkeeper_token) { token } } describe 'GET #show' do - let(:poll) { Fabricate(:poll) } + let(:poll) { Fabricate(:poll, status: Fabricate(:status, visibility: visibility)) } before do get :show, params: { id: poll.id } end - it 'returns http success' do - expect(response).to have_http_status(200) + context 'when parent status is public' do + let(:visibility) { 'public' } + + it 'returns http success' do + expect(response).to have_http_status(200) + end + end + + context 'when parent status is private' do + let(:visibility) { 'private' } + + it 'returns http not found' do + expect(response).to have_http_status(404) + end end end end