Skip to content

Commit

Permalink
Do not allow adding votes to expired polls (mastodon#10214)
Browse files Browse the repository at this point in the history
* Do not allow adding votes to expired polls

* Only validate expires_at on create
  • Loading branch information
ClearlyClaire authored and Gargron committed Mar 7, 2019
1 parent af136d6 commit 8a9f202
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 1 deletion.
1 change: 1 addition & 0 deletions app/lib/activitypub/activity/create.rb
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ def process_poll

def poll_vote?
return false if replied_to_status.nil? || replied_to_status.poll.nil? || !replied_to_status.local? || !replied_to_status.poll.options.include?(@object['name'])
return true if replied_to_status.poll.expired?
replied_to_status.poll.votes.create!(account: @account, choice: replied_to_status.poll.options.index(@object['name']), uri: @object['id'])
end

Expand Down
2 changes: 1 addition & 1 deletion app/models/poll.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class Poll < ApplicationRecord

validates :options, presence: true
validates :expires_at, presence: true, if: :local?
validates_with PollValidator, if: :local?
validates_with PollValidator, on: :create, if: :local?

scope :attached, -> { where.not(status_id: nil) }
scope :unattached, -> { where(status_id: nil) }
Expand Down
2 changes: 2 additions & 0 deletions app/services/vote_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ def call(account, poll, choices)
@choices = choices
@votes = []

return if @poll.expired?

ApplicationRecord.transaction do
@choices.each do |choice|
@votes << @poll.votes.create!(account: @account, choice: choice)
Expand Down
22 changes: 22 additions & 0 deletions spec/lib/activitypub/activity/create_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,28 @@
expect(poll.reload.cached_tallies).to eq [1, 0]
end
end

context 'when a vote to an expired local poll' do
let(:poll) do
poll = Fabricate.build(:poll, options: %w(Yellow Blue), expires_at: 1.day.ago)
poll.save(validate: false)
poll
end
let!(:local_status) { Fabricate(:status, owned_poll: poll) }

let(:object_json) do
{
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
type: 'Note',
name: 'Yellow',
inReplyTo: ActivityPub::TagManager.instance.uri_for(local_status)
}
end

it 'does not add a vote to the poll' do
expect(poll.votes.first).to be_nil
end
end
end

context 'when sender is followed by local users' do
Expand Down

0 comments on commit 8a9f202

Please sign in to comment.