Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix not being able to block a subdomain of an already-blocked domain through the API #30119

Merged
merged 1 commit into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 7 additions & 2 deletions app/controllers/api/v1/admin/domain_blocks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ def show
def create
authorize :domain_block, :create?

@domain_block = DomainBlock.new(resource_params)
existing_domain_block = resource_params[:domain].present? ? DomainBlock.rule_for(resource_params[:domain]) : nil
return render json: existing_domain_block, serializer: REST::Admin::ExistingDomainBlockErrorSerializer, status: 422 if existing_domain_block.present?
return render json: existing_domain_block, serializer: REST::Admin::ExistingDomainBlockErrorSerializer, status: 422 if conflicts_with_existing_block?(@domain_block, existing_domain_block)

@domain_block = DomainBlock.create!(resource_params)
@domain_block.save!
DomainBlockWorker.perform_async(@domain_block.id)
log_action :create, @domain_block
render json: @domain_block, serializer: REST::Admin::DomainBlockSerializer
Expand All @@ -55,6 +56,10 @@ def destroy

private

def conflicts_with_existing_block?(domain_block, existing_domain_block)
existing_domain_block.present? && (existing_domain_block.domain == TagManager.instance.normalize_domain(domain_block.domain) || !domain_block.stricter_than?(existing_domain_block))
end

def set_domain_blocks
@domain_blocks = filtered_domain_blocks.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
end
Expand Down
41 changes: 39 additions & 2 deletions spec/requests/api/v1/admin/domain_blocks_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
it_behaves_like 'forbidden for wrong role', ''
it_behaves_like 'forbidden for wrong role', 'Moderator'

it 'returns expected domain name and severity', :aggregate_failures do
it 'creates a domain block with the expected domain name and severity', :aggregate_failures do
subject

body = body_as_json
Expand All @@ -146,7 +146,44 @@
expect(DomainBlock.find_by(domain: 'foo.bar.com')).to be_present
end

context 'when a stricter domain block already exists' do
context 'when a looser domain block already exists on a higher level domain' do
let(:params) { { domain: 'foo.bar.com', severity: :suspend } }

before do
Fabricate(:domain_block, domain: 'bar.com', severity: :silence)
end

it 'creates a domain block with the expected domain name and severity', :aggregate_failures do
subject

body = body_as_json

expect(response).to have_http_status(200)
expect(body).to match a_hash_including(
{
domain: 'foo.bar.com',
severity: 'suspend',
}
)

expect(DomainBlock.find_by(domain: 'foo.bar.com')).to be_present
end
end

context 'when a domain block already exists on the same domain' do
before do
Fabricate(:domain_block, domain: 'foo.bar.com', severity: :silence)
end

it 'returns existing domain block in error', :aggregate_failures do
subject

expect(response).to have_http_status(422)
expect(body_as_json[:existing_domain_block][:domain]).to eq('foo.bar.com')
end
end

context 'when a stricter domain block already exists on a higher level domain' do
before do
Fabricate(:domain_block, domain: 'bar.com', severity: :suspend)
end
Expand Down