Do not allow adding votes to expired polls (#10214)
* Do not allow adding votes to expired polls * Only validate expires_at on create
This commit is contained in:
		
							parent
							
								
									054bbb3da2
								
							
						
					
					
						commit
						3aaac4f134
					
				@ -241,6 +241,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  def poll_vote?
 | 
					  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 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'])
 | 
					    replied_to_status.poll.votes.create!(account: @account, choice: replied_to_status.poll.options.index(@object['name']), uri: @object['id'])
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -28,7 +28,7 @@ class Poll < ApplicationRecord
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  validates :options, presence: true
 | 
					  validates :options, presence: true
 | 
				
			||||||
  validates :expires_at, presence: true, if: :local?
 | 
					  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 :attached, -> { where.not(status_id: nil) }
 | 
				
			||||||
  scope :unattached, -> { where(status_id: nil) }
 | 
					  scope :unattached, -> { where(status_id: nil) }
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,8 @@ class VoteService < BaseService
 | 
				
			|||||||
    @choices = choices
 | 
					    @choices = choices
 | 
				
			||||||
    @votes   = []
 | 
					    @votes   = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return if @poll.expired?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ApplicationRecord.transaction do
 | 
					    ApplicationRecord.transaction do
 | 
				
			||||||
      @choices.each do |choice|
 | 
					      @choices.each do |choice|
 | 
				
			||||||
        @votes << @poll.votes.create!(account: @account, choice: choice)
 | 
					        @votes << @poll.votes.create!(account: @account, choice: choice)
 | 
				
			||||||
 | 
				
			|||||||
@ -482,6 +482,28 @@ RSpec.describe ActivityPub::Activity::Create do
 | 
				
			|||||||
          expect(poll.reload.cached_tallies).to eq [1, 0]
 | 
					          expect(poll.reload.cached_tallies).to eq [1, 0]
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      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
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    context 'when sender is followed by local users' do
 | 
					    context 'when sender is followed by local users' do
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user