use a scheduled task to batch domain policy changes + revert `29643fd6` to avoid accidentally dosing servers when multiple users block a domain

master
multiple creatures 2019-08-30 22:03:46 -05:00
parent 60c449e1d7
commit 3b276d268f
17 changed files with 28 additions and 79 deletions

View File

@ -14,6 +14,7 @@ module Admin
resource_params[:domain].strip! if resource_params[:domain].present?
resource_params[:reason].strip! if resource_params[:reason].present?
resource_pararms[:processing] = true
@domain_block = DomainBlock.new(resource_params)
existing_domain_block = resource_params[:domain].present? ? DomainBlock.find_by(domain: resource_params[:domain].strip) : nil
@ -23,7 +24,6 @@ module Admin
end
if @domain_block.save
DomainBlockWorker.perform_async(@domain_block.id)
log_action :create, @domain_block
redirect_to admin_instance_path(id: @domain_block.domain, limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg')
else
@ -46,11 +46,10 @@ module Admin
def update
return destroy unless resource_params[:undo].to_i.zero?
resource_params[:reason].strip! if resource_params[:reason].present?
resource_pararms[:processing] = true
authorize @domain_block, :update?
@domain_block.update(resource_params.except(:domain, :undo))
changed = @domain_block.changed
if @domain_block.save
DomainBlockWorker.perform_async(@domain_block.id) if (changed & %w(severity force_sensitive reject_media reject_unknown)).any?
log_action :update, @domain_block
flash[:notice] = I18n.t('admin.domain_blocks.updated_msg')
else

View File

@ -23,7 +23,6 @@ class Api::V1::DomainBlocksController < Api::BaseController
def destroy
current_account.unblock_domain!(domain_block_params[:domain])
AfterAccountDomainUnblockWorker.perform_async(current_account.id, domain_block_params[:domain])
render_empty
end

View File

@ -110,7 +110,6 @@ module ModerationHelper
Admin::ActionLog.create(account: @account, action: :create, target: domain_block)
user_friendly_action_log(@account, :create, domain_block)
DomainBlockWorker.perform_async(domain_block.id)
else
domain_block = DomainBlock.find_by(domain: domain)
return false if domain_block.nil?

View File

@ -13,6 +13,7 @@
# force_sensitive :boolean default(FALSE), not null
# reason :text
# reject_unknown :boolean default(FALSE), not null
# processing :boolean default(TRUE), not null
#
class DomainBlock < ApplicationRecord
@ -26,6 +27,7 @@ class DomainBlock < ApplicationRecord
delegate :count, to: :accounts, prefix: true
scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) }
scope :unprocessed, -> { where(processing: true) }
def self.blocked?(domain)
where(domain: domain, severity: :suspend).exists?

View File

@ -31,6 +31,7 @@
# edited :boolean
# imported :boolean
# origin :string
# tsv :tsvector
# boostable :boolean
# reject_replies :boolean
#

View File

@ -27,7 +27,6 @@ class ActivityPub::ProcessAccountService < BaseService
create_account
end
update_account
update_account_domain_blocks if is_new_account
process_tags
process_attachments
else
@ -121,11 +120,6 @@ class ActivityPub::ProcessAccountService < BaseService
VerifyAccountLinksWorker.perform_async(@account.id)
end
def update_account_domain_blocks
return if @account.domain.nil? || @account.local?
UpdateAccountDomainBlocksWorker.perform_async(@account.id)
end
def actor_type
if @json['type'].is_a?(Array)
@json['type'].find { |type| ActivityPub::FetchRemoteAccountService::SUPPORTED_TYPES.include?(type) }

View File

@ -10,7 +10,6 @@ class AfterBlockDomainFromAccountService < BaseService
reject_existing_followers!
reject_pending_follow_requests!
block_accounts!
end
private
@ -27,12 +26,6 @@ class AfterBlockDomainFromAccountService < BaseService
end
end
def block_accounts!
Account.where(domain: @domain).find_each do |blocked_account|
BlockService.new.call(@account, blocked_account)
end
end
def reject_follow!(follow)
follow.destroy

View File

@ -1,18 +0,0 @@
# frozen_string_literal: true
class AfterUnblockDomainFromAccountService < BaseService
def call(account, domain)
@account = account
@domain = domain
unblock_accounts!
end
private
def unblock_accounts!
@account.blocking.where(domain: @domain).find_each do |blocked_account|
UnblockService.new.call(@account, blocked_account)
end
end
end

View File

@ -10,6 +10,8 @@ class BlockDomainService < BaseService
remove_existing_block!
process_domain_block!
invalidate_association_caches!
@domain_block.update(processing: false)
end
private

View File

@ -1,19 +0,0 @@
# frozen_string_literal: true
class UpdateAccountDomainBlocksService < BaseService
def call(account)
@account = account
@domain = account.domain
block_where_domain_blocked!
end
private
def block_where_domain_blocked!
account_ids = AccountDomainBlock.distinct.where(domain: @domain).pluck(:account_id)
Account.where(id: account_ids).find_each do |blocked_by|
BlockService.new.call(blocked_by, @account)
end
end
end

View File

@ -1,11 +0,0 @@
# frozen_string_literal: true
class AfterAccountDomainUnblockWorker
include Sidekiq::Worker
def perform(account_id, domain)
AfterUnblockDomainFromAccountService.new.call(Account.find(account_id), domain)
rescue ActiveRecord::RecordNotFound
true
end
end

View File

@ -0,0 +1,11 @@
# frozen_string_literal: true
class Scheduler::DomainPolicyScheduler
include Sidekiq::Worker
sidekiq_options unique: :until_executed
def perform
DomainBlock.unprocessed.find_each { |policy| BlockDomainService.new.call(policy) }
end
end

View File

@ -59,7 +59,6 @@ class Scheduler::JanitorScheduler
blocks.each do |entry|
next unless domain_exists?(entry[:domain])
block = DomainBlock.create!(entry)
DomainBlockWorker.perform_async(block)
Admin::ActionLog.create(account: @account, action: :create, target: block)
user_friendly_action_log(@account, :create, block)
end

View File

@ -1,11 +0,0 @@
# frozen_string_literal: true
class UpdateAccountDomainBlocksWorker
include Sidekiq::Worker
def perform(account_id)
UpdateAccountDomainBlocksService.new.call(Account.find(account_id))
rescue ActiveRecord::RecordNotFound
true
end
end

View File

@ -15,6 +15,9 @@
boosts_scheduler:
every: '1m'
class: Scheduler::BoostsScheduler
domain_policy_scheduler:
every: '15m'
class: Scheduler::DomainPolicyScheduler
janitor_scheduler:
every: '1h'
class: Scheduler::JanitorScheduler

View File

@ -0,0 +1,5 @@
class AddProcessingToDomainBlocks < ActiveRecord::Migration[5.2]
def change
safety_assured { add_column :domain_blocks, :processing, :boolean, null: false, default: true }
end
end

View File

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2019_08_15_232125) do
ActiveRecord::Schema.define(version: 2019_08_31_022432) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -278,6 +278,7 @@ ActiveRecord::Schema.define(version: 2019_08_15_232125) do
t.boolean "force_sensitive", default: false, null: false
t.text "reason"
t.boolean "reject_unknown", default: false, null: false
t.boolean "processing", default: true, null: false
t.index ["domain"], name: "index_domain_blocks_on_domain", unique: true
end