Provide a link to existing domain block when trying to block an already-blocked domain (#10663)

* When trying to block an already-blocked domain, provide a link to the block

* Fix styling for links in flash messages

* Allow blocks to be upgraded but not downgraded
This commit is contained in:
ThibG 2019-05-03 20:36:36 +02:00 committed by Eugen Rochko
parent eb63217210
commit 011b032300
6 changed files with 79 additions and 6 deletions

View File

@ -13,13 +13,25 @@ module Admin
authorize :domain_block, :create? authorize :domain_block, :create?
@domain_block = DomainBlock.new(resource_params) @domain_block = DomainBlock.new(resource_params)
existing_domain_block = resource_params[:domain].present? ? DomainBlock.find_by(domain: resource_params[:domain]) : nil
if @domain_block.save if existing_domain_block.present? && !@domain_block.stricter_than?(existing_domain_block)
DomainBlockWorker.perform_async(@domain_block.id) @domain_block.save
log_action :create, @domain_block flash[:alert] = I18n.t('admin.domain_blocks.existing_domain_block_html', name: existing_domain_block.domain, unblock_url: admin_domain_block_path(existing_domain_block)).html_safe # rubocop:disable Rails/OutputSafety
redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg') @domain_block.errors[:domain].clear
else
render :new render :new
else
if existing_domain_block.present?
@domain_block = existing_domain_block
@domain_block.update(resource_params)
end
if @domain_block.save
DomainBlockWorker.perform_async(@domain_block.id)
log_action :create, @domain_block
redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg')
else
render :new
end
end end
end end

View File

@ -533,6 +533,17 @@ code {
color: $error-value-color; color: $error-value-color;
} }
a {
display: inline-block;
color: $darker-text-color;
text-decoration: none;
&:hover {
color: $primary-text-color;
text-decoration: underline;
}
}
p { p {
margin-bottom: 15px; margin-bottom: 15px;
} }

View File

@ -29,4 +29,11 @@ class DomainBlock < ApplicationRecord
def self.blocked?(domain) def self.blocked?(domain)
where(domain: domain, severity: :suspend).exists? where(domain: domain, severity: :suspend).exists?
end end
def stricter_than?(other_block)
return true if suspend?
return false if other_block.suspend? && (silence? || noop?)
return false if other_block.silence? && noop?
(reject_media || !other_block.reject_media) && (reject_reports || !other_block.reject_reports)
end
end end

View File

@ -269,6 +269,7 @@ en:
created_msg: Domain block is now being processed created_msg: Domain block is now being processed
destroyed_msg: Domain block has been undone destroyed_msg: Domain block has been undone
domain: Domain domain: Domain
existing_domain_block_html: You have already imposed stricter limits on %{name}, you need to <a href="%{unblock_url}">unblock it</a> first.
new: new:
create: Create block create: Create block
hint: The domain block will not prevent creation of account entries in the database, but will retroactively and automatically apply specific moderation methods on those accounts. hint: The domain block will not prevent creation of account entries in the database, but will retroactively and automatically apply specific moderation methods on those accounts.

View File

@ -37,7 +37,7 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do
end end
it 'renders new when failed to save' do it 'renders new when failed to save' do
Fabricate(:domain_block, domain: 'example.com') Fabricate(:domain_block, domain: 'example.com', severity: 'suspend')
allow(DomainBlockWorker).to receive(:perform_async).and_return(true) allow(DomainBlockWorker).to receive(:perform_async).and_return(true)
post :create, params: { domain_block: { domain: 'example.com', severity: 'silence' } } post :create, params: { domain_block: { domain: 'example.com', severity: 'silence' } }
@ -45,6 +45,17 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do
expect(DomainBlockWorker).not_to have_received(:perform_async) expect(DomainBlockWorker).not_to have_received(:perform_async)
expect(response).to render_template :new expect(response).to render_template :new
end end
it 'allows upgrading a block' do
Fabricate(:domain_block, domain: 'example.com', severity: 'silence')
allow(DomainBlockWorker).to receive(:perform_async).and_return(true)
post :create, params: { domain_block: { domain: 'example.com', severity: 'silence', reject_media: true, reject_reports: true } }
expect(DomainBlockWorker).to have_received(:perform_async)
expect(flash[:notice]).to eq I18n.t('admin.domain_blocks.created_msg')
expect(response).to redirect_to(admin_instances_path(limited: '1'))
end
end end
describe 'DELETE #destroy' do describe 'DELETE #destroy' do

View File

@ -36,4 +36,35 @@ RSpec.describe DomainBlock, type: :model do
expect(DomainBlock.blocked?('domain')).to eq false expect(DomainBlock.blocked?('domain')).to eq false
end end
end end
describe 'stricter_than?' do
it 'returns true if the new block has suspend severity while the old has lower severity' do
suspend = DomainBlock.new(domain: 'domain', severity: :suspend)
silence = DomainBlock.new(domain: 'domain', severity: :silence)
noop = DomainBlock.new(domain: 'domain', severity: :noop)
expect(suspend.stricter_than?(silence)).to be true
expect(suspend.stricter_than?(noop)).to be true
end
it 'returns false if the new block has lower severity than the old one' do
suspend = DomainBlock.new(domain: 'domain', severity: :suspend)
silence = DomainBlock.new(domain: 'domain', severity: :silence)
noop = DomainBlock.new(domain: 'domain', severity: :noop)
expect(silence.stricter_than?(suspend)).to be false
expect(noop.stricter_than?(suspend)).to be false
expect(noop.stricter_than?(silence)).to be false
end
it 'returns false if the new block does is less strict regarding reports' do
older = DomainBlock.new(domain: 'domain', severity: :silence, reject_reports: true)
newer = DomainBlock.new(domain: 'domain', severity: :silence, reject_reports: false)
expect(newer.stricter_than?(older)).to be false
end
it 'returns false if the new block does is less strict regarding media' do
older = DomainBlock.new(domain: 'domain', severity: :silence, reject_media: true)
newer = DomainBlock.new(domain: 'domain', severity: :silence, reject_media: false)
expect(newer.stricter_than?(older)).to be false
end
end
end end