diff --git a/app/controllers/admin/instances_controller.rb b/app/controllers/admin/instances_controller.rb index a48c4773ed..20d5add54e 100644 --- a/app/controllers/admin/instances_controller.rb +++ b/app/controllers/admin/instances_controller.rb @@ -56,6 +56,12 @@ module Admin end def set_instances + # If we have `limited` in the query parameters, remove it and redirect to suspended: + return redirect_to admin_instances_path filter_params.merge(status: :suspended) if params[:limited].present? + + # If we're in limited federation mode and have a status parameter, remove it: + return redirect_to admin_instances_path filter_params.merge(status: nil) if limited_federation_mode? && params[:status].present? + @instances = filtered_instances.page(params[:page]) end @@ -68,7 +74,7 @@ module Admin end def filtered_instances - InstanceFilter.new(limited_federation_mode? ? { allowed: true } : filter_params).results + InstanceFilter.new(limited_federation_mode? ? filter_params.merge(status: :allowed) : filter_params).results end def filter_params diff --git a/app/models/instance_filter.rb b/app/models/instance_filter.rb index 7e71640e52..46174351f6 100644 --- a/app/models/instance_filter.rb +++ b/app/models/instance_filter.rb @@ -2,7 +2,7 @@ class InstanceFilter KEYS = %i( - limited + status by_domain availability ).freeze @@ -27,10 +27,8 @@ class InstanceFilter def scope_for(key, value) case key.to_s - when 'limited' - Instance.joins(:domain_block).reorder(domain_blocks: { id: :desc }) - when 'allowed' - Instance.joins(:domain_allow).reorder(domain_allows: { id: :desc }) + when 'status' + status_scope(value) when 'by_domain' Instance.matches_domain(value) when 'availability' @@ -40,6 +38,27 @@ class InstanceFilter end end + def status_scope(value) + # The `join where` queries here look like they have a bug due to `domain_block` + # vs `domain_blocks`, however the table is `domain_blocks` while the relation on + # Instances is `domain_block` + case value.to_sym + when :allowed + Instance.joins(:domain_allow).reorder(Arel.sql('domain_allows.id desc')) + when :suspended + Instance.joins(:domain_block).where(domain_blocks: { severity: :suspend }).reorder(Arel.sql('domain_blocks.id desc')) + when :silenced + Instance.joins(:domain_block).where(domain_blocks: { severity: :silence }).reorder(Arel.sql('domain_blocks.id desc')) + when :noop + Instance.joins(:domain_block).where(domain_blocks: { severity: :noop }).reorder(Arel.sql('domain_blocks.id desc')) + when :not_limited + # Finds all instances where there isn't a record in the domain_blocks table + Instance.left_outer_joins(:domain_block).where(domain_blocks: { domain: nil }) + else + raise Mastodon::InvalidParameterError, "Unknown limited scope value: #{value}" + end + end + def availability_scope(value) case value when 'failing' diff --git a/app/views/admin/instances/index.html.haml b/app/views/admin/instances/index.html.haml index b5f084f880..e21d696eac 100644 --- a/app/views/admin/instances/index.html.haml +++ b/app/views/admin/instances/index.html.haml @@ -15,10 +15,14 @@ .filter-subset %strong= t('admin.instances.moderation.title') %ul - %li= filter_link_to t('admin.instances.moderation.all'), limited: nil - - - unless limited_federation_mode? - %li= filter_link_to t('admin.instances.moderation.limited'), limited: '1' + - if limited_federation_mode? + %li= filter_link_to t('admin.instances.moderation.allowed'), status: nil + - else + %li= filter_link_to t('admin.instances.moderation.all'), status: nil + %li= filter_link_to t('admin.instances.moderation.not_limited'), status: 'not_limited' + %li= filter_link_to t('admin.instances.moderation.noop'), status: 'noop' + %li= filter_link_to t('admin.instances.moderation.silenced'), status: 'silenced' + %li= filter_link_to t('admin.instances.moderation.suspended'), status: 'suspended' .filter-subset %strong= t('admin.instances.availability.title') @@ -27,22 +31,20 @@ %li= filter_link_to t('admin.instances.delivery.failing'), availability: 'failing' %li= filter_link_to t('admin.instances.delivery.unavailable'), availability: 'unavailable' -- unless limited_federation_mode? - = form_with url: admin_instances_url, method: :get, class: :simple_form do |form| - .fields-group - - InstanceFilter::KEYS.each do |key| - = form.hidden_field key, value: params[key] if params[key].present? += form_with url: admin_instances_url, method: :get, class: :simple_form do |form| + .fields-group + - InstanceFilter::KEYS.each do |key| + = form.hidden_field key, value: params[key] if params[key].present? - - %i(by_domain).each do |key| - .input.string.optional - = form.text_field key, - value: params[key], - class: 'string optional', - placeholder: I18n.t("admin.instances.#{key}") + .input.string.optional + = form.text_field :by_domain, + value: params[:by_domain], + class: 'string optional', + placeholder: t('admin.instances.by_domain') - .actions - %button.button= t('admin.accounts.search') - = link_to t('admin.accounts.reset'), admin_instances_path, class: 'button negative' + .actions + %button.button= t('admin.accounts.search') + = link_to t('admin.accounts.reset'), admin_instances_path, class: 'button negative' %hr.spacer/ diff --git a/config/locales/en.yml b/config/locales/en.yml index 2971fe1f25..c379b53198 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -539,7 +539,11 @@ en: other: "%{count} known accounts" moderation: all: All - limited: Limited + allowed: Allowed + noop: Filtered + not_limited: Not Limited + silenced: Silenced + suspended: Suspended title: Moderation private_comment: Private comment public_comment: Public comment diff --git a/spec/controllers/admin/instances_controller_spec.rb b/spec/controllers/admin/instances_controller_spec.rb index 1e65373e1f..2bb3e74d81 100644 --- a/spec/controllers/admin/instances_controller_spec.rb +++ b/spec/controllers/admin/instances_controller_spec.rb @@ -34,6 +34,20 @@ RSpec.describe Admin::InstancesController do expect(response).to have_http_status(200) end + describe 'outdated filter parameters' do + it 'redirect to status suspended when just limited is set' do + get :index, params: { limited: 1 } + + expect(response).to redirect_to admin_instances_path({ status: :suspended }) + end + + it 'retains other filters when redirecting if limited is set' do + get :index, params: { limited: 1, availability: 'failing' } + + expect(response).to redirect_to admin_instances_path({ status: :suspended, availability: 'failing' }) + end + end + def instance_directory_links response.parsed_body.css('div.directory__tag a') end