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
This commit is contained in:
Eugen Rochko 2019-06-04 20:10:26 +02:00 committed by GitHub
parent 6077eca240
commit 48fee1a800
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 5 deletions

View File

@ -1,13 +1,28 @@
# frozen_string_literal: true # frozen_string_literal: true
class Api::V1::PollsController < Api::BaseController class Api::V1::PollsController < Api::BaseController
include Authorization
before_action -> { authorize_if_got_token! :read, :'read:statuses' }, only: :show before_action -> { authorize_if_got_token! :read, :'read:statuses' }, only: :show
before_action :set_poll
before_action :refresh_poll
respond_to :json respond_to :json
def show def show
@poll = Poll.attached.find(params[:id])
ActivityPub::FetchRemotePollService.new.call(@poll, current_account) if user_signed_in? && @poll.possibly_stale?
render json: @poll, serializer: REST::PollSerializer, include_results: true render json: @poll, serializer: REST::PollSerializer, include_results: true
end 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?
end
end end

View File

@ -10,14 +10,26 @@ RSpec.describe Api::V1::PollsController, type: :controller do
before { allow(controller).to receive(:doorkeeper_token) { token } } before { allow(controller).to receive(:doorkeeper_token) { token } }
describe 'GET #show' do describe 'GET #show' do
let(:poll) { Fabricate(:poll) } let(:poll) { Fabricate(:poll, status: Fabricate(:status, visibility: visibility)) }
before do before do
get :show, params: { id: poll.id } get :show, params: { id: poll.id }
end end
context 'when parent status is public' do
let(:visibility) { 'public' }
it 'returns http success' do it 'returns http success' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
end end
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 end