Skip to content

Commit

Permalink
Add public blocks to /about/blocks (mastodon#11298)
Browse files Browse the repository at this point in the history
* Add automatic blocklist display in /about/blocks

Inspired by https://github.com/Gargron/mastodon.social-misc

* Add admin option to set who can see instance blocks

* Normalize locales files

* Rename “Sandbox” to “Silence” for consistency

* Disable /about/blocks when in whitelist mode

* Optionally display rationale for domain blocks

* Only display domain blocks that have user-facing limitations, and order them

* Redesign table of blocked domains to better handle long domain names and rationales

* Change domain blocks ordering now that rationales aren't displayed right away

* Only show explanation for block severities actually in use

* Reword instance block explanations and add disclaimer for public fetch mode
  • Loading branch information
ClearlyClaire authored and hiyuki2578 committed Oct 2, 2019
1 parent fc5684b commit 18629b4
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 5 deletions.
34 changes: 32 additions & 2 deletions app/controllers/about_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
class AboutController < ApplicationController
layout 'public'

before_action :require_open_federation!, only: [:show, :more]
before_action :require_open_federation!, only: [:show, :more, :blocks]
before_action :check_blocklist_enabled, only: [:blocks]
before_action :authenticate_user!, only: [:blocks], if: :blocklist_account_required?
before_action :set_body_classes, only: :show
before_action :set_instance_presenter
before_action :set_expires_in
before_action :set_expires_in, only: [:show, :more, :terms]

skip_before_action :require_functional!, only: [:more, :terms]

Expand All @@ -18,12 +20,40 @@ def more

def terms; end

def blocks
@show_rationale = Setting.show_domain_blocks_rationale == 'all'
@show_rationale |= Setting.show_domain_blocks_rationale == 'users' && !current_user.nil? && current_user.functional?
@blocks = DomainBlock.with_user_facing_limitations.order('(CASE severity WHEN 0 THEN 1 WHEN 1 THEN 2 WHEN 2 THEN 0 END), reject_media, domain').to_a
end

private

def require_open_federation!
not_found if whitelist_mode?
end

def check_blocklist_enabled
not_found if Setting.show_domain_blocks == 'disabled'
end

def blocklist_account_required?
Setting.show_domain_blocks == 'users'
end

def block_severity_text(block)
if block.severity == 'suspend'
I18n.t('domain_blocks.suspension')
else
limitations = []
limitations << I18n.t('domain_blocks.media_block') if block.reject_media?
limitations << I18n.t('domain_blocks.silence') if block.severity == 'silence'
limitations.join(', ')
end
end

helper_method :block_severity_text
helper_method :public_fetch_mode?

def new_user
User.new.tap do |user|
user.build_account
Expand Down
9 changes: 9 additions & 0 deletions app/javascript/packs/public.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,15 @@ function main() {
return false;
});

delegate(document, '.blocks-table button.icon-button', 'click', function(e) {
e.preventDefault();

const classList = this.firstElementChild.classList;
classList.toggle('fa-chevron-down');
classList.toggle('fa-chevron-up');
this.parentElement.parentElement.nextElementSibling.classList.toggle('hidden');
});

delegate(document, '.modal-button', 'click', e => {
e.preventDefault();

Expand Down
67 changes: 67 additions & 0 deletions app/javascript/styles/mastodon/tables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,70 @@ a.table-action-link {
}
}
}

.blocks-table {
width: 100%;
max-width: 100%;
border-spacing: 0;
border-collapse: collapse;
table-layout: fixed;
border: 1px solid darken($ui-base-color, 8%);

thead {
border: 1px solid darken($ui-base-color, 8%);
background: darken($ui-base-color, 4%);
font-weight: 500;

th.severity-column {
width: 120px;
}

th.button-column {
width: 23px;
}
}

tbody > tr {
border: 1px solid darken($ui-base-color, 8%);
border-bottom: 0;
background: darken($ui-base-color, 4%);

&:hover {
background: darken($ui-base-color, 2%);
}

&.even {
background: $ui-base-color;

&:hover {
background: lighten($ui-base-color, 2%);
}
}

&.rationale {
background: lighten($ui-base-color, 4%);
border-top: 0;

&:hover {
background: lighten($ui-base-color, 6%);
}

&.hidden {
display: none;
}
}

td:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
}

th,
td {
padding: 8px;
line-height: 18px;
vertical-align: top;
text-align: left;
}
}
1 change: 1 addition & 0 deletions app/models/domain_block.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class DomainBlock < ApplicationRecord
delegate :count, to: :accounts, prefix: true

scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) }
scope :with_user_facing_limitations, -> { where(severity: [:silence, :suspend]).or(where(reject_media: true)) }

class << self
def suspend?(domain)
Expand Down
4 changes: 4 additions & 0 deletions app/models/form/admin_settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class Form::AdminSettings
mascot
spam_check_enabled
trends
show_domain_blocks
show_domain_blocks_rationale
).freeze

