about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFire Demon <firedemon@creature.cafe>2020-09-10 04:44:26 -0500
committerFire Demon <firedemon@creature.cafe>2020-09-10 04:52:56 -0500
commit346aa6566206c6a86371883e736984d1a14012dd (patch)
tree4166ab8422ccf490deba3376bc4a1d32cb62926a
parent4b97e1cb4e06b7e3afefb39b7f774de9160fca02 (diff)
[Moderation, Privacy] Ask remote servers to purge local account content when defederating
-rw-r--r--app/services/block_domain_service.rb1
-rw-r--r--app/services/defederate_account_serivice.rb38
-rw-r--r--app/services/defederate_domain_service.rb11
-rw-r--r--app/services/unallow_domain_service.rb3
-rw-r--r--app/workers/account_defederation_worker.rb11
-rw-r--r--app/workers/domain_defederation_worker.rb11
-rw-r--r--lib/mastodon/domains_cli.rb5
7 files changed, 79 insertions, 1 deletions
diff --git a/app/services/block_domain_service.rb b/app/services/block_domain_service.rb
index dc23ef8d8..d3f7cbc4d 100644
--- a/app/services/block_domain_service.rb
+++ b/app/services/block_domain_service.rb
@@ -23,6 +23,7 @@ class BlockDomainService < BaseService
     if domain_block.silence?
       silence_accounts!
     elsif domain_block.suspend?
+      DefederateDomainService.new.call(domain_block.domain)
       suspend_accounts!
     end
 
diff --git a/app/services/defederate_account_serivice.rb b/app/services/defederate_account_serivice.rb
new file mode 100644
index 000000000..5d9cc1597
--- /dev/null
+++ b/app/services/defederate_account_serivice.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+class DefederateAccountService < BaseService
+  include Payloadable
+
+  def call(account, domains)
+    @account = account
+    @domains = domains
+
+    return if account.blank? || !account.local? || domains.blank?
+
+    distribute_delete_actor!
+  end
+
+  private
+
+  def distribute_delete_actor!
+    ActivityPub::DeliveryWorker.push_bulk(delivery_inboxes) do |inbox_url|
+      [delete_actor_json, @account.id, inbox_url]
+    end
+
+    ActivityPub::LowPriorityDeliveryWorker.push_bulk(low_priority_delivery_inboxes) do |inbox_url|
+      [delete_actor_json, @account.id, inbox_url]
+    end
+  end
+
+  def delete_actor_json
+    @delete_actor_json ||= Oj.dump(serialize_payload(@account, ActivityPub::DeleteActorSerializer, signer: @account))
+  end
+
+  def delivery_inboxes
+    @delivery_inboxes ||= @account.followers.where(domain: @domains).inboxes
+  end
+
+  def low_priority_delivery_inboxes
+    Account.where(domain: @domains).inboxes - delivery_inboxes
+  end
+end
diff --git a/app/services/defederate_domain_service.rb b/app/services/defederate_domain_service.rb
new file mode 100644
index 000000000..d40f88e3f
--- /dev/null
+++ b/app/services/defederate_domain_service.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class DefederateDomainService < BaseService
+  def call(domains)
+    return if domains.blank?
+
+    Account.local.find_each do |account|
+      DefederateAccountService.new.call(account, domains)
+    end
+  end
+end
diff --git a/app/services/unallow_domain_service.rb b/app/services/unallow_domain_service.rb
index fc5260761..0d2d8f254 100644
--- a/app/services/unallow_domain_service.rb
+++ b/app/services/unallow_domain_service.rb
@@ -4,7 +4,7 @@ class UnallowDomainService < BaseService
   include DomainControlHelper
 
   def call(domain_allow)
-    suspend_accounts!(domain_allow.domain) if whitelist_mode?
+    suspend_accounts!(domain_allow.domain)
 
     domain_allow.destroy
   end
@@ -12,6 +12,7 @@ class UnallowDomainService < BaseService
   private
 
   def suspend_accounts!(domain)
+    DomainDefederationWorker.perform_async(domain)
     Account.where(domain: domain).in_batches.update_all(suspended_at: Time.now.utc)
     AfterUnallowDomainWorker.perform_async(domain)
   end
diff --git a/app/workers/account_defederation_worker.rb b/app/workers/account_defederation_worker.rb
new file mode 100644
index 000000000..150ed8ff0
--- /dev/null
+++ b/app/workers/account_defederation_worker.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class AccountDefederationWorker
+  include Sidekiq::Worker
+
+  def perform(account_id, domains)
+    DefederateAccountService.new.call(Account.find(account_id), domains)
+  rescue ActiveRecord::RecordNotFound
+    true
+  end
+end
diff --git a/app/workers/domain_defederation_worker.rb b/app/workers/domain_defederation_worker.rb
new file mode 100644
index 000000000..ec49d0265
--- /dev/null
+++ b/app/workers/domain_defederation_worker.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class DomainDefederationWorker
+  include Sidekiq::Worker
+
+  def perform(domains)
+    DefederateDomainService.new.call(domains)
+  rescue ActiveRecord::RecordNotFound
+    true
+  end
+end
diff --git a/lib/mastodon/domains_cli.rb b/lib/mastodon/domains_cli.rb
index 558737c27..1b2fa0dd8 100644
--- a/lib/mastodon/domains_cli.rb
+++ b/lib/mastodon/domains_cli.rb
@@ -41,6 +41,11 @@ module Mastodon
         end
       end
 
+      say('Scheduling account defederation messages to be sent to target domains...')
+      DefederateDomainService.new.call(scope.pluck(:domain).uniq)
+      say('Done!', :green)
+
+      say('Deleting accounts from target domains...')
       processed, = parallelize_with_progress(scope) do |account|
         SuspendAccountService.new.call(account, reserve_username: false, skip_side_effects: true) unless options[:dry_run]
       end