Move status reblog authorization into policy (#3425)
This commit is contained in:
		
							parent
							
								
									bc4fad9e22
								
							
						
					
					
						commit
						e031fd60ad
					
				
					 3 changed files with 42 additions and 11 deletions
				
			
		|  | @ -9,12 +9,26 @@ class StatusPolicy | |||
|   end | ||||
| 
 | ||||
|   def show? | ||||
|     if status.direct_visibility? | ||||
|     if direct? | ||||
|       status.account.id == account&.id || status.mentions.where(account: account).exists? | ||||
|     elsif status.private_visibility? | ||||
|     elsif private? | ||||
|       status.account.id == account&.id || account&.following?(status.account) || status.mentions.where(account: account).exists? | ||||
|     else | ||||
|       account.nil? || !status.account.blocking?(account) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def reblog? | ||||
|     !direct? && !private? && show? | ||||
|   end | ||||
| 
 | ||||
|   private | ||||
| 
 | ||||
|   def direct? | ||||
|     status.direct_visibility? | ||||
|   end | ||||
| 
 | ||||
|   def private? | ||||
|     status.private_visibility? | ||||
|   end | ||||
| end | ||||
|  |  | |||
|  | @ -11,8 +11,7 @@ class ReblogService < BaseService | |||
|   def call(account, reblogged_status) | ||||
|     reblogged_status = reblogged_status.reblog if reblogged_status.reblog? | ||||
| 
 | ||||
|     authorize_with account, reblogged_status, :show? | ||||
|     raise Mastodon::NotPermittedError if reblogged_status.direct_visibility? || reblogged_status.private_visibility? | ||||
|     authorize_with account, reblogged_status, :reblog? | ||||
| 
 | ||||
|     reblog = account.statuses.create!(reblog: reblogged_status, text: '') | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,6 +7,20 @@ RSpec.describe StatusPolicy, type: :model do | |||
|   let(:alice) { Fabricate(:account, username: 'alice') } | ||||
|   let(:status) { Fabricate(:status, account: alice) } | ||||
| 
 | ||||
|   permissions :show?, :reblog? do | ||||
|     it 'grants access when no viewer' do | ||||
|       expect(subject).to permit(nil, status) | ||||
|     end | ||||
| 
 | ||||
|     it 'denies access when viewer is blocked' do | ||||
|       block = Fabricate(:block) | ||||
|       status.visibility = :private | ||||
|       status.account = block.target_account | ||||
| 
 | ||||
|       expect(subject).to_not permit(block.account, status) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   permissions :show? do | ||||
|     it 'grants access when direct and account is viewer' do | ||||
|       status.visibility = :direct | ||||
|  | @ -54,17 +68,21 @@ RSpec.describe StatusPolicy, type: :model do | |||
| 
 | ||||
|       expect(subject).to_not permit(viewer, status) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|     it 'grants access when no viewer' do | ||||
|       expect(subject).to permit(nil, status) | ||||
|   permissions :reblog? do | ||||
|     it 'denies access when private' do | ||||
|       viewer = Fabricate(:account) | ||||
|       status.visibility = :private | ||||
| 
 | ||||
|       expect(subject).to_not permit(viewer, status) | ||||
|     end | ||||
| 
 | ||||
|     it 'denies access when viewer is blocked' do | ||||
|       block = Fabricate(:block) | ||||
|       status.visibility = :private | ||||
|       status.account = block.target_account | ||||
|     it 'denies access when direct' do | ||||
|       viewer = Fabricate(:account) | ||||
|       status.visibility = :direct | ||||
| 
 | ||||
|       expect(subject).to_not permit(block.account, status) | ||||
|       expect(subject).to_not permit(viewer, status) | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  |  | |||
		Reference in a new issue