]> cat aescling's git repositories - mastodon.git/commitdiff
Fix poll API not requiring authentication on non-public polls (#10960)
authorEugen Rochko <eugen@zeonfederated.com>
Tue, 4 Jun 2019 18:10:26 +0000 (20:10 +0200)
committerGitHub <noreply@github.com>
Tue, 4 Jun 2019 18:10:26 +0000 (20:10 +0200)
* 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
spec/controllers/api/v1/polls_controller_spec.rb

index 4f4a6858dbac1890d51c4304b1e4005466455181..031e6d42d668e380e917127203df72b647236d14 100644 (file)
@@ -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
index 2b8d5f3ef543437391a7b5d73fe0c37c0c7ccee2..851bccb7e2dce400ade477eb9caad1bf47ad609b 100644 (file)
@@ -10,14 +10,26 @@ RSpec.describe Api::V1::PollsController, type: :controller do
   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