From 216b85b053d091306e3311a21f5b050f70a75130 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 14 Dec 2020 09:06:34 +0100 Subject: Fix performance on instances list in admin UI (#15282) - Reduce duplicate queries - Remove n+1 queries - Add accounts count to detailed view - Add separate action log entry for updating existing domain blocks --- db/migrate/20201206004238_create_instances.rb | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 db/migrate/20201206004238_create_instances.rb (limited to 'db/migrate') diff --git a/db/migrate/20201206004238_create_instances.rb b/db/migrate/20201206004238_create_instances.rb new file mode 100644 index 000000000..a4b866894 --- /dev/null +++ b/db/migrate/20201206004238_create_instances.rb @@ -0,0 +1,9 @@ +class CreateInstances < ActiveRecord::Migration[5.2] + def change + create_view :instances, materialized: true + + # To be able to refresh the view concurrently, + # at least one unique index is required + safety_assured { add_index :instances, :domain, unique: true } + end +end -- cgit From 1390cc194bd07b85fe36e31a0cab22981315974d Mon Sep 17 00:00:00 2001 From: ThibG Date: Tue, 15 Dec 2020 04:30:15 +0100 Subject: Add indication to admin UI of whether a report has been forwarded (#13237) * Add indication to admin UI of whether a report has been forwarded * Rework how forwarded status is displayed Co-authored-by: Claire --- app/models/report.rb | 1 + app/services/report_service.rb | 3 ++- app/views/admin/reports/index.html.haml | 4 ++++ app/views/admin/reports/show.html.haml | 10 ++++++++++ config/locales/en.yml | 2 ++ db/migrate/20200309150742_add_forwarded_to_reports.rb | 5 +++++ db/schema.rb | 1 + 7 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20200309150742_add_forwarded_to_reports.rb (limited to 'db/migrate') diff --git a/app/models/report.rb b/app/models/report.rb index f31bcfd2e..cd08120e4 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -14,6 +14,7 @@ # target_account_id :bigint(8) not null # assigned_account_id :bigint(8) # uri :string +# forwarded :boolean # class Report < ApplicationRecord diff --git a/app/services/report_service.rb b/app/services/report_service.rb index 1e955c1e7..9d9c7d6c9 100644 --- a/app/services/report_service.rb +++ b/app/services/report_service.rb @@ -24,7 +24,8 @@ class ReportService < BaseService target_account: @target_account, status_ids: @status_ids, comment: @comment, - uri: @options[:uri] + uri: @options[:uri], + forwarded: ActiveModel::Type::Boolean.new.cast(@options[:forward]) ) end diff --git a/app/views/admin/reports/index.html.haml b/app/views/admin/reports/index.html.haml index bb441380e..721c55f71 100644 --- a/app/views/admin/reports/index.html.haml +++ b/app/views/admin/reports/index.html.haml @@ -59,6 +59,10 @@ = fa_icon('camera') = report.media_attachments.count + - if report.forwarded? + ยท + = t('admin.reports.forwarded_to', domain: target_account.domain) + .report-card__summary__item__assigned - if report.assigned_account.present? = admin_account_link_to report.assigned_account diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml index 2681419ca..b060c553f 100644 --- a/app/views/admin/reports/show.html.haml +++ b/app/views/admin/reports/show.html.haml @@ -46,6 +46,16 @@ %td{ colspan: 2 } - if @report.action_taken? = table_link_to 'envelope-open', t('admin.reports.reopen'), admin_report_path(@report, outcome: 'reopen'), method: :put + - unless @report.target_account.local? + %tr + %th= t('admin.reports.forwarded') + %td{ colspan: 3 } + - if @report.forwarded.nil? + \- + - elsif @report.forwarded? + = t('simple_form.yes') + - else + = t('simple_form.no') - if !@report.action_taken_by_account.nil? %tr %th= t('admin.reports.action_taken_by') diff --git a/config/locales/en.yml b/config/locales/en.yml index 114f86fd1..3ff01ac86 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -517,6 +517,8 @@ en: comment: none: None created_at: Reported + forwarded: Forwarded + forwarded_to: Forwarded to %{domain} mark_as_resolved: Mark as resolved mark_as_unresolved: Mark as unresolved notes: diff --git a/db/migrate/20200309150742_add_forwarded_to_reports.rb b/db/migrate/20200309150742_add_forwarded_to_reports.rb new file mode 100644 index 000000000..df278240b --- /dev/null +++ b/db/migrate/20200309150742_add_forwarded_to_reports.rb @@ -0,0 +1,5 @@ +class AddForwardedToReports < ActiveRecord::Migration[5.2] + def change + add_column :reports, :forwarded, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index 2f9d369be..55822a4b3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -717,6 +717,7 @@ ActiveRecord::Schema.define(version: 2020_12_06_004238) do t.bigint "target_account_id", null: false t.bigint "assigned_account_id" t.string "uri" + t.boolean "forwarded" t.index ["account_id"], name: "index_reports_on_account_id" t.index ["target_account_id"], name: "index_reports_on_target_account_id" end -- cgit From 8a95867693dfe072241d5ddcd0ba7ed8546eab1e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 18 Dec 2020 08:30:41 +0100 Subject: Add option to obfuscate domain name in public list of domain blocks (#15355) - Replace the middle of the domain with * characters (except for periods) - Add SHA-256 digest of the domain name in tooltip --- app/controllers/admin/domain_blocks_controller.rb | 4 ++-- app/models/domain_block.rb | 20 ++++++++++++++++++++ app/views/about/_domain_blocks.html.haml | 2 +- app/views/admin/domain_blocks/edit.html.haml | 3 +++ app/views/admin/domain_blocks/new.html.haml | 3 +++ config/locales/en.yml | 2 ++ .../20201218054746_add_obfuscate_to_domain_blocks.rb | 15 +++++++++++++++ db/schema.rb | 3 ++- 8 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 db/migrate/20201218054746_add_obfuscate_to_domain_blocks.rb (limited to 'db/migrate') diff --git a/app/controllers/admin/domain_blocks_controller.rb b/app/controllers/admin/domain_blocks_controller.rb index 6a5b41a74..ba927b04a 100644 --- a/app/controllers/admin/domain_blocks_controller.rb +++ b/app/controllers/admin/domain_blocks_controller.rb @@ -74,11 +74,11 @@ module Admin end def update_params - params.require(:domain_block).permit(:severity, :reject_media, :reject_reports, :private_comment, :public_comment) + params.require(:domain_block).permit(:severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate) end def resource_params - params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_reports, :private_comment, :public_comment) + params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate) end end end diff --git a/app/models/domain_block.rb b/app/models/domain_block.rb index 829d7583b..bba04c603 100644 --- a/app/models/domain_block.rb +++ b/app/models/domain_block.rb @@ -12,6 +12,7 @@ # reject_reports :boolean default(FALSE), not null # private_comment :text # public_comment :text +# obfuscate :boolean default(FALSE), not null # class DomainBlock < ApplicationRecord @@ -73,4 +74,23 @@ class DomainBlock < ApplicationRecord scope = suspend? ? accounts.where(suspended_at: created_at) : accounts.where(silenced_at: created_at) scope.count end + + def public_domain + return domain unless obfuscate? + + length = domain.size + visible_ratio = length / 4 + + domain.chars.map.with_index do |chr, i| + if i > visible_ratio && i < length - visible_ratio && chr != '.' + '*' + else + chr + end + end.join + end + + def domain_digest + Digest::SHA256.hexdigest(domain) + end end diff --git a/app/views/about/_domain_blocks.html.haml b/app/views/about/_domain_blocks.html.haml index e0c5df41d..35a30f16e 100644 --- a/app/views/about/_domain_blocks.html.haml +++ b/app/views/about/_domain_blocks.html.haml @@ -7,6 +7,6 @@ - domain_blocks.each do |domain_block| %tr %td.nowrap - %span{ title: domain_block.domain }= domain_block.domain + %span{ title: "SHA-256: #{domain_block.domain_digest}" }= domain_block.public_domain %td = domain_block.public_comment if display_blocks_rationale? diff --git a/app/views/admin/domain_blocks/edit.html.haml b/app/views/admin/domain_blocks/edit.html.haml index d5868070a..6fe2edc82 100644 --- a/app/views/admin/domain_blocks/edit.html.haml +++ b/app/views/admin/domain_blocks/edit.html.haml @@ -20,6 +20,9 @@ .fields-group = f.input :reject_reports, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_reports'), hint: I18n.t('admin.domain_blocks.reject_reports_hint') + .fields-group + = f.input :obfuscate, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.obfuscate'), hint: I18n.t('admin.domain_blocks.obfuscate_hint') + .field-group = f.input :private_comment, wrapper: :with_label, label: I18n.t('admin.domain_blocks.private_comment'), hint: t('admin.domain_blocks.private_comment_hint'), rows: 6 diff --git a/app/views/admin/domain_blocks/new.html.haml b/app/views/admin/domain_blocks/new.html.haml index f503f9b77..8b78f71f2 100644 --- a/app/views/admin/domain_blocks/new.html.haml +++ b/app/views/admin/domain_blocks/new.html.haml @@ -20,6 +20,9 @@ .fields-group = f.input :reject_reports, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_reports'), hint: I18n.t('admin.domain_blocks.reject_reports_hint') + .fields-group + = f.input :obfuscate, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.obfuscate'), hint: I18n.t('admin.domain_blocks.obfuscate_hint') + .field-group = f.input :private_comment, wrapper: :with_label, label: I18n.t('admin.domain_blocks.private_comment'), hint: t('admin.domain_blocks.private_comment_hint'), rows: 6 diff --git a/config/locales/en.yml b/config/locales/en.yml index 83f75b28f..e91f4344f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -402,6 +402,8 @@ en: silence: Silence suspend: Suspend title: New domain block + obfuscate: Obfuscate domain name + obfuscate_hint: Partially obfuscate the domain name in the list if advertising the list of domain limitations is enabled private_comment: Private comment private_comment_hint: Comment about this domain limitation for internal use by the moderators. public_comment: Public comment diff --git a/db/migrate/20201218054746_add_obfuscate_to_domain_blocks.rb b/db/migrate/20201218054746_add_obfuscate_to_domain_blocks.rb new file mode 100644 index 000000000..26f4ddb85 --- /dev/null +++ b/db/migrate/20201218054746_add_obfuscate_to_domain_blocks.rb @@ -0,0 +1,15 @@ +require Rails.root.join('lib', 'mastodon', 'migration_helpers') + +class AddObfuscateToDomainBlocks < ActiveRecord::Migration[5.2] + include Mastodon::MigrationHelpers + + disable_ddl_transaction! + + def up + safety_assured { add_column_with_default :domain_blocks, :obfuscate, :boolean, default: false, allow_null: false } + end + + def down + remove_column :domain_blocks, :obfuscate + end +end diff --git a/db/schema.rb b/db/schema.rb index 55822a4b3..18bf1d4ca 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_12_06_004238) do +ActiveRecord::Schema.define(version: 2020_12_18_054746) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -360,6 +360,7 @@ ActiveRecord::Schema.define(version: 2020_12_06_004238) do t.boolean "reject_reports", default: false, null: false t.text "private_comment" t.text "public_comment" + t.boolean "obfuscate", default: false, null: false t.index ["domain"], name: "index_domain_blocks_on_domain", unique: true end -- cgit From 052249588b77fe3d8e29658076eb385f64511d6b Mon Sep 17 00:00:00 2001 From: ThibG Date: Fri, 18 Dec 2020 17:51:24 +0100 Subject: Fix old migration script not being able to run if it fails midway (#15361) * Fix old migration script not being able to run if it fails midway Improve the robustness of a migration script likely to fail because of database corruption so it can run again once database corruptions are fixed. * Display a specific error message in case of index corruption Co-authored-by: Eugen Rochko Co-authored-by: Claire --- ...164023_add_fixed_lowercase_index_to_accounts.rb | 26 +++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'db/migrate') diff --git a/db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb b/db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb index c5688681f..c3aa8e33c 100644 --- a/db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb +++ b/db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb @@ -1,10 +1,30 @@ class AddFixedLowercaseIndexToAccounts < ActiveRecord::Migration[5.2] disable_ddl_transaction! + class CorruptionError < StandardError + def cause + nil + end + + def backtrace + [] + end + end + def up - rename_index :accounts, 'index_accounts_on_username_and_domain_lower', 'old_index_accounts_on_username_and_domain_lower' unless index_name_exists?(:accounts, 'old_index_accounts_on_username_and_domain_lower') - add_index :accounts, "lower (username), COALESCE(lower(domain), '')", name: 'index_accounts_on_username_and_domain_lower', unique: true, algorithm: :concurrently - remove_index :accounts, name: 'old_index_accounts_on_username_and_domain_lower' + if index_name_exists?(:accounts, 'old_index_accounts_on_username_and_domain_lower') && index_name_exists?(:accounts, 'index_accounts_on_username_and_domain_lower') + remove_index :accounts, name: 'index_accounts_on_username_and_domain_lower' + elsif index_name_exists?(:accounts, 'index_accounts_on_username_and_domain_lower') + rename_index :accounts, 'index_accounts_on_username_and_domain_lower', 'old_index_accounts_on_username_and_domain_lower' + end + + begin + add_index :accounts, "lower (username), COALESCE(lower(domain), '')", name: 'index_accounts_on_username_and_domain_lower', unique: true, algorithm: :concurrently + rescue ActiveRecord::RecordNotUnique + raise CorruptionError, 'Migration failed because of index corruption, see https://docs.joinmastodon.org/admin/troubleshooting/index-corruption/#fixing' + end + + remove_index :accounts, name: 'old_index_accounts_on_username_and_domain_lower' if index_name_exists?(:accounts, 'old_index_accounts_on_username_and_domain_lower') end def down -- cgit