BOOLEAN_KEYS = %i(
Expand Down Expand Up @@ -60,6 +62,8 @@ class Form::AdminSettings
validates :site_contact_email, :site_contact_username, presence: true
validates :site_contact_username, existing_username: true
validates :bootstrap_timeline_accounts, existing_username: { multiple: true }
validates :show_domain_blocks, inclusion: { in: %w(disabled users all) }
validates :show_domain_blocks_rationale, inclusion: { in: %w(disabled users all) }

def initialize(_attributes = {})
super
Expand Down
48 changes: 48 additions & 0 deletions app/views/about/blocks.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
- content_for :page_title do
= t('domain_blocks.title', instance: site_hostname)

.grid
.column-0
.box-widget.rich-formatting
%h2= t('domain_blocks.blocked_domains')
%p= t('domain_blocks.description', instance: site_hostname)
.table-wrapper
%table.blocks-table
%thead
%tr
%th= t('domain_blocks.domain')
%th.severity-column= t('domain_blocks.severity')
- if @show_rationale
%th.button-column
%tbody
- if @blocks.empty?
%tr
%td{ colspan: @show_rationale ? 3 : 2 }= t('domain_blocks.no_domain_blocks')
- else
- @blocks.each_with_index do |block, i|
%tr{ class: i % 2 == 0 ? 'even': nil }
%td{ title: block.domain }= block.domain
%td= block_severity_text(block)
- if @show_rationale
%td
- if block.public_comment.present?
%button.icon-button{ title: t('domain_blocks.show_rationale'), 'aria-label' => t('domain_blocks.show_rationale') }
= fa_icon 'chevron-down fw', 'aria-hidden' => true
- if @show_rationale
- if block.public_comment.present?
%tr.rationale.hidden
%td{ colspan: 3 }= block.public_comment.presence
%h2= t('domain_blocks.severity_legend.title')
- if @blocks.any? { |block| block.reject_media? }
%h3= t('domain_blocks.media_block')
%p= t('domain_blocks.severity_legend.media_block')
- if @blocks.any? { |block| block.severity == 'silence' }
%h3= t('domain_blocks.silence')
%p= t('domain_blocks.severity_legend.silence')
- if @blocks.any? { |block| block.severity == 'suspend' }
%h3= t('domain_blocks.suspension')
%p= t('domain_blocks.severity_legend.suspension')
- if public_fetch_mode?
%p= t('domain_blocks.severity_legend.suspension_disclaimer')
.column-1
= render 'application/sidebar'
6 changes: 6 additions & 0 deletions app/views/admin/settings/edit.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@
.fields-group
= f.input :min_invite_role, wrapper: :with_label, collection: %i(disabled user moderator admin), label: t('admin.settings.registrations.min_invite_role.title'), label_method: lambda { |role| role == :disabled ? t('admin.settings.registrations.min_invite_role.disabled') : t("admin.accounts.roles.#{role}") }, include_blank: false, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'

.fields-row
.fields-row__column.fields-row__column-6.fields-group
= f.input :show_domain_blocks, wrapper: :with_label, collection: %i(disabled users all), label: t('admin.settings.domain_blocks.title'), label_method: lambda { |value| t("admin.settings.domain_blocks.#{value}") }, include_blank: false, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
.fields-row__column.fields-row__column-6.fields-group
= f.input :show_domain_blocks_rationale, wrapper: :with_label, collection: %i(disabled users all), label: t('admin.settings.domain_blocks_rationale.title'), label_method: lambda { |value| t("admin.settings.domain_blocks.#{value}") }, include_blank: false, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'

.fields-group
= f.input :closed_registrations_message, as: :text, wrapper: :with_block_label, label: t('admin.settings.registrations.closed_message.title'), hint: t('admin.settings.registrations.closed_message.desc_html'), input_html: { rows: 8 }
= f.input :site_extended_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description_extended.title'), hint: t('admin.settings.site_description_extended.desc_html'), input_html: { rows: 8 } unless whitelist_mode?
Expand Down
24 changes: 24 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,13 @@ en:
custom_css:
desc_html: Modify the look with CSS loaded on every page
title: Custom CSS
domain_blocks:
all: To everyone
disabled: To no one
title: Show domain blocks
users: To logged-in local users
domain_blocks_rationale:
title: Show rationale
hero:
desc_html: Displayed on the frontpage. At least 600x100px recommended. When not set, falls back to server thumbnail
title: Hero image
Expand Down Expand Up @@ -631,6 +638,23 @@ en:
people:
one: "%{count} person"
other: "%{count} people"
domain_blocks:
blocked_domains: List of limited and blocked domains
description: This is the list of servers that %{instance} limits or reject federation with.
domain: Domain
media_block: Media block
no_domain_blocks: "(No domain blocks)"
severity: Severity
severity_legend:
media_block: Media files coming from the server are neither fetched, stored, or displayed to the user.
silence: Accounts from silenced servers can be found, followed and interacted with, but their toots will not appear in the public timelines, and notifications from them will not reach local users who are not following them.
suspension: No content from suspended servers is stored or displayed, nor is any content sent to them. Interactions from suspended servers are ignored.
suspension_disclaimer: Suspended servers may occasionally retrieve public content from this server.
title: Severities
show_rationale: Show rationale
silence: Silence
suspension: Suspension
title: "%{instance} List of blocked instances"
domain_validator:
invalid_domain: is not a valid domain name
errors:
Expand Down
7 changes: 4 additions & 3 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -423,9 +423,10 @@

get '/web/(*any)', to: 'home#index', as: :web

get '/about', to: 'about#show'
get '/about/more', to: 'about#more'
get '/terms', to: 'about#terms'
get '/about', to: 'about#show'
get '/about/more', to: 'about#more'
get '/about/blocks', to: 'about#blocks'
get '/terms', to: 'about#terms'

root 'home#index'

Expand Down
2 changes: 2 additions & 0 deletions config/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ defaults: &defaults
peers_api_enabled: true
show_known_fediverse_at_about_page: true
spam_check_enabled: true
show_domain_blocks: 'disabled'
show_domain_blocks_rationale: 'disabled'

development:
<<: *defaults
Expand Down

0 comments on commit 18629b4

Please sign in to comment.